Issue 1:
MWE:

struct Foo
a::Vector{Any}
end

xs = Vector{Union{Nothing, T} where T}([2, 3])
Foo(xs)

this leads to "illegal hardware instruction" on both Julia 1.5.2 and julia 1.6.0-DEV.1184

The lowered code and typed code seems fine, but code_llvm gives

julia> @code_llvm Foo(xs)
; @ REPL[1]:2 within `Foo'
define [1 x {}*] @julia_Foo_491({}* nonnull align 16 dereferenceable(40) %0) {
top:
call void @llvm.trap()
unreachable
}

also I find that the result of convert and Vector{Any}(x) does not match, though convert actually (should) calls Vector{Any} to convert xs to Vector{Any} (https://github.com/JuliaLang/julia/blob/master/base/array.jl#L554), e.g

julia> convert(Vector{Any}, xs)
2-element Vector{Union{Nothing, T} where T}:
2
3

julia> Vector{Any}(xs)
2-element Vector{Any}:
2
3

This is because Julia thinks xs of type Vector{Union{Nothing, T} where T} is a Vector{Any}, so convert returns xs directly but I'm not sure if this is actually true...

Issue 2:
LOAD_PATH

In #25455, I tried to keep things as compatible as possible, leaving the contents of LOAD_PATH as a superset of what was in it previously. The current default contents is:

[ [ Base.CurrentEnv(),
Base.NamedEnv("v0.7.0"),
Base.NamedEnv("v0.7"),
Base.NamedEnv("v0"),
Base.NamedEnv("default"),
Base.NamedEnv("v0.7", create=true) ],
Base.Pkg.dir,
"/Users/stefan/projects/julia/usr/local/share/julia/site/v0.7",
"/Users/stefan/projects/julia/usr/share/julia/site/v0.7" ]

This has the effect of looking in the following places:

The first of the following which succeeds:

parent directories of the current working directory with a Project.toml file, if any

joinpath(DEPOT_PATH[1], "environments", "v0.7.0") if it exists

joinpath(DEPOT_PATH[1], "environments", "v0.7") if it exists

joinpath(DEPOT_PATH[1], "environments", "v0") if it exists

joinpath(DEPOT_PATH[1], "environments", "default") if it exists

joinpath(DEPOT_PATH[1], "environments", "v0.7") even if it doesn't exist

The Pkg2 package directory indicated by JULIA_PKGDIR

The local site package directory (architecture-specific) – currently not created by default

The site package directory (architecture-independent) – this is where stdlib packages live

The first entry can be replaced and number of items by setting the JULIA_LOAD_PATH environment variable. The other three LOAD_PATH entries are added no matter what you do, which is not ideal since we would like for users to be able to control their load path entirely. However, that does mean that if the user does not include the stdlib environment in their load path, they will not be able to use stdlib packages.

The second entry is a legacy thing that allows us to continue loading Pkg2-installed packages. We should deprecate this whenever we replace Pkg2 with Pkg3: at that point, we can have a DeprecatedEnv loader that allows this to continue working but prints a warning message if the target directory actually exists. That way people can keep using Pkg2-installed packages during the 0.7 transition, but they'll get a warning that they should reinstall packages using Pkg3.

DEPOT_PATH

The new code loading system separates how to resolve what package names mean from where to look for installed versions of packages. The LOAD_PATH is involved in deciding what import Foo means in various contexts. A package name can mean one thing in your code while meaning a different thing to each of your dependencies; this is essential in Pkg3 since there is no longer a single global namespace of package names: METADATA is replaced with a federated system of package registries, which can be public or private.

Once the identity and version of Foo is resolved by looking in the LOAD_PATH, finding the code for that version of the package is a separate step, which involves looking through the DEPOT_PATH in the packages directory of each until an installed copy of the package is found (or isn't). Currently, the DEPOT_PATH defaults to only containing joinpath(homedir(), ".julia") – i.e. your "home depot" (I did not anticipate this pun when choosing the name "depot" but there it is). However, we'll want to support looking for installed packages in multiple different places, most likely including:

You home depot, typically ~/.julia

A platform-specific shared system directory, e.g. /usr/local/share/julia/site/

A platform-independent shared system directory, e.g. /usr/share/julia/site/

The standard library for the Julia binary you're using, maybe /usr/share/julia/stdlib?

I'm decreasingly sure what these paths should be so input and thoughts would be helpful here.

LOAD_PATH defaults

Since "what" is now addressed by LOAD_PATH while "where" is addressed by DEPOT_PATH, we generally want far fewer things in LOAD_PATH. In fact, when testing a project, you generally only want that project's environment – and maybe a a "test environment" – in the LOAD_PATH so that if you try to load anything that isn't recorded and identified in the project's Project.toml file, you'll get a failure. However, it's handy when developing to be able to augment the project environment with tools like debuggers, profilers, Revise.jl, etc.

What should be in the default load path in 1.0? Maybe just this:

[ [ Base.CurrentEnv(),
Base.NamedEnv("v0.7.0"),
Base.NamedEnv("v0.7"),
Base.NamedEnv("v0"),
Base.NamedEnv("default"),
Base.NamedEnv("v0.7", create=true) ],
"/usr/share/julia/stdlib" ]

If you start Julia in a project directory the, you'll only be able to load the project's dependencies and standard libraries – which, incidentally should probably also be recorded as project dependencies. Or maybe we want something more like this:

[ Base.CurrentEnv(),
"/usr/share/julia/stdlib",
[ Base.NamedEnv("v0.7.0"),
Base.NamedEnv("v0.7"),
Base.NamedEnv("v0"),
Base.NamedEnv("default"),
Base.NamedEnv("v0.7", create=true) ] ]

That would mean that you can load whatever's in the current project if it exists, the standard library, and whatever's in your default named environment, which would presumably include all your dev tools and other favorite packages.

Controlling the LOAD_PATH

We'll want some convenient ways to manipulate the LOAD_PATH, e.g. to run with only the current environment visible. Design ideas are welcomed here, but my thought was that we'd have some command-line options to control this such as:

julia --env=@ # just the current environment
julia --env=@devtools # just the named "devtools" environment
julia --env+@devtools # add the named "devtools" environment to the load path

It's a little weird to call this option --env when it manipulates the LOAD_PATH but maybe that's ok. We could also write it julia --load-path=... but I still like --env as a name for this since the LOAD_PATH is a list of environments to look in for dependencies.