mirror of
https://github.com/rust-lang/rust.git
synced 2025-06-05 03:38:29 +00:00
Merge branch 'master' into rusty-hermit, resolve conflicts
This commit is contained in:
commit
d349e32fc7
@ -128,6 +128,14 @@ the master branch to your feature branch.
|
|||||||
Also, please make sure that fixup commits are squashed into other related
|
Also, please make sure that fixup commits are squashed into other related
|
||||||
commits with meaningful commit messages.
|
commits with meaningful commit messages.
|
||||||
|
|
||||||
|
GitHub allows [closing issues using keywords][closing-keywords]. This feature
|
||||||
|
should be used to keep the issue tracker tidy. However, it is generally preferred
|
||||||
|
to put the "closes #123" text in the PR description rather than the issue commit;
|
||||||
|
particularly during rebasing, citing the issue number in the commit can "spam"
|
||||||
|
the issue in question.
|
||||||
|
|
||||||
|
[closing-keywords]: https://help.github.com/en/articles/closing-issues-using-keywords
|
||||||
|
|
||||||
Please make sure your pull request is in compliance with Rust's style
|
Please make sure your pull request is in compliance with Rust's style
|
||||||
guidelines by running
|
guidelines by running
|
||||||
|
|
||||||
|
12
Cargo.lock
12
Cargo.lock
@ -556,9 +556,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "compiletest_rs"
|
name = "compiletest_rs"
|
||||||
version = "0.3.24"
|
version = "0.3.25"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "676a74b493d50ac33cacd83fd536597e6b52c0b46b9856f7b9c809d82fef4ac0"
|
checksum = "f75b10a18fb53549fdd090846eb01c7f8593914494d1faabc4d3005c436e417a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"diff",
|
"diff",
|
||||||
"filetime",
|
"filetime",
|
||||||
@ -1297,9 +1297,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hashbrown"
|
name = "hashbrown"
|
||||||
version = "0.6.1"
|
version = "0.6.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6587d09be37fb98a11cb08b9000a3f592451c1b1b613ca69d949160e313a430a"
|
checksum = "3cd9867f119b19fecb08cd5c326ad4488d7a1da4bf75b4d95d71db742525aaab"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
"autocfg",
|
||||||
"compiler_builtins",
|
"compiler_builtins",
|
||||||
@ -3494,6 +3494,7 @@ dependencies = [
|
|||||||
"rustc_data_structures",
|
"rustc_data_structures",
|
||||||
"rustc_errors",
|
"rustc_errors",
|
||||||
"rustc_interface",
|
"rustc_interface",
|
||||||
|
"rustc_lint",
|
||||||
"rustc_metadata",
|
"rustc_metadata",
|
||||||
"rustc_mir",
|
"rustc_mir",
|
||||||
"rustc_plugin",
|
"rustc_plugin",
|
||||||
@ -4156,9 +4157,8 @@ dependencies = [
|
|||||||
"core",
|
"core",
|
||||||
"dlmalloc",
|
"dlmalloc",
|
||||||
"fortanix-sgx-abi",
|
"fortanix-sgx-abi",
|
||||||
"hashbrown 0.6.1",
|
"hashbrown 0.6.2",
|
||||||
"hermit-abi",
|
"hermit-abi",
|
||||||
"libc",
|
|
||||||
"panic_abort",
|
"panic_abort",
|
||||||
"panic_unwind",
|
"panic_unwind",
|
||||||
"profiler_builtins",
|
"profiler_builtins",
|
||||||
|
@ -443,6 +443,7 @@ impl<'a> Builder<'a> {
|
|||||||
dist::Rustc,
|
dist::Rustc,
|
||||||
dist::DebuggerScripts,
|
dist::DebuggerScripts,
|
||||||
dist::Std,
|
dist::Std,
|
||||||
|
dist::RustcDev,
|
||||||
dist::Analysis,
|
dist::Analysis,
|
||||||
dist::Src,
|
dist::Src,
|
||||||
dist::PlainSourceTarball,
|
dist::PlainSourceTarball,
|
||||||
|
@ -55,6 +55,7 @@ impl Step for Std {
|
|||||||
cargo,
|
cargo,
|
||||||
args(builder.kind),
|
args(builder.kind),
|
||||||
&libstd_stamp(builder, compiler, target),
|
&libstd_stamp(builder, compiler, target),
|
||||||
|
vec![],
|
||||||
true);
|
true);
|
||||||
|
|
||||||
let libdir = builder.sysroot_libdir(compiler, target);
|
let libdir = builder.sysroot_libdir(compiler, target);
|
||||||
@ -103,6 +104,7 @@ impl Step for Rustc {
|
|||||||
cargo,
|
cargo,
|
||||||
args(builder.kind),
|
args(builder.kind),
|
||||||
&librustc_stamp(builder, compiler, target),
|
&librustc_stamp(builder, compiler, target),
|
||||||
|
vec![],
|
||||||
true);
|
true);
|
||||||
|
|
||||||
let libdir = builder.sysroot_libdir(compiler, target);
|
let libdir = builder.sysroot_libdir(compiler, target);
|
||||||
@ -155,6 +157,7 @@ impl Step for CodegenBackend {
|
|||||||
cargo,
|
cargo,
|
||||||
args(builder.kind),
|
args(builder.kind),
|
||||||
&codegen_backend_stamp(builder, compiler, target, backend),
|
&codegen_backend_stamp(builder, compiler, target, backend),
|
||||||
|
vec![],
|
||||||
true);
|
true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -199,6 +202,7 @@ impl Step for Rustdoc {
|
|||||||
cargo,
|
cargo,
|
||||||
args(builder.kind),
|
args(builder.kind),
|
||||||
&rustdoc_stamp(builder, compiler, target),
|
&rustdoc_stamp(builder, compiler, target),
|
||||||
|
vec![],
|
||||||
true);
|
true);
|
||||||
|
|
||||||
let libdir = builder.sysroot_libdir(compiler, target);
|
let libdir = builder.sysroot_libdir(compiler, target);
|
||||||
|
@ -69,7 +69,7 @@ impl Step for Std {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.ensure(StartupObjects { compiler, target });
|
let mut target_deps = builder.ensure(StartupObjects { compiler, target });
|
||||||
|
|
||||||
let compiler_to_use = builder.compiler_for(compiler.stage, compiler.host, target);
|
let compiler_to_use = builder.compiler_for(compiler.stage, compiler.host, target);
|
||||||
if compiler_to_use != compiler {
|
if compiler_to_use != compiler {
|
||||||
@ -91,7 +91,7 @@ impl Step for Std {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
copy_third_party_objects(builder, &compiler, target);
|
target_deps.extend(copy_third_party_objects(builder, &compiler, target).into_iter());
|
||||||
|
|
||||||
let mut cargo = builder.cargo(compiler, Mode::Std, target, "build");
|
let mut cargo = builder.cargo(compiler, Mode::Std, target, "build");
|
||||||
std_cargo(builder, &compiler, target, &mut cargo);
|
std_cargo(builder, &compiler, target, &mut cargo);
|
||||||
@ -102,6 +102,7 @@ impl Step for Std {
|
|||||||
cargo,
|
cargo,
|
||||||
vec![],
|
vec![],
|
||||||
&libstd_stamp(builder, compiler, target),
|
&libstd_stamp(builder, compiler, target),
|
||||||
|
target_deps,
|
||||||
false);
|
false);
|
||||||
|
|
||||||
builder.ensure(StdLink {
|
builder.ensure(StdLink {
|
||||||
@ -113,9 +114,22 @@ impl Step for Std {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Copies third pary objects needed by various targets.
|
/// Copies third pary objects needed by various targets.
|
||||||
fn copy_third_party_objects(builder: &Builder<'_>, compiler: &Compiler, target: Interned<String>) {
|
fn copy_third_party_objects(builder: &Builder<'_>, compiler: &Compiler, target: Interned<String>)
|
||||||
|
-> Vec<PathBuf>
|
||||||
|
{
|
||||||
let libdir = builder.sysroot_libdir(*compiler, target);
|
let libdir = builder.sysroot_libdir(*compiler, target);
|
||||||
|
|
||||||
|
let mut target_deps = vec![];
|
||||||
|
|
||||||
|
let mut copy_and_stamp = |sourcedir: &Path, name: &str| {
|
||||||
|
let target = libdir.join(name);
|
||||||
|
builder.copy(
|
||||||
|
&sourcedir.join(name),
|
||||||
|
&target,
|
||||||
|
);
|
||||||
|
target_deps.push(target);
|
||||||
|
};
|
||||||
|
|
||||||
// Copies the crt(1,i,n).o startup objects
|
// Copies the crt(1,i,n).o startup objects
|
||||||
//
|
//
|
||||||
// Since musl supports fully static linking, we can cross link for it even
|
// Since musl supports fully static linking, we can cross link for it even
|
||||||
@ -123,19 +137,13 @@ fn copy_third_party_objects(builder: &Builder<'_>, compiler: &Compiler, target:
|
|||||||
// files. As those shipped with glibc won't work, copy the ones provided by
|
// files. As those shipped with glibc won't work, copy the ones provided by
|
||||||
// musl so we have them on linux-gnu hosts.
|
// musl so we have them on linux-gnu hosts.
|
||||||
if target.contains("musl") {
|
if target.contains("musl") {
|
||||||
|
let srcdir = builder.musl_root(target).unwrap().join("lib");
|
||||||
for &obj in &["crt1.o", "crti.o", "crtn.o"] {
|
for &obj in &["crt1.o", "crti.o", "crtn.o"] {
|
||||||
builder.copy(
|
copy_and_stamp(&srcdir, obj);
|
||||||
&builder.musl_root(target).unwrap().join("lib").join(obj),
|
|
||||||
&libdir.join(obj),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
} else if target.ends_with("-wasi") {
|
} else if target.ends_with("-wasi") {
|
||||||
for &obj in &["crt1.o"] {
|
let srcdir = builder.wasi_root(target).unwrap().join("lib/wasm32-wasi");
|
||||||
builder.copy(
|
copy_and_stamp(&srcdir, "crt1.o");
|
||||||
&builder.wasi_root(target).unwrap().join("lib/wasm32-wasi").join(obj),
|
|
||||||
&libdir.join(obj),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copies libunwind.a compiled to be linked wit x86_64-fortanix-unknown-sgx.
|
// Copies libunwind.a compiled to be linked wit x86_64-fortanix-unknown-sgx.
|
||||||
@ -145,11 +153,11 @@ fn copy_third_party_objects(builder: &Builder<'_>, compiler: &Compiler, target:
|
|||||||
// which is provided by std for this target.
|
// which is provided by std for this target.
|
||||||
if target == "x86_64-fortanix-unknown-sgx" {
|
if target == "x86_64-fortanix-unknown-sgx" {
|
||||||
let src_path_env = "X86_FORTANIX_SGX_LIBS";
|
let src_path_env = "X86_FORTANIX_SGX_LIBS";
|
||||||
let obj = "libunwind.a";
|
|
||||||
let src = env::var(src_path_env).expect(&format!("{} not found in env", src_path_env));
|
let src = env::var(src_path_env).expect(&format!("{} not found in env", src_path_env));
|
||||||
let src = Path::new(&src).join(obj);
|
copy_and_stamp(Path::new(&src), "libunwind.a");
|
||||||
builder.copy(&src, &libdir.join(obj));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
target_deps
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Configure cargo to compile the standard library, adding appropriate env vars
|
/// Configure cargo to compile the standard library, adding appropriate env vars
|
||||||
@ -306,7 +314,7 @@ pub struct StartupObjects {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Step for StartupObjects {
|
impl Step for StartupObjects {
|
||||||
type Output = ();
|
type Output = Vec<PathBuf>;
|
||||||
|
|
||||||
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
|
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
|
||||||
run.path("src/rtstartup")
|
run.path("src/rtstartup")
|
||||||
@ -325,13 +333,15 @@ impl Step for StartupObjects {
|
|||||||
/// They don't require any library support as they're just plain old object
|
/// They don't require any library support as they're just plain old object
|
||||||
/// files, so we just use the nightly snapshot compiler to always build them (as
|
/// files, so we just use the nightly snapshot compiler to always build them (as
|
||||||
/// no other compilers are guaranteed to be available).
|
/// no other compilers are guaranteed to be available).
|
||||||
fn run(self, builder: &Builder<'_>) {
|
fn run(self, builder: &Builder<'_>) -> Vec<PathBuf> {
|
||||||
let for_compiler = self.compiler;
|
let for_compiler = self.compiler;
|
||||||
let target = self.target;
|
let target = self.target;
|
||||||
if !target.contains("windows-gnu") {
|
if !target.contains("windows-gnu") {
|
||||||
return
|
return vec![]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mut target_deps = vec![];
|
||||||
|
|
||||||
let src_dir = &builder.src.join("src/rtstartup");
|
let src_dir = &builder.src.join("src/rtstartup");
|
||||||
let dst_dir = &builder.native_dir(target).join("rtstartup");
|
let dst_dir = &builder.native_dir(target).join("rtstartup");
|
||||||
let sysroot_dir = &builder.sysroot_libdir(for_compiler, target);
|
let sysroot_dir = &builder.sysroot_libdir(for_compiler, target);
|
||||||
@ -350,7 +360,9 @@ impl Step for StartupObjects {
|
|||||||
.arg(src_file));
|
.arg(src_file));
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.copy(dst_file, &sysroot_dir.join(file.to_string() + ".o"));
|
let target = sysroot_dir.join(file.to_string() + ".o");
|
||||||
|
builder.copy(dst_file, &target);
|
||||||
|
target_deps.push(target);
|
||||||
}
|
}
|
||||||
|
|
||||||
for obj in ["crt2.o", "dllcrt2.o"].iter() {
|
for obj in ["crt2.o", "dllcrt2.o"].iter() {
|
||||||
@ -358,8 +370,12 @@ impl Step for StartupObjects {
|
|||||||
builder.cc(target),
|
builder.cc(target),
|
||||||
target,
|
target,
|
||||||
obj);
|
obj);
|
||||||
builder.copy(&src, &sysroot_dir.join(obj));
|
let target = sysroot_dir.join(obj);
|
||||||
|
builder.copy(&src, &target);
|
||||||
|
target_deps.push(target);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
target_deps
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -437,6 +453,7 @@ impl Step for Rustc {
|
|||||||
cargo,
|
cargo,
|
||||||
vec![],
|
vec![],
|
||||||
&librustc_stamp(builder, compiler, target),
|
&librustc_stamp(builder, compiler, target),
|
||||||
|
vec![],
|
||||||
false);
|
false);
|
||||||
|
|
||||||
builder.ensure(RustcLink {
|
builder.ensure(RustcLink {
|
||||||
@ -585,7 +602,7 @@ impl Step for CodegenBackend {
|
|||||||
|
|
||||||
let tmp_stamp = out_dir.join(".tmp.stamp");
|
let tmp_stamp = out_dir.join(".tmp.stamp");
|
||||||
|
|
||||||
let files = run_cargo(builder, cargo, vec![], &tmp_stamp, false);
|
let files = run_cargo(builder, cargo, vec![], &tmp_stamp, vec![], false);
|
||||||
if builder.config.dry_run {
|
if builder.config.dry_run {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -941,6 +958,7 @@ pub fn run_cargo(builder: &Builder<'_>,
|
|||||||
cargo: Cargo,
|
cargo: Cargo,
|
||||||
tail_args: Vec<String>,
|
tail_args: Vec<String>,
|
||||||
stamp: &Path,
|
stamp: &Path,
|
||||||
|
additional_target_deps: Vec<PathBuf>,
|
||||||
is_check: bool)
|
is_check: bool)
|
||||||
-> Vec<PathBuf>
|
-> Vec<PathBuf>
|
||||||
{
|
{
|
||||||
@ -1057,6 +1075,7 @@ pub fn run_cargo(builder: &Builder<'_>,
|
|||||||
deps.push((path_to_add.into(), false));
|
deps.push((path_to_add.into(), false));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
deps.extend(additional_target_deps.into_iter().map(|d| (d, false)));
|
||||||
deps.sort();
|
deps.sort();
|
||||||
let mut new_contents = Vec::new();
|
let mut new_contents = Vec::new();
|
||||||
for (dep, proc_macro) in deps.iter() {
|
for (dep, proc_macro) in deps.iter() {
|
||||||
|
@ -637,6 +637,28 @@ impl Step for DebuggerScripts {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn skip_host_target_lib(builder: &Builder<'_>, compiler: Compiler) -> bool {
|
||||||
|
// The only true set of target libraries came from the build triple, so
|
||||||
|
// let's reduce redundant work by only producing archives from that host.
|
||||||
|
if compiler.host != builder.config.build {
|
||||||
|
builder.info("\tskipping, not a build host");
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Copy stamped files into an image's `target/lib` directory.
|
||||||
|
fn copy_target_libs(builder: &Builder<'_>, target: &str, image: &Path, stamp: &Path) {
|
||||||
|
let dst = image.join("lib/rustlib").join(target).join("lib");
|
||||||
|
t!(fs::create_dir_all(&dst));
|
||||||
|
for (path, host) in builder.read_stamp_file(stamp) {
|
||||||
|
if !host || builder.config.build == target {
|
||||||
|
builder.copy(&path, &dst.join(path.file_name().unwrap()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)]
|
#[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)]
|
||||||
pub struct Std {
|
pub struct Std {
|
||||||
pub compiler: Compiler,
|
pub compiler: Compiler,
|
||||||
@ -667,44 +689,19 @@ impl Step for Std {
|
|||||||
let target = self.target;
|
let target = self.target;
|
||||||
|
|
||||||
let name = pkgname(builder, "rust-std");
|
let name = pkgname(builder, "rust-std");
|
||||||
|
let archive = distdir(builder).join(format!("{}-{}.tar.gz", name, target));
|
||||||
// The only true set of target libraries came from the build triple, so
|
if skip_host_target_lib(builder, compiler) {
|
||||||
// let's reduce redundant work by only producing archives from that host.
|
return archive;
|
||||||
if compiler.host != builder.config.build {
|
|
||||||
builder.info("\tskipping, not a build host");
|
|
||||||
return distdir(builder).join(format!("{}-{}.tar.gz", name, target));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// We want to package up as many target libraries as possible
|
builder.ensure(compile::Std { compiler, target });
|
||||||
// for the `rust-std` package, so if this is a host target we
|
|
||||||
// depend on librustc and otherwise we just depend on libtest.
|
|
||||||
if builder.hosts.iter().any(|t| t == target) {
|
|
||||||
builder.ensure(compile::Rustc { compiler, target });
|
|
||||||
} else {
|
|
||||||
builder.ensure(compile::Std { compiler, target });
|
|
||||||
}
|
|
||||||
|
|
||||||
let image = tmpdir(builder).join(format!("{}-{}-image", name, target));
|
let image = tmpdir(builder).join(format!("{}-{}-image", name, target));
|
||||||
let _ = fs::remove_dir_all(&image);
|
let _ = fs::remove_dir_all(&image);
|
||||||
|
|
||||||
let dst = image.join("lib/rustlib").join(target);
|
let compiler_to_use = builder.compiler_for(compiler.stage, compiler.host, target);
|
||||||
t!(fs::create_dir_all(&dst));
|
let stamp = compile::libstd_stamp(builder, compiler_to_use, target);
|
||||||
let mut src = builder.sysroot_libdir(compiler, target).to_path_buf();
|
copy_target_libs(builder, &target, &image, &stamp);
|
||||||
src.pop(); // Remove the trailing /lib folder from the sysroot_libdir
|
|
||||||
builder.cp_filtered(&src, &dst, &|path| {
|
|
||||||
if let Some(name) = path.file_name().and_then(|s| s.to_str()) {
|
|
||||||
if name == builder.config.rust_codegen_backends_dir.as_str() {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if name == "bin" {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if name.contains("LLVM") {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
true
|
|
||||||
});
|
|
||||||
|
|
||||||
let mut cmd = rust_installer(builder);
|
let mut cmd = rust_installer(builder);
|
||||||
cmd.arg("generate")
|
cmd.arg("generate")
|
||||||
@ -723,7 +720,73 @@ impl Step for Std {
|
|||||||
let _time = timeit(builder);
|
let _time = timeit(builder);
|
||||||
builder.run(&mut cmd);
|
builder.run(&mut cmd);
|
||||||
builder.remove_dir(&image);
|
builder.remove_dir(&image);
|
||||||
distdir(builder).join(format!("{}-{}.tar.gz", name, target))
|
archive
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)]
|
||||||
|
pub struct RustcDev {
|
||||||
|
pub compiler: Compiler,
|
||||||
|
pub target: Interned<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Step for RustcDev {
|
||||||
|
type Output = PathBuf;
|
||||||
|
const DEFAULT: bool = true;
|
||||||
|
const ONLY_HOSTS: bool = true;
|
||||||
|
|
||||||
|
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
|
||||||
|
run.path("rustc-dev")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn make_run(run: RunConfig<'_>) {
|
||||||
|
run.builder.ensure(RustcDev {
|
||||||
|
compiler: run.builder.compiler_for(
|
||||||
|
run.builder.top_stage,
|
||||||
|
run.builder.config.build,
|
||||||
|
run.target,
|
||||||
|
),
|
||||||
|
target: run.target,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn run(self, builder: &Builder<'_>) -> PathBuf {
|
||||||
|
let compiler = self.compiler;
|
||||||
|
let target = self.target;
|
||||||
|
|
||||||
|
let name = pkgname(builder, "rustc-dev");
|
||||||
|
let archive = distdir(builder).join(format!("{}-{}.tar.gz", name, target));
|
||||||
|
if skip_host_target_lib(builder, compiler) {
|
||||||
|
return archive;
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.ensure(compile::Rustc { compiler, target });
|
||||||
|
|
||||||
|
let image = tmpdir(builder).join(format!("{}-{}-image", name, target));
|
||||||
|
let _ = fs::remove_dir_all(&image);
|
||||||
|
|
||||||
|
let compiler_to_use = builder.compiler_for(compiler.stage, compiler.host, target);
|
||||||
|
let stamp = compile::librustc_stamp(builder, compiler_to_use, target);
|
||||||
|
copy_target_libs(builder, &target, &image, &stamp);
|
||||||
|
|
||||||
|
let mut cmd = rust_installer(builder);
|
||||||
|
cmd.arg("generate")
|
||||||
|
.arg("--product-name=Rust")
|
||||||
|
.arg("--rel-manifest-dir=rustlib")
|
||||||
|
.arg("--success-message=Rust-is-ready-to-develop.")
|
||||||
|
.arg("--image-dir").arg(&image)
|
||||||
|
.arg("--work-dir").arg(&tmpdir(builder))
|
||||||
|
.arg("--output-dir").arg(&distdir(builder))
|
||||||
|
.arg(format!("--package-name={}-{}", name, target))
|
||||||
|
.arg(format!("--component-name=rustc-dev-{}", target))
|
||||||
|
.arg("--legacy-manifest-dirs=rustlib,cargo");
|
||||||
|
|
||||||
|
builder.info(&format!("Dist rustc-dev stage{} ({} -> {})",
|
||||||
|
compiler.stage, &compiler.host, target));
|
||||||
|
let _time = timeit(builder);
|
||||||
|
builder.run(&mut cmd);
|
||||||
|
builder.remove_dir(&image);
|
||||||
|
archive
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1137,6 +1137,7 @@ impl Build {
|
|||||||
pub fn copy(&self, src: &Path, dst: &Path) {
|
pub fn copy(&self, src: &Path, dst: &Path) {
|
||||||
if self.config.dry_run { return; }
|
if self.config.dry_run { return; }
|
||||||
self.verbose_than(1, &format!("Copy {:?} to {:?}", src, dst));
|
self.verbose_than(1, &format!("Copy {:?} to {:?}", src, dst));
|
||||||
|
if src == dst { return; }
|
||||||
let _ = fs::remove_file(&dst);
|
let _ = fs::remove_file(&dst);
|
||||||
let metadata = t!(src.symlink_metadata());
|
let metadata = t!(src.symlink_metadata());
|
||||||
if metadata.file_type().is_symlink() {
|
if metadata.file_type().is_symlink() {
|
||||||
|
@ -84,6 +84,17 @@ steps:
|
|||||||
condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'), ne(variables['MINGW_URL'],''))
|
condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'), ne(variables['MINGW_URL'],''))
|
||||||
displayName: Download custom MinGW
|
displayName: Download custom MinGW
|
||||||
|
|
||||||
|
# FIXME(#65767): workaround msys bug, step 1
|
||||||
|
- bash: |
|
||||||
|
set -e
|
||||||
|
arch=i686
|
||||||
|
if [ "$MSYS_BITS" = "64" ]; then
|
||||||
|
arch=x86_64
|
||||||
|
fi
|
||||||
|
curl -O https://ci-mirrors.rust-lang.org/rustc/msys2-repo/mingw/$arch/mingw-w64-$arch-ca-certificates-20180409-1-any.pkg.tar.xz
|
||||||
|
condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'))
|
||||||
|
displayName: Download working ca-certificates for msys
|
||||||
|
|
||||||
# Otherwise install MinGW through `pacman`
|
# Otherwise install MinGW through `pacman`
|
||||||
- bash: |
|
- bash: |
|
||||||
set -e
|
set -e
|
||||||
@ -96,6 +107,18 @@ steps:
|
|||||||
condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'), eq(variables['MINGW_URL'],''))
|
condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'), eq(variables['MINGW_URL'],''))
|
||||||
displayName: Download standard MinGW
|
displayName: Download standard MinGW
|
||||||
|
|
||||||
|
# FIXME(#65767): workaround msys bug, step 2
|
||||||
|
- bash: |
|
||||||
|
set -e
|
||||||
|
arch=i686
|
||||||
|
if [ "$MSYS_BITS" = "64" ]; then
|
||||||
|
arch=x86_64
|
||||||
|
fi
|
||||||
|
pacman -U --noconfirm --noprogressbar mingw-w64-$arch-ca-certificates-20180409-1-any.pkg.tar.xz
|
||||||
|
rm mingw-w64-$arch-ca-certificates-20180409-1-any.pkg.tar.xz
|
||||||
|
condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'))
|
||||||
|
displayName: Install working ca-certificates for msys
|
||||||
|
|
||||||
# Make sure we use the native python interpreter instead of some msys equivalent
|
# Make sure we use the native python interpreter instead of some msys equivalent
|
||||||
# one way or another. The msys interpreters seem to have weird path conversions
|
# one way or another. The msys interpreters seem to have weird path conversions
|
||||||
# baked in which break LLVM's build system one way or another, so let's use the
|
# baked in which break LLVM's build system one way or another, so let's use the
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
- [Targets](targets/index.md)
|
- [Targets](targets/index.md)
|
||||||
- [Built-in Targets](targets/built-in.md)
|
- [Built-in Targets](targets/built-in.md)
|
||||||
- [Custom Targets](targets/custom.md)
|
- [Custom Targets](targets/custom.md)
|
||||||
|
- [Known Issues](targets/known-issues.md)
|
||||||
- [Profile-guided Optimization](profile-guided-optimization.md)
|
- [Profile-guided Optimization](profile-guided-optimization.md)
|
||||||
- [Linker-plugin based LTO](linker-plugin-lto.md)
|
- [Linker-plugin based LTO](linker-plugin-lto.md)
|
||||||
- [Contributing to `rustc`](contributing.md)
|
- [Contributing to `rustc`](contributing.md)
|
||||||
|
@ -61,6 +61,8 @@ enabling or disabling a feature.
|
|||||||
To see the valid options and an example of use, run `rustc --print
|
To see the valid options and an example of use, run `rustc --print
|
||||||
target-features`.
|
target-features`.
|
||||||
|
|
||||||
|
Using this flag is unsafe and might result in [undefined runtime behavior](../targets/known-issues.md).
|
||||||
|
|
||||||
## passes
|
## passes
|
||||||
|
|
||||||
This flag can be used to add extra LLVM passes to the compilation.
|
This flag can be used to add extra LLVM passes to the compilation.
|
||||||
|
@ -145,7 +145,7 @@ of print values are:
|
|||||||
target CPU may be selected with the `-C target-cpu=val` flag.
|
target CPU may be selected with the `-C target-cpu=val` flag.
|
||||||
- `target-features` — List of available target features for the current
|
- `target-features` — List of available target features for the current
|
||||||
target. Target features may be enabled with the `-C target-feature=val`
|
target. Target features may be enabled with the `-C target-feature=val`
|
||||||
flag.
|
flag. This flag is unsafe. See [known issues](targets/known-issues.md) for more details.
|
||||||
- `relocation-models` — List of relocation models. Relocation models may be
|
- `relocation-models` — List of relocation models. Relocation models may be
|
||||||
selected with the `-C relocation-model=val` flag.
|
selected with the `-C relocation-model=val` flag.
|
||||||
- `code-models` — List of code models. Code models may be selected with the
|
- `code-models` — List of code models. Code models may be selected with the
|
||||||
|
@ -11,3 +11,9 @@ To compile to a particular target, use the `--target` flag:
|
|||||||
```bash
|
```bash
|
||||||
$ rustc src/main.rs --target=wasm32-unknown-unknown
|
$ rustc src/main.rs --target=wasm32-unknown-unknown
|
||||||
```
|
```
|
||||||
|
## Target Features
|
||||||
|
`x86`, and `ARMv8` are two popular CPU architectures. Their instruction sets form a common baseline across most CPUs. However, some CPUs extend these with custom instruction sets, e.g. vector (`AVX`), bitwise manipulation (`BMI`) or cryptographic (`AES`).
|
||||||
|
|
||||||
|
Developers, who know on which CPUs their compiled code is going to run can choose to add (or remove) CPU specific instruction sets via the `-C target-feature=val` flag.
|
||||||
|
|
||||||
|
Please note, that this flag is generally considered as unsafe. More details can be found in [this section](known-issues.md).
|
||||||
|
13
src/doc/rustc/src/targets/known-issues.md
Normal file
13
src/doc/rustc/src/targets/known-issues.md
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
# Known Issues
|
||||||
|
This section informs you about known "gotchas". Keep in mind, that this section is (and always will be) incomplete. For suggestions and amendments, feel free to [contribute](../contributing.md) to this guide.
|
||||||
|
|
||||||
|
## Target Features
|
||||||
|
Most target-feature problems arise, when mixing code that have the target-feature _enabled_ with code that have it _disabled_. If you want to avoid undefined behavior, it is recommended to build _all code_ (including the standard library and imported crates) with a common set of target-features.
|
||||||
|
|
||||||
|
By default, compiling your code with the `-C target-feature` flag will not recompile the entire standard library and/or imported crates with matching target features. Therefore, target features are generally considered as unsafe. Using `#[target_feature]` on individual functions makes the function unsafe.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
| Target-Feature | Issue | Seen on | Description | Details |
|
||||||
|
| -------------- | ----- | ------- | ----------- | ------- |
|
||||||
|
| `+soft-float` <br> and <br> `-sse` | Segfaults and ABI mismatches | `x86` and `x86-64` | The `x86` and `x86_64` architecture uses SSE registers (aka `xmm`) for floating point operations. Using software emulated floats ("soft-floats") disables usage of `xmm` registers, but parts of Rust's core libraries (e.g. `std::f32` or `std::f64`) are compiled without soft-floats and expect parameters to be passed in `xmm` registers. This leads to ABI mismatches. <br><br> Attempting to compile with disabled SSE causes the same error, too. | [#63466](https://github.com/rust-lang/rust/issues/63466) |
|
@ -207,6 +207,47 @@ impl<B: ?Sized + ToOwned> Clone for Cow<'_, B> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<B: ?Sized + ToOwned> Cow<'_, B> {
|
impl<B: ?Sized + ToOwned> Cow<'_, B> {
|
||||||
|
/// Returns true if the data is borrowed, i.e. if `to_mut` would require additional work.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// #![feature(cow_is_borrowed)]
|
||||||
|
/// use std::borrow::Cow;
|
||||||
|
///
|
||||||
|
/// let cow = Cow::Borrowed("moo");
|
||||||
|
/// assert!(cow.is_borrowed());
|
||||||
|
///
|
||||||
|
/// let bull: Cow<'_, str> = Cow::Owned("...moo?".to_string());
|
||||||
|
/// assert!(!bull.is_borrowed());
|
||||||
|
/// ```
|
||||||
|
#[unstable(feature = "cow_is_borrowed", issue = "65143")]
|
||||||
|
pub fn is_borrowed(&self) -> bool {
|
||||||
|
match *self {
|
||||||
|
Borrowed(_) => true,
|
||||||
|
Owned(_) => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns true if the data is owned, i.e. if `to_mut` would be a no-op.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// #![feature(cow_is_borrowed)]
|
||||||
|
/// use std::borrow::Cow;
|
||||||
|
///
|
||||||
|
/// let cow: Cow<'_, str> = Cow::Owned("moo".to_string());
|
||||||
|
/// assert!(cow.is_owned());
|
||||||
|
///
|
||||||
|
/// let bull = Cow::Borrowed("...moo?");
|
||||||
|
/// assert!(!bull.is_owned());
|
||||||
|
/// ```
|
||||||
|
#[unstable(feature = "cow_is_borrowed", issue = "65143")]
|
||||||
|
pub fn is_owned(&self) -> bool {
|
||||||
|
!self.is_borrowed()
|
||||||
|
}
|
||||||
|
|
||||||
/// Acquires a mutable reference to the owned form of the data.
|
/// Acquires a mutable reference to the owned form of the data.
|
||||||
///
|
///
|
||||||
/// Clones the data if it is not already owned.
|
/// Clones the data if it is not already owned.
|
||||||
|
@ -1817,7 +1817,7 @@ impl<T> VecDeque<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return elem;
|
elem
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Splits the `VecDeque` into two at the given index.
|
/// Splits the `VecDeque` into two at the given index.
|
||||||
|
@ -85,6 +85,7 @@
|
|||||||
#![feature(const_generic_impls_guard)]
|
#![feature(const_generic_impls_guard)]
|
||||||
#![feature(const_generics)]
|
#![feature(const_generics)]
|
||||||
#![feature(const_in_array_repeat_expressions)]
|
#![feature(const_in_array_repeat_expressions)]
|
||||||
|
#![feature(cow_is_borrowed)]
|
||||||
#![feature(dispatch_from_dyn)]
|
#![feature(dispatch_from_dyn)]
|
||||||
#![feature(core_intrinsics)]
|
#![feature(core_intrinsics)]
|
||||||
#![feature(container_error_extra)]
|
#![feature(container_error_extra)]
|
||||||
|
@ -456,7 +456,7 @@ impl str {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return s;
|
s
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts a [`Box<str>`] into a [`String`] without copying or allocating.
|
/// Converts a [`Box<str>`] into a [`String`] without copying or allocating.
|
||||||
|
@ -1638,7 +1638,7 @@ impl<T: ?Sized> Clone for Weak<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Weak { ptr: self.ptr };
|
Weak { ptr: self.ptr }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2025,7 +2025,7 @@ impl<T: ?Sized> Pointer for *const T {
|
|||||||
if f.alternate() {
|
if f.alternate() {
|
||||||
f.flags |= 1 << (FlagV1::SignAwareZeroPad as u32);
|
f.flags |= 1 << (FlagV1::SignAwareZeroPad as u32);
|
||||||
|
|
||||||
if let None = f.width {
|
if f.width.is_none() {
|
||||||
f.width = Some(((mem::size_of::<usize>() * 8) / 4) + 2);
|
f.width = Some(((mem::size_of::<usize>() * 8) / 4) + 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -238,6 +238,33 @@ macro_rules! debug_assert_ne {
|
|||||||
($($arg:tt)*) => (if $crate::cfg!(debug_assertions) { $crate::assert_ne!($($arg)*); })
|
($($arg:tt)*) => (if $crate::cfg!(debug_assertions) { $crate::assert_ne!($($arg)*); })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns whether the given expression matches any of the given patterns.
|
||||||
|
///
|
||||||
|
/// Like in a `match` expression, the pattern can be optionally followed by `if`
|
||||||
|
/// and a guard expression that has access to names bound by the pattern.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// #![feature(matches_macro)]
|
||||||
|
///
|
||||||
|
/// let foo = 'f';
|
||||||
|
/// assert!(matches!(foo, 'A'..='Z' | 'a'..='z'));
|
||||||
|
///
|
||||||
|
/// let bar = Some(4);
|
||||||
|
/// assert!(matches!(bar, Some(x) if x > 2));
|
||||||
|
/// ```
|
||||||
|
#[macro_export]
|
||||||
|
#[unstable(feature = "matches_macro", issue = "65721")]
|
||||||
|
macro_rules! matches {
|
||||||
|
($expression:expr, $( $pattern:pat )|+ $( if $guard: expr )?) => {
|
||||||
|
match $expression {
|
||||||
|
$( $pattern )|+ $( if $guard )? => true,
|
||||||
|
_ => false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Unwraps a result or propagates its error.
|
/// Unwraps a result or propagates its error.
|
||||||
///
|
///
|
||||||
/// The `?` operator was added to replace `try!` and should be used instead.
|
/// The `?` operator was added to replace `try!` and should be used instead.
|
||||||
|
@ -143,13 +143,12 @@ pub fn fast_path<T: RawFloat>(integral: &[u8], fractional: &[u8], e: i64) -> Opt
|
|||||||
/// > not a bound for the true error, but bounds the difference between the approximation z and
|
/// > not a bound for the true error, but bounds the difference between the approximation z and
|
||||||
/// > the best possible approximation that uses p bits of significand.)
|
/// > the best possible approximation that uses p bits of significand.)
|
||||||
pub fn bellerophon<T: RawFloat>(f: &Big, e: i16) -> T {
|
pub fn bellerophon<T: RawFloat>(f: &Big, e: i16) -> T {
|
||||||
let slop;
|
let slop = if f <= &Big::from_u64(T::MAX_SIG) {
|
||||||
if f <= &Big::from_u64(T::MAX_SIG) {
|
|
||||||
// The cases abs(e) < log5(2^N) are in fast_path()
|
// The cases abs(e) < log5(2^N) are in fast_path()
|
||||||
slop = if e >= 0 { 0 } else { 3 };
|
if e >= 0 { 0 } else { 3 }
|
||||||
} else {
|
} else {
|
||||||
slop = if e >= 0 { 1 } else { 4 };
|
if e >= 0 { 1 } else { 4 }
|
||||||
}
|
};
|
||||||
let z = rawfp::big_to_fp(f).mul(&power_of_ten(e)).normalize();
|
let z = rawfp::big_to_fp(f).mul(&power_of_ten(e)).normalize();
|
||||||
let exp_p_n = 1 << (P - T::SIG_BITS as u32);
|
let exp_p_n = 1 << (P - T::SIG_BITS as u32);
|
||||||
let lowbits: i64 = (z.f % exp_p_n) as i64;
|
let lowbits: i64 = (z.f % exp_p_n) as i64;
|
||||||
|
@ -837,9 +837,8 @@ impl<T> Option<T> {
|
|||||||
#[inline]
|
#[inline]
|
||||||
#[stable(feature = "option_entry", since = "1.20.0")]
|
#[stable(feature = "option_entry", since = "1.20.0")]
|
||||||
pub fn get_or_insert_with<F: FnOnce() -> T>(&mut self, f: F) -> &mut T {
|
pub fn get_or_insert_with<F: FnOnce() -> T>(&mut self, f: F) -> &mut T {
|
||||||
match *self {
|
if let None = *self {
|
||||||
None => *self = Some(f()),
|
*self = Some(f());
|
||||||
_ => (),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
match *self {
|
match *self {
|
||||||
|
@ -156,21 +156,21 @@ unsafe extern "C" fn rust_eh_personality(version: c_int,
|
|||||||
if actions as i32 & uw::_UA_SEARCH_PHASE as i32 != 0 {
|
if actions as i32 & uw::_UA_SEARCH_PHASE as i32 != 0 {
|
||||||
match eh_action {
|
match eh_action {
|
||||||
EHAction::None |
|
EHAction::None |
|
||||||
EHAction::Cleanup(_) => return uw::_URC_CONTINUE_UNWIND,
|
EHAction::Cleanup(_) => uw::_URC_CONTINUE_UNWIND,
|
||||||
EHAction::Catch(_) => return uw::_URC_HANDLER_FOUND,
|
EHAction::Catch(_) => uw::_URC_HANDLER_FOUND,
|
||||||
EHAction::Terminate => return uw::_URC_FATAL_PHASE1_ERROR,
|
EHAction::Terminate => uw::_URC_FATAL_PHASE1_ERROR,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
match eh_action {
|
match eh_action {
|
||||||
EHAction::None => return uw::_URC_CONTINUE_UNWIND,
|
EHAction::None => uw::_URC_CONTINUE_UNWIND,
|
||||||
EHAction::Cleanup(lpad) |
|
EHAction::Cleanup(lpad) |
|
||||||
EHAction::Catch(lpad) => {
|
EHAction::Catch(lpad) => {
|
||||||
uw::_Unwind_SetGR(context, UNWIND_DATA_REG.0, exception_object as uintptr_t);
|
uw::_Unwind_SetGR(context, UNWIND_DATA_REG.0, exception_object as uintptr_t);
|
||||||
uw::_Unwind_SetGR(context, UNWIND_DATA_REG.1, 0);
|
uw::_Unwind_SetGR(context, UNWIND_DATA_REG.1, 0);
|
||||||
uw::_Unwind_SetIP(context, lpad);
|
uw::_Unwind_SetIP(context, lpad);
|
||||||
return uw::_URC_INSTALL_CONTEXT;
|
uw::_URC_INSTALL_CONTEXT
|
||||||
}
|
}
|
||||||
EHAction::Terminate => return uw::_URC_FATAL_PHASE2_ERROR,
|
EHAction::Terminate => uw::_URC_FATAL_PHASE2_ERROR,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,7 @@ pub fn payload() -> *mut u8 {
|
|||||||
|
|
||||||
pub unsafe fn cleanup(ptr: *mut u8) -> Box<dyn Any + Send> {
|
pub unsafe fn cleanup(ptr: *mut u8) -> Box<dyn Any + Send> {
|
||||||
let panic_ctx = Box::from_raw(ptr as *mut PanicData);
|
let panic_ctx = Box::from_raw(ptr as *mut PanicData);
|
||||||
return panic_ctx.data;
|
panic_ctx.data
|
||||||
}
|
}
|
||||||
|
|
||||||
// SEH doesn't support resuming unwinds after calling a landing pad like
|
// SEH doesn't support resuming unwinds after calling a landing pad like
|
||||||
|
@ -59,7 +59,7 @@ use crate::ich::{Fingerprint, StableHashingContext};
|
|||||||
use rustc_data_structures::stable_hasher::{StableHasher, HashStable};
|
use rustc_data_structures::stable_hasher::{StableHasher, HashStable};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
use syntax_pos::symbol::InternedString;
|
use syntax_pos::symbol::Symbol;
|
||||||
use crate::traits;
|
use crate::traits;
|
||||||
use crate::traits::query::{
|
use crate::traits::query::{
|
||||||
CanonicalProjectionGoal, CanonicalTyGoal, CanonicalTypeOpAscribeUserTypeGoal,
|
CanonicalProjectionGoal, CanonicalTyGoal, CanonicalTypeOpAscribeUserTypeGoal,
|
||||||
@ -426,7 +426,7 @@ rustc_dep_node_append!([define_dep_nodes!][ <'tcx>
|
|||||||
|
|
||||||
[anon] TraitSelect,
|
[anon] TraitSelect,
|
||||||
|
|
||||||
[] CompileCodegenUnit(InternedString),
|
[] CompileCodegenUnit(Symbol),
|
||||||
|
|
||||||
[eval_always] Analysis(CrateNum),
|
[eval_always] Analysis(CrateNum),
|
||||||
]);
|
]);
|
||||||
|
@ -2045,8 +2045,8 @@ so that a generator can then be constructed:
|
|||||||
async fn bar<T>() -> () {}
|
async fn bar<T>() -> () {}
|
||||||
|
|
||||||
async fn foo() {
|
async fn foo() {
|
||||||
bar::<String>().await;
|
bar::<String>().await;
|
||||||
// ^^^^^^^^ specify type explicitly
|
// ^^^^^^^^ specify type explicitly
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
"##,
|
"##,
|
||||||
@ -2126,6 +2126,84 @@ static X: u32 = 42;
|
|||||||
```
|
```
|
||||||
"##,
|
"##,
|
||||||
|
|
||||||
|
E0728: r##"
|
||||||
|
[`await`] has been used outside [`async`] function or block.
|
||||||
|
|
||||||
|
Erroneous code examples:
|
||||||
|
|
||||||
|
```edition2018,compile_fail,E0728
|
||||||
|
# use std::pin::Pin;
|
||||||
|
# use std::future::Future;
|
||||||
|
# use std::task::{Context, Poll};
|
||||||
|
#
|
||||||
|
# struct WakeOnceThenComplete(bool);
|
||||||
|
#
|
||||||
|
# fn wake_and_yield_once() -> WakeOnceThenComplete {
|
||||||
|
# WakeOnceThenComplete(false)
|
||||||
|
# }
|
||||||
|
#
|
||||||
|
# impl Future for WakeOnceThenComplete {
|
||||||
|
# type Output = ();
|
||||||
|
# fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> {
|
||||||
|
# if self.0 {
|
||||||
|
# Poll::Ready(())
|
||||||
|
# } else {
|
||||||
|
# cx.waker().wake_by_ref();
|
||||||
|
# self.0 = true;
|
||||||
|
# Poll::Pending
|
||||||
|
# }
|
||||||
|
# }
|
||||||
|
# }
|
||||||
|
#
|
||||||
|
fn foo() {
|
||||||
|
wake_and_yield_once().await // `await` is used outside `async` context
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
[`await`] is used to suspend the current computation until the given
|
||||||
|
future is ready to produce a value. So it is legal only within
|
||||||
|
an [`async`] context, like an `async fn` or an `async` block.
|
||||||
|
|
||||||
|
```edition2018
|
||||||
|
# use std::pin::Pin;
|
||||||
|
# use std::future::Future;
|
||||||
|
# use std::task::{Context, Poll};
|
||||||
|
#
|
||||||
|
# struct WakeOnceThenComplete(bool);
|
||||||
|
#
|
||||||
|
# fn wake_and_yield_once() -> WakeOnceThenComplete {
|
||||||
|
# WakeOnceThenComplete(false)
|
||||||
|
# }
|
||||||
|
#
|
||||||
|
# impl Future for WakeOnceThenComplete {
|
||||||
|
# type Output = ();
|
||||||
|
# fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> {
|
||||||
|
# if self.0 {
|
||||||
|
# Poll::Ready(())
|
||||||
|
# } else {
|
||||||
|
# cx.waker().wake_by_ref();
|
||||||
|
# self.0 = true;
|
||||||
|
# Poll::Pending
|
||||||
|
# }
|
||||||
|
# }
|
||||||
|
# }
|
||||||
|
#
|
||||||
|
async fn foo() {
|
||||||
|
wake_and_yield_once().await // `await` is used within `async` function
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bar(x: u8) -> impl Future<Output = u8> {
|
||||||
|
async move {
|
||||||
|
wake_and_yield_once().await; // `await` is used within `async` block
|
||||||
|
x
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
[`async`]: https://doc.rust-lang.org/std/keyword.async.html
|
||||||
|
[`await`]: https://doc.rust-lang.org/std/keyword.await.html
|
||||||
|
"##,
|
||||||
|
|
||||||
E0734: r##"
|
E0734: r##"
|
||||||
A stability attribute has been used outside of the standard library.
|
A stability attribute has been used outside of the standard library.
|
||||||
|
|
||||||
@ -2218,6 +2296,5 @@ See [RFC 2091] for details on this and other limitations.
|
|||||||
// E0702, // replaced with a generic attribute input check
|
// E0702, // replaced with a generic attribute input check
|
||||||
E0726, // non-explicit (not `'_`) elided lifetime in unsupported position
|
E0726, // non-explicit (not `'_`) elided lifetime in unsupported position
|
||||||
E0727, // `async` generators are not yet supported
|
E0727, // `async` generators are not yet supported
|
||||||
E0728, // `await` must be in an `async` function or block
|
|
||||||
E0739, // invalid track_caller application/syntax
|
E0739, // invalid track_caller application/syntax
|
||||||
}
|
}
|
||||||
|
@ -83,8 +83,6 @@ pub struct LoweringContext<'a> {
|
|||||||
/// Used to assign IDs to HIR nodes that do not directly correspond to AST nodes.
|
/// Used to assign IDs to HIR nodes that do not directly correspond to AST nodes.
|
||||||
sess: &'a Session,
|
sess: &'a Session,
|
||||||
|
|
||||||
cstore: &'a dyn CrateStore,
|
|
||||||
|
|
||||||
resolver: &'a mut dyn Resolver,
|
resolver: &'a mut dyn Resolver,
|
||||||
|
|
||||||
/// HACK(Centril): there is a cyclic dependency between the parser and lowering
|
/// HACK(Centril): there is a cyclic dependency between the parser and lowering
|
||||||
@ -160,6 +158,8 @@ pub struct LoweringContext<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub trait Resolver {
|
pub trait Resolver {
|
||||||
|
fn cstore(&self) -> &dyn CrateStore;
|
||||||
|
|
||||||
/// Obtains resolution for a `NodeId` with a single resolution.
|
/// Obtains resolution for a `NodeId` with a single resolution.
|
||||||
fn get_partial_res(&mut self, id: NodeId) -> Option<PartialRes>;
|
fn get_partial_res(&mut self, id: NodeId) -> Option<PartialRes>;
|
||||||
|
|
||||||
@ -240,7 +240,6 @@ impl<'a> ImplTraitContext<'a> {
|
|||||||
|
|
||||||
pub fn lower_crate(
|
pub fn lower_crate(
|
||||||
sess: &Session,
|
sess: &Session,
|
||||||
cstore: &dyn CrateStore,
|
|
||||||
dep_graph: &DepGraph,
|
dep_graph: &DepGraph,
|
||||||
krate: &Crate,
|
krate: &Crate,
|
||||||
resolver: &mut dyn Resolver,
|
resolver: &mut dyn Resolver,
|
||||||
@ -256,7 +255,6 @@ pub fn lower_crate(
|
|||||||
LoweringContext {
|
LoweringContext {
|
||||||
crate_root: sess.parse_sess.injected_crate_name.try_get().copied(),
|
crate_root: sess.parse_sess.injected_crate_name.try_get().copied(),
|
||||||
sess,
|
sess,
|
||||||
cstore,
|
|
||||||
resolver,
|
resolver,
|
||||||
nt_to_tokenstream,
|
nt_to_tokenstream,
|
||||||
items: BTreeMap::new(),
|
items: BTreeMap::new(),
|
||||||
@ -792,15 +790,15 @@ impl<'a> LoweringContext<'a> {
|
|||||||
// really show up for end-user.
|
// really show up for end-user.
|
||||||
let (str_name, kind) = match hir_name {
|
let (str_name, kind) = match hir_name {
|
||||||
ParamName::Plain(ident) => (
|
ParamName::Plain(ident) => (
|
||||||
ident.as_interned_str(),
|
ident.name,
|
||||||
hir::LifetimeParamKind::InBand,
|
hir::LifetimeParamKind::InBand,
|
||||||
),
|
),
|
||||||
ParamName::Fresh(_) => (
|
ParamName::Fresh(_) => (
|
||||||
kw::UnderscoreLifetime.as_interned_str(),
|
kw::UnderscoreLifetime,
|
||||||
hir::LifetimeParamKind::Elided,
|
hir::LifetimeParamKind::Elided,
|
||||||
),
|
),
|
||||||
ParamName::Error => (
|
ParamName::Error => (
|
||||||
kw::UnderscoreLifetime.as_interned_str(),
|
kw::UnderscoreLifetime,
|
||||||
hir::LifetimeParamKind::Error,
|
hir::LifetimeParamKind::Error,
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
@ -980,7 +978,7 @@ impl<'a> LoweringContext<'a> {
|
|||||||
if id.is_local() {
|
if id.is_local() {
|
||||||
self.resolver.definitions().def_key(id.index)
|
self.resolver.definitions().def_key(id.index)
|
||||||
} else {
|
} else {
|
||||||
self.cstore.def_key(id)
|
self.resolver.cstore().def_key(id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1590,7 +1588,7 @@ impl<'a> LoweringContext<'a> {
|
|||||||
self.context.resolver.definitions().create_def_with_parent(
|
self.context.resolver.definitions().create_def_with_parent(
|
||||||
self.parent,
|
self.parent,
|
||||||
def_node_id,
|
def_node_id,
|
||||||
DefPathData::LifetimeNs(name.ident().as_interned_str()),
|
DefPathData::LifetimeNs(name.ident().name),
|
||||||
ExpnId::root(),
|
ExpnId::root(),
|
||||||
lifetime.span);
|
lifetime.span);
|
||||||
|
|
||||||
@ -1727,8 +1725,8 @@ impl<'a> LoweringContext<'a> {
|
|||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
assert!(!def_id.is_local());
|
assert!(!def_id.is_local());
|
||||||
let item_generics =
|
let item_generics = self.resolver.cstore()
|
||||||
self.cstore.item_generics_cloned_untracked(def_id, self.sess);
|
.item_generics_cloned_untracked(def_id, self.sess);
|
||||||
let n = item_generics.own_counts().lifetimes;
|
let n = item_generics.own_counts().lifetimes;
|
||||||
self.type_def_lifetime_params.insert(def_id, n);
|
self.type_def_lifetime_params.insert(def_id, n);
|
||||||
n
|
n
|
||||||
|
@ -186,13 +186,13 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
|
|||||||
});
|
});
|
||||||
|
|
||||||
let mut upstream_crates: Vec<_> = cstore.crates_untracked().iter().map(|&cnum| {
|
let mut upstream_crates: Vec<_> = cstore.crates_untracked().iter().map(|&cnum| {
|
||||||
let name = cstore.crate_name_untracked(cnum).as_interned_str();
|
let name = cstore.crate_name_untracked(cnum);
|
||||||
let disambiguator = cstore.crate_disambiguator_untracked(cnum).to_fingerprint();
|
let disambiguator = cstore.crate_disambiguator_untracked(cnum).to_fingerprint();
|
||||||
let hash = cstore.crate_hash_untracked(cnum);
|
let hash = cstore.crate_hash_untracked(cnum);
|
||||||
(name, disambiguator, hash)
|
(name, disambiguator, hash)
|
||||||
}).collect();
|
}).collect();
|
||||||
|
|
||||||
upstream_crates.sort_unstable_by_key(|&(name, dis, _)| (name, dis));
|
upstream_crates.sort_unstable_by_key(|&(name, dis, _)| (name.as_str(), dis));
|
||||||
|
|
||||||
// We hash the final, remapped names of all local source files so we
|
// We hash the final, remapped names of all local source files so we
|
||||||
// don't have to include the path prefix remapping commandline args.
|
// don't have to include the path prefix remapping commandline args.
|
||||||
|
@ -57,7 +57,7 @@ impl<'a> DefCollector<'a> {
|
|||||||
|
|
||||||
// For async functions, we need to create their inner defs inside of a
|
// For async functions, we need to create their inner defs inside of a
|
||||||
// closure to match their desugared representation.
|
// closure to match their desugared representation.
|
||||||
let fn_def_data = DefPathData::ValueNs(name.as_interned_str());
|
let fn_def_data = DefPathData::ValueNs(name);
|
||||||
let fn_def = self.create_def(id, fn_def_data, span);
|
let fn_def = self.create_def(id, fn_def_data, span);
|
||||||
return self.with_parent(fn_def, |this| {
|
return self.with_parent(fn_def, |this| {
|
||||||
this.create_def(return_impl_trait_id, DefPathData::ImplTrait, span);
|
this.create_def(return_impl_trait_id, DefPathData::ImplTrait, span);
|
||||||
@ -83,8 +83,7 @@ impl<'a> DefCollector<'a> {
|
|||||||
.unwrap_or_else(|| {
|
.unwrap_or_else(|| {
|
||||||
let node_id = NodeId::placeholder_from_expn_id(self.expansion);
|
let node_id = NodeId::placeholder_from_expn_id(self.expansion);
|
||||||
sym::integer(self.definitions.placeholder_field_indices[&node_id])
|
sym::integer(self.definitions.placeholder_field_indices[&node_id])
|
||||||
})
|
});
|
||||||
.as_interned_str();
|
|
||||||
let def = self.create_def(field.id, DefPathData::ValueNs(name), field.span);
|
let def = self.create_def(field.id, DefPathData::ValueNs(name), field.span);
|
||||||
self.with_parent(def, |this| visit::walk_struct_field(this, field));
|
self.with_parent(def, |this| visit::walk_struct_field(this, field));
|
||||||
}
|
}
|
||||||
@ -109,7 +108,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
|
|||||||
ItemKind::Mod(..) | ItemKind::Trait(..) | ItemKind::TraitAlias(..) |
|
ItemKind::Mod(..) | ItemKind::Trait(..) | ItemKind::TraitAlias(..) |
|
||||||
ItemKind::Enum(..) | ItemKind::Struct(..) | ItemKind::Union(..) |
|
ItemKind::Enum(..) | ItemKind::Struct(..) | ItemKind::Union(..) |
|
||||||
ItemKind::OpaqueTy(..) | ItemKind::ExternCrate(..) | ItemKind::ForeignMod(..) |
|
ItemKind::OpaqueTy(..) | ItemKind::ExternCrate(..) | ItemKind::ForeignMod(..) |
|
||||||
ItemKind::TyAlias(..) => DefPathData::TypeNs(i.ident.as_interned_str()),
|
ItemKind::TyAlias(..) => DefPathData::TypeNs(i.ident.name),
|
||||||
ItemKind::Fn(
|
ItemKind::Fn(
|
||||||
ref decl,
|
ref decl,
|
||||||
ref header,
|
ref header,
|
||||||
@ -127,8 +126,8 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
ItemKind::Static(..) | ItemKind::Const(..) | ItemKind::Fn(..) =>
|
ItemKind::Static(..) | ItemKind::Const(..) | ItemKind::Fn(..) =>
|
||||||
DefPathData::ValueNs(i.ident.as_interned_str()),
|
DefPathData::ValueNs(i.ident.name),
|
||||||
ItemKind::MacroDef(..) => DefPathData::MacroNs(i.ident.as_interned_str()),
|
ItemKind::MacroDef(..) => DefPathData::MacroNs(i.ident.name),
|
||||||
ItemKind::Mac(..) => return self.visit_macro_invoc(i.id),
|
ItemKind::Mac(..) => return self.visit_macro_invoc(i.id),
|
||||||
ItemKind::GlobalAsm(..) => DefPathData::Misc,
|
ItemKind::GlobalAsm(..) => DefPathData::Misc,
|
||||||
ItemKind::Use(..) => {
|
ItemKind::Use(..) => {
|
||||||
@ -162,7 +161,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let def = self.create_def(foreign_item.id,
|
let def = self.create_def(foreign_item.id,
|
||||||
DefPathData::ValueNs(foreign_item.ident.as_interned_str()),
|
DefPathData::ValueNs(foreign_item.ident.name),
|
||||||
foreign_item.span);
|
foreign_item.span);
|
||||||
|
|
||||||
self.with_parent(def, |this| {
|
self.with_parent(def, |this| {
|
||||||
@ -175,7 +174,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
|
|||||||
return self.visit_macro_invoc(v.id);
|
return self.visit_macro_invoc(v.id);
|
||||||
}
|
}
|
||||||
let def = self.create_def(v.id,
|
let def = self.create_def(v.id,
|
||||||
DefPathData::TypeNs(v.ident.as_interned_str()),
|
DefPathData::TypeNs(v.ident.name),
|
||||||
v.span);
|
v.span);
|
||||||
self.with_parent(def, |this| {
|
self.with_parent(def, |this| {
|
||||||
if let Some(ctor_hir_id) = v.data.ctor_id() {
|
if let Some(ctor_hir_id) = v.data.ctor_id() {
|
||||||
@ -202,7 +201,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
|
|||||||
self.visit_macro_invoc(param.id);
|
self.visit_macro_invoc(param.id);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let name = param.ident.as_interned_str();
|
let name = param.ident.name;
|
||||||
let def_path_data = match param.kind {
|
let def_path_data = match param.kind {
|
||||||
GenericParamKind::Lifetime { .. } => DefPathData::LifetimeNs(name),
|
GenericParamKind::Lifetime { .. } => DefPathData::LifetimeNs(name),
|
||||||
GenericParamKind::Type { .. } => DefPathData::TypeNs(name),
|
GenericParamKind::Type { .. } => DefPathData::TypeNs(name),
|
||||||
@ -216,9 +215,9 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
|
|||||||
fn visit_trait_item(&mut self, ti: &'a TraitItem) {
|
fn visit_trait_item(&mut self, ti: &'a TraitItem) {
|
||||||
let def_data = match ti.kind {
|
let def_data = match ti.kind {
|
||||||
TraitItemKind::Method(..) | TraitItemKind::Const(..) =>
|
TraitItemKind::Method(..) | TraitItemKind::Const(..) =>
|
||||||
DefPathData::ValueNs(ti.ident.as_interned_str()),
|
DefPathData::ValueNs(ti.ident.name),
|
||||||
TraitItemKind::Type(..) => {
|
TraitItemKind::Type(..) => {
|
||||||
DefPathData::TypeNs(ti.ident.as_interned_str())
|
DefPathData::TypeNs(ti.ident.name)
|
||||||
},
|
},
|
||||||
TraitItemKind::Macro(..) => return self.visit_macro_invoc(ti.id),
|
TraitItemKind::Macro(..) => return self.visit_macro_invoc(ti.id),
|
||||||
};
|
};
|
||||||
@ -243,12 +242,10 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
|
|||||||
body,
|
body,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
ImplItemKind::Method(..) | ImplItemKind::Const(..) =>
|
ImplItemKind::Method(..) |
|
||||||
DefPathData::ValueNs(ii.ident.as_interned_str()),
|
ImplItemKind::Const(..) => DefPathData::ValueNs(ii.ident.name),
|
||||||
ImplItemKind::TyAlias(..) |
|
ImplItemKind::TyAlias(..) |
|
||||||
ImplItemKind::OpaqueTy(..) => {
|
ImplItemKind::OpaqueTy(..) => DefPathData::TypeNs(ii.ident.name),
|
||||||
DefPathData::TypeNs(ii.ident.as_interned_str())
|
|
||||||
},
|
|
||||||
ImplItemKind::Macro(..) => return self.visit_macro_invoc(ii.id),
|
ImplItemKind::Macro(..) => return self.visit_macro_invoc(ii.id),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ use std::fmt::Write;
|
|||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use syntax_expand::hygiene::ExpnId;
|
use syntax_expand::hygiene::ExpnId;
|
||||||
use syntax::symbol::{Symbol, sym, InternedString};
|
use syntax::symbol::{Symbol, sym};
|
||||||
use syntax_pos::{Span, DUMMY_SP};
|
use syntax_pos::{Span, DUMMY_SP};
|
||||||
|
|
||||||
/// The `DefPathTable` maps `DefIndex`es to `DefKey`s and vice versa.
|
/// The `DefPathTable` maps `DefIndex`es to `DefKey`s and vice versa.
|
||||||
@ -136,7 +136,9 @@ impl DefKey {
|
|||||||
|
|
||||||
::std::mem::discriminant(data).hash(&mut hasher);
|
::std::mem::discriminant(data).hash(&mut hasher);
|
||||||
if let Some(name) = data.get_opt_name() {
|
if let Some(name) = data.get_opt_name() {
|
||||||
name.hash(&mut hasher);
|
// Get a stable hash by considering the symbol chars rather than
|
||||||
|
// the symbol index.
|
||||||
|
name.as_str().hash(&mut hasher);
|
||||||
}
|
}
|
||||||
|
|
||||||
disambiguator.hash(&mut hasher);
|
disambiguator.hash(&mut hasher);
|
||||||
@ -218,7 +220,7 @@ impl DefPath {
|
|||||||
for component in &self.data {
|
for component in &self.data {
|
||||||
write!(s,
|
write!(s,
|
||||||
"::{}[{}]",
|
"::{}[{}]",
|
||||||
component.data.as_interned_str(),
|
component.data.as_symbol(),
|
||||||
component.disambiguator)
|
component.disambiguator)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
@ -238,11 +240,11 @@ impl DefPath {
|
|||||||
|
|
||||||
for component in &self.data {
|
for component in &self.data {
|
||||||
if component.disambiguator == 0 {
|
if component.disambiguator == 0 {
|
||||||
write!(s, "::{}", component.data.as_interned_str()).unwrap();
|
write!(s, "::{}", component.data.as_symbol()).unwrap();
|
||||||
} else {
|
} else {
|
||||||
write!(s,
|
write!(s,
|
||||||
"{}[{}]",
|
"{}[{}]",
|
||||||
component.data.as_interned_str(),
|
component.data.as_symbol(),
|
||||||
component.disambiguator)
|
component.disambiguator)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
@ -262,11 +264,11 @@ impl DefPath {
|
|||||||
opt_delimiter.map(|d| s.push(d));
|
opt_delimiter.map(|d| s.push(d));
|
||||||
opt_delimiter = Some('-');
|
opt_delimiter = Some('-');
|
||||||
if component.disambiguator == 0 {
|
if component.disambiguator == 0 {
|
||||||
write!(s, "{}", component.data.as_interned_str()).unwrap();
|
write!(s, "{}", component.data.as_symbol()).unwrap();
|
||||||
} else {
|
} else {
|
||||||
write!(s,
|
write!(s,
|
||||||
"{}[{}]",
|
"{}[{}]",
|
||||||
component.data.as_interned_str(),
|
component.data.as_symbol(),
|
||||||
component.disambiguator)
|
component.disambiguator)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
@ -290,13 +292,13 @@ pub enum DefPathData {
|
|||||||
/// An impl.
|
/// An impl.
|
||||||
Impl,
|
Impl,
|
||||||
/// Something in the type namespace.
|
/// Something in the type namespace.
|
||||||
TypeNs(InternedString),
|
TypeNs(Symbol),
|
||||||
/// Something in the value namespace.
|
/// Something in the value namespace.
|
||||||
ValueNs(InternedString),
|
ValueNs(Symbol),
|
||||||
/// Something in the macro namespace.
|
/// Something in the macro namespace.
|
||||||
MacroNs(InternedString),
|
MacroNs(Symbol),
|
||||||
/// Something in the lifetime namespace.
|
/// Something in the lifetime namespace.
|
||||||
LifetimeNs(InternedString),
|
LifetimeNs(Symbol),
|
||||||
/// A closure expression.
|
/// A closure expression.
|
||||||
ClosureExpr,
|
ClosureExpr,
|
||||||
|
|
||||||
@ -311,7 +313,7 @@ pub enum DefPathData {
|
|||||||
/// Identifies a piece of crate metadata that is global to a whole crate
|
/// Identifies a piece of crate metadata that is global to a whole crate
|
||||||
/// (as opposed to just one item). `GlobalMetaData` components are only
|
/// (as opposed to just one item). `GlobalMetaData` components are only
|
||||||
/// supposed to show up right below the crate root.
|
/// supposed to show up right below the crate root.
|
||||||
GlobalMetaData(InternedString),
|
GlobalMetaData(Symbol),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord, Debug,
|
#[derive(Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord, Debug,
|
||||||
@ -545,7 +547,7 @@ impl Definitions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl DefPathData {
|
impl DefPathData {
|
||||||
pub fn get_opt_name(&self) -> Option<InternedString> {
|
pub fn get_opt_name(&self) -> Option<Symbol> {
|
||||||
use self::DefPathData::*;
|
use self::DefPathData::*;
|
||||||
match *self {
|
match *self {
|
||||||
TypeNs(name) |
|
TypeNs(name) |
|
||||||
@ -564,15 +566,15 @@ impl DefPathData {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_interned_str(&self) -> InternedString {
|
pub fn as_symbol(&self) -> Symbol {
|
||||||
use self::DefPathData::*;
|
use self::DefPathData::*;
|
||||||
let s = match *self {
|
match *self {
|
||||||
TypeNs(name) |
|
TypeNs(name) |
|
||||||
ValueNs(name) |
|
ValueNs(name) |
|
||||||
MacroNs(name) |
|
MacroNs(name) |
|
||||||
LifetimeNs(name) |
|
LifetimeNs(name) |
|
||||||
GlobalMetaData(name) => {
|
GlobalMetaData(name) => {
|
||||||
return name
|
name
|
||||||
}
|
}
|
||||||
// Note that this does not show up in user print-outs.
|
// Note that this does not show up in user print-outs.
|
||||||
CrateRoot => sym::double_braced_crate,
|
CrateRoot => sym::double_braced_crate,
|
||||||
@ -582,13 +584,11 @@ impl DefPathData {
|
|||||||
Ctor => sym::double_braced_constructor,
|
Ctor => sym::double_braced_constructor,
|
||||||
AnonConst => sym::double_braced_constant,
|
AnonConst => sym::double_braced_constant,
|
||||||
ImplTrait => sym::double_braced_opaque,
|
ImplTrait => sym::double_braced_opaque,
|
||||||
};
|
}
|
||||||
|
|
||||||
s.as_interned_str()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_string(&self) -> String {
|
pub fn to_string(&self) -> String {
|
||||||
self.as_interned_str().to_string()
|
self.as_symbol().to_string()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -610,7 +610,7 @@ macro_rules! define_global_metadata_kind {
|
|||||||
definitions.create_def_with_parent(
|
definitions.create_def_with_parent(
|
||||||
CRATE_DEF_INDEX,
|
CRATE_DEF_INDEX,
|
||||||
ast::DUMMY_NODE_ID,
|
ast::DUMMY_NODE_ID,
|
||||||
DefPathData::GlobalMetaData(instance.name().as_interned_str()),
|
DefPathData::GlobalMetaData(instance.name()),
|
||||||
ExpnId::root(),
|
ExpnId::root(),
|
||||||
DUMMY_SP
|
DUMMY_SP
|
||||||
);
|
);
|
||||||
@ -624,7 +624,7 @@ macro_rules! define_global_metadata_kind {
|
|||||||
let def_key = DefKey {
|
let def_key = DefKey {
|
||||||
parent: Some(CRATE_DEF_INDEX),
|
parent: Some(CRATE_DEF_INDEX),
|
||||||
disambiguated_data: DisambiguatedDefPathData {
|
disambiguated_data: DisambiguatedDefPathData {
|
||||||
data: DefPathData::GlobalMetaData(self.name().as_interned_str()),
|
data: DefPathData::GlobalMetaData(self.name()),
|
||||||
disambiguator: 0,
|
disambiguator: 0,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -19,7 +19,7 @@ use crate::ty::query::Providers;
|
|||||||
use crate::util::nodemap::{NodeMap, FxHashSet};
|
use crate::util::nodemap::{NodeMap, FxHashSet};
|
||||||
|
|
||||||
use errors::FatalError;
|
use errors::FatalError;
|
||||||
use syntax_pos::{Span, DUMMY_SP, symbol::InternedString, MultiSpan};
|
use syntax_pos::{Span, DUMMY_SP, MultiSpan};
|
||||||
use syntax::source_map::Spanned;
|
use syntax::source_map::Spanned;
|
||||||
use syntax::ast::{self, CrateSugar, Ident, Name, NodeId, AsmDialect};
|
use syntax::ast::{self, CrateSugar, Ident, Name, NodeId, AsmDialect};
|
||||||
use syntax::ast::{Attribute, Label, LitKind, StrStyle, FloatTy, IntTy, UintTy};
|
use syntax::ast::{Attribute, Label, LitKind, StrStyle, FloatTy, IntTy, UintTy};
|
||||||
@ -628,9 +628,9 @@ impl Generics {
|
|||||||
own_counts
|
own_counts
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_named(&self, name: InternedString) -> Option<&GenericParam> {
|
pub fn get_named(&self, name: Symbol) -> Option<&GenericParam> {
|
||||||
for param in &self.params {
|
for param in &self.params {
|
||||||
if name == param.name.ident().as_interned_str() {
|
if name == param.name.ident().name {
|
||||||
return Some(param);
|
return Some(param);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ use std::mem;
|
|||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use syntax::feature_gate;
|
use syntax::feature_gate;
|
||||||
use syntax::parse::token;
|
use syntax::parse::token;
|
||||||
use syntax::symbol::InternedString;
|
use syntax::symbol::LocalInternedString;
|
||||||
use syntax::tokenstream;
|
use syntax::tokenstream;
|
||||||
use syntax_pos::SourceFile;
|
use syntax_pos::SourceFile;
|
||||||
|
|
||||||
@ -18,20 +18,21 @@ use crate::hir::def_id::{DefId, CrateNum, CRATE_DEF_INDEX};
|
|||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use rustc_data_structures::stable_hasher::{HashStable, ToStableHashKey, StableHasher};
|
use rustc_data_structures::stable_hasher::{HashStable, ToStableHashKey, StableHasher};
|
||||||
|
|
||||||
impl<'a> HashStable<StableHashingContext<'a>> for InternedString {
|
impl<'a> HashStable<StableHashingContext<'a>> for LocalInternedString {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
|
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
|
||||||
self.with(|s| s.hash_stable(hcx, hasher))
|
let str = self as &str;
|
||||||
|
str.hash_stable(hcx, hasher)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> ToStableHashKey<StableHashingContext<'a>> for InternedString {
|
impl<'a> ToStableHashKey<StableHashingContext<'a>> for LocalInternedString {
|
||||||
type KeyType = InternedString;
|
type KeyType = LocalInternedString;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_stable_hash_key(&self,
|
fn to_stable_hash_key(&self,
|
||||||
_: &StableHashingContext<'a>)
|
_: &StableHashingContext<'a>)
|
||||||
-> InternedString {
|
-> LocalInternedString {
|
||||||
self.clone()
|
self.clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -44,13 +45,13 @@ impl<'a> HashStable<StableHashingContext<'a>> for ast::Name {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> ToStableHashKey<StableHashingContext<'a>> for ast::Name {
|
impl<'a> ToStableHashKey<StableHashingContext<'a>> for ast::Name {
|
||||||
type KeyType = InternedString;
|
type KeyType = LocalInternedString;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_stable_hash_key(&self,
|
fn to_stable_hash_key(&self,
|
||||||
_: &StableHashingContext<'a>)
|
_: &StableHashingContext<'a>)
|
||||||
-> InternedString {
|
-> LocalInternedString {
|
||||||
self.as_interned_str()
|
self.as_str()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -494,7 +494,7 @@ impl TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
|
|||||||
if sub_vid == self.for_vid_sub_root {
|
if sub_vid == self.for_vid_sub_root {
|
||||||
// If sub-roots are equal, then `for_vid` and
|
// If sub-roots are equal, then `for_vid` and
|
||||||
// `vid` are related via subtyping.
|
// `vid` are related via subtyping.
|
||||||
return Err(TypeError::CyclicTy(self.root_ty));
|
Err(TypeError::CyclicTy(self.root_ty))
|
||||||
} else {
|
} else {
|
||||||
match variables.probe(vid) {
|
match variables.probe(vid) {
|
||||||
TypeVariableValue::Known { value: u } => {
|
TypeVariableValue::Known { value: u } => {
|
||||||
@ -527,7 +527,7 @@ impl TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
|
|||||||
let u = self.tcx().mk_ty_var(new_var_id);
|
let u = self.tcx().mk_ty_var(new_var_id);
|
||||||
debug!("generalize: replacing original vid={:?} with new={:?}",
|
debug!("generalize: replacing original vid={:?} with new={:?}",
|
||||||
vid, u);
|
vid, u);
|
||||||
return Ok(u);
|
Ok(u)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -602,19 +602,26 @@ impl TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
|
|||||||
) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
|
) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
|
||||||
assert_eq!(c, c2); // we are abusing TypeRelation here; both LHS and RHS ought to be ==
|
assert_eq!(c, c2); // we are abusing TypeRelation here; both LHS and RHS ought to be ==
|
||||||
|
|
||||||
match c {
|
match c.val {
|
||||||
ty::Const { val: ConstValue::Infer(InferConst::Var(vid)), .. } => {
|
ConstValue::Infer(InferConst::Var(vid)) => {
|
||||||
let mut variable_table = self.infcx.const_unification_table.borrow_mut();
|
let mut variable_table = self.infcx.const_unification_table.borrow_mut();
|
||||||
match variable_table.probe_value(*vid).val.known() {
|
let var_value = variable_table.probe_value(vid);
|
||||||
Some(u) => {
|
match var_value.val {
|
||||||
self.relate(&u, &u)
|
ConstVariableValue::Known { value: u } => self.relate(&u, &u),
|
||||||
|
ConstVariableValue::Unknown { universe } => {
|
||||||
|
if self.for_universe.can_name(universe) {
|
||||||
|
Ok(c)
|
||||||
|
} else {
|
||||||
|
let new_var_id = variable_table.new_key(ConstVarValue {
|
||||||
|
origin: var_value.origin,
|
||||||
|
val: ConstVariableValue::Unknown { universe: self.for_universe },
|
||||||
|
});
|
||||||
|
Ok(self.tcx().mk_const_var(new_var_id, c.ty))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
None => Ok(c),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => relate::super_relate_consts(self, c, c),
|
||||||
relate::super_relate_consts(self, c, c)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -542,7 +542,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||||||
disambiguated_data: &DisambiguatedDefPathData,
|
disambiguated_data: &DisambiguatedDefPathData,
|
||||||
) -> Result<Self::Path, Self::Error> {
|
) -> Result<Self::Path, Self::Error> {
|
||||||
let mut path = print_prefix(self)?;
|
let mut path = print_prefix(self)?;
|
||||||
path.push(disambiguated_data.data.as_interned_str().to_string());
|
path.push(disambiguated_data.data.as_symbol().to_string());
|
||||||
Ok(path)
|
Ok(path)
|
||||||
}
|
}
|
||||||
fn path_generic_args(
|
fn path_generic_args(
|
||||||
@ -1146,10 +1146,17 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||||||
|
|
||||||
let span = cause.span(self.tcx);
|
let span = cause.span(self.tcx);
|
||||||
|
|
||||||
diag.span_label(span, terr.to_string());
|
// Ignore msg for object safe coercion
|
||||||
if let Some((sp, msg)) = secondary_span {
|
// since E0038 message will be printed
|
||||||
diag.span_label(sp, msg);
|
match terr {
|
||||||
}
|
TypeError::ObjectUnsafeCoercion(_) => {}
|
||||||
|
_ => {
|
||||||
|
diag.span_label(span, terr.to_string());
|
||||||
|
if let Some((sp, msg)) = secondary_span {
|
||||||
|
diag.span_label(sp, msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
if let Some((expected, found)) = expected_found {
|
if let Some((expected, found)) = expected_found {
|
||||||
match (terr, is_simple_error, expected == found) {
|
match (terr, is_simple_error, expected == found) {
|
||||||
@ -1169,6 +1176,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||||||
&sort_string(values.found),
|
&sort_string(values.found),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
(TypeError::ObjectUnsafeCoercion(_), ..) => {
|
||||||
|
diag.note_unsuccessfull_coercion(found, expected);
|
||||||
|
}
|
||||||
(_, false, _) => {
|
(_, false, _) => {
|
||||||
if let Some(exp_found) = exp_found {
|
if let Some(exp_found) = exp_found {
|
||||||
self.suggest_as_ref_where_appropriate(span, &exp_found, diag);
|
self.suggest_as_ref_where_appropriate(span, &exp_found, diag);
|
||||||
@ -1267,6 +1277,10 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||||||
let span = trace.cause.span(self.tcx);
|
let span = trace.cause.span(self.tcx);
|
||||||
let failure_code = trace.cause.as_failure_code(terr);
|
let failure_code = trace.cause.as_failure_code(terr);
|
||||||
let mut diag = match failure_code {
|
let mut diag = match failure_code {
|
||||||
|
FailureCode::Error0038(did) => {
|
||||||
|
let violations = self.tcx.object_safety_violations(did);
|
||||||
|
self.tcx.report_object_safety_error(span, did, violations)
|
||||||
|
}
|
||||||
FailureCode::Error0317(failure_str) => {
|
FailureCode::Error0317(failure_str) => {
|
||||||
struct_span_err!(self.tcx.sess, span, E0317, "{}", failure_str)
|
struct_span_err!(self.tcx.sess, span, E0317, "{}", failure_str)
|
||||||
}
|
}
|
||||||
@ -1628,6 +1642,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
enum FailureCode {
|
enum FailureCode {
|
||||||
|
Error0038(DefId),
|
||||||
Error0317(&'static str),
|
Error0317(&'static str),
|
||||||
Error0580(&'static str),
|
Error0580(&'static str),
|
||||||
Error0308(&'static str),
|
Error0308(&'static str),
|
||||||
@ -1666,6 +1681,7 @@ impl<'tcx> ObligationCause<'tcx> {
|
|||||||
TypeError::IntrinsicCast => {
|
TypeError::IntrinsicCast => {
|
||||||
Error0308("cannot coerce intrinsics to function pointers")
|
Error0308("cannot coerce intrinsics to function pointers")
|
||||||
}
|
}
|
||||||
|
TypeError::ObjectUnsafeCoercion(did) => Error0038(did.clone()),
|
||||||
_ => Error0308("mismatched types"),
|
_ => Error0308("mismatched types"),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,7 @@ use std::cell::{Cell, Ref, RefCell, RefMut};
|
|||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use syntax_pos::symbol::InternedString;
|
use syntax_pos::symbol::Symbol;
|
||||||
use syntax_pos::Span;
|
use syntax_pos::Span;
|
||||||
|
|
||||||
use self::combine::CombineFields;
|
use self::combine::CombineFields;
|
||||||
@ -392,7 +392,7 @@ pub enum RegionVariableOrigin {
|
|||||||
Coercion(Span),
|
Coercion(Span),
|
||||||
|
|
||||||
/// Region variables created as the values for early-bound regions
|
/// Region variables created as the values for early-bound regions
|
||||||
EarlyBoundRegion(Span, InternedString),
|
EarlyBoundRegion(Span, Symbol),
|
||||||
|
|
||||||
/// Region variables created for bound regions
|
/// Region variables created for bound regions
|
||||||
/// in a function or method that is called
|
/// in a function or method that is called
|
||||||
|
@ -27,7 +27,8 @@ use crate::ty::error::TypeError;
|
|||||||
use crate::ty::fold::{TypeFoldable, TypeVisitor};
|
use crate::ty::fold::{TypeFoldable, TypeVisitor};
|
||||||
use crate::ty::relate::{self, Relate, RelateResult, TypeRelation};
|
use crate::ty::relate::{self, Relate, RelateResult, TypeRelation};
|
||||||
use crate::ty::subst::GenericArg;
|
use crate::ty::subst::GenericArg;
|
||||||
use crate::ty::{self, Ty, TyCtxt};
|
use crate::ty::{self, Ty, TyCtxt, InferConst};
|
||||||
|
use crate::infer::{ConstVariableValue, ConstVarValue};
|
||||||
use crate::mir::interpret::ConstValue;
|
use crate::mir::interpret::ConstValue;
|
||||||
use rustc_data_structures::fx::FxHashMap;
|
use rustc_data_structures::fx::FxHashMap;
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
@ -324,7 +325,7 @@ where
|
|||||||
let vid = pair.vid();
|
let vid = pair.vid();
|
||||||
let value_ty = pair.value_ty();
|
let value_ty = pair.value_ty();
|
||||||
|
|
||||||
// FIXME -- this logic assumes invariance, but that is wrong.
|
// FIXME(invariance) -- this logic assumes invariance, but that is wrong.
|
||||||
// This only presently applies to chalk integration, as NLL
|
// This only presently applies to chalk integration, as NLL
|
||||||
// doesn't permit type variables to appear on both sides (and
|
// doesn't permit type variables to appear on both sides (and
|
||||||
// doesn't use lazy norm).
|
// doesn't use lazy norm).
|
||||||
@ -616,15 +617,21 @@ where
|
|||||||
fn consts(
|
fn consts(
|
||||||
&mut self,
|
&mut self,
|
||||||
a: &'tcx ty::Const<'tcx>,
|
a: &'tcx ty::Const<'tcx>,
|
||||||
b: &'tcx ty::Const<'tcx>,
|
mut b: &'tcx ty::Const<'tcx>,
|
||||||
) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
|
) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
|
||||||
if let ty::Const { val: ConstValue::Bound(..), .. } = a {
|
let a = self.infcx.shallow_resolve(a);
|
||||||
// FIXME(const_generics): I'm unsure how this branch should actually be handled,
|
|
||||||
// so this is probably not correct.
|
if !D::forbid_inference_vars() {
|
||||||
self.infcx.super_combine_consts(self, a, b)
|
b = self.infcx.shallow_resolve(b);
|
||||||
} else {
|
}
|
||||||
debug!("consts(a={:?}, b={:?}, variance={:?})", a, b, self.ambient_variance);
|
|
||||||
relate::super_relate_consts(self, a, b)
|
match b.val {
|
||||||
|
ConstValue::Infer(InferConst::Var(_)) if D::forbid_inference_vars() => {
|
||||||
|
// Forbid inference variables in the RHS.
|
||||||
|
bug!("unexpected inference var {:?}", b)
|
||||||
|
}
|
||||||
|
// FIXME(invariance): see the related FIXME above.
|
||||||
|
_ => self.infcx.super_combine_consts(self, a, b)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -991,15 +998,28 @@ where
|
|||||||
a: &'tcx ty::Const<'tcx>,
|
a: &'tcx ty::Const<'tcx>,
|
||||||
_: &'tcx ty::Const<'tcx>,
|
_: &'tcx ty::Const<'tcx>,
|
||||||
) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
|
) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
|
||||||
debug!("TypeGeneralizer::consts(a={:?})", a);
|
match a.val {
|
||||||
|
ConstValue::Infer(InferConst::Var(_)) if D::forbid_inference_vars() => {
|
||||||
if let ty::Const { val: ConstValue::Bound(..), .. } = a {
|
bug!(
|
||||||
bug!(
|
"unexpected inference variable encountered in NLL generalization: {:?}",
|
||||||
"unexpected inference variable encountered in NLL generalization: {:?}",
|
a
|
||||||
a
|
);
|
||||||
);
|
}
|
||||||
} else {
|
ConstValue::Infer(InferConst::Var(vid)) => {
|
||||||
relate::super_relate_consts(self, a, a)
|
let mut variable_table = self.infcx.const_unification_table.borrow_mut();
|
||||||
|
let var_value = variable_table.probe_value(vid);
|
||||||
|
match var_value.val.known() {
|
||||||
|
Some(u) => self.relate(&u, &u),
|
||||||
|
None => {
|
||||||
|
let new_var_id = variable_table.new_key(ConstVarValue {
|
||||||
|
origin: var_value.origin,
|
||||||
|
val: ConstVariableValue::Unknown { universe: self.universe },
|
||||||
|
});
|
||||||
|
Ok(self.tcx().mk_const_var(new_var_id, a.ty))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => relate::super_relate_consts(self, a, a),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use syntax::symbol::InternedString;
|
use syntax::symbol::Symbol;
|
||||||
use syntax_pos::Span;
|
use syntax_pos::Span;
|
||||||
use crate::ty::{self, Ty, TyVid};
|
use crate::ty::{self, Ty, TyVid};
|
||||||
|
|
||||||
@ -49,7 +49,7 @@ pub enum TypeVariableOriginKind {
|
|||||||
MiscVariable,
|
MiscVariable,
|
||||||
NormalizeProjectionType,
|
NormalizeProjectionType,
|
||||||
TypeInference,
|
TypeInference,
|
||||||
TypeParameterDefinition(InternedString),
|
TypeParameterDefinition(Symbol),
|
||||||
|
|
||||||
/// One of the upvars or closure kind parameters in a `ClosureSubsts`
|
/// One of the upvars or closure kind parameters in a `ClosureSubsts`
|
||||||
/// (before it has been determined).
|
/// (before it has been determined).
|
||||||
|
@ -3,7 +3,7 @@ use crate::mir::interpret::ConstValue;
|
|||||||
use rustc_data_structures::unify::{NoError, EqUnifyValue, UnifyKey, UnifyValue, UnificationTable};
|
use rustc_data_structures::unify::{NoError, EqUnifyValue, UnifyKey, UnifyValue, UnificationTable};
|
||||||
use rustc_data_structures::unify::InPlace;
|
use rustc_data_structures::unify::InPlace;
|
||||||
use syntax_pos::{Span, DUMMY_SP};
|
use syntax_pos::{Span, DUMMY_SP};
|
||||||
use syntax::symbol::InternedString;
|
use syntax::symbol::Symbol;
|
||||||
|
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
@ -90,7 +90,7 @@ pub struct ConstVariableOrigin {
|
|||||||
pub enum ConstVariableOriginKind {
|
pub enum ConstVariableOriginKind {
|
||||||
MiscVariable,
|
MiscVariable,
|
||||||
ConstInference,
|
ConstInference,
|
||||||
ConstParameterDefinition(InternedString),
|
ConstParameterDefinition(Symbol),
|
||||||
SubstitutionPlaceholder,
|
SubstitutionPlaceholder,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,11 +4,12 @@
|
|||||||
//! compiler code, rather than using their own custom pass. Those
|
//! compiler code, rather than using their own custom pass. Those
|
||||||
//! lints are all available in `rustc_lint::builtin`.
|
//! lints are all available in `rustc_lint::builtin`.
|
||||||
|
|
||||||
use crate::lint::{LintPass, LateLintPass, LintArray};
|
use crate::lint::{LintPass, LateLintPass, LintArray, FutureIncompatibleInfo};
|
||||||
use crate::middle::stability;
|
use crate::middle::stability;
|
||||||
use crate::session::Session;
|
use crate::session::Session;
|
||||||
use errors::{Applicability, DiagnosticBuilder, pluralise};
|
use errors::{Applicability, DiagnosticBuilder, pluralise};
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
|
use syntax::edition::Edition;
|
||||||
use syntax::source_map::Span;
|
use syntax::source_map::Span;
|
||||||
use syntax::symbol::Symbol;
|
use syntax::symbol::Symbol;
|
||||||
|
|
||||||
@ -22,7 +23,7 @@ declare_lint! {
|
|||||||
pub CONST_ERR,
|
pub CONST_ERR,
|
||||||
Deny,
|
Deny,
|
||||||
"constant evaluation detected erroneous expression",
|
"constant evaluation detected erroneous expression",
|
||||||
report_in_external_macro: true
|
report_in_external_macro
|
||||||
}
|
}
|
||||||
|
|
||||||
declare_lint! {
|
declare_lint! {
|
||||||
@ -71,7 +72,7 @@ declare_lint! {
|
|||||||
pub UNREACHABLE_CODE,
|
pub UNREACHABLE_CODE,
|
||||||
Warn,
|
Warn,
|
||||||
"detects unreachable code paths",
|
"detects unreachable code paths",
|
||||||
report_in_external_macro: true
|
report_in_external_macro
|
||||||
}
|
}
|
||||||
|
|
||||||
declare_lint! {
|
declare_lint! {
|
||||||
@ -131,7 +132,11 @@ declare_lint! {
|
|||||||
declare_lint! {
|
declare_lint! {
|
||||||
pub PRIVATE_IN_PUBLIC,
|
pub PRIVATE_IN_PUBLIC,
|
||||||
Warn,
|
Warn,
|
||||||
"detect private items in public interfaces not caught by the old implementation"
|
"detect private items in public interfaces not caught by the old implementation",
|
||||||
|
@future_incompatible = FutureIncompatibleInfo {
|
||||||
|
reference: "issue #34537 <https://github.com/rust-lang/rust/issues/34537>",
|
||||||
|
edition: None,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
declare_lint! {
|
declare_lint! {
|
||||||
@ -143,13 +148,21 @@ declare_lint! {
|
|||||||
declare_lint! {
|
declare_lint! {
|
||||||
pub PUB_USE_OF_PRIVATE_EXTERN_CRATE,
|
pub PUB_USE_OF_PRIVATE_EXTERN_CRATE,
|
||||||
Deny,
|
Deny,
|
||||||
"detect public re-exports of private extern crates"
|
"detect public re-exports of private extern crates",
|
||||||
|
@future_incompatible = FutureIncompatibleInfo {
|
||||||
|
reference: "issue #34537 <https://github.com/rust-lang/rust/issues/34537>",
|
||||||
|
edition: None,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
declare_lint! {
|
declare_lint! {
|
||||||
pub INVALID_TYPE_PARAM_DEFAULT,
|
pub INVALID_TYPE_PARAM_DEFAULT,
|
||||||
Deny,
|
Deny,
|
||||||
"type parameter default erroneously allowed in invalid location"
|
"type parameter default erroneously allowed in invalid location",
|
||||||
|
@future_incompatible = FutureIncompatibleInfo {
|
||||||
|
reference: "issue #36887 <https://github.com/rust-lang/rust/issues/36887>",
|
||||||
|
edition: None,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
declare_lint! {
|
declare_lint! {
|
||||||
@ -161,63 +174,99 @@ declare_lint! {
|
|||||||
declare_lint! {
|
declare_lint! {
|
||||||
pub SAFE_EXTERN_STATICS,
|
pub SAFE_EXTERN_STATICS,
|
||||||
Deny,
|
Deny,
|
||||||
"safe access to extern statics was erroneously allowed"
|
"safe access to extern statics was erroneously allowed",
|
||||||
|
@future_incompatible = FutureIncompatibleInfo {
|
||||||
|
reference: "issue #36247 <https://github.com/rust-lang/rust/issues/36247>",
|
||||||
|
edition: None,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
declare_lint! {
|
declare_lint! {
|
||||||
pub SAFE_PACKED_BORROWS,
|
pub SAFE_PACKED_BORROWS,
|
||||||
Warn,
|
Warn,
|
||||||
"safe borrows of fields of packed structs were was erroneously allowed"
|
"safe borrows of fields of packed structs were was erroneously allowed",
|
||||||
|
@future_incompatible = FutureIncompatibleInfo {
|
||||||
|
reference: "issue #46043 <https://github.com/rust-lang/rust/issues/46043>",
|
||||||
|
edition: None,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
declare_lint! {
|
declare_lint! {
|
||||||
pub PATTERNS_IN_FNS_WITHOUT_BODY,
|
pub PATTERNS_IN_FNS_WITHOUT_BODY,
|
||||||
Warn,
|
Warn,
|
||||||
"patterns in functions without body were erroneously allowed"
|
"patterns in functions without body were erroneously allowed",
|
||||||
|
@future_incompatible = FutureIncompatibleInfo {
|
||||||
|
reference: "issue #35203 <https://github.com/rust-lang/rust/issues/35203>",
|
||||||
|
edition: None,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
declare_lint! {
|
declare_lint! {
|
||||||
pub LEGACY_DIRECTORY_OWNERSHIP,
|
pub LEGACY_DIRECTORY_OWNERSHIP,
|
||||||
Deny,
|
Deny,
|
||||||
"non-inline, non-`#[path]` modules (e.g., `mod foo;`) were erroneously allowed in some files \
|
"non-inline, non-`#[path]` modules (e.g., `mod foo;`) were erroneously allowed in some files \
|
||||||
not named `mod.rs`"
|
not named `mod.rs`",
|
||||||
|
@future_incompatible = FutureIncompatibleInfo {
|
||||||
|
reference: "issue #37872 <https://github.com/rust-lang/rust/issues/37872>",
|
||||||
|
edition: None,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
declare_lint! {
|
declare_lint! {
|
||||||
pub LEGACY_CONSTRUCTOR_VISIBILITY,
|
pub LEGACY_CONSTRUCTOR_VISIBILITY,
|
||||||
Deny,
|
Deny,
|
||||||
"detects use of struct constructors that would be invisible with new visibility rules"
|
"detects use of struct constructors that would be invisible with new visibility rules",
|
||||||
|
@future_incompatible = FutureIncompatibleInfo {
|
||||||
|
reference: "issue #39207 <https://github.com/rust-lang/rust/issues/39207>",
|
||||||
|
edition: None,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
declare_lint! {
|
declare_lint! {
|
||||||
pub MISSING_FRAGMENT_SPECIFIER,
|
pub MISSING_FRAGMENT_SPECIFIER,
|
||||||
Deny,
|
Deny,
|
||||||
"detects missing fragment specifiers in unused `macro_rules!` patterns"
|
"detects missing fragment specifiers in unused `macro_rules!` patterns",
|
||||||
|
@future_incompatible = FutureIncompatibleInfo {
|
||||||
|
reference: "issue #40107 <https://github.com/rust-lang/rust/issues/40107>",
|
||||||
|
edition: None,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
declare_lint! {
|
declare_lint! {
|
||||||
pub PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES,
|
pub PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES,
|
||||||
Deny,
|
Deny,
|
||||||
"detects parenthesized generic parameters in type and module names"
|
"detects parenthesized generic parameters in type and module names",
|
||||||
|
@future_incompatible = FutureIncompatibleInfo {
|
||||||
|
reference: "issue #42238 <https://github.com/rust-lang/rust/issues/42238>",
|
||||||
|
edition: None,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
declare_lint! {
|
declare_lint! {
|
||||||
pub LATE_BOUND_LIFETIME_ARGUMENTS,
|
pub LATE_BOUND_LIFETIME_ARGUMENTS,
|
||||||
Warn,
|
Warn,
|
||||||
"detects generic lifetime arguments in path segments with late bound lifetime parameters"
|
"detects generic lifetime arguments in path segments with late bound lifetime parameters",
|
||||||
|
@future_incompatible = FutureIncompatibleInfo {
|
||||||
|
reference: "issue #42868 <https://github.com/rust-lang/rust/issues/42868>",
|
||||||
|
edition: None,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
declare_lint! {
|
declare_lint! {
|
||||||
pub ORDER_DEPENDENT_TRAIT_OBJECTS,
|
pub ORDER_DEPENDENT_TRAIT_OBJECTS,
|
||||||
Deny,
|
Deny,
|
||||||
"trait-object types were treated as different depending on marker-trait order"
|
"trait-object types were treated as different depending on marker-trait order",
|
||||||
|
@future_incompatible = FutureIncompatibleInfo {
|
||||||
|
reference: "issue #56484 <https://github.com/rust-lang/rust/issues/56484>",
|
||||||
|
edition: None,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
declare_lint! {
|
declare_lint! {
|
||||||
pub DEPRECATED,
|
pub DEPRECATED,
|
||||||
Warn,
|
Warn,
|
||||||
"detects use of deprecated items",
|
"detects use of deprecated items",
|
||||||
report_in_external_macro: true
|
report_in_external_macro
|
||||||
}
|
}
|
||||||
|
|
||||||
declare_lint! {
|
declare_lint! {
|
||||||
@ -253,7 +302,11 @@ declare_lint! {
|
|||||||
declare_lint! {
|
declare_lint! {
|
||||||
pub TYVAR_BEHIND_RAW_POINTER,
|
pub TYVAR_BEHIND_RAW_POINTER,
|
||||||
Warn,
|
Warn,
|
||||||
"raw pointer to an inference variable"
|
"raw pointer to an inference variable",
|
||||||
|
@future_incompatible = FutureIncompatibleInfo {
|
||||||
|
reference: "issue #46906 <https://github.com/rust-lang/rust/issues/46906>",
|
||||||
|
edition: Some(Edition::Edition2018),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
declare_lint! {
|
declare_lint! {
|
||||||
@ -272,19 +325,33 @@ declare_lint! {
|
|||||||
pub ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE,
|
pub ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE,
|
||||||
Allow,
|
Allow,
|
||||||
"fully qualified paths that start with a module name \
|
"fully qualified paths that start with a module name \
|
||||||
instead of `crate`, `self`, or an extern crate name"
|
instead of `crate`, `self`, or an extern crate name",
|
||||||
|
@future_incompatible = FutureIncompatibleInfo {
|
||||||
|
reference: "issue #53130 <https://github.com/rust-lang/rust/issues/53130>",
|
||||||
|
edition: Some(Edition::Edition2018),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
declare_lint! {
|
declare_lint! {
|
||||||
pub ILLEGAL_FLOATING_POINT_LITERAL_PATTERN,
|
pub ILLEGAL_FLOATING_POINT_LITERAL_PATTERN,
|
||||||
Warn,
|
Warn,
|
||||||
"floating-point literals cannot be used in patterns"
|
"floating-point literals cannot be used in patterns",
|
||||||
|
@future_incompatible = FutureIncompatibleInfo {
|
||||||
|
reference: "issue #41620 <https://github.com/rust-lang/rust/issues/41620>",
|
||||||
|
edition: None,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
declare_lint! {
|
declare_lint! {
|
||||||
pub UNSTABLE_NAME_COLLISIONS,
|
pub UNSTABLE_NAME_COLLISIONS,
|
||||||
Warn,
|
Warn,
|
||||||
"detects name collision with an existing but unstable method"
|
"detects name collision with an existing but unstable method",
|
||||||
|
@future_incompatible = FutureIncompatibleInfo {
|
||||||
|
reference: "issue #48919 <https://github.com/rust-lang/rust/issues/48919>",
|
||||||
|
edition: None,
|
||||||
|
// Note: this item represents future incompatibility of all unstable functions in the
|
||||||
|
// standard library, and thus should never be removed or changed to an error.
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
declare_lint! {
|
declare_lint! {
|
||||||
@ -302,7 +369,11 @@ declare_lint! {
|
|||||||
declare_lint! {
|
declare_lint! {
|
||||||
pub DUPLICATE_MACRO_EXPORTS,
|
pub DUPLICATE_MACRO_EXPORTS,
|
||||||
Deny,
|
Deny,
|
||||||
"detects duplicate macro exports"
|
"detects duplicate macro exports",
|
||||||
|
@future_incompatible = FutureIncompatibleInfo {
|
||||||
|
reference: "issue #35896 <https://github.com/rust-lang/rust/issues/35896>",
|
||||||
|
edition: Some(Edition::Edition2018),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
declare_lint! {
|
declare_lint! {
|
||||||
@ -326,13 +397,21 @@ declare_lint! {
|
|||||||
declare_lint! {
|
declare_lint! {
|
||||||
pub WHERE_CLAUSES_OBJECT_SAFETY,
|
pub WHERE_CLAUSES_OBJECT_SAFETY,
|
||||||
Warn,
|
Warn,
|
||||||
"checks the object safety of where clauses"
|
"checks the object safety of where clauses",
|
||||||
|
@future_incompatible = FutureIncompatibleInfo {
|
||||||
|
reference: "issue #51443 <https://github.com/rust-lang/rust/issues/51443>",
|
||||||
|
edition: None,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
declare_lint! {
|
declare_lint! {
|
||||||
pub PROC_MACRO_DERIVE_RESOLUTION_FALLBACK,
|
pub PROC_MACRO_DERIVE_RESOLUTION_FALLBACK,
|
||||||
Warn,
|
Warn,
|
||||||
"detects proc macro derives using inaccessible names from parent modules"
|
"detects proc macro derives using inaccessible names from parent modules",
|
||||||
|
@future_incompatible = FutureIncompatibleInfo {
|
||||||
|
reference: "issue #50504 <https://github.com/rust-lang/rust/issues/50504>",
|
||||||
|
edition: None,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
declare_lint! {
|
declare_lint! {
|
||||||
@ -346,7 +425,11 @@ declare_lint! {
|
|||||||
pub MACRO_EXPANDED_MACRO_EXPORTS_ACCESSED_BY_ABSOLUTE_PATHS,
|
pub MACRO_EXPANDED_MACRO_EXPORTS_ACCESSED_BY_ABSOLUTE_PATHS,
|
||||||
Deny,
|
Deny,
|
||||||
"macro-expanded `macro_export` macros from the current crate \
|
"macro-expanded `macro_export` macros from the current crate \
|
||||||
cannot be referred to by absolute paths"
|
cannot be referred to by absolute paths",
|
||||||
|
@future_incompatible = FutureIncompatibleInfo {
|
||||||
|
reference: "issue #52234 <https://github.com/rust-lang/rust/issues/52234>",
|
||||||
|
edition: None,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
declare_lint! {
|
declare_lint! {
|
||||||
@ -359,7 +442,11 @@ declare_lint! {
|
|||||||
pub INDIRECT_STRUCTURAL_MATCH,
|
pub INDIRECT_STRUCTURAL_MATCH,
|
||||||
// defaulting to allow until rust-lang/rust#62614 is fixed.
|
// defaulting to allow until rust-lang/rust#62614 is fixed.
|
||||||
Allow,
|
Allow,
|
||||||
"pattern with const indirectly referencing non-`#[structural_match]` type"
|
"pattern with const indirectly referencing non-`#[structural_match]` type",
|
||||||
|
@future_incompatible = FutureIncompatibleInfo {
|
||||||
|
reference: "issue #62411 <https://github.com/rust-lang/rust/issues/62411>",
|
||||||
|
edition: None,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Some lints that are buffered from `libsyntax`. See `syntax::early_buffered_lints`.
|
/// Some lints that are buffered from `libsyntax`. See `syntax::early_buffered_lints`.
|
||||||
@ -367,7 +454,11 @@ pub mod parser {
|
|||||||
declare_lint! {
|
declare_lint! {
|
||||||
pub ILL_FORMED_ATTRIBUTE_INPUT,
|
pub ILL_FORMED_ATTRIBUTE_INPUT,
|
||||||
Warn,
|
Warn,
|
||||||
"ill-formed attribute inputs that were previously accepted and used in practice"
|
"ill-formed attribute inputs that were previously accepted and used in practice",
|
||||||
|
@future_incompatible = super::FutureIncompatibleInfo {
|
||||||
|
reference: "issue #57571 <https://github.com/rust-lang/rust/issues/57571>",
|
||||||
|
edition: None,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
declare_lint! {
|
declare_lint! {
|
||||||
@ -387,31 +478,47 @@ declare_lint! {
|
|||||||
pub DEPRECATED_IN_FUTURE,
|
pub DEPRECATED_IN_FUTURE,
|
||||||
Allow,
|
Allow,
|
||||||
"detects use of items that will be deprecated in a future version",
|
"detects use of items that will be deprecated in a future version",
|
||||||
report_in_external_macro: true
|
report_in_external_macro
|
||||||
}
|
}
|
||||||
|
|
||||||
declare_lint! {
|
declare_lint! {
|
||||||
pub AMBIGUOUS_ASSOCIATED_ITEMS,
|
pub AMBIGUOUS_ASSOCIATED_ITEMS,
|
||||||
Deny,
|
Deny,
|
||||||
"ambiguous associated items"
|
"ambiguous associated items",
|
||||||
|
@future_incompatible = FutureIncompatibleInfo {
|
||||||
|
reference: "issue #57644 <https://github.com/rust-lang/rust/issues/57644>",
|
||||||
|
edition: None,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
declare_lint! {
|
declare_lint! {
|
||||||
pub NESTED_IMPL_TRAIT,
|
pub NESTED_IMPL_TRAIT,
|
||||||
Warn,
|
Warn,
|
||||||
"nested occurrence of `impl Trait` type"
|
"nested occurrence of `impl Trait` type",
|
||||||
|
@future_incompatible = FutureIncompatibleInfo {
|
||||||
|
reference: "issue #59014 <https://github.com/rust-lang/rust/issues/59014>",
|
||||||
|
edition: None,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
declare_lint! {
|
declare_lint! {
|
||||||
pub MUTABLE_BORROW_RESERVATION_CONFLICT,
|
pub MUTABLE_BORROW_RESERVATION_CONFLICT,
|
||||||
Warn,
|
Warn,
|
||||||
"reservation of a two-phased borrow conflicts with other shared borrows"
|
"reservation of a two-phased borrow conflicts with other shared borrows",
|
||||||
|
@future_incompatible = FutureIncompatibleInfo {
|
||||||
|
reference: "issue #59159 <https://github.com/rust-lang/rust/issues/59159>",
|
||||||
|
edition: None,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
declare_lint! {
|
declare_lint! {
|
||||||
pub SOFT_UNSTABLE,
|
pub SOFT_UNSTABLE,
|
||||||
Deny,
|
Deny,
|
||||||
"a feature gate that doesn't break dependent crates"
|
"a feature gate that doesn't break dependent crates",
|
||||||
|
@future_incompatible = FutureIncompatibleInfo {
|
||||||
|
reference: "issue #64266 <https://github.com/rust-lang/rust/issues/64266>",
|
||||||
|
edition: None,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
declare_lint_pass! {
|
declare_lint_pass! {
|
||||||
|
@ -22,11 +22,11 @@ use crate::hir::intravisit as hir_visit;
|
|||||||
use crate::hir::intravisit::Visitor;
|
use crate::hir::intravisit::Visitor;
|
||||||
use crate::hir::map::{definitions::DisambiguatedDefPathData, DefPathData};
|
use crate::hir::map::{definitions::DisambiguatedDefPathData, DefPathData};
|
||||||
use crate::lint::{EarlyLintPass, LateLintPass, EarlyLintPassObject, LateLintPassObject};
|
use crate::lint::{EarlyLintPass, LateLintPass, EarlyLintPassObject, LateLintPassObject};
|
||||||
use crate::lint::{LintArray, Level, Lint, LintId, LintPass, LintBuffer};
|
use crate::lint::{Level, Lint, LintId, LintPass, LintBuffer, FutureIncompatibleInfo};
|
||||||
use crate::lint::builtin::BuiltinLintDiagnostics;
|
use crate::lint::builtin::BuiltinLintDiagnostics;
|
||||||
use crate::lint::levels::{LintLevelSets, LintLevelsBuilder};
|
use crate::lint::levels::{LintLevelSets, LintLevelsBuilder};
|
||||||
use crate::middle::privacy::AccessLevels;
|
use crate::middle::privacy::AccessLevels;
|
||||||
use crate::session::{config, early_error, Session};
|
use crate::session::Session;
|
||||||
use crate::ty::{self, print::Printer, subst::GenericArg, TyCtxt, Ty};
|
use crate::ty::{self, print::Printer, subst::GenericArg, TyCtxt, Ty};
|
||||||
use crate::ty::layout::{LayoutError, LayoutOf, TyLayout};
|
use crate::ty::layout::{LayoutError, LayoutOf, TyLayout};
|
||||||
use crate::util::nodemap::FxHashMap;
|
use crate::util::nodemap::FxHashMap;
|
||||||
@ -35,10 +35,9 @@ use crate::util::common::time;
|
|||||||
use errors::DiagnosticBuilder;
|
use errors::DiagnosticBuilder;
|
||||||
use std::slice;
|
use std::slice;
|
||||||
use std::default::Default as StdDefault;
|
use std::default::Default as StdDefault;
|
||||||
use rustc_data_structures::sync::{ReadGuard, Lock, ParallelIterator, join, par_iter};
|
use rustc_data_structures::sync::{self, ParallelIterator, join, par_iter};
|
||||||
use rustc_serialize::{Decoder, Decodable, Encoder, Encodable};
|
use rustc_serialize::{Decoder, Decodable, Encoder, Encodable};
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use syntax::edition;
|
|
||||||
use syntax::util::lev_distance::find_best_match_for_name;
|
use syntax::util::lev_distance::find_best_match_for_name;
|
||||||
use syntax::visit as ast_visit;
|
use syntax::visit as ast_visit;
|
||||||
use syntax_pos::{MultiSpan, Span, symbol::Symbol};
|
use syntax_pos::{MultiSpan, Span, symbol::Symbol};
|
||||||
@ -50,24 +49,25 @@ use syntax_pos::{MultiSpan, Span, symbol::Symbol};
|
|||||||
pub struct LintStore {
|
pub struct LintStore {
|
||||||
/// Registered lints. The bool is true if the lint was
|
/// Registered lints. The bool is true if the lint was
|
||||||
/// added by a plugin.
|
/// added by a plugin.
|
||||||
lints: Vec<(&'static Lint, bool)>,
|
lints: Vec<&'static Lint>,
|
||||||
|
|
||||||
/// Trait objects for each lint pass.
|
/// Constructor functions for each variety of lint pass.
|
||||||
/// This is only `None` while performing a lint pass.
|
///
|
||||||
pre_expansion_passes: Option<Vec<EarlyLintPassObject>>,
|
/// These should only be called once, but since we want to avoid locks or
|
||||||
early_passes: Option<Vec<EarlyLintPassObject>>,
|
/// interior mutability, we don't enforce this (and lints should, in theory,
|
||||||
late_passes: Lock<Option<Vec<LateLintPassObject>>>,
|
/// be compatible with being constructed more than once, though not
|
||||||
late_module_passes: Vec<LateLintPassObject>,
|
/// necessarily in a sane manner. This is safe though.)
|
||||||
|
pre_expansion_passes: Vec<Box<dyn Fn() -> EarlyLintPassObject + sync::Send + sync::Sync>>,
|
||||||
|
early_passes: Vec<Box<dyn Fn() -> EarlyLintPassObject + sync::Send + sync::Sync>>,
|
||||||
|
late_passes: Vec<Box<dyn Fn() -> LateLintPassObject + sync::Send + sync::Sync>>,
|
||||||
|
/// This is unique in that we construct them per-module, so not once.
|
||||||
|
late_module_passes: Vec<Box<dyn Fn() -> LateLintPassObject + sync::Send + sync::Sync>>,
|
||||||
|
|
||||||
/// Lints indexed by name.
|
/// Lints indexed by name.
|
||||||
by_name: FxHashMap<String, TargetLint>,
|
by_name: FxHashMap<String, TargetLint>,
|
||||||
|
|
||||||
/// Map of registered lint groups to what lints they expand to.
|
/// Map of registered lint groups to what lints they expand to.
|
||||||
lint_groups: FxHashMap<&'static str, LintGroup>,
|
lint_groups: FxHashMap<&'static str, LintGroup>,
|
||||||
|
|
||||||
/// Extra info for future incompatibility lints, describing the
|
|
||||||
/// issue or RFC that caused the incompatibility.
|
|
||||||
future_incompatible: FxHashMap<LintId, FutureIncompatibleInfo>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Lints that are buffered up early on in the `Session` before the
|
/// Lints that are buffered up early on in the `Session` before the
|
||||||
@ -81,18 +81,6 @@ pub struct BufferedEarlyLint {
|
|||||||
pub diagnostic: BuiltinLintDiagnostics,
|
pub diagnostic: BuiltinLintDiagnostics,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Extra information for a future incompatibility lint. See the call
|
|
||||||
/// to `register_future_incompatible` in `librustc_lint/lib.rs` for
|
|
||||||
/// guidelines.
|
|
||||||
pub struct FutureIncompatibleInfo {
|
|
||||||
pub id: LintId,
|
|
||||||
/// e.g., a URL for an issue/PR/RFC or error code
|
|
||||||
pub reference: &'static str,
|
|
||||||
/// If this is an edition fixing lint, the edition in which
|
|
||||||
/// this lint becomes obsolete
|
|
||||||
pub edition: Option<edition::Edition>,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The target of the `by_name` map, which accounts for renaming/deprecation.
|
/// The target of the `by_name` map, which accounts for renaming/deprecation.
|
||||||
enum TargetLint {
|
enum TargetLint {
|
||||||
/// A direct lint target
|
/// A direct lint target
|
||||||
@ -142,17 +130,16 @@ impl LintStore {
|
|||||||
pub fn new() -> LintStore {
|
pub fn new() -> LintStore {
|
||||||
LintStore {
|
LintStore {
|
||||||
lints: vec![],
|
lints: vec![],
|
||||||
pre_expansion_passes: Some(vec![]),
|
pre_expansion_passes: vec![],
|
||||||
early_passes: Some(vec![]),
|
early_passes: vec![],
|
||||||
late_passes: Lock::new(Some(vec![])),
|
late_passes: vec![],
|
||||||
late_module_passes: vec![],
|
late_module_passes: vec![],
|
||||||
by_name: Default::default(),
|
by_name: Default::default(),
|
||||||
future_incompatible: Default::default(),
|
|
||||||
lint_groups: Default::default(),
|
lint_groups: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_lints<'t>(&'t self) -> &'t [(&'static Lint, bool)] {
|
pub fn get_lints<'t>(&'t self) -> &'t [&'static Lint] {
|
||||||
&self.lints
|
&self.lints
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -168,101 +155,66 @@ impl LintStore {
|
|||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn register_early_pass(&mut self,
|
pub fn register_early_pass(
|
||||||
sess: Option<&Session>,
|
&mut self,
|
||||||
from_plugin: bool,
|
pass: impl Fn() -> EarlyLintPassObject + 'static + sync::Send + sync::Sync
|
||||||
register_only: bool,
|
) {
|
||||||
pass: EarlyLintPassObject) {
|
self.early_passes.push(Box::new(pass));
|
||||||
self.push_pass(sess, from_plugin, &pass);
|
|
||||||
if !register_only {
|
|
||||||
self.early_passes.as_mut().unwrap().push(pass);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn register_pre_expansion_pass(
|
pub fn register_pre_expansion_pass(
|
||||||
&mut self,
|
&mut self,
|
||||||
sess: Option<&Session>,
|
pass: impl Fn() -> EarlyLintPassObject + 'static + sync::Send + sync::Sync,
|
||||||
from_plugin: bool,
|
|
||||||
register_only: bool,
|
|
||||||
pass: EarlyLintPassObject,
|
|
||||||
) {
|
) {
|
||||||
self.push_pass(sess, from_plugin, &pass);
|
self.pre_expansion_passes.push(Box::new(pass));
|
||||||
if !register_only {
|
|
||||||
self.pre_expansion_passes.as_mut().unwrap().push(pass);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn register_late_pass(&mut self,
|
pub fn register_late_pass(
|
||||||
sess: Option<&Session>,
|
&mut self,
|
||||||
from_plugin: bool,
|
pass: impl Fn() -> LateLintPassObject + 'static + sync::Send + sync::Sync,
|
||||||
register_only: bool,
|
) {
|
||||||
per_module: bool,
|
self.late_passes.push(Box::new(pass));
|
||||||
pass: LateLintPassObject) {
|
}
|
||||||
self.push_pass(sess, from_plugin, &pass);
|
|
||||||
if !register_only {
|
pub fn register_late_mod_pass(
|
||||||
if per_module {
|
&mut self,
|
||||||
self.late_module_passes.push(pass);
|
pass: impl Fn() -> LateLintPassObject + 'static + sync::Send + sync::Sync,
|
||||||
} else {
|
) {
|
||||||
self.late_passes.lock().as_mut().unwrap().push(pass);
|
self.late_module_passes.push(Box::new(pass));
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper method for register_early/late_pass
|
// Helper method for register_early/late_pass
|
||||||
fn push_pass<P: LintPass + ?Sized + 'static>(&mut self,
|
pub fn register_lints(&mut self, lints: &[&'static Lint]) {
|
||||||
sess: Option<&Session>,
|
for lint in lints {
|
||||||
from_plugin: bool,
|
self.lints.push(lint);
|
||||||
pass: &Box<P>) {
|
|
||||||
for lint in pass.get_lints() {
|
|
||||||
self.lints.push((lint, from_plugin));
|
|
||||||
|
|
||||||
let id = LintId::of(lint);
|
let id = LintId::of(lint);
|
||||||
if self.by_name.insert(lint.name_lower(), Id(id)).is_some() {
|
if self.by_name.insert(lint.name_lower(), Id(id)).is_some() {
|
||||||
let msg = format!("duplicate specification of lint {}", lint.name_lower());
|
bug!("duplicate specification of lint {}", lint.name_lower())
|
||||||
match (sess, from_plugin) {
|
}
|
||||||
// We load builtin lints first, so a duplicate is a compiler bug.
|
|
||||||
// Use early_error when handling -W help with no crate.
|
|
||||||
(None, _) => early_error(config::ErrorOutputType::default(), &msg[..]),
|
|
||||||
(Some(_), false) => bug!("{}", msg),
|
|
||||||
|
|
||||||
// A duplicate name from a plugin is a user error.
|
if let Some(FutureIncompatibleInfo { edition, .. }) = lint.future_incompatible {
|
||||||
(Some(sess), true) => sess.err(&msg[..]),
|
if let Some(edition) = edition {
|
||||||
|
self.lint_groups.entry(edition.lint_name())
|
||||||
|
.or_insert(LintGroup {
|
||||||
|
lint_ids: vec![],
|
||||||
|
from_plugin: lint.is_plugin,
|
||||||
|
depr: None,
|
||||||
|
})
|
||||||
|
.lint_ids.push(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.lint_groups.entry("future_incompatible")
|
||||||
|
.or_insert(LintGroup {
|
||||||
|
lint_ids: vec![],
|
||||||
|
from_plugin: lint.is_plugin,
|
||||||
|
depr: None,
|
||||||
|
})
|
||||||
|
.lint_ids.push(id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn register_future_incompatible(&mut self,
|
|
||||||
sess: Option<&Session>,
|
|
||||||
lints: Vec<FutureIncompatibleInfo>) {
|
|
||||||
|
|
||||||
for edition in edition::ALL_EDITIONS {
|
|
||||||
let lints = lints.iter().filter(|f| f.edition == Some(*edition)).map(|f| f.id)
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
if !lints.is_empty() {
|
|
||||||
self.register_group(sess, false, edition.lint_name(), None, lints)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut future_incompatible = Vec::with_capacity(lints.len());
|
|
||||||
for lint in lints {
|
|
||||||
future_incompatible.push(lint.id);
|
|
||||||
self.future_incompatible.insert(lint.id, lint);
|
|
||||||
}
|
|
||||||
|
|
||||||
self.register_group(
|
|
||||||
sess,
|
|
||||||
false,
|
|
||||||
"future_incompatible",
|
|
||||||
None,
|
|
||||||
future_incompatible,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn future_incompatible(&self, id: LintId) -> Option<&FutureIncompatibleInfo> {
|
|
||||||
self.future_incompatible.get(&id)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn register_group_alias(
|
pub fn register_group_alias(
|
||||||
&mut self,
|
&mut self,
|
||||||
lint_name: &'static str,
|
lint_name: &'static str,
|
||||||
@ -277,7 +229,6 @@ impl LintStore {
|
|||||||
|
|
||||||
pub fn register_group(
|
pub fn register_group(
|
||||||
&mut self,
|
&mut self,
|
||||||
sess: Option<&Session>,
|
|
||||||
from_plugin: bool,
|
from_plugin: bool,
|
||||||
name: &'static str,
|
name: &'static str,
|
||||||
deprecated_name: Option<&'static str>,
|
deprecated_name: Option<&'static str>,
|
||||||
@ -300,16 +251,7 @@ impl LintStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !new {
|
if !new {
|
||||||
let msg = format!("duplicate specification of lint group {}", name);
|
bug!("duplicate specification of lint group {}", name);
|
||||||
match (sess, from_plugin) {
|
|
||||||
// We load builtin lints first, so a duplicate is a compiler bug.
|
|
||||||
// Use early_error when handling -W help with no crate.
|
|
||||||
(None, _) => early_error(config::ErrorOutputType::default(), &msg[..]),
|
|
||||||
(Some(_), false) => bug!("{}", msg),
|
|
||||||
|
|
||||||
// A duplicate name from a plugin is a user error.
|
|
||||||
(Some(sess), true) => sess.err(&msg[..]),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -522,7 +464,7 @@ pub struct LateContext<'a, 'tcx> {
|
|||||||
pub access_levels: &'a AccessLevels,
|
pub access_levels: &'a AccessLevels,
|
||||||
|
|
||||||
/// The store of registered lints and the lint levels.
|
/// The store of registered lints and the lint levels.
|
||||||
lint_store: ReadGuard<'a, LintStore>,
|
lint_store: &'tcx LintStore,
|
||||||
|
|
||||||
last_node_with_lint_attrs: hir::HirId,
|
last_node_with_lint_attrs: hir::HirId,
|
||||||
|
|
||||||
@ -550,7 +492,7 @@ pub struct EarlyContext<'a> {
|
|||||||
builder: LintLevelsBuilder<'a>,
|
builder: LintLevelsBuilder<'a>,
|
||||||
|
|
||||||
/// The store of registered lints and the lint levels.
|
/// The store of registered lints and the lint levels.
|
||||||
lint_store: ReadGuard<'a, LintStore>,
|
lint_store: &'a LintStore,
|
||||||
|
|
||||||
buffered: LintBuffer,
|
buffered: LintBuffer,
|
||||||
}
|
}
|
||||||
@ -639,14 +581,15 @@ pub trait LintContext: Sized {
|
|||||||
impl<'a> EarlyContext<'a> {
|
impl<'a> EarlyContext<'a> {
|
||||||
fn new(
|
fn new(
|
||||||
sess: &'a Session,
|
sess: &'a Session,
|
||||||
|
lint_store: &'a LintStore,
|
||||||
krate: &'a ast::Crate,
|
krate: &'a ast::Crate,
|
||||||
buffered: LintBuffer,
|
buffered: LintBuffer,
|
||||||
) -> EarlyContext<'a> {
|
) -> EarlyContext<'a> {
|
||||||
EarlyContext {
|
EarlyContext {
|
||||||
sess,
|
sess,
|
||||||
krate,
|
krate,
|
||||||
lint_store: sess.lint_store.borrow(),
|
lint_store,
|
||||||
builder: LintLevelSets::builder(sess),
|
builder: LintLevelSets::builder(sess, lint_store),
|
||||||
buffered,
|
buffered,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -681,7 +624,7 @@ impl<'a, T: EarlyLintPass> EarlyContextAndPass<'a, T> {
|
|||||||
f: F)
|
f: F)
|
||||||
where F: FnOnce(&mut Self)
|
where F: FnOnce(&mut Self)
|
||||||
{
|
{
|
||||||
let push = self.context.builder.push(attrs);
|
let push = self.context.builder.push(attrs, &self.context.lint_store);
|
||||||
self.check_id(id);
|
self.check_id(id);
|
||||||
self.enter_attrs(attrs);
|
self.enter_attrs(attrs);
|
||||||
f(self);
|
f(self);
|
||||||
@ -875,7 +818,7 @@ impl<'a, 'tcx> LateContext<'a, 'tcx> {
|
|||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
path.push(disambiguated_data.data.as_interned_str().as_symbol());
|
path.push(disambiguated_data.data.as_symbol());
|
||||||
Ok(path)
|
Ok(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1355,10 +1298,6 @@ impl LintPass for LateLintPassObjects<'_> {
|
|||||||
fn name(&self) -> &'static str {
|
fn name(&self) -> &'static str {
|
||||||
panic!()
|
panic!()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_lints(&self) -> LintArray {
|
|
||||||
panic!()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! expand_late_lint_pass_impl_methods {
|
macro_rules! expand_late_lint_pass_impl_methods {
|
||||||
@ -1393,7 +1332,7 @@ fn late_lint_mod_pass<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>(
|
|||||||
tables: &ty::TypeckTables::empty(None),
|
tables: &ty::TypeckTables::empty(None),
|
||||||
param_env: ty::ParamEnv::empty(),
|
param_env: ty::ParamEnv::empty(),
|
||||||
access_levels,
|
access_levels,
|
||||||
lint_store: tcx.sess.lint_store.borrow(),
|
lint_store: &tcx.lint_store,
|
||||||
last_node_with_lint_attrs: tcx.hir().as_local_hir_id(module_def_id).unwrap(),
|
last_node_with_lint_attrs: tcx.hir().as_local_hir_id(module_def_id).unwrap(),
|
||||||
generics: None,
|
generics: None,
|
||||||
only_module: true,
|
only_module: true,
|
||||||
@ -1425,8 +1364,8 @@ pub fn late_lint_mod<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>(
|
|||||||
|
|
||||||
late_lint_mod_pass(tcx, module_def_id, builtin_lints);
|
late_lint_mod_pass(tcx, module_def_id, builtin_lints);
|
||||||
|
|
||||||
let mut passes: Vec<_> = tcx.sess.lint_store.borrow().late_module_passes
|
let mut passes: Vec<_> = tcx.lint_store.late_module_passes
|
||||||
.iter().map(|pass| pass.fresh_late_pass()).collect();
|
.iter().map(|pass| (pass)()).collect();
|
||||||
|
|
||||||
if !passes.is_empty() {
|
if !passes.is_empty() {
|
||||||
late_lint_mod_pass(tcx, module_def_id, LateLintPassObjects { lints: &mut passes[..] });
|
late_lint_mod_pass(tcx, module_def_id, LateLintPassObjects { lints: &mut passes[..] });
|
||||||
@ -1443,7 +1382,7 @@ fn late_lint_pass_crate<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>(tcx: TyCtxt<'tc
|
|||||||
tables: &ty::TypeckTables::empty(None),
|
tables: &ty::TypeckTables::empty(None),
|
||||||
param_env: ty::ParamEnv::empty(),
|
param_env: ty::ParamEnv::empty(),
|
||||||
access_levels,
|
access_levels,
|
||||||
lint_store: tcx.sess.lint_store.borrow(),
|
lint_store: &tcx.lint_store,
|
||||||
last_node_with_lint_attrs: hir::CRATE_HIR_ID,
|
last_node_with_lint_attrs: hir::CRATE_HIR_ID,
|
||||||
generics: None,
|
generics: None,
|
||||||
only_module: false,
|
only_module: false,
|
||||||
@ -1467,7 +1406,8 @@ fn late_lint_pass_crate<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>(tcx: TyCtxt<'tc
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn late_lint_crate<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>(tcx: TyCtxt<'tcx>, builtin_lints: T) {
|
fn late_lint_crate<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>(tcx: TyCtxt<'tcx>, builtin_lints: T) {
|
||||||
let mut passes = tcx.sess.lint_store.borrow().late_passes.lock().take().unwrap();
|
let mut passes = tcx.lint_store
|
||||||
|
.late_passes.iter().map(|p| (p)()).collect::<Vec<_>>();
|
||||||
|
|
||||||
if !tcx.sess.opts.debugging_opts.no_interleave_lints {
|
if !tcx.sess.opts.debugging_opts.no_interleave_lints {
|
||||||
if !passes.is_empty() {
|
if !passes.is_empty() {
|
||||||
@ -1482,8 +1422,8 @@ fn late_lint_crate<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>(tcx: TyCtxt<'tcx>, b
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut passes: Vec<_> = tcx.sess.lint_store.borrow().late_module_passes
|
let mut passes: Vec<_> = tcx.lint_store.late_module_passes
|
||||||
.iter().map(|pass| pass.fresh_late_pass()).collect();
|
.iter().map(|pass| (pass)()).collect();
|
||||||
|
|
||||||
for pass in &mut passes {
|
for pass in &mut passes {
|
||||||
time(tcx.sess, &format!("running late module lint: {}", pass.name()), || {
|
time(tcx.sess, &format!("running late module lint: {}", pass.name()), || {
|
||||||
@ -1491,9 +1431,6 @@ fn late_lint_crate<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>(tcx: TyCtxt<'tcx>, b
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Put the passes back in the session.
|
|
||||||
*tcx.sess.lint_store.borrow().late_passes.lock() = Some(passes);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Performs lint checking on a crate.
|
/// Performs lint checking on a crate.
|
||||||
@ -1525,10 +1462,6 @@ impl LintPass for EarlyLintPassObjects<'_> {
|
|||||||
fn name(&self) -> &'static str {
|
fn name(&self) -> &'static str {
|
||||||
panic!()
|
panic!()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_lints(&self) -> LintArray {
|
|
||||||
panic!()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! expand_early_lint_pass_impl_methods {
|
macro_rules! expand_early_lint_pass_impl_methods {
|
||||||
@ -1553,12 +1486,13 @@ early_lint_methods!(early_lint_pass_impl, []);
|
|||||||
|
|
||||||
fn early_lint_crate<T: EarlyLintPass>(
|
fn early_lint_crate<T: EarlyLintPass>(
|
||||||
sess: &Session,
|
sess: &Session,
|
||||||
|
lint_store: &LintStore,
|
||||||
krate: &ast::Crate,
|
krate: &ast::Crate,
|
||||||
pass: T,
|
pass: T,
|
||||||
buffered: LintBuffer,
|
buffered: LintBuffer,
|
||||||
) -> LintBuffer {
|
) -> LintBuffer {
|
||||||
let mut cx = EarlyContextAndPass {
|
let mut cx = EarlyContextAndPass {
|
||||||
context: EarlyContext::new(sess, krate, buffered),
|
context: EarlyContext::new(sess, lint_store, krate, buffered),
|
||||||
pass,
|
pass,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1577,28 +1511,30 @@ fn early_lint_crate<T: EarlyLintPass>(
|
|||||||
|
|
||||||
pub fn check_ast_crate<T: EarlyLintPass>(
|
pub fn check_ast_crate<T: EarlyLintPass>(
|
||||||
sess: &Session,
|
sess: &Session,
|
||||||
|
lint_store: &LintStore,
|
||||||
krate: &ast::Crate,
|
krate: &ast::Crate,
|
||||||
pre_expansion: bool,
|
pre_expansion: bool,
|
||||||
builtin_lints: T,
|
builtin_lints: T,
|
||||||
) {
|
) {
|
||||||
let (mut passes, mut buffered) = if pre_expansion {
|
let (mut passes, mut buffered): (Vec<_>, _) = if pre_expansion {
|
||||||
(
|
(
|
||||||
sess.lint_store.borrow_mut().pre_expansion_passes.take().unwrap(),
|
lint_store.pre_expansion_passes.iter().map(|p| (p)()).collect(),
|
||||||
LintBuffer::default(),
|
LintBuffer::default(),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
(
|
(
|
||||||
sess.lint_store.borrow_mut().early_passes.take().unwrap(),
|
lint_store.early_passes.iter().map(|p| (p)()).collect(),
|
||||||
sess.buffered_lints.borrow_mut().take().unwrap(),
|
sess.buffered_lints.borrow_mut().take().unwrap(),
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
if !sess.opts.debugging_opts.no_interleave_lints {
|
if !sess.opts.debugging_opts.no_interleave_lints {
|
||||||
buffered = early_lint_crate(sess, krate, builtin_lints, buffered);
|
buffered = early_lint_crate(sess, lint_store, krate, builtin_lints, buffered);
|
||||||
|
|
||||||
if !passes.is_empty() {
|
if !passes.is_empty() {
|
||||||
buffered = early_lint_crate(
|
buffered = early_lint_crate(
|
||||||
sess,
|
sess,
|
||||||
|
lint_store,
|
||||||
krate,
|
krate,
|
||||||
EarlyLintPassObjects { lints: &mut passes[..] },
|
EarlyLintPassObjects { lints: &mut passes[..] },
|
||||||
buffered,
|
buffered,
|
||||||
@ -1609,6 +1545,7 @@ pub fn check_ast_crate<T: EarlyLintPass>(
|
|||||||
buffered = time(sess, &format!("running lint: {}", pass.name()), || {
|
buffered = time(sess, &format!("running lint: {}", pass.name()), || {
|
||||||
early_lint_crate(
|
early_lint_crate(
|
||||||
sess,
|
sess,
|
||||||
|
lint_store,
|
||||||
krate,
|
krate,
|
||||||
EarlyLintPassObjects { lints: slice::from_mut(pass) },
|
EarlyLintPassObjects { lints: slice::from_mut(pass) },
|
||||||
buffered,
|
buffered,
|
||||||
@ -1617,13 +1554,6 @@ pub fn check_ast_crate<T: EarlyLintPass>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Put the lint store levels and passes back in the session.
|
|
||||||
if pre_expansion {
|
|
||||||
sess.lint_store.borrow_mut().pre_expansion_passes = Some(passes);
|
|
||||||
} else {
|
|
||||||
sess.lint_store.borrow_mut().early_passes = Some(passes);
|
|
||||||
}
|
|
||||||
|
|
||||||
// All of the buffered lints should have been emitted at this point.
|
// All of the buffered lints should have been emitted at this point.
|
||||||
// If not, that means that we somehow buffered a lint for a node id
|
// If not, that means that we somehow buffered a lint for a node id
|
||||||
// that was not lint-checked (perhaps it doesn't exist?). This is a bug.
|
// that was not lint-checked (perhaps it doesn't exist?). This is a bug.
|
||||||
@ -1653,7 +1583,7 @@ impl Decodable for LintId {
|
|||||||
fn decode<D: Decoder>(d: &mut D) -> Result<LintId, D::Error> {
|
fn decode<D: Decoder>(d: &mut D) -> Result<LintId, D::Error> {
|
||||||
let s = d.read_str()?;
|
let s = d.read_str()?;
|
||||||
ty::tls::with(|tcx| {
|
ty::tls::with(|tcx| {
|
||||||
match tcx.sess.lint_store.borrow().find_lints(&s) {
|
match tcx.lint_store.find_lints(&s) {
|
||||||
Ok(ids) => {
|
Ok(ids) => {
|
||||||
if ids.len() != 0 {
|
if ids.len() != 0 {
|
||||||
panic!("invalid lint-id `{}`", s);
|
panic!("invalid lint-id `{}`", s);
|
||||||
|
@ -3,7 +3,7 @@ use std::cmp;
|
|||||||
use crate::hir::HirId;
|
use crate::hir::HirId;
|
||||||
use crate::ich::StableHashingContext;
|
use crate::ich::StableHashingContext;
|
||||||
use crate::lint::builtin;
|
use crate::lint::builtin;
|
||||||
use crate::lint::context::CheckLintNameResult;
|
use crate::lint::context::{LintStore, CheckLintNameResult};
|
||||||
use crate::lint::{self, Lint, LintId, Level, LintSource};
|
use crate::lint::{self, Lint, LintId, Level, LintSource};
|
||||||
use crate::session::Session;
|
use crate::session::Session;
|
||||||
use crate::util::nodemap::FxHashMap;
|
use crate::util::nodemap::FxHashMap;
|
||||||
@ -35,21 +35,20 @@ enum LintSet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl LintLevelSets {
|
impl LintLevelSets {
|
||||||
pub fn new(sess: &Session) -> LintLevelSets {
|
pub fn new(sess: &Session, lint_store: &LintStore) -> LintLevelSets {
|
||||||
let mut me = LintLevelSets {
|
let mut me = LintLevelSets {
|
||||||
list: Vec::new(),
|
list: Vec::new(),
|
||||||
lint_cap: Level::Forbid,
|
lint_cap: Level::Forbid,
|
||||||
};
|
};
|
||||||
me.process_command_line(sess);
|
me.process_command_line(sess, lint_store);
|
||||||
return me
|
return me
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn builder(sess: &Session) -> LintLevelsBuilder<'_> {
|
pub fn builder<'a>(sess: &'a Session, store: &LintStore) -> LintLevelsBuilder<'a> {
|
||||||
LintLevelsBuilder::new(sess, LintLevelSets::new(sess))
|
LintLevelsBuilder::new(sess, LintLevelSets::new(sess, store))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process_command_line(&mut self, sess: &Session) {
|
fn process_command_line(&mut self, sess: &Session, store: &LintStore) {
|
||||||
let store = sess.lint_store.borrow();
|
|
||||||
let mut specs = FxHashMap::default();
|
let mut specs = FxHashMap::default();
|
||||||
self.lint_cap = sess.opts.lint_cap.unwrap_or(Level::Forbid);
|
self.lint_cap = sess.opts.lint_cap.unwrap_or(Level::Forbid);
|
||||||
|
|
||||||
@ -186,9 +185,8 @@ impl<'a> LintLevelsBuilder<'a> {
|
|||||||
/// #[allow]
|
/// #[allow]
|
||||||
///
|
///
|
||||||
/// Don't forget to call `pop`!
|
/// Don't forget to call `pop`!
|
||||||
pub fn push(&mut self, attrs: &[ast::Attribute]) -> BuilderPush {
|
pub fn push(&mut self, attrs: &[ast::Attribute], store: &LintStore) -> BuilderPush {
|
||||||
let mut specs = FxHashMap::default();
|
let mut specs = FxHashMap::default();
|
||||||
let store = self.sess.lint_store.borrow();
|
|
||||||
let sess = self.sess;
|
let sess = self.sess;
|
||||||
let bad_attr = |span| {
|
let bad_attr = |span| {
|
||||||
struct_span_err!(sess, span, E0452, "malformed lint attribute input")
|
struct_span_err!(sess, span, E0452, "malformed lint attribute input")
|
||||||
|
@ -45,7 +45,7 @@ use syntax_pos::Span;
|
|||||||
|
|
||||||
pub use crate::lint::context::{LateContext, EarlyContext, LintContext, LintStore,
|
pub use crate::lint::context::{LateContext, EarlyContext, LintContext, LintStore,
|
||||||
check_crate, check_ast_crate, late_lint_mod, CheckLintNameResult,
|
check_crate, check_ast_crate, late_lint_mod, CheckLintNameResult,
|
||||||
FutureIncompatibleInfo, BufferedEarlyLint,};
|
BufferedEarlyLint,};
|
||||||
|
|
||||||
/// Specification of a single lint.
|
/// Specification of a single lint.
|
||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
@ -76,9 +76,35 @@ pub struct Lint {
|
|||||||
|
|
||||||
/// `true` if this lint is reported even inside expansions of external macros.
|
/// `true` if this lint is reported even inside expansions of external macros.
|
||||||
pub report_in_external_macro: bool,
|
pub report_in_external_macro: bool,
|
||||||
|
|
||||||
|
pub future_incompatible: Option<FutureIncompatibleInfo>,
|
||||||
|
|
||||||
|
pub is_plugin: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Extra information for a future incompatibility lint.
|
||||||
|
#[derive(Copy, Clone, Debug)]
|
||||||
|
pub struct FutureIncompatibleInfo {
|
||||||
|
/// e.g., a URL for an issue/PR/RFC or error code
|
||||||
|
pub reference: &'static str,
|
||||||
|
/// If this is an edition fixing lint, the edition in which
|
||||||
|
/// this lint becomes obsolete
|
||||||
|
pub edition: Option<Edition>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Lint {
|
impl Lint {
|
||||||
|
pub const fn default_fields_for_macro() -> Self {
|
||||||
|
Lint {
|
||||||
|
name: "",
|
||||||
|
default_level: Level::Forbid,
|
||||||
|
desc: "",
|
||||||
|
edition_lint_opts: None,
|
||||||
|
is_plugin: false,
|
||||||
|
report_in_external_macro: false,
|
||||||
|
future_incompatible: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns the `rust::lint::Lint` for a `syntax::early_buffered_lints::BufferedEarlyLintId`.
|
/// Returns the `rust::lint::Lint` for a `syntax::early_buffered_lints::BufferedEarlyLintId`.
|
||||||
pub fn from_parser_lint_id(lint_id: BufferedEarlyLintId) -> &'static Self {
|
pub fn from_parser_lint_id(lint_id: BufferedEarlyLintId) -> &'static Self {
|
||||||
match lint_id {
|
match lint_id {
|
||||||
@ -105,18 +131,21 @@ impl Lint {
|
|||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! declare_lint {
|
macro_rules! declare_lint {
|
||||||
($vis: vis $NAME: ident, $Level: ident, $desc: expr) => (
|
($vis: vis $NAME: ident, $Level: ident, $desc: expr) => (
|
||||||
declare_lint!{$vis $NAME, $Level, $desc, false}
|
declare_lint!(
|
||||||
|
$vis $NAME, $Level, $desc,
|
||||||
|
);
|
||||||
);
|
);
|
||||||
($vis: vis $NAME: ident, $Level: ident, $desc: expr, report_in_external_macro: $rep: expr) => (
|
($vis: vis $NAME: ident, $Level: ident, $desc: expr,
|
||||||
declare_lint!{$vis $NAME, $Level, $desc, $rep}
|
$(@future_incompatible = $fi:expr;)? $($v:ident),*) => (
|
||||||
);
|
|
||||||
($vis: vis $NAME: ident, $Level: ident, $desc: expr, $external: expr) => (
|
|
||||||
$vis static $NAME: &$crate::lint::Lint = &$crate::lint::Lint {
|
$vis static $NAME: &$crate::lint::Lint = &$crate::lint::Lint {
|
||||||
name: stringify!($NAME),
|
name: stringify!($NAME),
|
||||||
default_level: $crate::lint::$Level,
|
default_level: $crate::lint::$Level,
|
||||||
desc: $desc,
|
desc: $desc,
|
||||||
edition_lint_opts: None,
|
edition_lint_opts: None,
|
||||||
report_in_external_macro: $external,
|
is_plugin: false,
|
||||||
|
$($v: true,)*
|
||||||
|
$(future_incompatible: Some($fi),)*
|
||||||
|
..$crate::lint::Lint::default_fields_for_macro()
|
||||||
};
|
};
|
||||||
);
|
);
|
||||||
($vis: vis $NAME: ident, $Level: ident, $desc: expr,
|
($vis: vis $NAME: ident, $Level: ident, $desc: expr,
|
||||||
@ -128,6 +157,7 @@ macro_rules! declare_lint {
|
|||||||
desc: $desc,
|
desc: $desc,
|
||||||
edition_lint_opts: Some(($lint_edition, $crate::lint::Level::$edition_level)),
|
edition_lint_opts: Some(($lint_edition, $crate::lint::Level::$edition_level)),
|
||||||
report_in_external_macro: false,
|
report_in_external_macro: false,
|
||||||
|
is_plugin: false,
|
||||||
};
|
};
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -156,6 +186,8 @@ macro_rules! declare_tool_lint {
|
|||||||
desc: $desc,
|
desc: $desc,
|
||||||
edition_lint_opts: None,
|
edition_lint_opts: None,
|
||||||
report_in_external_macro: $external,
|
report_in_external_macro: $external,
|
||||||
|
future_incompatible: None,
|
||||||
|
is_plugin: true,
|
||||||
};
|
};
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -173,14 +205,6 @@ pub type LintArray = Vec<&'static Lint>;
|
|||||||
|
|
||||||
pub trait LintPass {
|
pub trait LintPass {
|
||||||
fn name(&self) -> &'static str;
|
fn name(&self) -> &'static str;
|
||||||
|
|
||||||
/// Gets descriptions of the lints this `LintPass` object can emit.
|
|
||||||
///
|
|
||||||
/// N.B., there is no enforcement that the object only emits lints it registered.
|
|
||||||
/// And some `rustc` internal `LintPass`es register lints to be emitted by other
|
|
||||||
/// parts of the compiler. If you want enforced access restrictions for your
|
|
||||||
/// `Lint`, make it a private `static` item in its own module.
|
|
||||||
fn get_lints(&self) -> LintArray;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Implements `LintPass for $name` with the given list of `Lint` statics.
|
/// Implements `LintPass for $name` with the given list of `Lint` statics.
|
||||||
@ -189,7 +213,9 @@ macro_rules! impl_lint_pass {
|
|||||||
($name:ident => [$($lint:expr),* $(,)?]) => {
|
($name:ident => [$($lint:expr),* $(,)?]) => {
|
||||||
impl LintPass for $name {
|
impl LintPass for $name {
|
||||||
fn name(&self) -> &'static str { stringify!($name) }
|
fn name(&self) -> &'static str { stringify!($name) }
|
||||||
fn get_lints(&self) -> LintArray { $crate::lint_array!($($lint),*) }
|
}
|
||||||
|
impl $name {
|
||||||
|
pub fn get_lints() -> LintArray { $crate::lint_array!($($lint),*) }
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -287,9 +313,6 @@ macro_rules! expand_lint_pass_methods {
|
|||||||
macro_rules! declare_late_lint_pass {
|
macro_rules! declare_late_lint_pass {
|
||||||
([], [$hir:tt], [$($methods:tt)*]) => (
|
([], [$hir:tt], [$($methods:tt)*]) => (
|
||||||
pub trait LateLintPass<'a, $hir>: LintPass {
|
pub trait LateLintPass<'a, $hir>: LintPass {
|
||||||
fn fresh_late_pass(&self) -> LateLintPassObject {
|
|
||||||
panic!()
|
|
||||||
}
|
|
||||||
expand_lint_pass_methods!(&LateContext<'a, $hir>, [$($methods)*]);
|
expand_lint_pass_methods!(&LateContext<'a, $hir>, [$($methods)*]);
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@ -327,6 +350,12 @@ macro_rules! declare_combined_late_lint_pass {
|
|||||||
$($passes: $constructor,)*
|
$($passes: $constructor,)*
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$v fn get_lints() -> LintArray {
|
||||||
|
let mut lints = Vec::new();
|
||||||
|
$(lints.extend_from_slice(&$passes::get_lints());)*
|
||||||
|
lints
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for $name {
|
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for $name {
|
||||||
@ -337,12 +366,6 @@ macro_rules! declare_combined_late_lint_pass {
|
|||||||
fn name(&self) -> &'static str {
|
fn name(&self) -> &'static str {
|
||||||
panic!()
|
panic!()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_lints(&self) -> LintArray {
|
|
||||||
let mut lints = Vec::new();
|
|
||||||
$(lints.extend_from_slice(&self.$passes.get_lints());)*
|
|
||||||
lints
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -454,6 +477,12 @@ macro_rules! declare_combined_early_lint_pass {
|
|||||||
$($passes: $constructor,)*
|
$($passes: $constructor,)*
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$v fn get_lints() -> LintArray {
|
||||||
|
let mut lints = Vec::new();
|
||||||
|
$(lints.extend_from_slice(&$passes::get_lints());)*
|
||||||
|
lints
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EarlyLintPass for $name {
|
impl EarlyLintPass for $name {
|
||||||
@ -464,12 +493,6 @@ macro_rules! declare_combined_early_lint_pass {
|
|||||||
fn name(&self) -> &'static str {
|
fn name(&self) -> &'static str {
|
||||||
panic!()
|
panic!()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_lints(&self) -> LintArray {
|
|
||||||
let mut lints = Vec::new();
|
|
||||||
$(lints.extend_from_slice(&self.$passes.get_lints());)*
|
|
||||||
lints
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -649,9 +672,8 @@ pub fn struct_lint_level<'a>(sess: &'a Session,
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Check for future incompatibility lints and issue a stronger warning.
|
// Check for future incompatibility lints and issue a stronger warning.
|
||||||
let lints = sess.lint_store.borrow();
|
|
||||||
let lint_id = LintId::of(lint);
|
let lint_id = LintId::of(lint);
|
||||||
let future_incompatible = lints.future_incompatible(lint_id);
|
let future_incompatible = lint.future_incompatible;
|
||||||
|
|
||||||
// If this code originates in a foreign macro, aka something that this crate
|
// If this code originates in a foreign macro, aka something that this crate
|
||||||
// did not itself author, then it's likely that there's nothing this crate
|
// did not itself author, then it's likely that there's nothing this crate
|
||||||
@ -755,13 +777,15 @@ pub fn maybe_lint_level_root(tcx: TyCtxt<'_>, id: hir::HirId) -> bool {
|
|||||||
|
|
||||||
fn lint_levels(tcx: TyCtxt<'_>, cnum: CrateNum) -> &LintLevelMap {
|
fn lint_levels(tcx: TyCtxt<'_>, cnum: CrateNum) -> &LintLevelMap {
|
||||||
assert_eq!(cnum, LOCAL_CRATE);
|
assert_eq!(cnum, LOCAL_CRATE);
|
||||||
|
let store = &tcx.lint_store;
|
||||||
let mut builder = LintLevelMapBuilder {
|
let mut builder = LintLevelMapBuilder {
|
||||||
levels: LintLevelSets::builder(tcx.sess),
|
levels: LintLevelSets::builder(tcx.sess, &store),
|
||||||
tcx: tcx,
|
tcx: tcx,
|
||||||
|
store: store,
|
||||||
};
|
};
|
||||||
let krate = tcx.hir().krate();
|
let krate = tcx.hir().krate();
|
||||||
|
|
||||||
let push = builder.levels.push(&krate.attrs);
|
let push = builder.levels.push(&krate.attrs, &store);
|
||||||
builder.levels.register_id(hir::CRATE_HIR_ID);
|
builder.levels.register_id(hir::CRATE_HIR_ID);
|
||||||
for macro_def in &krate.exported_macros {
|
for macro_def in &krate.exported_macros {
|
||||||
builder.levels.register_id(macro_def.hir_id);
|
builder.levels.register_id(macro_def.hir_id);
|
||||||
@ -772,19 +796,20 @@ fn lint_levels(tcx: TyCtxt<'_>, cnum: CrateNum) -> &LintLevelMap {
|
|||||||
tcx.arena.alloc(builder.levels.build_map())
|
tcx.arena.alloc(builder.levels.build_map())
|
||||||
}
|
}
|
||||||
|
|
||||||
struct LintLevelMapBuilder<'tcx> {
|
struct LintLevelMapBuilder<'a, 'tcx> {
|
||||||
levels: levels::LintLevelsBuilder<'tcx>,
|
levels: levels::LintLevelsBuilder<'tcx>,
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
|
store: &'a LintStore,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LintLevelMapBuilder<'tcx> {
|
impl LintLevelMapBuilder<'_, '_> {
|
||||||
fn with_lint_attrs<F>(&mut self,
|
fn with_lint_attrs<F>(&mut self,
|
||||||
id: hir::HirId,
|
id: hir::HirId,
|
||||||
attrs: &[ast::Attribute],
|
attrs: &[ast::Attribute],
|
||||||
f: F)
|
f: F)
|
||||||
where F: FnOnce(&mut Self)
|
where F: FnOnce(&mut Self)
|
||||||
{
|
{
|
||||||
let push = self.levels.push(attrs);
|
let push = self.levels.push(attrs, self.store);
|
||||||
if push.changed {
|
if push.changed {
|
||||||
self.levels.register_id(id);
|
self.levels.register_id(id);
|
||||||
}
|
}
|
||||||
@ -793,7 +818,7 @@ impl LintLevelMapBuilder<'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl intravisit::Visitor<'tcx> for LintLevelMapBuilder<'tcx> {
|
impl intravisit::Visitor<'tcx> for LintLevelMapBuilder<'_, 'tcx> {
|
||||||
fn nested_visit_map<'this>(&'this mut self) -> intravisit::NestedVisitorMap<'this, 'tcx> {
|
fn nested_visit_map<'this>(&'this mut self) -> intravisit::NestedVisitorMap<'this, 'tcx> {
|
||||||
intravisit::NestedVisitorMap::All(&self.tcx.hir())
|
intravisit::NestedVisitorMap::All(&self.tcx.hir())
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ use syntax::ast;
|
|||||||
use syntax::symbol::Symbol;
|
use syntax::symbol::Symbol;
|
||||||
use syntax_pos::Span;
|
use syntax_pos::Span;
|
||||||
use rustc_target::spec::Target;
|
use rustc_target::spec::Target;
|
||||||
use rustc_data_structures::sync::{self, MetadataRef, Lrc};
|
use rustc_data_structures::sync::{self, MetadataRef};
|
||||||
use rustc_macros::HashStable;
|
use rustc_macros::HashStable;
|
||||||
|
|
||||||
pub use self::NativeLibraryKind::*;
|
pub use self::NativeLibraryKind::*;
|
||||||
@ -191,6 +191,8 @@ pub trait MetadataLoader {
|
|||||||
-> Result<MetadataRef, String>;
|
-> Result<MetadataRef, String>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub type MetadataLoaderDyn = dyn MetadataLoader + Sync;
|
||||||
|
|
||||||
/// A store of Rust crates, through which their metadata can be accessed.
|
/// A store of Rust crates, through which their metadata can be accessed.
|
||||||
///
|
///
|
||||||
/// Note that this trait should probably not be expanding today. All new
|
/// Note that this trait should probably not be expanding today. All new
|
||||||
@ -201,13 +203,13 @@ pub trait MetadataLoader {
|
|||||||
/// (it'd break incremental compilation) and should only be called pre-HIR (e.g.
|
/// (it'd break incremental compilation) and should only be called pre-HIR (e.g.
|
||||||
/// during resolve)
|
/// during resolve)
|
||||||
pub trait CrateStore {
|
pub trait CrateStore {
|
||||||
fn crate_data_as_rc_any(&self, krate: CrateNum) -> Lrc<dyn Any>;
|
fn crate_data_as_any(&self, cnum: CrateNum) -> &dyn Any;
|
||||||
|
|
||||||
// resolve
|
// resolve
|
||||||
fn def_key(&self, def: DefId) -> DefKey;
|
fn def_key(&self, def: DefId) -> DefKey;
|
||||||
fn def_path(&self, def: DefId) -> hir_map::DefPath;
|
fn def_path(&self, def: DefId) -> hir_map::DefPath;
|
||||||
fn def_path_hash(&self, def: DefId) -> hir_map::DefPathHash;
|
fn def_path_hash(&self, def: DefId) -> hir_map::DefPathHash;
|
||||||
fn def_path_table(&self, cnum: CrateNum) -> Lrc<DefPathTable>;
|
fn def_path_table(&self, cnum: CrateNum) -> &DefPathTable;
|
||||||
|
|
||||||
// "queries" used in resolve that aren't tracked for incremental compilation
|
// "queries" used in resolve that aren't tracked for incremental compilation
|
||||||
fn crate_name_untracked(&self, cnum: CrateNum) -> Symbol;
|
fn crate_name_untracked(&self, cnum: CrateNum) -> Symbol;
|
||||||
|
@ -353,11 +353,14 @@ impl<'tcx, Tag: Copy, Extra: AllocationExtra<Tag>> Allocation<Tag, Extra> {
|
|||||||
&mut self,
|
&mut self,
|
||||||
cx: &impl HasDataLayout,
|
cx: &impl HasDataLayout,
|
||||||
ptr: Pointer<Tag>,
|
ptr: Pointer<Tag>,
|
||||||
src: impl IntoIterator<Item=u8, IntoIter: iter::ExactSizeIterator>,
|
src: impl IntoIterator<Item=u8>,
|
||||||
) -> InterpResult<'tcx>
|
) -> InterpResult<'tcx>
|
||||||
{
|
{
|
||||||
let mut src = src.into_iter();
|
let mut src = src.into_iter();
|
||||||
let bytes = self.get_bytes_mut(cx, ptr, Size::from_bytes(src.len() as u64))?;
|
let (lower, upper) = src.size_hint();
|
||||||
|
let len = upper.expect("can only write bounded iterators");
|
||||||
|
assert_eq!(lower, len, "can only write iterators with a precise length");
|
||||||
|
let bytes = self.get_bytes_mut(cx, ptr, Size::from_bytes(len as u64))?;
|
||||||
// `zip` would stop when the first iterator ends; we want to definitely
|
// `zip` would stop when the first iterator ends; we want to definitely
|
||||||
// cover all of `bytes`.
|
// cover all of `bytes`.
|
||||||
for dest in bytes {
|
for dest in bytes {
|
||||||
|
@ -37,7 +37,7 @@ use std::slice;
|
|||||||
use std::vec::IntoIter;
|
use std::vec::IntoIter;
|
||||||
use std::{iter, mem, option, u32};
|
use std::{iter, mem, option, u32};
|
||||||
use syntax::ast::Name;
|
use syntax::ast::Name;
|
||||||
use syntax::symbol::{InternedString, Symbol};
|
use syntax::symbol::Symbol;
|
||||||
use syntax_pos::{Span, DUMMY_SP};
|
use syntax_pos::{Span, DUMMY_SP};
|
||||||
|
|
||||||
pub use crate::mir::interpret::AssertMessage;
|
pub use crate::mir::interpret::AssertMessage;
|
||||||
@ -2736,8 +2736,8 @@ pub enum UnsafetyViolationKind {
|
|||||||
#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, HashStable)]
|
#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, HashStable)]
|
||||||
pub struct UnsafetyViolation {
|
pub struct UnsafetyViolation {
|
||||||
pub source_info: SourceInfo,
|
pub source_info: SourceInfo,
|
||||||
pub description: InternedString,
|
pub description: Symbol,
|
||||||
pub details: InternedString,
|
pub details: Symbol,
|
||||||
pub kind: UnsafetyViolationKind,
|
pub kind: UnsafetyViolationKind,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use crate::hir::def_id::{DefId, CrateNum, LOCAL_CRATE};
|
use crate::hir::def_id::{DefId, CrateNum, LOCAL_CRATE};
|
||||||
use crate::hir::HirId;
|
use crate::hir::HirId;
|
||||||
use syntax::symbol::InternedString;
|
use syntax::symbol::Symbol;
|
||||||
use syntax::attr::InlineAttr;
|
use syntax::attr::InlineAttr;
|
||||||
use syntax::source_map::Span;
|
use syntax::source_map::Span;
|
||||||
use crate::ty::{Instance, InstanceDef, TyCtxt, SymbolName, subst::InternalSubsts};
|
use crate::ty::{Instance, InstanceDef, TyCtxt, SymbolName, subst::InternalSubsts};
|
||||||
@ -80,7 +80,7 @@ impl<'tcx> MonoItem<'tcx> {
|
|||||||
MonoItem::GlobalAsm(hir_id) => {
|
MonoItem::GlobalAsm(hir_id) => {
|
||||||
let def_id = tcx.hir().local_def_id(hir_id);
|
let def_id = tcx.hir().local_def_id(hir_id);
|
||||||
SymbolName {
|
SymbolName {
|
||||||
name: InternedString::intern(&format!("global_asm_{:?}", def_id))
|
name: Symbol::intern(&format!("global_asm_{:?}", def_id))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -246,7 +246,7 @@ pub struct CodegenUnit<'tcx> {
|
|||||||
/// name be unique amongst **all** crates. Therefore, it should
|
/// name be unique amongst **all** crates. Therefore, it should
|
||||||
/// contain something unique to this crate (e.g., a module path)
|
/// contain something unique to this crate (e.g., a module path)
|
||||||
/// as well as the crate name and disambiguator.
|
/// as well as the crate name and disambiguator.
|
||||||
name: InternedString,
|
name: Symbol,
|
||||||
items: FxHashMap<MonoItem<'tcx>, (Linkage, Visibility)>,
|
items: FxHashMap<MonoItem<'tcx>, (Linkage, Visibility)>,
|
||||||
size_estimate: Option<usize>,
|
size_estimate: Option<usize>,
|
||||||
}
|
}
|
||||||
@ -294,7 +294,7 @@ impl_stable_hash_for!(enum self::Visibility {
|
|||||||
});
|
});
|
||||||
|
|
||||||
impl<'tcx> CodegenUnit<'tcx> {
|
impl<'tcx> CodegenUnit<'tcx> {
|
||||||
pub fn new(name: InternedString) -> CodegenUnit<'tcx> {
|
pub fn new(name: Symbol) -> CodegenUnit<'tcx> {
|
||||||
CodegenUnit {
|
CodegenUnit {
|
||||||
name: name,
|
name: name,
|
||||||
items: Default::default(),
|
items: Default::default(),
|
||||||
@ -302,11 +302,11 @@ impl<'tcx> CodegenUnit<'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn name(&self) -> &InternedString {
|
pub fn name(&self) -> Symbol {
|
||||||
&self.name
|
self.name
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_name(&mut self, name: InternedString) {
|
pub fn set_name(&mut self, name: Symbol) {
|
||||||
self.name = name;
|
self.name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -474,7 +474,7 @@ impl CodegenUnitNameBuilder<'tcx> {
|
|||||||
cnum: CrateNum,
|
cnum: CrateNum,
|
||||||
components: I,
|
components: I,
|
||||||
special_suffix: Option<S>)
|
special_suffix: Option<S>)
|
||||||
-> InternedString
|
-> Symbol
|
||||||
where I: IntoIterator<Item=C>,
|
where I: IntoIterator<Item=C>,
|
||||||
C: fmt::Display,
|
C: fmt::Display,
|
||||||
S: fmt::Display,
|
S: fmt::Display,
|
||||||
@ -487,7 +487,7 @@ impl CodegenUnitNameBuilder<'tcx> {
|
|||||||
cgu_name
|
cgu_name
|
||||||
} else {
|
} else {
|
||||||
let cgu_name = &cgu_name.as_str()[..];
|
let cgu_name = &cgu_name.as_str()[..];
|
||||||
InternedString::intern(&CodegenUnit::mangle_name(cgu_name))
|
Symbol::intern(&CodegenUnit::mangle_name(cgu_name))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -497,7 +497,7 @@ impl CodegenUnitNameBuilder<'tcx> {
|
|||||||
cnum: CrateNum,
|
cnum: CrateNum,
|
||||||
components: I,
|
components: I,
|
||||||
special_suffix: Option<S>)
|
special_suffix: Option<S>)
|
||||||
-> InternedString
|
-> Symbol
|
||||||
where I: IntoIterator<Item=C>,
|
where I: IntoIterator<Item=C>,
|
||||||
C: fmt::Display,
|
C: fmt::Display,
|
||||||
S: fmt::Display,
|
S: fmt::Display,
|
||||||
@ -543,6 +543,6 @@ impl CodegenUnitNameBuilder<'tcx> {
|
|||||||
write!(cgu_name, ".{}", special_suffix).unwrap();
|
write!(cgu_name, ".{}", special_suffix).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
InternedString::intern(&cgu_name[..])
|
Symbol::intern(&cgu_name[..])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ use crate::traits::query::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use syntax_pos::symbol::InternedString;
|
use syntax_pos::symbol::Symbol;
|
||||||
|
|
||||||
// Each of these queries corresponds to a function pointer field in the
|
// Each of these queries corresponds to a function pointer field in the
|
||||||
// `Providers` struct for requesting a value of that type, and a method
|
// `Providers` struct for requesting a value of that type, and a method
|
||||||
@ -924,7 +924,7 @@ rustc_queries! {
|
|||||||
desc { "collect_and_partition_mono_items" }
|
desc { "collect_and_partition_mono_items" }
|
||||||
}
|
}
|
||||||
query is_codegened_item(_: DefId) -> bool {}
|
query is_codegened_item(_: DefId) -> bool {}
|
||||||
query codegen_unit(_: InternedString) -> Arc<CodegenUnit<'tcx>> {
|
query codegen_unit(_: Symbol) -> Arc<CodegenUnit<'tcx>> {
|
||||||
no_force
|
no_force
|
||||||
desc { "codegen_unit" }
|
desc { "codegen_unit" }
|
||||||
}
|
}
|
||||||
|
@ -1149,7 +1149,8 @@ options! {CodegenOptions, CodegenSetter, basic_codegen_options,
|
|||||||
target_cpu: Option<String> = (None, parse_opt_string, [TRACKED],
|
target_cpu: Option<String> = (None, parse_opt_string, [TRACKED],
|
||||||
"select target processor (`rustc --print target-cpus` for details)"),
|
"select target processor (`rustc --print target-cpus` for details)"),
|
||||||
target_feature: String = (String::new(), parse_string, [TRACKED],
|
target_feature: String = (String::new(), parse_string, [TRACKED],
|
||||||
"target specific attributes (`rustc --print target-features` for details)"),
|
"target specific attributes. (`rustc --print target-features` for details). \
|
||||||
|
This feature is unsafe."),
|
||||||
passes: Vec<String> = (Vec::new(), parse_list, [TRACKED],
|
passes: Vec<String> = (Vec::new(), parse_list, [TRACKED],
|
||||||
"a list of extra LLVM passes to run (space separated)"),
|
"a list of extra LLVM passes to run (space separated)"),
|
||||||
llvm_args: Vec<String> = (Vec::new(), parse_list, [TRACKED],
|
llvm_args: Vec<String> = (Vec::new(), parse_list, [TRACKED],
|
||||||
|
@ -14,7 +14,7 @@ use crate::util::common::{duration_to_secs_str, ErrorReported};
|
|||||||
|
|
||||||
use rustc_data_structures::base_n;
|
use rustc_data_structures::base_n;
|
||||||
use rustc_data_structures::sync::{
|
use rustc_data_structures::sync::{
|
||||||
self, Lrc, Lock, OneThread, Once, RwLock, AtomicU64, AtomicUsize, Ordering,
|
self, Lrc, Lock, OneThread, Once, AtomicU64, AtomicUsize, Ordering,
|
||||||
Ordering::SeqCst,
|
Ordering::SeqCst,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -77,9 +77,11 @@ pub struct Session {
|
|||||||
/// if the value stored here has been affected by path remapping.
|
/// if the value stored here has been affected by path remapping.
|
||||||
pub working_dir: (PathBuf, bool),
|
pub working_dir: (PathBuf, bool),
|
||||||
|
|
||||||
// FIXME: `lint_store` and `buffered_lints` are not thread-safe,
|
/// This is intended to be used from a single thread.
|
||||||
// but are only used in a single thread.
|
///
|
||||||
pub lint_store: RwLock<lint::LintStore>,
|
/// FIXME: there was a previous comment about this not being thread safe,
|
||||||
|
/// but it's not clear how or why that's the case. The LintBuffer itself is certainly thread
|
||||||
|
/// safe at least from a "Rust safety" standpoint.
|
||||||
pub buffered_lints: Lock<Option<lint::LintBuffer>>,
|
pub buffered_lints: Lock<Option<lint::LintBuffer>>,
|
||||||
|
|
||||||
/// Set of `(DiagnosticId, Option<Span>, message)` tuples tracking
|
/// Set of `(DiagnosticId, Option<Span>, message)` tuples tracking
|
||||||
@ -1213,7 +1215,6 @@ fn build_session_(
|
|||||||
sysroot,
|
sysroot,
|
||||||
local_crate_source_file,
|
local_crate_source_file,
|
||||||
working_dir,
|
working_dir,
|
||||||
lint_store: RwLock::new(lint::LintStore::new()),
|
|
||||||
buffered_lints: Lock::new(Some(Default::default())),
|
buffered_lints: Lock::new(Some(Default::default())),
|
||||||
one_time_diagnostics: Default::default(),
|
one_time_diagnostics: Default::default(),
|
||||||
plugin_llvm_passes: OneThread::new(RefCell::new(Vec::new())),
|
plugin_llvm_passes: OneThread::new(RefCell::new(Vec::new())),
|
||||||
|
@ -406,7 +406,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||||||
},
|
},
|
||||||
GenericParamDefKind::Lifetime => continue,
|
GenericParamDefKind::Lifetime => continue,
|
||||||
};
|
};
|
||||||
let name = param.name.as_symbol();
|
let name = param.name;
|
||||||
flags.push((name, Some(value)));
|
flags.push((name, Some(value)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -793,15 +793,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||||||
|
|
||||||
ty::Predicate::ObjectSafe(trait_def_id) => {
|
ty::Predicate::ObjectSafe(trait_def_id) => {
|
||||||
let violations = self.tcx.object_safety_violations(trait_def_id);
|
let violations = self.tcx.object_safety_violations(trait_def_id);
|
||||||
if let Some(err) = self.tcx.report_object_safety_error(
|
self.tcx.report_object_safety_error(
|
||||||
span,
|
span,
|
||||||
trait_def_id,
|
trait_def_id,
|
||||||
violations,
|
violations,
|
||||||
) {
|
)
|
||||||
err
|
|
||||||
} else {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::Predicate::ClosureKind(closure_def_id, closure_substs, kind) => {
|
ty::Predicate::ClosureKind(closure_def_id, closure_substs, kind) => {
|
||||||
@ -937,11 +933,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||||||
|
|
||||||
TraitNotObjectSafe(did) => {
|
TraitNotObjectSafe(did) => {
|
||||||
let violations = self.tcx.object_safety_violations(did);
|
let violations = self.tcx.object_safety_violations(did);
|
||||||
if let Some(err) = self.tcx.report_object_safety_error(span, did, violations) {
|
self.tcx.report_object_safety_error(span, did, violations)
|
||||||
err
|
|
||||||
} else {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// already reported in the query
|
// already reported in the query
|
||||||
@ -1665,11 +1657,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||||||
span: Span,
|
span: Span,
|
||||||
trait_def_id: DefId,
|
trait_def_id: DefId,
|
||||||
violations: Vec<ObjectSafetyViolation>,
|
violations: Vec<ObjectSafetyViolation>,
|
||||||
) -> Option<DiagnosticBuilder<'tcx>> {
|
) -> DiagnosticBuilder<'tcx> {
|
||||||
if self.sess.trait_methods_not_found.borrow().contains(&span) {
|
|
||||||
// Avoid emitting error caused by non-existing method (#58734)
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
let trait_str = self.def_path_str(trait_def_id);
|
let trait_str = self.def_path_str(trait_def_id);
|
||||||
let span = self.sess.source_map().def_span(span);
|
let span = self.sess.source_map().def_span(span);
|
||||||
let mut err = struct_span_err!(
|
let mut err = struct_span_err!(
|
||||||
@ -1687,7 +1675,13 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(err)
|
|
||||||
|
if self.sess.trait_methods_not_found.borrow().contains(&span) {
|
||||||
|
// Avoid emitting error caused by non-existing method (#58734)
|
||||||
|
err.cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2098,6 +2092,10 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||||||
err.note(&format!("required for the cast to the object type `{}`",
|
err.note(&format!("required for the cast to the object type `{}`",
|
||||||
self.ty_to_string(object_ty)));
|
self.ty_to_string(object_ty)));
|
||||||
}
|
}
|
||||||
|
ObligationCauseCode::Coercion { source: _, target } => {
|
||||||
|
err.note(&format!("required by cast to type `{}`",
|
||||||
|
self.ty_to_string(target)));
|
||||||
|
}
|
||||||
ObligationCauseCode::RepeatVec => {
|
ObligationCauseCode::RepeatVec => {
|
||||||
err.note("the `Copy` trait is required because the \
|
err.note("the `Copy` trait is required because the \
|
||||||
repeated element will be copied");
|
repeated element will be copied");
|
||||||
|
@ -188,6 +188,9 @@ pub enum ObligationCauseCode<'tcx> {
|
|||||||
/// Obligation incurred due to an object cast.
|
/// Obligation incurred due to an object cast.
|
||||||
ObjectCastObligation(/* Object type */ Ty<'tcx>),
|
ObjectCastObligation(/* Object type */ Ty<'tcx>),
|
||||||
|
|
||||||
|
/// Obligation incurred due to a coercion.
|
||||||
|
Coercion { source: Ty<'tcx>, target: Ty<'tcx> },
|
||||||
|
|
||||||
// Various cases where expressions must be sized/copy/etc:
|
// Various cases where expressions must be sized/copy/etc:
|
||||||
/// L = X implies that L is Sized
|
/// L = X implies that L is Sized
|
||||||
AssignmentLhsSized,
|
AssignmentLhsSized,
|
||||||
|
@ -19,7 +19,7 @@ use crate::ty::subst::{Subst, InternalSubsts};
|
|||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::iter::{self};
|
use std::iter::{self};
|
||||||
use syntax::ast::{self};
|
use syntax::ast::{self};
|
||||||
use syntax::symbol::InternedString;
|
use syntax::symbol::Symbol;
|
||||||
use syntax_pos::{Span, DUMMY_SP};
|
use syntax_pos::{Span, DUMMY_SP};
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
|
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
|
||||||
@ -560,7 +560,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||||||
// are implemented
|
// are implemented
|
||||||
let unsized_self_ty: Ty<'tcx> = self.mk_ty_param(
|
let unsized_self_ty: Ty<'tcx> = self.mk_ty_param(
|
||||||
::std::u32::MAX,
|
::std::u32::MAX,
|
||||||
InternedString::intern("RustaceansAreAwesome"),
|
Symbol::intern("RustaceansAreAwesome"),
|
||||||
);
|
);
|
||||||
|
|
||||||
// `Receiver[Self => U]`
|
// `Receiver[Self => U]`
|
||||||
|
@ -250,7 +250,7 @@ impl<'tcx> OnUnimplementedFormatString {
|
|||||||
Position::ArgumentNamed(s) if s == sym::from_desugaring => (),
|
Position::ArgumentNamed(s) if s == sym::from_desugaring => (),
|
||||||
// So is `{A}` if A is a type parameter
|
// So is `{A}` if A is a type parameter
|
||||||
Position::ArgumentNamed(s) => match generics.params.iter().find(|param| {
|
Position::ArgumentNamed(s) => match generics.params.iter().find(|param| {
|
||||||
param.name.as_symbol() == s
|
param.name == s
|
||||||
}) {
|
}) {
|
||||||
Some(_) => (),
|
Some(_) => (),
|
||||||
None => {
|
None => {
|
||||||
@ -289,7 +289,7 @@ impl<'tcx> OnUnimplementedFormatString {
|
|||||||
},
|
},
|
||||||
GenericParamDefKind::Lifetime => return None
|
GenericParamDefKind::Lifetime => return None
|
||||||
};
|
};
|
||||||
let name = param.name.as_symbol();
|
let name = param.name;
|
||||||
Some((name, value))
|
Some((name, value))
|
||||||
}).collect::<FxHashMap<Symbol, String>>();
|
}).collect::<FxHashMap<Symbol, String>>();
|
||||||
let empty_string = String::new();
|
let empty_string = String::new();
|
||||||
|
@ -2246,7 +2246,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let Some(principal) = data.principal() {
|
if let Some(principal) = data.principal() {
|
||||||
principal.with_self_ty(self.tcx(), self_ty)
|
if !self.infcx.tcx.features().object_safe_for_dispatch {
|
||||||
|
principal.with_self_ty(self.tcx(), self_ty)
|
||||||
|
} else if self.tcx().is_object_safe(principal.def_id()) {
|
||||||
|
principal.with_self_ty(self.tcx(), self_ty)
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// Only auto-trait bounds exist.
|
// Only auto-trait bounds exist.
|
||||||
return;
|
return;
|
||||||
|
@ -4,7 +4,7 @@ use crate::traits;
|
|||||||
use crate::traits::project::Normalized;
|
use crate::traits::project::Normalized;
|
||||||
use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
|
use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
|
||||||
use crate::ty::{self, Lift, Ty, TyCtxt};
|
use crate::ty::{self, Lift, Ty, TyCtxt};
|
||||||
use syntax::symbol::InternedString;
|
use syntax::symbol::Symbol;
|
||||||
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
@ -261,11 +261,11 @@ impl fmt::Display for traits::QuantifierKind {
|
|||||||
/// for debug output in tests anyway.
|
/// for debug output in tests anyway.
|
||||||
struct BoundNamesCollector {
|
struct BoundNamesCollector {
|
||||||
// Just sort by name because `BoundRegion::BrNamed` does not have a `BoundVar` index anyway.
|
// Just sort by name because `BoundRegion::BrNamed` does not have a `BoundVar` index anyway.
|
||||||
regions: BTreeSet<InternedString>,
|
regions: BTreeSet<Symbol>,
|
||||||
|
|
||||||
// Sort by `BoundVar` index, so usually this should be equivalent to the order given
|
// Sort by `BoundVar` index, so usually this should be equivalent to the order given
|
||||||
// by the list of type parameters.
|
// by the list of type parameters.
|
||||||
types: BTreeMap<u32, InternedString>,
|
types: BTreeMap<u32, Symbol>,
|
||||||
|
|
||||||
binder_index: ty::DebruijnIndex,
|
binder_index: ty::DebruijnIndex,
|
||||||
}
|
}
|
||||||
@ -319,7 +319,7 @@ impl<'tcx> TypeVisitor<'tcx> for BoundNamesCollector {
|
|||||||
match bound_ty.kind {
|
match bound_ty.kind {
|
||||||
ty::BoundTyKind::Param(name) => name,
|
ty::BoundTyKind::Param(name) => name,
|
||||||
ty::BoundTyKind::Anon =>
|
ty::BoundTyKind::Anon =>
|
||||||
InternedString::intern(&format!("^{}", bound_ty.var.as_u32()),
|
Symbol::intern(&format!("^{}", bound_ty.var.as_u32()),
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@ -340,7 +340,7 @@ impl<'tcx> TypeVisitor<'tcx> for BoundNamesCollector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ty::BoundRegion::BrAnon(var) => {
|
ty::BoundRegion::BrAnon(var) => {
|
||||||
self.regions.insert(InternedString::intern(&format!("'^{}", var)));
|
self.regions.insert(Symbol::intern(&format!("'^{}", var)));
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => (),
|
_ => (),
|
||||||
@ -481,6 +481,10 @@ impl<'a, 'tcx> Lift<'tcx> for traits::ObligationCauseCode<'a> {
|
|||||||
.and_then(|r| Some(super::ObjectTypeBound(ty, r)))
|
.and_then(|r| Some(super::ObjectTypeBound(ty, r)))
|
||||||
),
|
),
|
||||||
super::ObjectCastObligation(ty) => tcx.lift(&ty).map(super::ObjectCastObligation),
|
super::ObjectCastObligation(ty) => tcx.lift(&ty).map(super::ObjectCastObligation),
|
||||||
|
super::Coercion { source, target } => Some(super::Coercion {
|
||||||
|
source: tcx.lift(&source)?,
|
||||||
|
target: tcx.lift(&target)?,
|
||||||
|
}),
|
||||||
super::AssignmentLhsSized => Some(super::AssignmentLhsSized),
|
super::AssignmentLhsSized => Some(super::AssignmentLhsSized),
|
||||||
super::TupleInitializerSized => Some(super::TupleInitializerSized),
|
super::TupleInitializerSized => Some(super::TupleInitializerSized),
|
||||||
super::StructInitializerSized => Some(super::StructInitializerSized),
|
super::StructInitializerSized => Some(super::StructInitializerSized),
|
||||||
|
@ -72,7 +72,7 @@ use syntax::ast;
|
|||||||
use syntax::attr;
|
use syntax::attr;
|
||||||
use syntax::source_map::MultiSpan;
|
use syntax::source_map::MultiSpan;
|
||||||
use syntax::feature_gate;
|
use syntax::feature_gate;
|
||||||
use syntax::symbol::{Symbol, InternedString, kw, sym};
|
use syntax::symbol::{Symbol, kw, sym};
|
||||||
use syntax_pos::Span;
|
use syntax_pos::Span;
|
||||||
|
|
||||||
pub struct AllArenas {
|
pub struct AllArenas {
|
||||||
@ -949,7 +949,7 @@ impl<'tcx> CommonTypes<'tcx> {
|
|||||||
f64: mk(Float(ast::FloatTy::F64)),
|
f64: mk(Float(ast::FloatTy::F64)),
|
||||||
self_param: mk(ty::Param(ty::ParamTy {
|
self_param: mk(ty::Param(ty::ParamTy {
|
||||||
index: 0,
|
index: 0,
|
||||||
name: kw::SelfUpper.as_interned_str(),
|
name: kw::SelfUpper,
|
||||||
})),
|
})),
|
||||||
|
|
||||||
trait_object_dummy_self: mk(Infer(ty::FreshTy(0))),
|
trait_object_dummy_self: mk(Infer(ty::FreshTy(0))),
|
||||||
@ -1027,10 +1027,12 @@ pub struct GlobalCtxt<'tcx> {
|
|||||||
|
|
||||||
interners: CtxtInterners<'tcx>,
|
interners: CtxtInterners<'tcx>,
|
||||||
|
|
||||||
cstore: &'tcx CrateStoreDyn,
|
cstore: Box<CrateStoreDyn>,
|
||||||
|
|
||||||
pub sess: &'tcx Session,
|
pub sess: &'tcx Session,
|
||||||
|
|
||||||
|
pub lint_store: Lrc<lint::LintStore>,
|
||||||
|
|
||||||
pub dep_graph: DepGraph,
|
pub dep_graph: DepGraph,
|
||||||
|
|
||||||
pub prof: SelfProfilerRef,
|
pub prof: SelfProfilerRef,
|
||||||
@ -1192,11 +1194,11 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||||||
/// reference to the context, to allow formatting values that need it.
|
/// reference to the context, to allow formatting values that need it.
|
||||||
pub fn create_global_ctxt(
|
pub fn create_global_ctxt(
|
||||||
s: &'tcx Session,
|
s: &'tcx Session,
|
||||||
cstore: &'tcx CrateStoreDyn,
|
lint_store: Lrc<lint::LintStore>,
|
||||||
local_providers: ty::query::Providers<'tcx>,
|
local_providers: ty::query::Providers<'tcx>,
|
||||||
extern_providers: ty::query::Providers<'tcx>,
|
extern_providers: ty::query::Providers<'tcx>,
|
||||||
arenas: &'tcx AllArenas,
|
arenas: &'tcx AllArenas,
|
||||||
resolutions: ty::Resolutions,
|
resolutions: ty::ResolverOutputs,
|
||||||
hir: hir_map::Map<'tcx>,
|
hir: hir_map::Map<'tcx>,
|
||||||
on_disk_query_result_cache: query::OnDiskCache<'tcx>,
|
on_disk_query_result_cache: query::OnDiskCache<'tcx>,
|
||||||
crate_name: &str,
|
crate_name: &str,
|
||||||
@ -1210,34 +1212,28 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||||||
let common_lifetimes = CommonLifetimes::new(&interners);
|
let common_lifetimes = CommonLifetimes::new(&interners);
|
||||||
let common_consts = CommonConsts::new(&interners, &common_types);
|
let common_consts = CommonConsts::new(&interners, &common_types);
|
||||||
let dep_graph = hir.dep_graph.clone();
|
let dep_graph = hir.dep_graph.clone();
|
||||||
let max_cnum = cstore.crates_untracked().iter().map(|c| c.as_usize()).max().unwrap_or(0);
|
let cstore = resolutions.cstore;
|
||||||
|
let crates = cstore.crates_untracked();
|
||||||
|
let max_cnum = crates.iter().map(|c| c.as_usize()).max().unwrap_or(0);
|
||||||
let mut providers = IndexVec::from_elem_n(extern_providers, max_cnum + 1);
|
let mut providers = IndexVec::from_elem_n(extern_providers, max_cnum + 1);
|
||||||
providers[LOCAL_CRATE] = local_providers;
|
providers[LOCAL_CRATE] = local_providers;
|
||||||
|
|
||||||
let def_path_hash_to_def_id = if s.opts.build_dep_graph() {
|
let def_path_hash_to_def_id = if s.opts.build_dep_graph() {
|
||||||
let upstream_def_path_tables: Vec<(CrateNum, Lrc<_>)> = cstore
|
let def_path_tables = crates
|
||||||
.crates_untracked()
|
|
||||||
.iter()
|
.iter()
|
||||||
.map(|&cnum| (cnum, cstore.def_path_table(cnum)))
|
.map(|&cnum| (cnum, cstore.def_path_table(cnum)))
|
||||||
.collect();
|
.chain(iter::once((LOCAL_CRATE, hir.definitions().def_path_table())));
|
||||||
|
|
||||||
let def_path_tables = || {
|
|
||||||
upstream_def_path_tables
|
|
||||||
.iter()
|
|
||||||
.map(|&(cnum, ref rc)| (cnum, &**rc))
|
|
||||||
.chain(iter::once((LOCAL_CRATE, hir.definitions().def_path_table())))
|
|
||||||
};
|
|
||||||
|
|
||||||
// Precompute the capacity of the hashmap so we don't have to
|
// Precompute the capacity of the hashmap so we don't have to
|
||||||
// re-allocate when populating it.
|
// re-allocate when populating it.
|
||||||
let capacity = def_path_tables().map(|(_, t)| t.size()).sum::<usize>();
|
let capacity = def_path_tables.clone().map(|(_, t)| t.size()).sum::<usize>();
|
||||||
|
|
||||||
let mut map: FxHashMap<_, _> = FxHashMap::with_capacity_and_hasher(
|
let mut map: FxHashMap<_, _> = FxHashMap::with_capacity_and_hasher(
|
||||||
capacity,
|
capacity,
|
||||||
::std::default::Default::default()
|
::std::default::Default::default()
|
||||||
);
|
);
|
||||||
|
|
||||||
for (cnum, def_path_table) in def_path_tables() {
|
for (cnum, def_path_table) in def_path_tables {
|
||||||
def_path_table.add_def_path_hashes_to(cnum, &mut map);
|
def_path_table.add_def_path_hashes_to(cnum, &mut map);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1255,6 +1251,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||||||
|
|
||||||
GlobalCtxt {
|
GlobalCtxt {
|
||||||
sess: s,
|
sess: s,
|
||||||
|
lint_store,
|
||||||
cstore,
|
cstore,
|
||||||
arena: WorkerLocal::new(|_| Arena::default()),
|
arena: WorkerLocal::new(|_| Arena::default()),
|
||||||
interners,
|
interners,
|
||||||
@ -1413,8 +1410,8 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||||||
|
|
||||||
// Note that this is *untracked* and should only be used within the query
|
// Note that this is *untracked* and should only be used within the query
|
||||||
// system if the result is otherwise tracked through queries
|
// system if the result is otherwise tracked through queries
|
||||||
pub fn crate_data_as_rc_any(self, cnum: CrateNum) -> Lrc<dyn Any> {
|
pub fn crate_data_as_any(self, cnum: CrateNum) -> &'tcx dyn Any {
|
||||||
self.cstore.crate_data_as_rc_any(cnum)
|
self.cstore.crate_data_as_any(cnum)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
@ -1424,7 +1421,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||||||
StableHashingContext::new(self.sess,
|
StableHashingContext::new(self.sess,
|
||||||
krate,
|
krate,
|
||||||
self.hir().definitions(),
|
self.hir().definitions(),
|
||||||
self.cstore)
|
&*self.cstore)
|
||||||
}
|
}
|
||||||
|
|
||||||
// This method makes sure that we have a DepNode and a Fingerprint for
|
// This method makes sure that we have a DepNode and a Fingerprint for
|
||||||
@ -2552,7 +2549,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn mk_ty_param(self, index: u32, name: InternedString) -> Ty<'tcx> {
|
pub fn mk_ty_param(self, index: u32, name: Symbol) -> Ty<'tcx> {
|
||||||
self.mk_ty(Param(ParamTy { index, name: name }))
|
self.mk_ty(Param(ParamTy { index, name: name }))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2560,7 +2557,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||||||
pub fn mk_const_param(
|
pub fn mk_const_param(
|
||||||
self,
|
self,
|
||||||
index: u32,
|
index: u32,
|
||||||
name: InternedString,
|
name: Symbol,
|
||||||
ty: Ty<'tcx>
|
ty: Ty<'tcx>
|
||||||
) -> &'tcx Const<'tcx> {
|
) -> &'tcx Const<'tcx> {
|
||||||
self.mk_const(ty::Const {
|
self.mk_const(ty::Const {
|
||||||
|
@ -45,7 +45,7 @@ pub enum TypeError<'tcx> {
|
|||||||
ProjectionMismatched(ExpectedFound<DefId>),
|
ProjectionMismatched(ExpectedFound<DefId>),
|
||||||
ProjectionBoundsLength(ExpectedFound<usize>),
|
ProjectionBoundsLength(ExpectedFound<usize>),
|
||||||
ExistentialMismatch(ExpectedFound<&'tcx ty::List<ty::ExistentialPredicate<'tcx>>>),
|
ExistentialMismatch(ExpectedFound<&'tcx ty::List<ty::ExistentialPredicate<'tcx>>>),
|
||||||
|
ObjectUnsafeCoercion(DefId),
|
||||||
ConstMismatch(ExpectedFound<&'tcx ty::Const<'tcx>>),
|
ConstMismatch(ExpectedFound<&'tcx ty::Const<'tcx>>),
|
||||||
|
|
||||||
IntrinsicCast,
|
IntrinsicCast,
|
||||||
@ -178,6 +178,7 @@ impl<'tcx> fmt::Display for TypeError<'tcx> {
|
|||||||
IntrinsicCast => {
|
IntrinsicCast => {
|
||||||
write!(f, "cannot coerce intrinsics to function pointers")
|
write!(f, "cannot coerce intrinsics to function pointers")
|
||||||
}
|
}
|
||||||
|
ObjectUnsafeCoercion(_) => write!(f, "coercion to object-unsafe trait object"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@ pub use self::Variance::*;
|
|||||||
pub use self::AssocItemContainer::*;
|
pub use self::AssocItemContainer::*;
|
||||||
pub use self::BorrowKind::*;
|
pub use self::BorrowKind::*;
|
||||||
pub use self::IntVarValue::*;
|
pub use self::IntVarValue::*;
|
||||||
pub use self::fold::TypeFoldable;
|
pub use self::fold::{TypeFoldable, TypeVisitor};
|
||||||
|
|
||||||
use crate::hir::{map as hir_map, GlobMap, TraitMap};
|
use crate::hir::{map as hir_map, GlobMap, TraitMap};
|
||||||
use crate::hir::Node;
|
use crate::hir::Node;
|
||||||
@ -15,6 +15,7 @@ use rustc_macros::HashStable;
|
|||||||
use crate::ich::Fingerprint;
|
use crate::ich::Fingerprint;
|
||||||
use crate::ich::StableHashingContext;
|
use crate::ich::StableHashingContext;
|
||||||
use crate::infer::canonical::Canonical;
|
use crate::infer::canonical::Canonical;
|
||||||
|
use crate::middle::cstore::CrateStoreDyn;
|
||||||
use crate::middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem, FnOnceTraitLangItem};
|
use crate::middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem, FnOnceTraitLangItem};
|
||||||
use crate::middle::resolve_lifetime::ObjectLifetimeDefault;
|
use crate::middle::resolve_lifetime::ObjectLifetimeDefault;
|
||||||
use crate::mir::Body;
|
use crate::mir::Body;
|
||||||
@ -46,11 +47,11 @@ use std::ops::Range;
|
|||||||
use syntax::ast::{self, Name, Ident, NodeId};
|
use syntax::ast::{self, Name, Ident, NodeId};
|
||||||
use syntax::attr;
|
use syntax::attr;
|
||||||
use syntax_expand::hygiene::ExpnId;
|
use syntax_expand::hygiene::ExpnId;
|
||||||
use syntax::symbol::{kw, sym, Symbol, InternedString};
|
use syntax::symbol::{kw, sym, Symbol};
|
||||||
use syntax_pos::Span;
|
use syntax_pos::Span;
|
||||||
|
|
||||||
use smallvec;
|
use smallvec;
|
||||||
use rustc_data_structures::fx::FxIndexMap;
|
use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
|
||||||
use rustc_data_structures::stable_hasher::{StableHasher, HashStable};
|
use rustc_data_structures::stable_hasher::{StableHasher, HashStable};
|
||||||
use rustc_index::vec::{Idx, IndexVec};
|
use rustc_index::vec::{Idx, IndexVec};
|
||||||
|
|
||||||
@ -119,8 +120,9 @@ mod sty;
|
|||||||
|
|
||||||
// Data types
|
// Data types
|
||||||
|
|
||||||
#[derive(Clone)]
|
pub struct ResolverOutputs {
|
||||||
pub struct Resolutions {
|
pub definitions: hir_map::Definitions,
|
||||||
|
pub cstore: Box<CrateStoreDyn>,
|
||||||
pub extern_crate_map: NodeMap<CrateNum>,
|
pub extern_crate_map: NodeMap<CrateNum>,
|
||||||
pub trait_map: TraitMap,
|
pub trait_map: TraitMap,
|
||||||
pub maybe_unused_trait_imports: NodeSet,
|
pub maybe_unused_trait_imports: NodeSet,
|
||||||
@ -849,7 +851,7 @@ impl ty::EarlyBoundRegion {
|
|||||||
/// Does this early bound region have a name? Early bound regions normally
|
/// Does this early bound region have a name? Early bound regions normally
|
||||||
/// always have names except when using anonymous lifetimes (`'_`).
|
/// always have names except when using anonymous lifetimes (`'_`).
|
||||||
pub fn has_name(&self) -> bool {
|
pub fn has_name(&self) -> bool {
|
||||||
self.name != kw::UnderscoreLifetime.as_interned_str()
|
self.name != kw::UnderscoreLifetime
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -866,7 +868,7 @@ pub enum GenericParamDefKind {
|
|||||||
|
|
||||||
#[derive(Clone, RustcEncodable, RustcDecodable, HashStable)]
|
#[derive(Clone, RustcEncodable, RustcDecodable, HashStable)]
|
||||||
pub struct GenericParamDef {
|
pub struct GenericParamDef {
|
||||||
pub name: InternedString,
|
pub name: Symbol,
|
||||||
pub def_id: DefId,
|
pub def_id: DefId,
|
||||||
pub index: u32,
|
pub index: u32,
|
||||||
|
|
||||||
@ -3019,7 +3021,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||||||
}),
|
}),
|
||||||
_ => def_key.disambiguated_data.data.get_opt_name().unwrap_or_else(|| {
|
_ => def_key.disambiguated_data.data.get_opt_name().unwrap_or_else(|| {
|
||||||
bug!("item_name: no name for {:?}", self.def_path(id));
|
bug!("item_name: no name for {:?}", self.def_path(id));
|
||||||
}).as_symbol(),
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3393,6 +3395,129 @@ fn asyncness(tcx: TyCtxt<'_>, def_id: DefId) -> hir::IsAsync {
|
|||||||
fn_like.asyncness()
|
fn_like.asyncness()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub enum NonStructuralMatchTy<'tcx> {
|
||||||
|
Adt(&'tcx AdtDef),
|
||||||
|
Param,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// This method traverses the structure of `ty`, trying to find an
|
||||||
|
/// instance of an ADT (i.e. struct or enum) that was declared without
|
||||||
|
/// the `#[structural_match]` attribute, or a generic type parameter
|
||||||
|
/// (which cannot be determined to be `structural_match`).
|
||||||
|
///
|
||||||
|
/// The "structure of a type" includes all components that would be
|
||||||
|
/// considered when doing a pattern match on a constant of that
|
||||||
|
/// type.
|
||||||
|
///
|
||||||
|
/// * This means this method descends into fields of structs/enums,
|
||||||
|
/// and also descends into the inner type `T` of `&T` and `&mut T`
|
||||||
|
///
|
||||||
|
/// * The traversal doesn't dereference unsafe pointers (`*const T`,
|
||||||
|
/// `*mut T`), and it does not visit the type arguments of an
|
||||||
|
/// instantiated generic like `PhantomData<T>`.
|
||||||
|
///
|
||||||
|
/// The reason we do this search is Rust currently require all ADTs
|
||||||
|
/// reachable from a constant's type to be annotated with
|
||||||
|
/// `#[structural_match]`, an attribute which essentially says that
|
||||||
|
/// the implementation of `PartialEq::eq` behaves *equivalently* to a
|
||||||
|
/// comparison against the unfolded structure.
|
||||||
|
///
|
||||||
|
/// For more background on why Rust has this requirement, and issues
|
||||||
|
/// that arose when the requirement was not enforced completely, see
|
||||||
|
/// Rust RFC 1445, rust-lang/rust#61188, and rust-lang/rust#62307.
|
||||||
|
pub fn search_for_structural_match_violation<'tcx>(
|
||||||
|
tcx: TyCtxt<'tcx>,
|
||||||
|
ty: Ty<'tcx>,
|
||||||
|
) -> Option<NonStructuralMatchTy<'tcx>> {
|
||||||
|
let mut search = Search { tcx, found: None, seen: FxHashSet::default() };
|
||||||
|
ty.visit_with(&mut search);
|
||||||
|
return search.found;
|
||||||
|
|
||||||
|
struct Search<'tcx> {
|
||||||
|
tcx: TyCtxt<'tcx>,
|
||||||
|
|
||||||
|
// Records the first ADT or type parameter we find without `#[structural_match`.
|
||||||
|
found: Option<NonStructuralMatchTy<'tcx>>,
|
||||||
|
|
||||||
|
// Tracks ADTs previously encountered during search, so that
|
||||||
|
// we will not recurse on them again.
|
||||||
|
seen: FxHashSet<hir::def_id::DefId>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'tcx> TypeVisitor<'tcx> for Search<'tcx> {
|
||||||
|
fn visit_ty(&mut self, ty: Ty<'tcx>) -> bool {
|
||||||
|
debug!("Search visiting ty: {:?}", ty);
|
||||||
|
|
||||||
|
let (adt_def, substs) = match ty.kind {
|
||||||
|
ty::Adt(adt_def, substs) => (adt_def, substs),
|
||||||
|
ty::Param(_) => {
|
||||||
|
self.found = Some(NonStructuralMatchTy::Param);
|
||||||
|
return true; // Stop visiting.
|
||||||
|
}
|
||||||
|
ty::RawPtr(..) => {
|
||||||
|
// `#[structural_match]` ignores substructure of
|
||||||
|
// `*const _`/`*mut _`, so skip super_visit_with
|
||||||
|
//
|
||||||
|
// (But still tell caller to continue search.)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ty::FnDef(..) | ty::FnPtr(..) => {
|
||||||
|
// types of formals and return in `fn(_) -> _` are also irrelevant
|
||||||
|
//
|
||||||
|
// (But still tell caller to continue search.)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ty::Array(_, n) if n.try_eval_usize(self.tcx, ty::ParamEnv::reveal_all()) == Some(0)
|
||||||
|
=> {
|
||||||
|
// rust-lang/rust#62336: ignore type of contents
|
||||||
|
// for empty array.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
ty.super_visit_with(self);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if !self.tcx.has_attr(adt_def.did, sym::structural_match) {
|
||||||
|
self.found = Some(NonStructuralMatchTy::Adt(&adt_def));
|
||||||
|
debug!("Search found adt_def: {:?}", adt_def);
|
||||||
|
return true; // Stop visiting.
|
||||||
|
}
|
||||||
|
|
||||||
|
if !self.seen.insert(adt_def.did) {
|
||||||
|
debug!("Search already seen adt_def: {:?}", adt_def);
|
||||||
|
// let caller continue its search
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// `#[structural_match]` does not care about the
|
||||||
|
// instantiation of the generics in an ADT (it
|
||||||
|
// instead looks directly at its fields outside
|
||||||
|
// this match), so we skip super_visit_with.
|
||||||
|
//
|
||||||
|
// (Must not recur on substs for `PhantomData<T>` cf
|
||||||
|
// rust-lang/rust#55028 and rust-lang/rust#55837; but also
|
||||||
|
// want to skip substs when only uses of generic are
|
||||||
|
// behind unsafe pointers `*const T`/`*mut T`.)
|
||||||
|
|
||||||
|
// even though we skip super_visit_with, we must recur on
|
||||||
|
// fields of ADT.
|
||||||
|
let tcx = self.tcx;
|
||||||
|
for field_ty in adt_def.all_fields().map(|field| field.ty(tcx, substs)) {
|
||||||
|
if field_ty.visit_with(self) {
|
||||||
|
// found an ADT without `#[structural_match]`; halt visiting!
|
||||||
|
assert!(self.found.is_some());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Even though we do not want to recur on substs, we do
|
||||||
|
// want our caller to continue its own search.
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn provide(providers: &mut ty::query::Providers<'_>) {
|
pub fn provide(providers: &mut ty::query::Providers<'_>) {
|
||||||
context::provide(providers);
|
context::provide(providers);
|
||||||
@ -3429,11 +3554,11 @@ pub struct CrateInherentImpls {
|
|||||||
pub inherent_impls: DefIdMap<Vec<DefId>>,
|
pub inherent_impls: DefIdMap<Vec<DefId>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, RustcEncodable, RustcDecodable)]
|
#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable)]
|
||||||
pub struct SymbolName {
|
pub struct SymbolName {
|
||||||
// FIXME: we don't rely on interning or equality here - better have
|
// FIXME: we don't rely on interning or equality here - better have
|
||||||
// this be a `&'tcx str`.
|
// this be a `&'tcx str`.
|
||||||
pub name: InternedString
|
pub name: Symbol
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_stable_hash_for!(struct self::SymbolName {
|
impl_stable_hash_for!(struct self::SymbolName {
|
||||||
@ -3443,11 +3568,24 @@ impl_stable_hash_for!(struct self::SymbolName {
|
|||||||
impl SymbolName {
|
impl SymbolName {
|
||||||
pub fn new(name: &str) -> SymbolName {
|
pub fn new(name: &str) -> SymbolName {
|
||||||
SymbolName {
|
SymbolName {
|
||||||
name: InternedString::intern(name)
|
name: Symbol::intern(name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl PartialOrd for SymbolName {
|
||||||
|
fn partial_cmp(&self, other: &SymbolName) -> Option<Ordering> {
|
||||||
|
self.name.as_str().partial_cmp(&other.name.as_str())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Ordering must use the chars to ensure reproducible builds.
|
||||||
|
impl Ord for SymbolName {
|
||||||
|
fn cmp(&self, other: &SymbolName) -> Ordering {
|
||||||
|
self.name.as_str().cmp(&other.name.as_str())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl fmt::Display for SymbolName {
|
impl fmt::Display for SymbolName {
|
||||||
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
fmt::Display::fmt(&self.name, fmt)
|
fmt::Display::fmt(&self.name, fmt)
|
||||||
|
@ -218,9 +218,9 @@ impl DefPathBasedNames<'tcx> {
|
|||||||
// foo::bar::ItemName::
|
// foo::bar::ItemName::
|
||||||
for part in self.tcx.def_path(def_id).data {
|
for part in self.tcx.def_path(def_id).data {
|
||||||
if self.omit_disambiguators {
|
if self.omit_disambiguators {
|
||||||
write!(output, "{}::", part.data.as_interned_str()).unwrap();
|
write!(output, "{}::", part.data.as_symbol()).unwrap();
|
||||||
} else {
|
} else {
|
||||||
write!(output, "{}[{}]::", part.data.as_interned_str(), part.disambiguator)
|
write!(output, "{}[{}]::", part.data.as_symbol(), part.disambiguator)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ use rustc_apfloat::Float;
|
|||||||
use rustc_target::spec::abi::Abi;
|
use rustc_target::spec::abi::Abi;
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use syntax::attr::{SignedInt, UnsignedInt};
|
use syntax::attr::{SignedInt, UnsignedInt};
|
||||||
use syntax::symbol::{kw, InternedString};
|
use syntax::symbol::{kw, Symbol};
|
||||||
|
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use std::fmt::{self, Write as _};
|
use std::fmt::{self, Write as _};
|
||||||
@ -384,7 +384,7 @@ pub trait PrettyPrinter<'tcx>:
|
|||||||
let reexport = self.tcx().item_children(visible_parent)
|
let reexport = self.tcx().item_children(visible_parent)
|
||||||
.iter()
|
.iter()
|
||||||
.find(|child| child.res.def_id() == def_id)
|
.find(|child| child.res.def_id() == def_id)
|
||||||
.map(|child| child.ident.as_interned_str());
|
.map(|child| child.ident.name);
|
||||||
if let Some(reexport) = reexport {
|
if let Some(reexport) = reexport {
|
||||||
*name = reexport;
|
*name = reexport;
|
||||||
}
|
}
|
||||||
@ -392,7 +392,7 @@ pub trait PrettyPrinter<'tcx>:
|
|||||||
// Re-exported `extern crate` (#43189).
|
// Re-exported `extern crate` (#43189).
|
||||||
DefPathData::CrateRoot => {
|
DefPathData::CrateRoot => {
|
||||||
data = DefPathData::TypeNs(
|
data = DefPathData::TypeNs(
|
||||||
self.tcx().original_crate_name(def_id.krate).as_interned_str(),
|
self.tcx().original_crate_name(def_id.krate),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
@ -992,7 +992,7 @@ pub struct FmtPrinterData<'a, 'tcx, F> {
|
|||||||
empty_path: bool,
|
empty_path: bool,
|
||||||
in_value: bool,
|
in_value: bool,
|
||||||
|
|
||||||
used_region_names: FxHashSet<InternedString>,
|
used_region_names: FxHashSet<Symbol>,
|
||||||
region_index: usize,
|
region_index: usize,
|
||||||
binder_depth: usize,
|
binder_depth: usize,
|
||||||
|
|
||||||
@ -1222,7 +1222,7 @@ impl<F: fmt::Write> Printer<'tcx> for FmtPrinter<'_, 'tcx, F> {
|
|||||||
|
|
||||||
// FIXME(eddyb) `name` should never be empty, but it
|
// FIXME(eddyb) `name` should never be empty, but it
|
||||||
// currently is for `extern { ... }` "foreign modules".
|
// currently is for `extern { ... }` "foreign modules".
|
||||||
let name = disambiguated_data.data.as_interned_str().as_str();
|
let name = disambiguated_data.data.as_symbol().as_str();
|
||||||
if !name.is_empty() {
|
if !name.is_empty() {
|
||||||
if !self.empty_path {
|
if !self.empty_path {
|
||||||
write!(self, "::")?;
|
write!(self, "::")?;
|
||||||
@ -1332,16 +1332,16 @@ impl<F: fmt::Write> PrettyPrinter<'tcx> for FmtPrinter<'_, 'tcx, F> {
|
|||||||
|
|
||||||
match *region {
|
match *region {
|
||||||
ty::ReEarlyBound(ref data) => {
|
ty::ReEarlyBound(ref data) => {
|
||||||
data.name.as_symbol() != kw::Invalid &&
|
data.name != kw::Invalid &&
|
||||||
data.name.as_symbol() != kw::UnderscoreLifetime
|
data.name != kw::UnderscoreLifetime
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::ReLateBound(_, br) |
|
ty::ReLateBound(_, br) |
|
||||||
ty::ReFree(ty::FreeRegion { bound_region: br, .. }) |
|
ty::ReFree(ty::FreeRegion { bound_region: br, .. }) |
|
||||||
ty::RePlaceholder(ty::Placeholder { name: br, .. }) => {
|
ty::RePlaceholder(ty::Placeholder { name: br, .. }) => {
|
||||||
if let ty::BrNamed(_, name) = br {
|
if let ty::BrNamed(_, name) = br {
|
||||||
if name.as_symbol() != kw::Invalid &&
|
if name != kw::Invalid &&
|
||||||
name.as_symbol() != kw::UnderscoreLifetime {
|
name != kw::UnderscoreLifetime {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1397,7 +1397,7 @@ impl<F: fmt::Write> FmtPrinter<'_, '_, F> {
|
|||||||
// `explain_region()` or `note_and_explain_region()`.
|
// `explain_region()` or `note_and_explain_region()`.
|
||||||
match *region {
|
match *region {
|
||||||
ty::ReEarlyBound(ref data) => {
|
ty::ReEarlyBound(ref data) => {
|
||||||
if data.name.as_symbol() != kw::Invalid {
|
if data.name != kw::Invalid {
|
||||||
p!(write("{}", data.name));
|
p!(write("{}", data.name));
|
||||||
return Ok(self);
|
return Ok(self);
|
||||||
}
|
}
|
||||||
@ -1406,8 +1406,8 @@ impl<F: fmt::Write> FmtPrinter<'_, '_, F> {
|
|||||||
ty::ReFree(ty::FreeRegion { bound_region: br, .. }) |
|
ty::ReFree(ty::FreeRegion { bound_region: br, .. }) |
|
||||||
ty::RePlaceholder(ty::Placeholder { name: br, .. }) => {
|
ty::RePlaceholder(ty::Placeholder { name: br, .. }) => {
|
||||||
if let ty::BrNamed(_, name) = br {
|
if let ty::BrNamed(_, name) = br {
|
||||||
if name.as_symbol() != kw::Invalid &&
|
if name != kw::Invalid &&
|
||||||
name.as_symbol() != kw::UnderscoreLifetime {
|
name != kw::UnderscoreLifetime {
|
||||||
p!(write("{}", name));
|
p!(write("{}", name));
|
||||||
return Ok(self);
|
return Ok(self);
|
||||||
}
|
}
|
||||||
@ -1474,11 +1474,11 @@ impl<F: fmt::Write> FmtPrinter<'_, 'tcx, F> {
|
|||||||
where
|
where
|
||||||
T: Print<'tcx, Self, Output = Self, Error = fmt::Error> + TypeFoldable<'tcx>,
|
T: Print<'tcx, Self, Output = Self, Error = fmt::Error> + TypeFoldable<'tcx>,
|
||||||
{
|
{
|
||||||
fn name_by_region_index(index: usize) -> InternedString {
|
fn name_by_region_index(index: usize) -> Symbol {
|
||||||
match index {
|
match index {
|
||||||
0 => InternedString::intern("'r"),
|
0 => Symbol::intern("'r"),
|
||||||
1 => InternedString::intern("'s"),
|
1 => Symbol::intern("'s"),
|
||||||
i => InternedString::intern(&format!("'t{}", i-2)),
|
i => Symbol::intern(&format!("'t{}", i-2)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1541,7 +1541,7 @@ impl<F: fmt::Write> FmtPrinter<'_, 'tcx, F> {
|
|||||||
where T: TypeFoldable<'tcx>
|
where T: TypeFoldable<'tcx>
|
||||||
{
|
{
|
||||||
|
|
||||||
struct LateBoundRegionNameCollector<'a>(&'a mut FxHashSet<InternedString>);
|
struct LateBoundRegionNameCollector<'a>(&'a mut FxHashSet<Symbol>);
|
||||||
impl<'tcx> ty::fold::TypeVisitor<'tcx> for LateBoundRegionNameCollector<'_> {
|
impl<'tcx> ty::fold::TypeVisitor<'tcx> for LateBoundRegionNameCollector<'_> {
|
||||||
fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
|
fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
|
||||||
match *r {
|
match *r {
|
||||||
|
@ -9,7 +9,7 @@ use crate::ty::fast_reject::SimplifiedType;
|
|||||||
use crate::mir;
|
use crate::mir;
|
||||||
|
|
||||||
use syntax_pos::{Span, DUMMY_SP};
|
use syntax_pos::{Span, DUMMY_SP};
|
||||||
use syntax_pos::symbol::InternedString;
|
use syntax_pos::symbol::Symbol;
|
||||||
|
|
||||||
/// The `Key` trait controls what types can legally be used as the key
|
/// The `Key` trait controls what types can legally be used as the key
|
||||||
/// for a query.
|
/// for a query.
|
||||||
@ -188,7 +188,7 @@ impl<'tcx> Key for traits::Environment<'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Key for InternedString {
|
impl Key for Symbol {
|
||||||
fn query_crate(&self) -> CrateNum {
|
fn query_crate(&self) -> CrateNum {
|
||||||
LOCAL_CRATE
|
LOCAL_CRATE
|
||||||
}
|
}
|
||||||
|
@ -55,7 +55,6 @@ use std::ops::Deref;
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::any::type_name;
|
use std::any::type_name;
|
||||||
use syntax_pos::{Span, DUMMY_SP};
|
use syntax_pos::{Span, DUMMY_SP};
|
||||||
use syntax_pos::symbol::InternedString;
|
|
||||||
use syntax::attr;
|
use syntax::attr;
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use syntax::feature_gate;
|
use syntax::feature_gate;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use crate::ty::{self, Ty, TyCtxt, AdtSizedConstraint};
|
use crate::ty::{self, Ty, TyCtxt, AdtSizedConstraint};
|
||||||
use crate::ty::util::NeedsDrop;
|
use crate::ty::util::NeedsDrop;
|
||||||
|
|
||||||
use syntax::symbol::InternedString;
|
use syntax::symbol::Symbol;
|
||||||
|
|
||||||
pub(super) trait Value<'tcx>: Sized {
|
pub(super) trait Value<'tcx>: Sized {
|
||||||
fn from_cycle_error(tcx: TyCtxt<'tcx>) -> Self;
|
fn from_cycle_error(tcx: TyCtxt<'tcx>) -> Self;
|
||||||
@ -22,7 +22,7 @@ impl<'tcx> Value<'tcx> for Ty<'tcx> {
|
|||||||
|
|
||||||
impl<'tcx> Value<'tcx> for ty::SymbolName {
|
impl<'tcx> Value<'tcx> for ty::SymbolName {
|
||||||
fn from_cycle_error(_: TyCtxt<'tcx>) -> Self {
|
fn from_cycle_error(_: TyCtxt<'tcx>) -> Self {
|
||||||
ty::SymbolName { name: InternedString::intern("<error>") }
|
ty::SymbolName { name: Symbol::intern("<error>") }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -557,10 +557,9 @@ pub fn super_relate_consts<R: TypeRelation<'tcx>>(
|
|||||||
x.val
|
x.val
|
||||||
};
|
};
|
||||||
|
|
||||||
// Currently, the values that can be unified are those that
|
// Currently, the values that can be unified are primitive types,
|
||||||
// implement both `PartialEq` and `Eq`, corresponding to
|
// and those that derive both `PartialEq` and `Eq`, corresponding
|
||||||
// `structural_match` types.
|
// to `structural_match` types.
|
||||||
// FIXME(const_generics): check for `structural_match` synthetic attribute.
|
|
||||||
let new_const_val = match (eagerly_eval(a), eagerly_eval(b)) {
|
let new_const_val = match (eagerly_eval(a), eagerly_eval(b)) {
|
||||||
(ConstValue::Infer(_), _) | (_, ConstValue::Infer(_)) => {
|
(ConstValue::Infer(_), _) | (_, ConstValue::Infer(_)) => {
|
||||||
// The caller should handle these cases!
|
// The caller should handle these cases!
|
||||||
|
@ -749,6 +749,7 @@ impl<'a, 'tcx> Lift<'tcx> for ty::error::TypeError<'a> {
|
|||||||
ExistentialMismatch(ref x) => return tcx.lift(x).map(ExistentialMismatch),
|
ExistentialMismatch(ref x) => return tcx.lift(x).map(ExistentialMismatch),
|
||||||
ConstMismatch(ref x) => return tcx.lift(x).map(ConstMismatch),
|
ConstMismatch(ref x) => return tcx.lift(x).map(ConstMismatch),
|
||||||
IntrinsicCast => IntrinsicCast,
|
IntrinsicCast => IntrinsicCast,
|
||||||
|
ObjectUnsafeCoercion(ref x) => return tcx.lift(x).map(ObjectUnsafeCoercion),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1350,6 +1351,7 @@ EnumTypeFoldableImpl! {
|
|||||||
(ty::error::TypeError::ExistentialMismatch)(x),
|
(ty::error::TypeError::ExistentialMismatch)(x),
|
||||||
(ty::error::TypeError::ConstMismatch)(x),
|
(ty::error::TypeError::ConstMismatch)(x),
|
||||||
(ty::error::TypeError::IntrinsicCast),
|
(ty::error::TypeError::IntrinsicCast),
|
||||||
|
(ty::error::TypeError::ObjectUnsafeCoercion)(x),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ use std::marker::PhantomData;
|
|||||||
use std::ops::Range;
|
use std::ops::Range;
|
||||||
use rustc_target::spec::abi;
|
use rustc_target::spec::abi;
|
||||||
use syntax::ast::{self, Ident};
|
use syntax::ast::{self, Ident};
|
||||||
use syntax::symbol::{kw, InternedString};
|
use syntax::symbol::{kw, Symbol};
|
||||||
|
|
||||||
use self::InferTy::*;
|
use self::InferTy::*;
|
||||||
use self::TyKind::*;
|
use self::TyKind::*;
|
||||||
@ -55,7 +55,7 @@ pub enum BoundRegion {
|
|||||||
///
|
///
|
||||||
/// The `DefId` is needed to distinguish free regions in
|
/// The `DefId` is needed to distinguish free regions in
|
||||||
/// the event of shadowing.
|
/// the event of shadowing.
|
||||||
BrNamed(DefId, InternedString),
|
BrNamed(DefId, Symbol),
|
||||||
|
|
||||||
/// Anonymous region for the implicit env pointer parameter
|
/// Anonymous region for the implicit env pointer parameter
|
||||||
/// to a closure
|
/// to a closure
|
||||||
@ -1121,16 +1121,16 @@ pub type CanonicalPolyFnSig<'tcx> = Canonical<'tcx, Binder<FnSig<'tcx>>>;
|
|||||||
Hash, RustcEncodable, RustcDecodable, HashStable)]
|
Hash, RustcEncodable, RustcDecodable, HashStable)]
|
||||||
pub struct ParamTy {
|
pub struct ParamTy {
|
||||||
pub index: u32,
|
pub index: u32,
|
||||||
pub name: InternedString,
|
pub name: Symbol,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> ParamTy {
|
impl<'tcx> ParamTy {
|
||||||
pub fn new(index: u32, name: InternedString) -> ParamTy {
|
pub fn new(index: u32, name: Symbol) -> ParamTy {
|
||||||
ParamTy { index, name: name }
|
ParamTy { index, name: name }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn for_self() -> ParamTy {
|
pub fn for_self() -> ParamTy {
|
||||||
ParamTy::new(0, kw::SelfUpper.as_interned_str())
|
ParamTy::new(0, kw::SelfUpper)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn for_def(def: &ty::GenericParamDef) -> ParamTy {
|
pub fn for_def(def: &ty::GenericParamDef) -> ParamTy {
|
||||||
@ -1146,11 +1146,11 @@ impl<'tcx> ParamTy {
|
|||||||
Eq, PartialEq, Ord, PartialOrd, HashStable)]
|
Eq, PartialEq, Ord, PartialOrd, HashStable)]
|
||||||
pub struct ParamConst {
|
pub struct ParamConst {
|
||||||
pub index: u32,
|
pub index: u32,
|
||||||
pub name: InternedString,
|
pub name: Symbol,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> ParamConst {
|
impl<'tcx> ParamConst {
|
||||||
pub fn new(index: u32, name: InternedString) -> ParamConst {
|
pub fn new(index: u32, name: Symbol) -> ParamConst {
|
||||||
ParamConst { index, name }
|
ParamConst { index, name }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1323,7 +1323,7 @@ impl<'tcx> rustc_serialize::UseSpecializedDecodable for Region<'tcx> {}
|
|||||||
pub struct EarlyBoundRegion {
|
pub struct EarlyBoundRegion {
|
||||||
pub def_id: DefId,
|
pub def_id: DefId,
|
||||||
pub index: u32,
|
pub index: u32,
|
||||||
pub name: InternedString,
|
pub name: Symbol,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
|
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
|
||||||
@ -1387,7 +1387,7 @@ pub struct BoundTy {
|
|||||||
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)]
|
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)]
|
||||||
pub enum BoundTyKind {
|
pub enum BoundTyKind {
|
||||||
Anon,
|
Anon,
|
||||||
Param(InternedString),
|
Param(Symbol),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_stable_hash_for!(struct BoundTy { var, kind });
|
impl_stable_hash_for!(struct BoundTy { var, kind });
|
||||||
|
@ -380,16 +380,21 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
|
|||||||
// obligations that don't refer to Self and
|
// obligations that don't refer to Self and
|
||||||
// checking those
|
// checking those
|
||||||
|
|
||||||
let cause = self.cause(traits::MiscObligation);
|
let defer_to_coercion =
|
||||||
let component_traits =
|
self.infcx.tcx.features().object_safe_for_dispatch;
|
||||||
data.auto_traits().chain(data.principal_def_id());
|
|
||||||
self.out.extend(
|
if !defer_to_coercion {
|
||||||
component_traits.map(|did| traits::Obligation::new(
|
let cause = self.cause(traits::MiscObligation);
|
||||||
cause.clone(),
|
let component_traits =
|
||||||
param_env,
|
data.auto_traits().chain(data.principal_def_id());
|
||||||
ty::Predicate::ObjectSafe(did)
|
self.out.extend(
|
||||||
))
|
component_traits.map(|did| traits::Obligation::new(
|
||||||
);
|
cause.clone(),
|
||||||
|
param_env,
|
||||||
|
ty::Predicate::ObjectSafe(did)
|
||||||
|
))
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Inference variables are the complicated case, since we don't
|
// Inference variables are the complicated case, since we don't
|
||||||
|
@ -36,7 +36,7 @@ use rustc_codegen_ssa::back::write::submit_codegened_module_to_llvm;
|
|||||||
|
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
use syntax_pos::symbol::InternedString;
|
use syntax_pos::symbol::Symbol;
|
||||||
use rustc::hir::CodegenFnAttrs;
|
use rustc::hir::CodegenFnAttrs;
|
||||||
|
|
||||||
use crate::value::Value;
|
use crate::value::Value;
|
||||||
@ -105,7 +105,7 @@ pub fn iter_globals(llmod: &'ll llvm::Module) -> ValueIter<'ll> {
|
|||||||
|
|
||||||
pub fn compile_codegen_unit(
|
pub fn compile_codegen_unit(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
cgu_name: InternedString,
|
cgu_name: Symbol,
|
||||||
tx_to_llvm_workers: &std::sync::mpsc::Sender<Box<dyn std::any::Any + Send>>,
|
tx_to_llvm_workers: &std::sync::mpsc::Sender<Box<dyn std::any::Any + Send>>,
|
||||||
) {
|
) {
|
||||||
let prof_timer = tcx.prof.generic_activity("codegen_module");
|
let prof_timer = tcx.prof.generic_activity("codegen_module");
|
||||||
@ -131,7 +131,7 @@ pub fn compile_codegen_unit(
|
|||||||
|
|
||||||
fn module_codegen(
|
fn module_codegen(
|
||||||
tcx: TyCtxt<'_>,
|
tcx: TyCtxt<'_>,
|
||||||
cgu_name: InternedString,
|
cgu_name: Symbol,
|
||||||
) -> ModuleCodegen<ModuleLlvm> {
|
) -> ModuleCodegen<ModuleLlvm> {
|
||||||
let cgu = tcx.codegen_unit(cgu_name);
|
let cgu = tcx.codegen_unit(cgu_name);
|
||||||
// Instantiate monomorphizations without filling out definitions yet...
|
// Instantiate monomorphizations without filling out definitions yet...
|
||||||
|
@ -221,7 +221,7 @@ impl CodegenCx<'ll, 'tcx> {
|
|||||||
def_id);
|
def_id);
|
||||||
|
|
||||||
let ty = instance.ty(self.tcx);
|
let ty = instance.ty(self.tcx);
|
||||||
let sym = self.tcx.symbol_name(instance).name.as_symbol();
|
let sym = self.tcx.symbol_name(instance).name;
|
||||||
|
|
||||||
debug!("get_static: sym={} instance={:?}", sym, instance);
|
debug!("get_static: sym={} instance={:?}", sym, instance);
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ use std::iter;
|
|||||||
use std::ptr;
|
use std::ptr;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use syntax::symbol::{Interner, InternedString};
|
use syntax::symbol::{Interner, Symbol};
|
||||||
use syntax_pos::{self, Span, FileName};
|
use syntax_pos::{self, Span, FileName};
|
||||||
|
|
||||||
impl PartialEq for llvm::Metadata {
|
impl PartialEq for llvm::Metadata {
|
||||||
@ -2125,7 +2125,7 @@ fn compute_type_parameters(cx: &CodegenCx<'ll, 'tcx>, ty: Ty<'tcx>) -> Option<&'
|
|||||||
|
|
||||||
fn get_parameter_names(cx: &CodegenCx<'_, '_>,
|
fn get_parameter_names(cx: &CodegenCx<'_, '_>,
|
||||||
generics: &ty::Generics)
|
generics: &ty::Generics)
|
||||||
-> Vec<InternedString> {
|
-> Vec<Symbol> {
|
||||||
let mut names = generics.parent.map_or(vec![], |def_id| {
|
let mut names = generics.parent.map_or(vec![], |def_id| {
|
||||||
get_parameter_names(cx, cx.tcx.generics_of(def_id))
|
get_parameter_names(cx, cx.tcx.generics_of(def_id))
|
||||||
});
|
});
|
||||||
|
@ -36,7 +36,7 @@ use std::ffi::{CStr, CString};
|
|||||||
|
|
||||||
use syntax_pos::{self, Span, Pos};
|
use syntax_pos::{self, Span, Pos};
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use syntax::symbol::InternedString;
|
use syntax::symbol::Symbol;
|
||||||
use rustc::ty::layout::{self, LayoutOf, HasTyCtxt};
|
use rustc::ty::layout::{self, LayoutOf, HasTyCtxt};
|
||||||
use rustc_codegen_ssa::traits::*;
|
use rustc_codegen_ssa::traits::*;
|
||||||
|
|
||||||
@ -490,7 +490,7 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
|
|||||||
|
|
||||||
fn get_parameter_names(cx: &CodegenCx<'_, '_>,
|
fn get_parameter_names(cx: &CodegenCx<'_, '_>,
|
||||||
generics: &ty::Generics)
|
generics: &ty::Generics)
|
||||||
-> Vec<InternedString> {
|
-> Vec<Symbol> {
|
||||||
let mut names = generics.parent.map_or(vec![], |def_id| {
|
let mut names = generics.parent.map_or(vec![], |def_id| {
|
||||||
get_parameter_names(cx, cx.tcx.generics_of(def_id))
|
get_parameter_names(cx, cx.tcx.generics_of(def_id))
|
||||||
});
|
});
|
||||||
|
@ -35,7 +35,7 @@ pub fn item_namespace(cx: &CodegenCx<'ll, '_>, def_id: DefId) -> &'ll DIScope {
|
|||||||
|
|
||||||
let namespace_name = match def_key.disambiguated_data.data {
|
let namespace_name = match def_key.disambiguated_data.data {
|
||||||
DefPathData::CrateRoot => cx.tcx.crate_name(def_id.krate).as_str(),
|
DefPathData::CrateRoot => cx.tcx.crate_name(def_id.krate).as_str(),
|
||||||
data => data.as_interned_str().as_str()
|
data => data.as_symbol().as_str()
|
||||||
};
|
};
|
||||||
|
|
||||||
let namespace_name = SmallCStr::new(&namespace_name);
|
let namespace_name = SmallCStr::new(&namespace_name);
|
||||||
|
@ -50,14 +50,13 @@ use rustc_codegen_ssa::CompiledModule;
|
|||||||
use errors::{FatalError, Handler};
|
use errors::{FatalError, Handler};
|
||||||
use rustc::dep_graph::WorkProduct;
|
use rustc::dep_graph::WorkProduct;
|
||||||
use syntax_expand::allocator::AllocatorKind;
|
use syntax_expand::allocator::AllocatorKind;
|
||||||
use syntax_pos::symbol::InternedString;
|
|
||||||
pub use llvm_util::target_features;
|
pub use llvm_util::target_features;
|
||||||
use std::any::Any;
|
use std::any::Any;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::ffi::CStr;
|
use std::ffi::CStr;
|
||||||
|
|
||||||
use rustc::dep_graph::DepGraph;
|
use rustc::dep_graph::DepGraph;
|
||||||
use rustc::middle::cstore::{EncodedMetadata, MetadataLoader};
|
use rustc::middle::cstore::{EncodedMetadata, MetadataLoaderDyn};
|
||||||
use rustc::session::Session;
|
use rustc::session::Session;
|
||||||
use rustc::session::config::{OutputFilenames, OutputType, PrintRequest, OptLevel};
|
use rustc::session::config::{OutputFilenames, OutputType, PrintRequest, OptLevel};
|
||||||
use rustc::ty::{self, TyCtxt};
|
use rustc::ty::{self, TyCtxt};
|
||||||
@ -123,7 +122,7 @@ impl ExtraBackendMethods for LlvmCodegenBackend {
|
|||||||
}
|
}
|
||||||
fn compile_codegen_unit(
|
fn compile_codegen_unit(
|
||||||
&self, tcx: TyCtxt<'_>,
|
&self, tcx: TyCtxt<'_>,
|
||||||
cgu_name: InternedString,
|
cgu_name: Symbol,
|
||||||
tx: &std::sync::mpsc::Sender<Box<dyn Any + Send>>,
|
tx: &std::sync::mpsc::Sender<Box<dyn Any + Send>>,
|
||||||
) {
|
) {
|
||||||
base::compile_codegen_unit(tcx, cgu_name, tx);
|
base::compile_codegen_unit(tcx, cgu_name, tx);
|
||||||
@ -261,7 +260,7 @@ impl CodegenBackend for LlvmCodegenBackend {
|
|||||||
target_features(sess)
|
target_features(sess)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn metadata_loader(&self) -> Box<dyn MetadataLoader + Sync> {
|
fn metadata_loader(&self) -> Box<MetadataLoaderDyn> {
|
||||||
box metadata::LlvmMetadataLoader
|
box metadata::LlvmMetadataLoader
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -259,7 +259,7 @@ fn generate_lto_work<B: ExtraBackendMethods>(
|
|||||||
needs_thin_lto: Vec<(String, B::ThinBuffer)>,
|
needs_thin_lto: Vec<(String, B::ThinBuffer)>,
|
||||||
import_only_modules: Vec<(SerializedModule<B::ModuleBuffer>, WorkProduct)>
|
import_only_modules: Vec<(SerializedModule<B::ModuleBuffer>, WorkProduct)>
|
||||||
) -> Vec<(WorkItem<B>, u64)> {
|
) -> Vec<(WorkItem<B>, u64)> {
|
||||||
let _prof_timer = cgcx.prof.generic_activity("codegen_run_lto");
|
let _prof_timer = cgcx.prof.generic_activity("codegen_generate_lto_work");
|
||||||
|
|
||||||
let (lto_modules, copy_jobs) = if !needs_fat_lto.is_empty() {
|
let (lto_modules, copy_jobs) = if !needs_fat_lto.is_empty() {
|
||||||
assert!(needs_thin_lto.is_empty());
|
assert!(needs_thin_lto.is_empty());
|
||||||
@ -674,11 +674,11 @@ impl<B: WriteBackendMethods> WorkItem<B> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn name(&self) -> String {
|
fn profiling_event_id(&self) -> &'static str {
|
||||||
match *self {
|
match *self {
|
||||||
WorkItem::Optimize(ref m) => format!("optimize: {}", m.name),
|
WorkItem::Optimize(_) => "codegen_module_optimize",
|
||||||
WorkItem::CopyPostLtoArtifacts(ref m) => format!("copy post LTO artifacts: {}", m.name),
|
WorkItem::CopyPostLtoArtifacts(_) => "codegen_copy_artifacts_from_incr_cache",
|
||||||
WorkItem::LTO(ref m) => format!("lto: {}", m.name()),
|
WorkItem::LTO(_) => "codegen_module_perform_lto",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1587,7 +1587,7 @@ fn spawn_work<B: ExtraBackendMethods>(
|
|||||||
// as a diagnostic was already sent off to the main thread - just
|
// as a diagnostic was already sent off to the main thread - just
|
||||||
// surface that there was an error in this worker.
|
// surface that there was an error in this worker.
|
||||||
bomb.result = {
|
bomb.result = {
|
||||||
let _prof_timer = cgcx.prof.generic_activity(&work.name());
|
let _prof_timer = cgcx.prof.generic_activity(work.profiling_event_id());
|
||||||
execute_work_item(&cgcx, work).ok()
|
execute_work_item(&cgcx, work).ok()
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
@ -406,6 +406,8 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(cx: &'
|
|||||||
rust_main_def_id: DefId,
|
rust_main_def_id: DefId,
|
||||||
use_start_lang_item: bool,
|
use_start_lang_item: bool,
|
||||||
) {
|
) {
|
||||||
|
// The entry function is either `int main(void)` or `int main(int argc, char **argv)`,
|
||||||
|
// depending on whether the target needs `argc` and `argv` to be passed in.
|
||||||
let llfty = if cx.sess().target.target.options.main_needs_argc_argv {
|
let llfty = if cx.sess().target.target.options.main_needs_argc_argv {
|
||||||
cx.type_func(&[cx.type_int(), cx.type_ptr_to(cx.type_i8p())], cx.type_int())
|
cx.type_func(&[cx.type_int(), cx.type_ptr_to(cx.type_i8p())], cx.type_int())
|
||||||
} else {
|
} else {
|
||||||
@ -440,19 +442,7 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(cx: &'
|
|||||||
|
|
||||||
bx.insert_reference_to_gdb_debug_scripts_section_global();
|
bx.insert_reference_to_gdb_debug_scripts_section_global();
|
||||||
|
|
||||||
let (arg_argc, arg_argv) = if cx.sess().target.target.options.main_needs_argc_argv {
|
let (arg_argc, arg_argv) = get_argc_argv(cx, &mut bx);
|
||||||
// Params from native main() used as args for rust start function
|
|
||||||
let param_argc = bx.get_param(0);
|
|
||||||
let param_argv = bx.get_param(1);
|
|
||||||
let arg_argc = bx.intcast(param_argc, cx.type_isize(), true);
|
|
||||||
let arg_argv = param_argv;
|
|
||||||
(arg_argc, arg_argv)
|
|
||||||
} else {
|
|
||||||
// The Rust start function doesn't need argc and argv, so just pass zeros.
|
|
||||||
let arg_argc = bx.const_int(cx.type_int(), 0);
|
|
||||||
let arg_argv = bx.const_null(cx.type_ptr_to(cx.type_i8p()));
|
|
||||||
(arg_argc, arg_argv)
|
|
||||||
};
|
|
||||||
|
|
||||||
let (start_fn, args) = if use_start_lang_item {
|
let (start_fn, args) = if use_start_lang_item {
|
||||||
let start_def_id = cx.tcx().require_lang_item(StartFnLangItem, None);
|
let start_def_id = cx.tcx().require_lang_item(StartFnLangItem, None);
|
||||||
@ -477,6 +467,27 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(cx: &'
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Obtain the `argc` and `argv` values to pass to the rust start function.
|
||||||
|
fn get_argc_argv<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
|
||||||
|
cx: &'a Bx::CodegenCx,
|
||||||
|
bx: &mut Bx
|
||||||
|
) -> (Bx::Value, Bx::Value)
|
||||||
|
{
|
||||||
|
if cx.sess().target.target.options.main_needs_argc_argv {
|
||||||
|
// Params from native `main()` used as args for rust start function
|
||||||
|
let param_argc = bx.get_param(0);
|
||||||
|
let param_argv = bx.get_param(1);
|
||||||
|
let arg_argc = bx.intcast(param_argc, cx.type_isize(), true);
|
||||||
|
let arg_argv = param_argv;
|
||||||
|
(arg_argc, arg_argv)
|
||||||
|
} else {
|
||||||
|
// The Rust start function doesn't need `argc` and `argv`, so just pass zeros.
|
||||||
|
let arg_argc = bx.const_int(cx.type_int(), 0);
|
||||||
|
let arg_argv = bx.const_null(cx.type_ptr_to(cx.type_i8p()));
|
||||||
|
(arg_argc, arg_argv)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub const CODEGEN_WORKER_ID: usize = ::std::usize::MAX;
|
pub const CODEGEN_WORKER_ID: usize = ::std::usize::MAX;
|
||||||
|
|
||||||
pub fn codegen_crate<B: ExtraBackendMethods>(
|
pub fn codegen_crate<B: ExtraBackendMethods>(
|
||||||
@ -515,7 +526,7 @@ pub fn codegen_crate<B: ExtraBackendMethods>(
|
|||||||
// unnecessarily.
|
// unnecessarily.
|
||||||
if tcx.dep_graph.is_fully_enabled() {
|
if tcx.dep_graph.is_fully_enabled() {
|
||||||
for cgu in &codegen_units {
|
for cgu in &codegen_units {
|
||||||
tcx.codegen_unit(cgu.name().clone());
|
tcx.codegen_unit(cgu.name());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -603,7 +614,7 @@ pub fn codegen_crate<B: ExtraBackendMethods>(
|
|||||||
match cgu_reuse {
|
match cgu_reuse {
|
||||||
CguReuse::No => {
|
CguReuse::No => {
|
||||||
let start_time = Instant::now();
|
let start_time = Instant::now();
|
||||||
backend.compile_codegen_unit(tcx, *cgu.name(), &ongoing_codegen.coordinator_send);
|
backend.compile_codegen_unit(tcx, cgu.name(), &ongoing_codegen.coordinator_send);
|
||||||
total_codegen_time += start_time.elapsed();
|
total_codegen_time += start_time.elapsed();
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
@ -221,7 +221,7 @@ pub fn push_debuginfo_type_name<'tcx>(
|
|||||||
output.push_str(&tcx.crate_name(def_id.krate).as_str());
|
output.push_str(&tcx.crate_name(def_id.krate).as_str());
|
||||||
for path_element in tcx.def_path(def_id).data {
|
for path_element in tcx.def_path(def_id).data {
|
||||||
output.push_str("::");
|
output.push_str("::");
|
||||||
output.push_str(&path_element.data.as_interned_str().as_str());
|
output.push_str(&path_element.data.as_symbol().as_str());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
output.push_str(&tcx.item_name(def_id).as_str());
|
output.push_str(&tcx.item_name(def_id).as_str());
|
||||||
|
@ -10,7 +10,7 @@ use rustc_codegen_utils::codegen_backend::CodegenBackend;
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::sync::mpsc;
|
use std::sync::mpsc;
|
||||||
use syntax_expand::allocator::AllocatorKind;
|
use syntax_expand::allocator::AllocatorKind;
|
||||||
use syntax_pos::symbol::InternedString;
|
use syntax_pos::symbol::Symbol;
|
||||||
|
|
||||||
pub trait BackendTypes {
|
pub trait BackendTypes {
|
||||||
type Value: CodegenObject;
|
type Value: CodegenObject;
|
||||||
@ -50,7 +50,7 @@ pub trait ExtraBackendMethods: CodegenBackend + WriteBackendMethods + Sized + Se
|
|||||||
fn compile_codegen_unit(
|
fn compile_codegen_unit(
|
||||||
&self,
|
&self,
|
||||||
tcx: TyCtxt<'_>,
|
tcx: TyCtxt<'_>,
|
||||||
cgu_name: InternedString,
|
cgu_name: Symbol,
|
||||||
tx_to_llvm_workers: &mpsc::Sender<Box<dyn std::any::Any + Send>>,
|
tx_to_llvm_workers: &mpsc::Sender<Box<dyn std::any::Any + Send>>,
|
||||||
);
|
);
|
||||||
// If find_features is true this won't access `sess.crate_types` by assuming
|
// If find_features is true this won't access `sess.crate_types` by assuming
|
||||||
|
@ -14,7 +14,7 @@ use rustc::util::common::ErrorReported;
|
|||||||
use rustc::session::config::{OutputFilenames, PrintRequest};
|
use rustc::session::config::{OutputFilenames, PrintRequest};
|
||||||
use rustc::ty::TyCtxt;
|
use rustc::ty::TyCtxt;
|
||||||
use rustc::ty::query::Providers;
|
use rustc::ty::query::Providers;
|
||||||
use rustc::middle::cstore::{EncodedMetadata, MetadataLoader};
|
use rustc::middle::cstore::{EncodedMetadata, MetadataLoaderDyn};
|
||||||
use rustc::dep_graph::DepGraph;
|
use rustc::dep_graph::DepGraph;
|
||||||
|
|
||||||
pub use rustc_data_structures::sync::MetadataRef;
|
pub use rustc_data_structures::sync::MetadataRef;
|
||||||
@ -26,7 +26,7 @@ pub trait CodegenBackend {
|
|||||||
fn print_passes(&self) {}
|
fn print_passes(&self) {}
|
||||||
fn print_version(&self) {}
|
fn print_version(&self) {}
|
||||||
|
|
||||||
fn metadata_loader(&self) -> Box<dyn MetadataLoader + Sync>;
|
fn metadata_loader(&self) -> Box<MetadataLoaderDyn>;
|
||||||
fn provide(&self, _providers: &mut Providers<'_>);
|
fn provide(&self, _providers: &mut Providers<'_>);
|
||||||
fn provide_extern(&self, _providers: &mut Providers<'_>);
|
fn provide_extern(&self, _providers: &mut Providers<'_>);
|
||||||
fn codegen_crate<'tcx>(
|
fn codegen_crate<'tcx>(
|
||||||
|
@ -95,7 +95,7 @@ use rustc::ty::query::Providers;
|
|||||||
use rustc::ty::{self, TyCtxt, Instance};
|
use rustc::ty::{self, TyCtxt, Instance};
|
||||||
use rustc::mir::mono::{MonoItem, InstantiationMode};
|
use rustc::mir::mono::{MonoItem, InstantiationMode};
|
||||||
|
|
||||||
use syntax_pos::symbol::InternedString;
|
use syntax_pos::symbol::Symbol;
|
||||||
|
|
||||||
use log::debug;
|
use log::debug;
|
||||||
|
|
||||||
@ -112,7 +112,7 @@ pub fn provide(providers: &mut Providers<'_>) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn symbol_name(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> InternedString {
|
fn symbol_name(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> Symbol {
|
||||||
let def_id = instance.def_id();
|
let def_id = instance.def_id();
|
||||||
let substs = instance.substs;
|
let substs = instance.substs;
|
||||||
|
|
||||||
@ -123,13 +123,11 @@ fn symbol_name(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> InternedString {
|
|||||||
if def_id.is_local() {
|
if def_id.is_local() {
|
||||||
if tcx.plugin_registrar_fn(LOCAL_CRATE) == Some(def_id) {
|
if tcx.plugin_registrar_fn(LOCAL_CRATE) == Some(def_id) {
|
||||||
let disambiguator = tcx.sess.local_crate_disambiguator();
|
let disambiguator = tcx.sess.local_crate_disambiguator();
|
||||||
return
|
return Symbol::intern(&tcx.sess.generate_plugin_registrar_symbol(disambiguator));
|
||||||
InternedString::intern(&tcx.sess.generate_plugin_registrar_symbol(disambiguator));
|
|
||||||
}
|
}
|
||||||
if tcx.proc_macro_decls_static(LOCAL_CRATE) == Some(def_id) {
|
if tcx.proc_macro_decls_static(LOCAL_CRATE) == Some(def_id) {
|
||||||
let disambiguator = tcx.sess.local_crate_disambiguator();
|
let disambiguator = tcx.sess.local_crate_disambiguator();
|
||||||
return
|
return Symbol::intern(&tcx.sess.generate_proc_macro_decls_symbol(disambiguator));
|
||||||
InternedString::intern(&tcx.sess.generate_proc_macro_decls_symbol(disambiguator));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -146,23 +144,22 @@ fn symbol_name(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> InternedString {
|
|||||||
let attrs = tcx.codegen_fn_attrs(def_id);
|
let attrs = tcx.codegen_fn_attrs(def_id);
|
||||||
if is_foreign {
|
if is_foreign {
|
||||||
if let Some(name) = attrs.link_name {
|
if let Some(name) = attrs.link_name {
|
||||||
return name.as_interned_str();
|
return name;
|
||||||
}
|
}
|
||||||
// Don't mangle foreign items.
|
// Don't mangle foreign items.
|
||||||
return tcx.item_name(def_id).as_interned_str();
|
return tcx.item_name(def_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(name) = &attrs.export_name {
|
if let Some(name) = attrs.export_name {
|
||||||
// Use provided name
|
// Use provided name
|
||||||
return name.as_interned_str();
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
if attrs.flags.contains(CodegenFnAttrFlags::NO_MANGLE) {
|
if attrs.flags.contains(CodegenFnAttrFlags::NO_MANGLE) {
|
||||||
// Don't mangle
|
// Don't mangle
|
||||||
return tcx.item_name(def_id).as_interned_str();
|
return tcx.item_name(def_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
let is_generic = substs.non_erasable_generics().next().is_some();
|
let is_generic = substs.non_erasable_generics().next().is_some();
|
||||||
let avoid_cross_crate_conflicts =
|
let avoid_cross_crate_conflicts =
|
||||||
// If this is an instance of a generic function, we also hash in
|
// If this is an instance of a generic function, we also hash in
|
||||||
@ -222,5 +219,5 @@ fn symbol_name(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> InternedString {
|
|||||||
SymbolManglingVersion::V0 => v0::mangle(tcx, instance, instantiating_crate),
|
SymbolManglingVersion::V0 => v0::mangle(tcx, instance, instantiating_crate),
|
||||||
};
|
};
|
||||||
|
|
||||||
InternedString::intern(&mangled)
|
Symbol::intern(&mangled)
|
||||||
}
|
}
|
||||||
|
@ -335,7 +335,7 @@ impl Printer<'tcx> for SymbolPrinter<'tcx> {
|
|||||||
self.path.finalize_pending_component();
|
self.path.finalize_pending_component();
|
||||||
}
|
}
|
||||||
|
|
||||||
self.write_str(&disambiguated_data.data.as_interned_str().as_str())?;
|
self.write_str(&disambiguated_data.data.as_symbol().as_str())?;
|
||||||
Ok(self)
|
Ok(self)
|
||||||
}
|
}
|
||||||
fn path_generic_args(
|
fn path_generic_args(
|
||||||
|
@ -17,7 +17,7 @@ pub fn dominators<G: ControlFlowGraph>(graph: &G) -> Dominators<G::Node> {
|
|||||||
dominators_given_rpo(graph, &rpo)
|
dominators_given_rpo(graph, &rpo)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn dominators_given_rpo<G: ControlFlowGraph>(
|
fn dominators_given_rpo<G: ControlFlowGraph>(
|
||||||
graph: &G,
|
graph: &G,
|
||||||
rpo: &[G::Node],
|
rpo: &[G::Node],
|
||||||
) -> Dominators<G::Node> {
|
) -> Dominators<G::Node> {
|
||||||
@ -43,14 +43,12 @@ pub fn dominators_given_rpo<G: ControlFlowGraph>(
|
|||||||
let mut new_idom = None;
|
let mut new_idom = None;
|
||||||
for pred in graph.predecessors(node) {
|
for pred in graph.predecessors(node) {
|
||||||
if immediate_dominators[pred].is_some() {
|
if immediate_dominators[pred].is_some() {
|
||||||
// (*)
|
|
||||||
// (*) dominators for `pred` have been calculated
|
// (*) dominators for `pred` have been calculated
|
||||||
new_idom = intersect_opt(
|
new_idom = Some(if let Some(new_idom) = new_idom {
|
||||||
&post_order_rank,
|
intersect(&post_order_rank, &immediate_dominators, new_idom, pred)
|
||||||
&immediate_dominators,
|
} else {
|
||||||
new_idom,
|
pred
|
||||||
Some(pred),
|
});
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,19 +65,6 @@ pub fn dominators_given_rpo<G: ControlFlowGraph>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn intersect_opt<Node: Idx>(
|
|
||||||
post_order_rank: &IndexVec<Node, usize>,
|
|
||||||
immediate_dominators: &IndexVec<Node, Option<Node>>,
|
|
||||||
node1: Option<Node>,
|
|
||||||
node2: Option<Node>,
|
|
||||||
) -> Option<Node> {
|
|
||||||
match (node1, node2) {
|
|
||||||
(None, None) => None,
|
|
||||||
(Some(n), None) | (None, Some(n)) => Some(n),
|
|
||||||
(Some(n1), Some(n2)) => Some(intersect(post_order_rank, immediate_dominators, n1, n2)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn intersect<Node: Idx>(
|
fn intersect<Node: Idx>(
|
||||||
post_order_rank: &IndexVec<Node, usize>,
|
post_order_rank: &IndexVec<Node, usize>,
|
||||||
immediate_dominators: &IndexVec<Node, Option<Node>>,
|
immediate_dominators: &IndexVec<Node, Option<Node>>,
|
||||||
|
@ -16,6 +16,7 @@ log = "0.4"
|
|||||||
env_logger = { version = "0.7", default-features = false }
|
env_logger = { version = "0.7", default-features = false }
|
||||||
rustc = { path = "../librustc" }
|
rustc = { path = "../librustc" }
|
||||||
rustc_target = { path = "../librustc_target" }
|
rustc_target = { path = "../librustc_target" }
|
||||||
|
rustc_lint = { path = "../librustc_lint" }
|
||||||
rustc_data_structures = { path = "../librustc_data_structures" }
|
rustc_data_structures = { path = "../librustc_data_structures" }
|
||||||
errors = { path = "../librustc_errors", package = "rustc_errors" }
|
errors = { path = "../librustc_errors", package = "rustc_errors" }
|
||||||
rustc_metadata = { path = "../librustc_metadata" }
|
rustc_metadata = { path = "../librustc_metadata" }
|
||||||
|
@ -36,11 +36,11 @@ use rustc::session::config::nightly_options;
|
|||||||
use rustc::session::{early_error, early_warn};
|
use rustc::session::{early_error, early_warn};
|
||||||
use rustc::lint::Lint;
|
use rustc::lint::Lint;
|
||||||
use rustc::lint;
|
use rustc::lint;
|
||||||
|
use rustc::middle::cstore::MetadataLoader;
|
||||||
use rustc::hir::def_id::LOCAL_CRATE;
|
use rustc::hir::def_id::LOCAL_CRATE;
|
||||||
use rustc::ty::TyCtxt;
|
use rustc::ty::TyCtxt;
|
||||||
use rustc::util::common::{set_time_depth, time, print_time_passes_entry, ErrorReported};
|
use rustc::util::common::{set_time_depth, time, print_time_passes_entry, ErrorReported};
|
||||||
use rustc_metadata::locator;
|
use rustc_metadata::locator;
|
||||||
use rustc_metadata::cstore::CStore;
|
|
||||||
use rustc_codegen_utils::codegen_backend::CodegenBackend;
|
use rustc_codegen_utils::codegen_backend::CodegenBackend;
|
||||||
use rustc_interface::interface;
|
use rustc_interface::interface;
|
||||||
use rustc_interface::util::get_codegen_sysroot;
|
use rustc_interface::util::get_codegen_sysroot;
|
||||||
@ -106,6 +106,8 @@ pub fn abort_on_err<T>(result: Result<T, ErrorReported>, sess: &Session) -> T {
|
|||||||
pub trait Callbacks {
|
pub trait Callbacks {
|
||||||
/// Called before creating the compiler instance
|
/// Called before creating the compiler instance
|
||||||
fn config(&mut self, _config: &mut interface::Config) {}
|
fn config(&mut self, _config: &mut interface::Config) {}
|
||||||
|
/// Called early during compilation to allow other drivers to easily register lints.
|
||||||
|
fn extra_lints(&mut self, _ls: &mut lint::LintStore) {}
|
||||||
/// Called after parsing. Return value instructs the compiler whether to
|
/// Called after parsing. Return value instructs the compiler whether to
|
||||||
/// continue the compilation afterwards (defaults to `Compilation::Continue`)
|
/// continue the compilation afterwards (defaults to `Compilation::Continue`)
|
||||||
fn after_parsing(&mut self, _compiler: &interface::Compiler) -> Compilation {
|
fn after_parsing(&mut self, _compiler: &interface::Compiler) -> Compilation {
|
||||||
@ -182,6 +184,7 @@ pub fn run_compiler(
|
|||||||
stderr: None,
|
stderr: None,
|
||||||
crate_name: None,
|
crate_name: None,
|
||||||
lint_caps: Default::default(),
|
lint_caps: Default::default(),
|
||||||
|
register_lints: None,
|
||||||
};
|
};
|
||||||
callbacks.config(&mut config);
|
callbacks.config(&mut config);
|
||||||
config
|
config
|
||||||
@ -202,9 +205,13 @@ pub fn run_compiler(
|
|||||||
interface::run_compiler(config, |compiler| {
|
interface::run_compiler(config, |compiler| {
|
||||||
let sopts = &compiler.session().opts;
|
let sopts = &compiler.session().opts;
|
||||||
if sopts.describe_lints {
|
if sopts.describe_lints {
|
||||||
|
let lint_store = rustc_lint::new_lint_store(
|
||||||
|
sopts.debugging_opts.no_interleave_lints,
|
||||||
|
compiler.session().unstable_options(),
|
||||||
|
);
|
||||||
describe_lints(
|
describe_lints(
|
||||||
compiler.session(),
|
compiler.session(),
|
||||||
&*compiler.session().lint_store.borrow(),
|
&lint_store,
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
@ -255,6 +262,7 @@ pub fn run_compiler(
|
|||||||
stderr: None,
|
stderr: None,
|
||||||
crate_name: None,
|
crate_name: None,
|
||||||
lint_caps: Default::default(),
|
lint_caps: Default::default(),
|
||||||
|
register_lints: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
callbacks.config(&mut config);
|
callbacks.config(&mut config);
|
||||||
@ -269,7 +277,7 @@ pub fn run_compiler(
|
|||||||
compiler.output_file(),
|
compiler.output_file(),
|
||||||
).and_then(|| RustcDefaultCalls::list_metadata(
|
).and_then(|| RustcDefaultCalls::list_metadata(
|
||||||
sess,
|
sess,
|
||||||
compiler.cstore(),
|
&*compiler.codegen_backend().metadata_loader(),
|
||||||
&matches,
|
&matches,
|
||||||
compiler.input()
|
compiler.input()
|
||||||
));
|
));
|
||||||
@ -321,12 +329,14 @@ pub fn run_compiler(
|
|||||||
return sess.compile_status();
|
return sess.compile_status();
|
||||||
}
|
}
|
||||||
|
|
||||||
compiler.register_plugins()?;
|
{
|
||||||
|
let (_, _, lint_store) = &*compiler.register_plugins()?.peek();
|
||||||
|
|
||||||
// Lint plugins are registered; now we can process command line flags.
|
// Lint plugins are registered; now we can process command line flags.
|
||||||
if sess.opts.describe_lints {
|
if sess.opts.describe_lints {
|
||||||
describe_lints(&sess, &sess.lint_store.borrow(), true);
|
describe_lints(&sess, &lint_store, true);
|
||||||
return sess.compile_status();
|
return sess.compile_status();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
compiler.expansion()?;
|
compiler.expansion()?;
|
||||||
@ -604,7 +614,7 @@ fn show_content_with_pager(content: &String) {
|
|||||||
|
|
||||||
impl RustcDefaultCalls {
|
impl RustcDefaultCalls {
|
||||||
pub fn list_metadata(sess: &Session,
|
pub fn list_metadata(sess: &Session,
|
||||||
cstore: &CStore,
|
metadata_loader: &dyn MetadataLoader,
|
||||||
matches: &getopts::Matches,
|
matches: &getopts::Matches,
|
||||||
input: &Input)
|
input: &Input)
|
||||||
-> Compilation {
|
-> Compilation {
|
||||||
@ -616,7 +626,7 @@ impl RustcDefaultCalls {
|
|||||||
let mut v = Vec::new();
|
let mut v = Vec::new();
|
||||||
locator::list_file_metadata(&sess.target.target,
|
locator::list_file_metadata(&sess.target.target,
|
||||||
path,
|
path,
|
||||||
cstore,
|
metadata_loader,
|
||||||
&mut v)
|
&mut v)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
println!("{}", String::from_utf8(v).unwrap());
|
println!("{}", String::from_utf8(v).unwrap());
|
||||||
@ -835,8 +845,7 @@ Available lint options:
|
|||||||
|
|
||||||
");
|
");
|
||||||
|
|
||||||
fn sort_lints(sess: &Session, lints: Vec<(&'static Lint, bool)>) -> Vec<&'static Lint> {
|
fn sort_lints(sess: &Session, mut lints: Vec<&'static Lint>) -> Vec<&'static Lint> {
|
||||||
let mut lints: Vec<_> = lints.into_iter().map(|(x, _)| x).collect();
|
|
||||||
// The sort doesn't case-fold but it's doubtful we care.
|
// The sort doesn't case-fold but it's doubtful we care.
|
||||||
lints.sort_by_cached_key(|x: &&Lint| (x.default_level(sess), x.name));
|
lints.sort_by_cached_key(|x: &&Lint| (x.default_level(sess), x.name));
|
||||||
lints
|
lints
|
||||||
@ -852,7 +861,7 @@ Available lint options:
|
|||||||
let (plugin, builtin): (Vec<_>, _) = lint_store.get_lints()
|
let (plugin, builtin): (Vec<_>, _) = lint_store.get_lints()
|
||||||
.iter()
|
.iter()
|
||||||
.cloned()
|
.cloned()
|
||||||
.partition(|&(_, p)| p);
|
.partition(|&lint| lint.is_plugin);
|
||||||
let plugin = sort_lints(sess, plugin);
|
let plugin = sort_lints(sess, plugin);
|
||||||
let builtin = sort_lints(sess, builtin);
|
let builtin = sort_lints(sess, builtin);
|
||||||
|
|
||||||
|
@ -152,6 +152,32 @@ impl Diagnostic {
|
|||||||
self.note_expected_found_extra(label, expected, found, &"", &"")
|
self.note_expected_found_extra(label, expected, found, &"", &"")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn note_unsuccessfull_coercion(&mut self,
|
||||||
|
expected: DiagnosticStyledString,
|
||||||
|
found: DiagnosticStyledString)
|
||||||
|
-> &mut Self
|
||||||
|
{
|
||||||
|
let mut msg: Vec<_> =
|
||||||
|
vec![(format!("required when trying to coerce from type `"),
|
||||||
|
Style::NoStyle)];
|
||||||
|
msg.extend(expected.0.iter()
|
||||||
|
.map(|x| match *x {
|
||||||
|
StringPart::Normal(ref s) => (s.to_owned(), Style::NoStyle),
|
||||||
|
StringPart::Highlighted(ref s) => (s.to_owned(), Style::Highlight),
|
||||||
|
}));
|
||||||
|
msg.push((format!("` to type '"), Style::NoStyle));
|
||||||
|
msg.extend(found.0.iter()
|
||||||
|
.map(|x| match *x {
|
||||||
|
StringPart::Normal(ref s) => (s.to_owned(), Style::NoStyle),
|
||||||
|
StringPart::Highlighted(ref s) => (s.to_owned(), Style::Highlight),
|
||||||
|
}));
|
||||||
|
msg.push((format!("`"), Style::NoStyle));
|
||||||
|
|
||||||
|
// For now, just attach these as notes
|
||||||
|
self.highlighted_note(msg);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
pub fn note_expected_found_extra(&mut self,
|
pub fn note_expected_found_extra(&mut self,
|
||||||
label: &dyn fmt::Display,
|
label: &dyn fmt::Display,
|
||||||
expected: DiagnosticStyledString,
|
expected: DiagnosticStyledString,
|
||||||
|
@ -209,6 +209,11 @@ impl<'a> DiagnosticBuilder<'a> {
|
|||||||
found_extra: &dyn fmt::Display,
|
found_extra: &dyn fmt::Display,
|
||||||
) -> &mut Self);
|
) -> &mut Self);
|
||||||
|
|
||||||
|
forward!(pub fn note_unsuccessfull_coercion(&mut self,
|
||||||
|
expected: DiagnosticStyledString,
|
||||||
|
found: DiagnosticStyledString,
|
||||||
|
) -> &mut Self);
|
||||||
|
|
||||||
forward!(pub fn note(&mut self, msg: &str) -> &mut Self);
|
forward!(pub fn note(&mut self, msg: &str) -> &mut Self);
|
||||||
forward!(pub fn span_note<S: Into<MultiSpan>>(&mut self,
|
forward!(pub fn span_note<S: Into<MultiSpan>>(&mut self,
|
||||||
sp: S,
|
sp: S,
|
||||||
|
@ -27,7 +27,7 @@ use rustc::mir::mono::CodegenUnitNameBuilder;
|
|||||||
use rustc::ty::TyCtxt;
|
use rustc::ty::TyCtxt;
|
||||||
use std::collections::BTreeSet;
|
use std::collections::BTreeSet;
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use syntax::symbol::{InternedString, Symbol, sym};
|
use syntax::symbol::{Symbol, sym};
|
||||||
use rustc::ich::{ATTR_PARTITION_REUSED, ATTR_PARTITION_CODEGENED,
|
use rustc::ich::{ATTR_PARTITION_REUSED, ATTR_PARTITION_CODEGENED,
|
||||||
ATTR_EXPECTED_CGU_REUSE};
|
ATTR_EXPECTED_CGU_REUSE};
|
||||||
|
|
||||||
@ -45,8 +45,8 @@ pub fn assert_module_sources(tcx: TyCtxt<'_>) {
|
|||||||
.collect_and_partition_mono_items(LOCAL_CRATE)
|
.collect_and_partition_mono_items(LOCAL_CRATE)
|
||||||
.1
|
.1
|
||||||
.iter()
|
.iter()
|
||||||
.map(|cgu| *cgu.name())
|
.map(|cgu| cgu.name())
|
||||||
.collect::<BTreeSet<InternedString>>();
|
.collect::<BTreeSet<Symbol>>();
|
||||||
|
|
||||||
let ams = AssertModuleSource {
|
let ams = AssertModuleSource {
|
||||||
tcx,
|
tcx,
|
||||||
@ -61,7 +61,7 @@ pub fn assert_module_sources(tcx: TyCtxt<'_>) {
|
|||||||
|
|
||||||
struct AssertModuleSource<'tcx> {
|
struct AssertModuleSource<'tcx> {
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
available_cgus: BTreeSet<InternedString>,
|
available_cgus: BTreeSet<Symbol>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AssertModuleSource<'tcx> {
|
impl AssertModuleSource<'tcx> {
|
||||||
|
@ -11,7 +11,6 @@ use rustc_codegen_utils::codegen_backend::CodegenBackend;
|
|||||||
use rustc_data_structures::OnDrop;
|
use rustc_data_structures::OnDrop;
|
||||||
use rustc_data_structures::sync::Lrc;
|
use rustc_data_structures::sync::Lrc;
|
||||||
use rustc_data_structures::fx::{FxHashSet, FxHashMap};
|
use rustc_data_structures::fx::{FxHashSet, FxHashMap};
|
||||||
use rustc_metadata::cstore::CStore;
|
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::result;
|
use std::result;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
@ -37,8 +36,8 @@ pub struct Compiler {
|
|||||||
pub(crate) output_dir: Option<PathBuf>,
|
pub(crate) output_dir: Option<PathBuf>,
|
||||||
pub(crate) output_file: Option<PathBuf>,
|
pub(crate) output_file: Option<PathBuf>,
|
||||||
pub(crate) queries: Queries,
|
pub(crate) queries: Queries,
|
||||||
pub(crate) cstore: Lrc<CStore>,
|
|
||||||
pub(crate) crate_name: Option<String>,
|
pub(crate) crate_name: Option<String>,
|
||||||
|
pub(crate) register_lints: Option<Box<dyn Fn(&Session, &mut lint::LintStore) + Send + Sync>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Compiler {
|
impl Compiler {
|
||||||
@ -48,9 +47,6 @@ impl Compiler {
|
|||||||
pub fn codegen_backend(&self) -> &Lrc<Box<dyn CodegenBackend>> {
|
pub fn codegen_backend(&self) -> &Lrc<Box<dyn CodegenBackend>> {
|
||||||
&self.codegen_backend
|
&self.codegen_backend
|
||||||
}
|
}
|
||||||
pub fn cstore(&self) -> &Lrc<CStore> {
|
|
||||||
&self.cstore
|
|
||||||
}
|
|
||||||
pub fn source_map(&self) -> &Lrc<SourceMap> {
|
pub fn source_map(&self) -> &Lrc<SourceMap> {
|
||||||
&self.source_map
|
&self.source_map
|
||||||
}
|
}
|
||||||
@ -137,6 +133,13 @@ pub struct Config {
|
|||||||
|
|
||||||
pub crate_name: Option<String>,
|
pub crate_name: Option<String>,
|
||||||
pub lint_caps: FxHashMap<lint::LintId, lint::Level>,
|
pub lint_caps: FxHashMap<lint::LintId, lint::Level>,
|
||||||
|
|
||||||
|
/// This is a callback from the driver that is called when we're registering lints;
|
||||||
|
/// it is called during plugin registration when we have the LintStore in a non-shared state.
|
||||||
|
///
|
||||||
|
/// Note that if you find a Some here you probably want to call that function in the new
|
||||||
|
/// function being registered.
|
||||||
|
pub register_lints: Option<Box<dyn Fn(&Session, &mut lint::LintStore) + Send + Sync>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_compiler_in_existing_thread_pool<F, R>(config: Config, f: F) -> R
|
pub fn run_compiler_in_existing_thread_pool<F, R>(config: Config, f: F) -> R
|
||||||
@ -152,19 +155,17 @@ where
|
|||||||
config.lint_caps,
|
config.lint_caps,
|
||||||
);
|
);
|
||||||
|
|
||||||
let cstore = Lrc::new(CStore::new(codegen_backend.metadata_loader()));
|
|
||||||
|
|
||||||
let compiler = Compiler {
|
let compiler = Compiler {
|
||||||
sess,
|
sess,
|
||||||
codegen_backend,
|
codegen_backend,
|
||||||
source_map,
|
source_map,
|
||||||
cstore,
|
|
||||||
input: config.input,
|
input: config.input,
|
||||||
input_path: config.input_path,
|
input_path: config.input_path,
|
||||||
output_dir: config.output_dir,
|
output_dir: config.output_dir,
|
||||||
output_file: config.output_file,
|
output_file: config.output_file,
|
||||||
queries: Default::default(),
|
queries: Default::default(),
|
||||||
crate_name: config.crate_name,
|
crate_name: config.crate_name,
|
||||||
|
register_lints: config.register_lints,
|
||||||
};
|
};
|
||||||
|
|
||||||
let _sess_abort_error = OnDrop(|| {
|
let _sess_abort_error = OnDrop(|| {
|
||||||
|
@ -9,8 +9,8 @@ use rustc::hir::lowering::lower_crate;
|
|||||||
use rustc::hir::def_id::{CrateNum, LOCAL_CRATE};
|
use rustc::hir::def_id::{CrateNum, LOCAL_CRATE};
|
||||||
use rustc::lint;
|
use rustc::lint;
|
||||||
use rustc::middle::{self, reachable, resolve_lifetime, stability};
|
use rustc::middle::{self, reachable, resolve_lifetime, stability};
|
||||||
use rustc::middle::cstore::CrateStore;
|
use rustc::middle::cstore::{CrateStore, MetadataLoader, MetadataLoaderDyn};
|
||||||
use rustc::ty::{self, AllArenas, Resolutions, TyCtxt, GlobalCtxt};
|
use rustc::ty::{self, AllArenas, ResolverOutputs, TyCtxt, GlobalCtxt};
|
||||||
use rustc::ty::steal::Steal;
|
use rustc::ty::steal::Steal;
|
||||||
use rustc::traits;
|
use rustc::traits;
|
||||||
use rustc::util::common::{time, ErrorReported};
|
use rustc::util::common::{time, ErrorReported};
|
||||||
@ -23,8 +23,7 @@ use rustc_codegen_utils::link::filename_for_metadata;
|
|||||||
use rustc_data_structures::{box_region_allow_access, declare_box_region_type, parallel};
|
use rustc_data_structures::{box_region_allow_access, declare_box_region_type, parallel};
|
||||||
use rustc_data_structures::sync::{Lrc, ParallelIterator, par_iter};
|
use rustc_data_structures::sync::{Lrc, ParallelIterator, par_iter};
|
||||||
use rustc_incremental;
|
use rustc_incremental;
|
||||||
use rustc_metadata::creader::CrateLoader;
|
use rustc_metadata::cstore;
|
||||||
use rustc_metadata::cstore::{self, CStore};
|
|
||||||
use rustc_mir as mir;
|
use rustc_mir as mir;
|
||||||
use rustc_passes::{self, ast_validation, hir_stats, layout_test};
|
use rustc_passes::{self, ast_validation, hir_stats, layout_test};
|
||||||
use rustc_plugin as plugin;
|
use rustc_plugin as plugin;
|
||||||
@ -46,12 +45,10 @@ use syntax_ext;
|
|||||||
use rustc_serialize::json;
|
use rustc_serialize::json;
|
||||||
use tempfile::Builder as TempFileBuilder;
|
use tempfile::Builder as TempFileBuilder;
|
||||||
|
|
||||||
|
use std::{env, fs, iter, mem};
|
||||||
use std::any::Any;
|
use std::any::Any;
|
||||||
use std::env;
|
|
||||||
use std::ffi::OsString;
|
use std::ffi::OsString;
|
||||||
use std::fs;
|
|
||||||
use std::io::{self, Write};
|
use std::io::{self, Write};
|
||||||
use std::iter;
|
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
@ -105,7 +102,7 @@ fn count_nodes(krate: &ast::Crate) -> usize {
|
|||||||
declare_box_region_type!(
|
declare_box_region_type!(
|
||||||
pub BoxedResolver,
|
pub BoxedResolver,
|
||||||
for(),
|
for(),
|
||||||
(&mut Resolver<'_>) -> (Result<ast::Crate>, ExpansionResult)
|
(&mut Resolver<'_>) -> (Result<ast::Crate>, ResolverOutputs)
|
||||||
);
|
);
|
||||||
|
|
||||||
/// Runs the "early phases" of the compiler: initial `cfg` processing,
|
/// Runs the "early phases" of the compiler: initial `cfg` processing,
|
||||||
@ -117,7 +114,8 @@ declare_box_region_type!(
|
|||||||
/// Returns `None` if we're aborting after handling -W help.
|
/// Returns `None` if we're aborting after handling -W help.
|
||||||
pub fn configure_and_expand(
|
pub fn configure_and_expand(
|
||||||
sess: Lrc<Session>,
|
sess: Lrc<Session>,
|
||||||
cstore: Lrc<CStore>,
|
lint_store: Lrc<lint::LintStore>,
|
||||||
|
metadata_loader: Box<MetadataLoaderDyn>,
|
||||||
krate: ast::Crate,
|
krate: ast::Crate,
|
||||||
crate_name: &str,
|
crate_name: &str,
|
||||||
plugin_info: PluginInfo,
|
plugin_info: PluginInfo,
|
||||||
@ -130,15 +128,14 @@ pub fn configure_and_expand(
|
|||||||
let crate_name = crate_name.to_string();
|
let crate_name = crate_name.to_string();
|
||||||
let (result, resolver) = BoxedResolver::new(static move || {
|
let (result, resolver) = BoxedResolver::new(static move || {
|
||||||
let sess = &*sess;
|
let sess = &*sess;
|
||||||
let crate_loader = CrateLoader::new(sess, &*cstore, &crate_name);
|
|
||||||
let resolver_arenas = Resolver::arenas();
|
let resolver_arenas = Resolver::arenas();
|
||||||
let res = configure_and_expand_inner(
|
let res = configure_and_expand_inner(
|
||||||
sess,
|
sess,
|
||||||
&*cstore,
|
&lint_store,
|
||||||
krate,
|
krate,
|
||||||
&crate_name,
|
&crate_name,
|
||||||
&resolver_arenas,
|
&resolver_arenas,
|
||||||
&crate_loader,
|
&*metadata_loader,
|
||||||
plugin_info,
|
plugin_info,
|
||||||
);
|
);
|
||||||
let mut resolver = match res {
|
let mut resolver = match res {
|
||||||
@ -152,68 +149,16 @@ pub fn configure_and_expand(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
box_region_allow_access!(for(), (&mut Resolver<'_>), (&mut resolver));
|
box_region_allow_access!(for(), (&mut Resolver<'_>), (&mut resolver));
|
||||||
ExpansionResult::from_owned_resolver(resolver)
|
resolver.into_outputs()
|
||||||
});
|
});
|
||||||
result.map(|k| (k, resolver))
|
result.map(|k| (k, resolver))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ExpansionResult {
|
|
||||||
pub defs: Steal<hir::map::Definitions>,
|
|
||||||
pub resolutions: Steal<Resolutions>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ExpansionResult {
|
|
||||||
fn from_owned_resolver(
|
|
||||||
resolver: Resolver<'_>,
|
|
||||||
) -> Self {
|
|
||||||
ExpansionResult {
|
|
||||||
defs: Steal::new(resolver.definitions),
|
|
||||||
resolutions: Steal::new(Resolutions {
|
|
||||||
extern_crate_map: resolver.extern_crate_map,
|
|
||||||
export_map: resolver.export_map,
|
|
||||||
trait_map: resolver.trait_map,
|
|
||||||
glob_map: resolver.glob_map,
|
|
||||||
maybe_unused_trait_imports: resolver.maybe_unused_trait_imports,
|
|
||||||
maybe_unused_extern_crates: resolver.maybe_unused_extern_crates,
|
|
||||||
extern_prelude: resolver.extern_prelude.iter().map(|(ident, entry)| {
|
|
||||||
(ident.name, entry.introduced_by_item)
|
|
||||||
}).collect(),
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn from_resolver_ref(
|
|
||||||
resolver: &Resolver<'_>,
|
|
||||||
) -> Self {
|
|
||||||
ExpansionResult {
|
|
||||||
defs: Steal::new(resolver.definitions.clone()),
|
|
||||||
resolutions: Steal::new(Resolutions {
|
|
||||||
extern_crate_map: resolver.extern_crate_map.clone(),
|
|
||||||
export_map: resolver.export_map.clone(),
|
|
||||||
trait_map: resolver.trait_map.clone(),
|
|
||||||
glob_map: resolver.glob_map.clone(),
|
|
||||||
maybe_unused_trait_imports: resolver.maybe_unused_trait_imports.clone(),
|
|
||||||
maybe_unused_extern_crates: resolver.maybe_unused_extern_crates.clone(),
|
|
||||||
extern_prelude: resolver.extern_prelude.iter().map(|(ident, entry)| {
|
|
||||||
(ident.name, entry.introduced_by_item)
|
|
||||||
}).collect(),
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl BoxedResolver {
|
impl BoxedResolver {
|
||||||
pub fn to_expansion_result(
|
pub fn to_resolver_outputs(resolver: Rc<RefCell<BoxedResolver>>) -> ResolverOutputs {
|
||||||
resolver: Rc<RefCell<BoxedResolver>>,
|
|
||||||
) -> ExpansionResult {
|
|
||||||
match Rc::try_unwrap(resolver) {
|
match Rc::try_unwrap(resolver) {
|
||||||
Ok(resolver) => resolver.into_inner().complete(),
|
Ok(resolver) => resolver.into_inner().complete(),
|
||||||
Err(resolver) => {
|
Err(resolver) => resolver.borrow_mut().access(|resolver| resolver.clone_outputs()),
|
||||||
let resolver = &*resolver;
|
|
||||||
resolver.borrow_mut().access(|resolver| {
|
|
||||||
ExpansionResult::from_resolver_ref(resolver)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -224,10 +169,11 @@ pub struct PluginInfo {
|
|||||||
|
|
||||||
pub fn register_plugins<'a>(
|
pub fn register_plugins<'a>(
|
||||||
sess: &'a Session,
|
sess: &'a Session,
|
||||||
cstore: &'a CStore,
|
metadata_loader: &'a dyn MetadataLoader,
|
||||||
|
register_lints: impl Fn(&Session, &mut lint::LintStore),
|
||||||
mut krate: ast::Crate,
|
mut krate: ast::Crate,
|
||||||
crate_name: &str,
|
crate_name: &str,
|
||||||
) -> Result<(ast::Crate, PluginInfo)> {
|
) -> Result<(ast::Crate, PluginInfo, Lrc<lint::LintStore>)> {
|
||||||
krate = time(sess, "attributes injection", || {
|
krate = time(sess, "attributes injection", || {
|
||||||
syntax_ext::cmdline_attrs::inject(
|
syntax_ext::cmdline_attrs::inject(
|
||||||
krate, &sess.parse_sess, &sess.opts.debugging_opts.crate_attr
|
krate, &sess.parse_sess, &sess.opts.debugging_opts.crate_attr
|
||||||
@ -271,14 +217,20 @@ pub fn register_plugins<'a>(
|
|||||||
let registrars = time(sess, "plugin loading", || {
|
let registrars = time(sess, "plugin loading", || {
|
||||||
plugin::load::load_plugins(
|
plugin::load::load_plugins(
|
||||||
sess,
|
sess,
|
||||||
&cstore,
|
metadata_loader,
|
||||||
&krate,
|
&krate,
|
||||||
crate_name,
|
|
||||||
Some(sess.opts.debugging_opts.extra_plugins.clone()),
|
Some(sess.opts.debugging_opts.extra_plugins.clone()),
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
let mut registry = Registry::new(sess, krate.span);
|
let mut lint_store = rustc_lint::new_lint_store(
|
||||||
|
sess.opts.debugging_opts.no_interleave_lints,
|
||||||
|
sess.unstable_options(),
|
||||||
|
);
|
||||||
|
|
||||||
|
(register_lints)(&sess, &mut lint_store);
|
||||||
|
|
||||||
|
let mut registry = Registry::new(sess, &mut lint_store, krate.span);
|
||||||
|
|
||||||
time(sess, "plugin registration", || {
|
time(sess, "plugin registration", || {
|
||||||
for registrar in registrars {
|
for registrar in registrars {
|
||||||
@ -289,44 +241,30 @@ pub fn register_plugins<'a>(
|
|||||||
|
|
||||||
let Registry {
|
let Registry {
|
||||||
syntax_exts,
|
syntax_exts,
|
||||||
early_lint_passes,
|
|
||||||
late_lint_passes,
|
|
||||||
lint_groups,
|
|
||||||
llvm_passes,
|
llvm_passes,
|
||||||
attributes,
|
attributes,
|
||||||
..
|
..
|
||||||
} = registry;
|
} = registry;
|
||||||
|
|
||||||
let mut ls = sess.lint_store.borrow_mut();
|
|
||||||
for pass in early_lint_passes {
|
|
||||||
ls.register_early_pass(Some(sess), true, false, pass);
|
|
||||||
}
|
|
||||||
for pass in late_lint_passes {
|
|
||||||
ls.register_late_pass(Some(sess), true, false, false, pass);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (name, (to, deprecated_name)) in lint_groups {
|
|
||||||
ls.register_group(Some(sess), true, name, deprecated_name, to);
|
|
||||||
}
|
|
||||||
|
|
||||||
*sess.plugin_llvm_passes.borrow_mut() = llvm_passes;
|
*sess.plugin_llvm_passes.borrow_mut() = llvm_passes;
|
||||||
*sess.plugin_attributes.borrow_mut() = attributes;
|
*sess.plugin_attributes.borrow_mut() = attributes;
|
||||||
|
|
||||||
Ok((krate, PluginInfo { syntax_exts }))
|
Ok((krate, PluginInfo { syntax_exts }, Lrc::new(lint_store)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn configure_and_expand_inner<'a>(
|
fn configure_and_expand_inner<'a>(
|
||||||
sess: &'a Session,
|
sess: &'a Session,
|
||||||
cstore: &'a CStore,
|
lint_store: &'a lint::LintStore,
|
||||||
mut krate: ast::Crate,
|
mut krate: ast::Crate,
|
||||||
crate_name: &str,
|
crate_name: &str,
|
||||||
resolver_arenas: &'a ResolverArenas<'a>,
|
resolver_arenas: &'a ResolverArenas<'a>,
|
||||||
crate_loader: &'a CrateLoader<'a>,
|
metadata_loader: &'a MetadataLoaderDyn,
|
||||||
plugin_info: PluginInfo,
|
plugin_info: PluginInfo,
|
||||||
) -> Result<(ast::Crate, Resolver<'a>)> {
|
) -> Result<(ast::Crate, Resolver<'a>)> {
|
||||||
time(sess, "pre-AST-expansion lint checks", || {
|
time(sess, "pre-AST-expansion lint checks", || {
|
||||||
lint::check_ast_crate(
|
lint::check_ast_crate(
|
||||||
sess,
|
sess,
|
||||||
|
lint_store,
|
||||||
&krate,
|
&krate,
|
||||||
true,
|
true,
|
||||||
rustc_lint::BuiltinCombinedPreExpansionLintPass::new());
|
rustc_lint::BuiltinCombinedPreExpansionLintPass::new());
|
||||||
@ -334,10 +272,9 @@ fn configure_and_expand_inner<'a>(
|
|||||||
|
|
||||||
let mut resolver = Resolver::new(
|
let mut resolver = Resolver::new(
|
||||||
sess,
|
sess,
|
||||||
cstore,
|
|
||||||
&krate,
|
&krate,
|
||||||
crate_name,
|
crate_name,
|
||||||
crate_loader,
|
metadata_loader,
|
||||||
&resolver_arenas,
|
&resolver_arenas,
|
||||||
);
|
);
|
||||||
syntax_ext::register_builtin_macros(&mut resolver, sess.edition());
|
syntax_ext::register_builtin_macros(&mut resolver, sess.edition());
|
||||||
@ -536,7 +473,7 @@ fn configure_and_expand_inner<'a>(
|
|||||||
|
|
||||||
pub fn lower_to_hir(
|
pub fn lower_to_hir(
|
||||||
sess: &Session,
|
sess: &Session,
|
||||||
cstore: &CStore,
|
lint_store: &lint::LintStore,
|
||||||
resolver: &mut Resolver<'_>,
|
resolver: &mut Resolver<'_>,
|
||||||
dep_graph: &DepGraph,
|
dep_graph: &DepGraph,
|
||||||
krate: &ast::Crate,
|
krate: &ast::Crate,
|
||||||
@ -544,7 +481,7 @@ pub fn lower_to_hir(
|
|||||||
// Lower AST to HIR.
|
// Lower AST to HIR.
|
||||||
let hir_forest = time(sess, "lowering AST -> HIR", || {
|
let hir_forest = time(sess, "lowering AST -> HIR", || {
|
||||||
let nt_to_tokenstream = syntax::parse::nt_to_tokenstream;
|
let nt_to_tokenstream = syntax::parse::nt_to_tokenstream;
|
||||||
let hir_crate = lower_crate(sess, cstore, &dep_graph, &krate, resolver, nt_to_tokenstream);
|
let hir_crate = lower_crate(sess, &dep_graph, &krate, resolver, nt_to_tokenstream);
|
||||||
|
|
||||||
if sess.opts.debugging_opts.hir_stats {
|
if sess.opts.debugging_opts.hir_stats {
|
||||||
hir_stats::print_hir_stats(&hir_crate);
|
hir_stats::print_hir_stats(&hir_crate);
|
||||||
@ -554,7 +491,13 @@ pub fn lower_to_hir(
|
|||||||
});
|
});
|
||||||
|
|
||||||
time(sess, "early lint checks", || {
|
time(sess, "early lint checks", || {
|
||||||
lint::check_ast_crate(sess, &krate, false, rustc_lint::BuiltinCombinedEarlyLintPass::new())
|
lint::check_ast_crate(
|
||||||
|
sess,
|
||||||
|
lint_store,
|
||||||
|
&krate,
|
||||||
|
false,
|
||||||
|
rustc_lint::BuiltinCombinedEarlyLintPass::new(),
|
||||||
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
// Discard hygiene data, which isn't required after lowering to HIR.
|
// Discard hygiene data, which isn't required after lowering to HIR.
|
||||||
@ -644,8 +587,12 @@ fn escape_dep_filename(filename: &FileName) -> String {
|
|||||||
filename.to_string().replace(" ", "\\ ")
|
filename.to_string().replace(" ", "\\ ")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_out_deps(compiler: &Compiler, outputs: &OutputFilenames, out_filenames: &[PathBuf]) {
|
fn write_out_deps(
|
||||||
let sess = &compiler.sess;
|
sess: &Session,
|
||||||
|
boxed_resolver: &Steal<Rc<RefCell<BoxedResolver>>>,
|
||||||
|
outputs: &OutputFilenames,
|
||||||
|
out_filenames: &[PathBuf],
|
||||||
|
) {
|
||||||
// Write out dependency rules to the dep-info file if requested
|
// Write out dependency rules to the dep-info file if requested
|
||||||
if !sess.opts.output_types.contains_key(&OutputType::DepInfo) {
|
if !sess.opts.output_types.contains_key(&OutputType::DepInfo) {
|
||||||
return;
|
return;
|
||||||
@ -664,18 +611,20 @@ fn write_out_deps(compiler: &Compiler, outputs: &OutputFilenames, out_filenames:
|
|||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
if sess.binary_dep_depinfo() {
|
if sess.binary_dep_depinfo() {
|
||||||
for cnum in compiler.cstore.crates_untracked() {
|
boxed_resolver.borrow().borrow_mut().access(|resolver| {
|
||||||
let source = compiler.cstore.crate_source_untracked(cnum);
|
for cnum in resolver.cstore().crates_untracked() {
|
||||||
if let Some((path, _)) = source.dylib {
|
let source = resolver.cstore().crate_source_untracked(cnum);
|
||||||
files.push(escape_dep_filename(&FileName::Real(path)));
|
if let Some((path, _)) = source.dylib {
|
||||||
|
files.push(escape_dep_filename(&FileName::Real(path)));
|
||||||
|
}
|
||||||
|
if let Some((path, _)) = source.rlib {
|
||||||
|
files.push(escape_dep_filename(&FileName::Real(path)));
|
||||||
|
}
|
||||||
|
if let Some((path, _)) = source.rmeta {
|
||||||
|
files.push(escape_dep_filename(&FileName::Real(path)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if let Some((path, _)) = source.rlib {
|
});
|
||||||
files.push(escape_dep_filename(&FileName::Real(path)));
|
|
||||||
}
|
|
||||||
if let Some((path, _)) = source.rmeta {
|
|
||||||
files.push(escape_dep_filename(&FileName::Real(path)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut file = fs::File::create(&deps_filename)?;
|
let mut file = fs::File::create(&deps_filename)?;
|
||||||
@ -713,6 +662,7 @@ pub fn prepare_outputs(
|
|||||||
sess: &Session,
|
sess: &Session,
|
||||||
compiler: &Compiler,
|
compiler: &Compiler,
|
||||||
krate: &ast::Crate,
|
krate: &ast::Crate,
|
||||||
|
boxed_resolver: &Steal<Rc<RefCell<BoxedResolver>>>,
|
||||||
crate_name: &str
|
crate_name: &str
|
||||||
) -> Result<OutputFilenames> {
|
) -> Result<OutputFilenames> {
|
||||||
// FIXME: rustdoc passes &[] instead of &krate.attrs here
|
// FIXME: rustdoc passes &[] instead of &krate.attrs here
|
||||||
@ -754,7 +704,7 @@ pub fn prepare_outputs(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
write_out_deps(compiler, &outputs, &output_paths);
|
write_out_deps(sess, boxed_resolver, &outputs, &output_paths);
|
||||||
|
|
||||||
let only_dep_info = sess.opts.output_types.contains_key(&OutputType::DepInfo)
|
let only_dep_info = sess.opts.output_types.contains_key(&OutputType::DepInfo)
|
||||||
&& sess.opts.output_types.len() == 1;
|
&& sess.opts.output_types.len() == 1;
|
||||||
@ -817,27 +767,26 @@ impl BoxedGlobalCtxt {
|
|||||||
|
|
||||||
pub fn create_global_ctxt(
|
pub fn create_global_ctxt(
|
||||||
compiler: &Compiler,
|
compiler: &Compiler,
|
||||||
|
lint_store: Lrc<lint::LintStore>,
|
||||||
mut hir_forest: hir::map::Forest,
|
mut hir_forest: hir::map::Forest,
|
||||||
defs: hir::map::Definitions,
|
mut resolver_outputs: ResolverOutputs,
|
||||||
resolutions: Resolutions,
|
|
||||||
outputs: OutputFilenames,
|
outputs: OutputFilenames,
|
||||||
crate_name: &str,
|
crate_name: &str,
|
||||||
) -> BoxedGlobalCtxt {
|
) -> BoxedGlobalCtxt {
|
||||||
let sess = compiler.session().clone();
|
let sess = compiler.session().clone();
|
||||||
let cstore = compiler.cstore.clone();
|
|
||||||
let codegen_backend = compiler.codegen_backend().clone();
|
let codegen_backend = compiler.codegen_backend().clone();
|
||||||
let crate_name = crate_name.to_string();
|
let crate_name = crate_name.to_string();
|
||||||
|
let defs = mem::take(&mut resolver_outputs.definitions);
|
||||||
|
|
||||||
let ((), result) = BoxedGlobalCtxt::new(static move || {
|
let ((), result) = BoxedGlobalCtxt::new(static move || {
|
||||||
let sess = &*sess;
|
let sess = &*sess;
|
||||||
let cstore = &*cstore;
|
|
||||||
|
|
||||||
let global_ctxt: Option<GlobalCtxt<'_>>;
|
let global_ctxt: Option<GlobalCtxt<'_>>;
|
||||||
let arenas = AllArenas::new();
|
let arenas = AllArenas::new();
|
||||||
|
|
||||||
// Construct the HIR map.
|
// Construct the HIR map.
|
||||||
let hir_map = time(sess, "indexing HIR", || {
|
let hir_map = time(sess, "indexing HIR", || {
|
||||||
hir::map::map_crate(sess, cstore, &mut hir_forest, &defs)
|
hir::map::map_crate(sess, &*resolver_outputs.cstore, &mut hir_forest, &defs)
|
||||||
});
|
});
|
||||||
|
|
||||||
let query_result_on_disk_cache = time(sess, "load query result cache", || {
|
let query_result_on_disk_cache = time(sess, "load query result cache", || {
|
||||||
@ -854,11 +803,11 @@ pub fn create_global_ctxt(
|
|||||||
|
|
||||||
let gcx = TyCtxt::create_global_ctxt(
|
let gcx = TyCtxt::create_global_ctxt(
|
||||||
sess,
|
sess,
|
||||||
cstore,
|
lint_store,
|
||||||
local_providers,
|
local_providers,
|
||||||
extern_providers,
|
extern_providers,
|
||||||
&arenas,
|
&arenas,
|
||||||
resolutions,
|
resolver_outputs,
|
||||||
hir_map,
|
hir_map,
|
||||||
query_result_on_disk_cache,
|
query_result_on_disk_cache,
|
||||||
&crate_name,
|
&crate_name,
|
||||||
|
@ -1,12 +1,17 @@
|
|||||||
use crate::interface::{Compiler, Result};
|
use crate::interface::{Compiler, Result};
|
||||||
use crate::passes::{self, BoxedResolver, ExpansionResult, BoxedGlobalCtxt, PluginInfo};
|
use crate::passes::{self, BoxedResolver, BoxedGlobalCtxt, PluginInfo};
|
||||||
|
|
||||||
use rustc_incremental::DepGraphFuture;
|
use rustc_incremental::DepGraphFuture;
|
||||||
|
use rustc_data_structures::sync::Lrc;
|
||||||
use rustc::session::config::{OutputFilenames, OutputType};
|
use rustc::session::config::{OutputFilenames, OutputType};
|
||||||
use rustc::util::common::{time, ErrorReported};
|
use rustc::util::common::{time, ErrorReported};
|
||||||
use rustc::hir;
|
use rustc::hir;
|
||||||
|
use rustc::lint;
|
||||||
|
use rustc::session::Session;
|
||||||
|
use rustc::lint::LintStore;
|
||||||
use rustc::hir::def_id::LOCAL_CRATE;
|
use rustc::hir::def_id::LOCAL_CRATE;
|
||||||
use rustc::ty::steal::Steal;
|
use rustc::ty::steal::Steal;
|
||||||
|
use rustc::ty::ResolverOutputs;
|
||||||
use rustc::dep_graph::DepGraph;
|
use rustc::dep_graph::DepGraph;
|
||||||
use std::cell::{Ref, RefMut, RefCell};
|
use std::cell::{Ref, RefMut, RefCell};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
@ -74,10 +79,10 @@ pub(crate) struct Queries {
|
|||||||
dep_graph_future: Query<Option<DepGraphFuture>>,
|
dep_graph_future: Query<Option<DepGraphFuture>>,
|
||||||
parse: Query<ast::Crate>,
|
parse: Query<ast::Crate>,
|
||||||
crate_name: Query<String>,
|
crate_name: Query<String>,
|
||||||
register_plugins: Query<(ast::Crate, PluginInfo)>,
|
register_plugins: Query<(ast::Crate, PluginInfo, Lrc<LintStore>)>,
|
||||||
expansion: Query<(ast::Crate, Steal<Rc<RefCell<BoxedResolver>>>)>,
|
expansion: Query<(ast::Crate, Steal<Rc<RefCell<BoxedResolver>>>, Lrc<LintStore>)>,
|
||||||
dep_graph: Query<DepGraph>,
|
dep_graph: Query<DepGraph>,
|
||||||
lower_to_hir: Query<(Steal<hir::map::Forest>, ExpansionResult)>,
|
lower_to_hir: Query<(Steal<hir::map::Forest>, Steal<ResolverOutputs>)>,
|
||||||
prepare_outputs: Query<OutputFilenames>,
|
prepare_outputs: Query<OutputFilenames>,
|
||||||
global_ctxt: Query<BoxedGlobalCtxt>,
|
global_ctxt: Query<BoxedGlobalCtxt>,
|
||||||
ongoing_codegen: Query<Box<dyn Any>>,
|
ongoing_codegen: Query<Box<dyn Any>>,
|
||||||
@ -106,14 +111,19 @@ impl Compiler {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn register_plugins(&self) -> Result<&Query<(ast::Crate, PluginInfo)>> {
|
pub fn register_plugins(&self) -> Result<&Query<(ast::Crate, PluginInfo, Lrc<LintStore>)>> {
|
||||||
self.queries.register_plugins.compute(|| {
|
self.queries.register_plugins.compute(|| {
|
||||||
let crate_name = self.crate_name()?.peek().clone();
|
let crate_name = self.crate_name()?.peek().clone();
|
||||||
let krate = self.parse()?.take();
|
let krate = self.parse()?.take();
|
||||||
|
|
||||||
|
let empty: &(dyn Fn(&Session, &mut lint::LintStore) + Sync + Send) = &|_, _| {};
|
||||||
let result = passes::register_plugins(
|
let result = passes::register_plugins(
|
||||||
self.session(),
|
self.session(),
|
||||||
self.cstore(),
|
&*self.codegen_backend().metadata_loader(),
|
||||||
|
self.register_lints
|
||||||
|
.as_ref()
|
||||||
|
.map(|p| &**p)
|
||||||
|
.unwrap_or_else(|| empty),
|
||||||
krate,
|
krate,
|
||||||
&crate_name,
|
&crate_name,
|
||||||
);
|
);
|
||||||
@ -148,17 +158,20 @@ impl Compiler {
|
|||||||
|
|
||||||
pub fn expansion(
|
pub fn expansion(
|
||||||
&self
|
&self
|
||||||
) -> Result<&Query<(ast::Crate, Steal<Rc<RefCell<BoxedResolver>>>)>> {
|
) -> Result<&Query<(ast::Crate, Steal<Rc<RefCell<BoxedResolver>>>, Lrc<LintStore>)>> {
|
||||||
self.queries.expansion.compute(|| {
|
self.queries.expansion.compute(|| {
|
||||||
let crate_name = self.crate_name()?.peek().clone();
|
let crate_name = self.crate_name()?.peek().clone();
|
||||||
let (krate, plugin_info) = self.register_plugins()?.take();
|
let (krate, plugin_info, lint_store) = self.register_plugins()?.take();
|
||||||
passes::configure_and_expand(
|
passes::configure_and_expand(
|
||||||
self.sess.clone(),
|
self.sess.clone(),
|
||||||
self.cstore().clone(),
|
lint_store.clone(),
|
||||||
|
self.codegen_backend().metadata_loader(),
|
||||||
krate,
|
krate,
|
||||||
&crate_name,
|
&crate_name,
|
||||||
plugin_info,
|
plugin_info,
|
||||||
).map(|(krate, resolver)| (krate, Steal::new(Rc::new(RefCell::new(resolver)))))
|
).map(|(krate, resolver)| {
|
||||||
|
(krate, Steal::new(Rc::new(RefCell::new(resolver))), lint_store)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -179,32 +192,35 @@ impl Compiler {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn lower_to_hir(&self) -> Result<&Query<(Steal<hir::map::Forest>, ExpansionResult)>> {
|
pub fn lower_to_hir(
|
||||||
|
&self,
|
||||||
|
) -> Result<&Query<(Steal<hir::map::Forest>, Steal<ResolverOutputs>)>> {
|
||||||
self.queries.lower_to_hir.compute(|| {
|
self.queries.lower_to_hir.compute(|| {
|
||||||
let expansion_result = self.expansion()?;
|
let expansion_result = self.expansion()?;
|
||||||
let peeked = expansion_result.peek();
|
let peeked = expansion_result.peek();
|
||||||
let krate = &peeked.0;
|
let krate = &peeked.0;
|
||||||
let resolver = peeked.1.steal();
|
let resolver = peeked.1.steal();
|
||||||
|
let lint_store = &peeked.2;
|
||||||
let hir = Steal::new(resolver.borrow_mut().access(|resolver| {
|
let hir = Steal::new(resolver.borrow_mut().access(|resolver| {
|
||||||
passes::lower_to_hir(
|
passes::lower_to_hir(
|
||||||
self.session(),
|
self.session(),
|
||||||
self.cstore(),
|
lint_store,
|
||||||
resolver,
|
resolver,
|
||||||
&*self.dep_graph()?.peek(),
|
&*self.dep_graph()?.peek(),
|
||||||
&krate
|
&krate
|
||||||
)
|
)
|
||||||
})?);
|
})?);
|
||||||
Ok((hir, BoxedResolver::to_expansion_result(resolver)))
|
Ok((hir, Steal::new(BoxedResolver::to_resolver_outputs(resolver))))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn prepare_outputs(&self) -> Result<&Query<OutputFilenames>> {
|
pub fn prepare_outputs(&self) -> Result<&Query<OutputFilenames>> {
|
||||||
self.queries.prepare_outputs.compute(|| {
|
self.queries.prepare_outputs.compute(|| {
|
||||||
let krate = self.expansion()?;
|
let expansion_result = self.expansion()?;
|
||||||
let krate = krate.peek();
|
let (krate, boxed_resolver, _) = &*expansion_result.peek();
|
||||||
let crate_name = self.crate_name()?;
|
let crate_name = self.crate_name()?;
|
||||||
let crate_name = crate_name.peek();
|
let crate_name = crate_name.peek();
|
||||||
passes::prepare_outputs(self.session(), self, &krate.0, &*crate_name)
|
passes::prepare_outputs(self.session(), self, &krate, &boxed_resolver, &crate_name)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -212,14 +228,15 @@ impl Compiler {
|
|||||||
self.queries.global_ctxt.compute(|| {
|
self.queries.global_ctxt.compute(|| {
|
||||||
let crate_name = self.crate_name()?.peek().clone();
|
let crate_name = self.crate_name()?.peek().clone();
|
||||||
let outputs = self.prepare_outputs()?.peek().clone();
|
let outputs = self.prepare_outputs()?.peek().clone();
|
||||||
|
let lint_store = self.expansion()?.peek().2.clone();
|
||||||
let hir = self.lower_to_hir()?;
|
let hir = self.lower_to_hir()?;
|
||||||
let hir = hir.peek();
|
let hir = hir.peek();
|
||||||
let (ref hir_forest, ref expansion) = *hir;
|
let (hir_forest, resolver_outputs) = &*hir;
|
||||||
Ok(passes::create_global_ctxt(
|
Ok(passes::create_global_ctxt(
|
||||||
self,
|
self,
|
||||||
|
lint_store,
|
||||||
hir_forest.steal(),
|
hir_forest.steal(),
|
||||||
expansion.defs.steal(),
|
resolver_outputs.steal(),
|
||||||
expansion.resolutions.steal(),
|
|
||||||
outputs,
|
outputs,
|
||||||
&crate_name))
|
&crate_name))
|
||||||
})
|
})
|
||||||
|
@ -13,7 +13,6 @@ use rustc_data_structures::fingerprint::Fingerprint;
|
|||||||
use rustc_data_structures::thin_vec::ThinVec;
|
use rustc_data_structures::thin_vec::ThinVec;
|
||||||
use rustc_data_structures::fx::{FxHashSet, FxHashMap};
|
use rustc_data_structures::fx::{FxHashSet, FxHashMap};
|
||||||
use rustc_errors::registry::Registry;
|
use rustc_errors::registry::Registry;
|
||||||
use rustc_lint;
|
|
||||||
use rustc_metadata::dynamic_lib::DynamicLibrary;
|
use rustc_metadata::dynamic_lib::DynamicLibrary;
|
||||||
use rustc_mir;
|
use rustc_mir;
|
||||||
use rustc_passes;
|
use rustc_passes;
|
||||||
@ -108,11 +107,6 @@ pub fn create_session(
|
|||||||
|
|
||||||
let codegen_backend = get_codegen_backend(&sess);
|
let codegen_backend = get_codegen_backend(&sess);
|
||||||
|
|
||||||
rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
|
|
||||||
if sess.unstable_options() {
|
|
||||||
rustc_lint::register_internals(&mut sess.lint_store.borrow_mut(), Some(&sess));
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut cfg = config::build_configuration(&sess, config::to_crate_config(cfg));
|
let mut cfg = config::build_configuration(&sess, config::to_crate_config(cfg));
|
||||||
add_configuration(&mut cfg, &sess, &*codegen_backend);
|
add_configuration(&mut cfg, &sess, &*codegen_backend);
|
||||||
sess.parse_sess.config = cfg;
|
sess.parse_sess.config = cfg;
|
||||||
|
@ -27,6 +27,7 @@ use rustc::hir::def::{Res, DefKind};
|
|||||||
use rustc::hir::def_id::{DefId, LOCAL_CRATE};
|
use rustc::hir::def_id::{DefId, LOCAL_CRATE};
|
||||||
use rustc::ty::{self, Ty, TyCtxt, layout::VariantIdx};
|
use rustc::ty::{self, Ty, TyCtxt, layout::VariantIdx};
|
||||||
use rustc::{lint, util};
|
use rustc::{lint, util};
|
||||||
|
use rustc::lint::FutureIncompatibleInfo;
|
||||||
use hir::Node;
|
use hir::Node;
|
||||||
use util::nodemap::HirIdSet;
|
use util::nodemap::HirIdSet;
|
||||||
use lint::{LateContext, LintContext, LintArray};
|
use lint::{LateContext, LintContext, LintArray};
|
||||||
@ -280,7 +281,7 @@ declare_lint! {
|
|||||||
pub MISSING_DOCS,
|
pub MISSING_DOCS,
|
||||||
Allow,
|
Allow,
|
||||||
"detects missing documentation for public members",
|
"detects missing documentation for public members",
|
||||||
report_in_external_macro: true
|
report_in_external_macro
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct MissingDoc {
|
pub struct MissingDoc {
|
||||||
@ -601,7 +602,11 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingDebugImplementations {
|
|||||||
declare_lint! {
|
declare_lint! {
|
||||||
pub ANONYMOUS_PARAMETERS,
|
pub ANONYMOUS_PARAMETERS,
|
||||||
Allow,
|
Allow,
|
||||||
"detects anonymous parameters"
|
"detects anonymous parameters",
|
||||||
|
@future_incompatible = FutureIncompatibleInfo {
|
||||||
|
reference: "issue #41686 <https://github.com/rust-lang/rust/issues/41686>",
|
||||||
|
edition: Some(Edition::Edition2018),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
declare_lint_pass!(
|
declare_lint_pass!(
|
||||||
@ -1344,7 +1349,7 @@ declare_lint! {
|
|||||||
UNNAMEABLE_TEST_ITEMS,
|
UNNAMEABLE_TEST_ITEMS,
|
||||||
Warn,
|
Warn,
|
||||||
"detects an item that cannot be named being marked as `#[test_case]`",
|
"detects an item that cannot be named being marked as `#[test_case]`",
|
||||||
report_in_external_macro: true
|
report_in_external_macro
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct UnnameableTestItems {
|
pub struct UnnameableTestItems {
|
||||||
@ -1393,7 +1398,11 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnnameableTestItems {
|
|||||||
declare_lint! {
|
declare_lint! {
|
||||||
pub KEYWORD_IDENTS,
|
pub KEYWORD_IDENTS,
|
||||||
Allow,
|
Allow,
|
||||||
"detects edition keywords being used as an identifier"
|
"detects edition keywords being used as an identifier",
|
||||||
|
@future_incompatible = FutureIncompatibleInfo {
|
||||||
|
reference: "issue #49716 <https://github.com/rust-lang/rust/issues/49716>",
|
||||||
|
edition: Some(Edition::Edition2018),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
declare_lint_pass!(
|
declare_lint_pass!(
|
||||||
|
@ -33,27 +33,21 @@ use rustc::lint;
|
|||||||
use rustc::lint::{EarlyContext, LateContext, LateLintPass, EarlyLintPass, LintPass, LintArray};
|
use rustc::lint::{EarlyContext, LateContext, LateLintPass, EarlyLintPass, LintPass, LintArray};
|
||||||
use rustc::lint::builtin::{
|
use rustc::lint::builtin::{
|
||||||
BARE_TRAIT_OBJECTS,
|
BARE_TRAIT_OBJECTS,
|
||||||
ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE,
|
|
||||||
ELIDED_LIFETIMES_IN_PATHS,
|
ELIDED_LIFETIMES_IN_PATHS,
|
||||||
EXPLICIT_OUTLIVES_REQUIREMENTS,
|
EXPLICIT_OUTLIVES_REQUIREMENTS,
|
||||||
INTRA_DOC_LINK_RESOLUTION_FAILURE,
|
INTRA_DOC_LINK_RESOLUTION_FAILURE,
|
||||||
MISSING_DOC_CODE_EXAMPLES,
|
MISSING_DOC_CODE_EXAMPLES,
|
||||||
PRIVATE_DOC_TESTS,
|
PRIVATE_DOC_TESTS,
|
||||||
parser::ILL_FORMED_ATTRIBUTE_INPUT,
|
|
||||||
};
|
};
|
||||||
use rustc::session;
|
|
||||||
use rustc::hir;
|
use rustc::hir;
|
||||||
use rustc::hir::def_id::DefId;
|
use rustc::hir::def_id::DefId;
|
||||||
use rustc::ty::query::Providers;
|
use rustc::ty::query::Providers;
|
||||||
use rustc::ty::TyCtxt;
|
use rustc::ty::TyCtxt;
|
||||||
|
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use syntax::edition::Edition;
|
|
||||||
use syntax_pos::Span;
|
use syntax_pos::Span;
|
||||||
|
|
||||||
use session::Session;
|
|
||||||
use lint::LintId;
|
use lint::LintId;
|
||||||
use lint::FutureIncompatibleInfo;
|
|
||||||
|
|
||||||
use redundant_semicolon::*;
|
use redundant_semicolon::*;
|
||||||
use nonstandard_style::*;
|
use nonstandard_style::*;
|
||||||
@ -192,59 +186,60 @@ late_lint_passes!(declare_combined_late_pass, [pub BuiltinCombinedLateLintPass])
|
|||||||
|
|
||||||
late_lint_mod_passes!(declare_combined_late_pass, [BuiltinCombinedModuleLateLintPass]);
|
late_lint_mod_passes!(declare_combined_late_pass, [BuiltinCombinedModuleLateLintPass]);
|
||||||
|
|
||||||
|
pub fn new_lint_store(no_interleave_lints: bool, internal_lints: bool) -> lint::LintStore {
|
||||||
|
let mut lint_store = lint::LintStore::new();
|
||||||
|
|
||||||
|
register_builtins(&mut lint_store, no_interleave_lints);
|
||||||
|
if internal_lints {
|
||||||
|
register_internals(&mut lint_store);
|
||||||
|
}
|
||||||
|
|
||||||
|
lint_store
|
||||||
|
}
|
||||||
|
|
||||||
/// Tell the `LintStore` about all the built-in lints (the ones
|
/// Tell the `LintStore` about all the built-in lints (the ones
|
||||||
/// defined in this crate and the ones defined in
|
/// defined in this crate and the ones defined in
|
||||||
/// `rustc::lint::builtin`).
|
/// `rustc::lint::builtin`).
|
||||||
pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
|
fn register_builtins(store: &mut lint::LintStore, no_interleave_lints: bool) {
|
||||||
macro_rules! add_lint_group {
|
macro_rules! add_lint_group {
|
||||||
($sess:ident, $name:expr, $($lint:ident),*) => (
|
($name:expr, $($lint:ident),*) => (
|
||||||
store.register_group($sess, false, $name, None, vec![$(LintId::of($lint)),*]);
|
store.register_group(false, $name, None, vec![$(LintId::of($lint)),*]);
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! register_pass {
|
macro_rules! register_pass {
|
||||||
($method:ident, $constructor:expr, [$($args:expr),*]) => (
|
($method:ident, $ty:ident, $constructor:expr) => (
|
||||||
store.$method(sess, false, false, $($args,)* box $constructor);
|
store.register_lints(&$ty::get_lints());
|
||||||
|
store.$method(|| box $constructor);
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! register_passes {
|
macro_rules! register_passes {
|
||||||
([$method:ident, $args:tt], [$($passes:ident: $constructor:expr,)*]) => (
|
($method:ident, [$($passes:ident: $constructor:expr,)*]) => (
|
||||||
$(
|
$(
|
||||||
register_pass!($method, $constructor, $args);
|
register_pass!($method, $passes, $constructor);
|
||||||
)*
|
)*
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
if sess.map(|sess| sess.opts.debugging_opts.no_interleave_lints).unwrap_or(false) {
|
if no_interleave_lints {
|
||||||
pre_expansion_lint_passes!(register_passes, [register_pre_expansion_pass, []]);
|
pre_expansion_lint_passes!(register_passes, register_pre_expansion_pass);
|
||||||
early_lint_passes!(register_passes, [register_early_pass, []]);
|
early_lint_passes!(register_passes, register_early_pass);
|
||||||
late_lint_passes!(register_passes, [register_late_pass, [false]]);
|
late_lint_passes!(register_passes, register_late_pass);
|
||||||
late_lint_mod_passes!(register_passes, [register_late_pass, [true]]);
|
late_lint_mod_passes!(register_passes, register_late_mod_pass);
|
||||||
} else {
|
} else {
|
||||||
store.register_pre_expansion_pass(
|
store.register_lints(&BuiltinCombinedPreExpansionLintPass::get_lints());
|
||||||
sess,
|
store.register_lints(&BuiltinCombinedEarlyLintPass::get_lints());
|
||||||
false,
|
store.register_lints(&BuiltinCombinedModuleLateLintPass::get_lints());
|
||||||
true,
|
store.register_lints(&BuiltinCombinedLateLintPass::get_lints());
|
||||||
box BuiltinCombinedPreExpansionLintPass::new()
|
|
||||||
);
|
|
||||||
store.register_early_pass(sess, false, true, box BuiltinCombinedEarlyLintPass::new());
|
|
||||||
store.register_late_pass(
|
|
||||||
sess, false, true, true, box BuiltinCombinedModuleLateLintPass::new()
|
|
||||||
);
|
|
||||||
store.register_late_pass(
|
|
||||||
sess, false, true, false, box BuiltinCombinedLateLintPass::new()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
add_lint_group!(sess,
|
add_lint_group!("nonstandard_style",
|
||||||
"nonstandard_style",
|
|
||||||
NON_CAMEL_CASE_TYPES,
|
NON_CAMEL_CASE_TYPES,
|
||||||
NON_SNAKE_CASE,
|
NON_SNAKE_CASE,
|
||||||
NON_UPPER_CASE_GLOBALS);
|
NON_UPPER_CASE_GLOBALS);
|
||||||
|
|
||||||
add_lint_group!(sess,
|
add_lint_group!("unused",
|
||||||
"unused",
|
|
||||||
UNUSED_IMPORTS,
|
UNUSED_IMPORTS,
|
||||||
UNUSED_VARIABLES,
|
UNUSED_VARIABLES,
|
||||||
UNUSED_ASSIGNMENTS,
|
UNUSED_ASSIGNMENTS,
|
||||||
@ -265,8 +260,7 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
|
|||||||
UNUSED_LABELS,
|
UNUSED_LABELS,
|
||||||
UNUSED_PARENS);
|
UNUSED_PARENS);
|
||||||
|
|
||||||
add_lint_group!(sess,
|
add_lint_group!("rust_2018_idioms",
|
||||||
"rust_2018_idioms",
|
|
||||||
BARE_TRAIT_OBJECTS,
|
BARE_TRAIT_OBJECTS,
|
||||||
UNUSED_EXTERN_CRATES,
|
UNUSED_EXTERN_CRATES,
|
||||||
ELLIPSIS_INCLUSIVE_RANGE_PATTERNS,
|
ELLIPSIS_INCLUSIVE_RANGE_PATTERNS,
|
||||||
@ -282,165 +276,11 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
|
|||||||
// MACRO_USE_EXTERN_CRATE,
|
// MACRO_USE_EXTERN_CRATE,
|
||||||
);
|
);
|
||||||
|
|
||||||
add_lint_group!(sess,
|
add_lint_group!("rustdoc",
|
||||||
"rustdoc",
|
|
||||||
INTRA_DOC_LINK_RESOLUTION_FAILURE,
|
INTRA_DOC_LINK_RESOLUTION_FAILURE,
|
||||||
MISSING_DOC_CODE_EXAMPLES,
|
MISSING_DOC_CODE_EXAMPLES,
|
||||||
PRIVATE_DOC_TESTS);
|
PRIVATE_DOC_TESTS);
|
||||||
|
|
||||||
// Guidelines for creating a future incompatibility lint:
|
|
||||||
//
|
|
||||||
// - Create a lint defaulting to warn as normal, with ideally the same error
|
|
||||||
// message you would normally give
|
|
||||||
// - Add a suitable reference, typically an RFC or tracking issue. Go ahead
|
|
||||||
// and include the full URL, sort items in ascending order of issue numbers.
|
|
||||||
// - Later, change lint to error
|
|
||||||
// - Eventually, remove lint
|
|
||||||
store.register_future_incompatible(sess, vec![
|
|
||||||
FutureIncompatibleInfo {
|
|
||||||
id: LintId::of(PRIVATE_IN_PUBLIC),
|
|
||||||
reference: "issue #34537 <https://github.com/rust-lang/rust/issues/34537>",
|
|
||||||
edition: None,
|
|
||||||
},
|
|
||||||
FutureIncompatibleInfo {
|
|
||||||
id: LintId::of(PUB_USE_OF_PRIVATE_EXTERN_CRATE),
|
|
||||||
reference: "issue #34537 <https://github.com/rust-lang/rust/issues/34537>",
|
|
||||||
edition: None,
|
|
||||||
},
|
|
||||||
FutureIncompatibleInfo {
|
|
||||||
id: LintId::of(PATTERNS_IN_FNS_WITHOUT_BODY),
|
|
||||||
reference: "issue #35203 <https://github.com/rust-lang/rust/issues/35203>",
|
|
||||||
edition: None,
|
|
||||||
},
|
|
||||||
FutureIncompatibleInfo {
|
|
||||||
id: LintId::of(DUPLICATE_MACRO_EXPORTS),
|
|
||||||
reference: "issue #35896 <https://github.com/rust-lang/rust/issues/35896>",
|
|
||||||
edition: Some(Edition::Edition2018),
|
|
||||||
},
|
|
||||||
FutureIncompatibleInfo {
|
|
||||||
id: LintId::of(KEYWORD_IDENTS),
|
|
||||||
reference: "issue #49716 <https://github.com/rust-lang/rust/issues/49716>",
|
|
||||||
edition: Some(Edition::Edition2018),
|
|
||||||
},
|
|
||||||
FutureIncompatibleInfo {
|
|
||||||
id: LintId::of(SAFE_EXTERN_STATICS),
|
|
||||||
reference: "issue #36247 <https://github.com/rust-lang/rust/issues/36247>",
|
|
||||||
edition: None,
|
|
||||||
},
|
|
||||||
FutureIncompatibleInfo {
|
|
||||||
id: LintId::of(INVALID_TYPE_PARAM_DEFAULT),
|
|
||||||
reference: "issue #36887 <https://github.com/rust-lang/rust/issues/36887>",
|
|
||||||
edition: None,
|
|
||||||
},
|
|
||||||
FutureIncompatibleInfo {
|
|
||||||
id: LintId::of(LEGACY_DIRECTORY_OWNERSHIP),
|
|
||||||
reference: "issue #37872 <https://github.com/rust-lang/rust/issues/37872>",
|
|
||||||
edition: None,
|
|
||||||
},
|
|
||||||
FutureIncompatibleInfo {
|
|
||||||
id: LintId::of(LEGACY_CONSTRUCTOR_VISIBILITY),
|
|
||||||
reference: "issue #39207 <https://github.com/rust-lang/rust/issues/39207>",
|
|
||||||
edition: None,
|
|
||||||
},
|
|
||||||
FutureIncompatibleInfo {
|
|
||||||
id: LintId::of(MISSING_FRAGMENT_SPECIFIER),
|
|
||||||
reference: "issue #40107 <https://github.com/rust-lang/rust/issues/40107>",
|
|
||||||
edition: None,
|
|
||||||
},
|
|
||||||
FutureIncompatibleInfo {
|
|
||||||
id: LintId::of(ILLEGAL_FLOATING_POINT_LITERAL_PATTERN),
|
|
||||||
reference: "issue #41620 <https://github.com/rust-lang/rust/issues/41620>",
|
|
||||||
edition: None,
|
|
||||||
},
|
|
||||||
FutureIncompatibleInfo {
|
|
||||||
id: LintId::of(ANONYMOUS_PARAMETERS),
|
|
||||||
reference: "issue #41686 <https://github.com/rust-lang/rust/issues/41686>",
|
|
||||||
edition: Some(Edition::Edition2018),
|
|
||||||
},
|
|
||||||
FutureIncompatibleInfo {
|
|
||||||
id: LintId::of(PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES),
|
|
||||||
reference: "issue #42238 <https://github.com/rust-lang/rust/issues/42238>",
|
|
||||||
edition: None,
|
|
||||||
},
|
|
||||||
FutureIncompatibleInfo {
|
|
||||||
id: LintId::of(LATE_BOUND_LIFETIME_ARGUMENTS),
|
|
||||||
reference: "issue #42868 <https://github.com/rust-lang/rust/issues/42868>",
|
|
||||||
edition: None,
|
|
||||||
},
|
|
||||||
FutureIncompatibleInfo {
|
|
||||||
id: LintId::of(SAFE_PACKED_BORROWS),
|
|
||||||
reference: "issue #46043 <https://github.com/rust-lang/rust/issues/46043>",
|
|
||||||
edition: None,
|
|
||||||
},
|
|
||||||
FutureIncompatibleInfo {
|
|
||||||
id: LintId::of(ORDER_DEPENDENT_TRAIT_OBJECTS),
|
|
||||||
reference: "issue #56484 <https://github.com/rust-lang/rust/issues/56484>",
|
|
||||||
edition: None,
|
|
||||||
},
|
|
||||||
FutureIncompatibleInfo {
|
|
||||||
id: LintId::of(TYVAR_BEHIND_RAW_POINTER),
|
|
||||||
reference: "issue #46906 <https://github.com/rust-lang/rust/issues/46906>",
|
|
||||||
edition: Some(Edition::Edition2018),
|
|
||||||
},
|
|
||||||
FutureIncompatibleInfo {
|
|
||||||
id: LintId::of(UNSTABLE_NAME_COLLISIONS),
|
|
||||||
reference: "issue #48919 <https://github.com/rust-lang/rust/issues/48919>",
|
|
||||||
edition: None,
|
|
||||||
// Note: this item represents future incompatibility of all unstable functions in the
|
|
||||||
// standard library, and thus should never be removed or changed to an error.
|
|
||||||
},
|
|
||||||
FutureIncompatibleInfo {
|
|
||||||
id: LintId::of(ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE),
|
|
||||||
reference: "issue #53130 <https://github.com/rust-lang/rust/issues/53130>",
|
|
||||||
edition: Some(Edition::Edition2018),
|
|
||||||
},
|
|
||||||
FutureIncompatibleInfo {
|
|
||||||
id: LintId::of(WHERE_CLAUSES_OBJECT_SAFETY),
|
|
||||||
reference: "issue #51443 <https://github.com/rust-lang/rust/issues/51443>",
|
|
||||||
edition: None,
|
|
||||||
},
|
|
||||||
FutureIncompatibleInfo {
|
|
||||||
id: LintId::of(PROC_MACRO_DERIVE_RESOLUTION_FALLBACK),
|
|
||||||
reference: "issue #50504 <https://github.com/rust-lang/rust/issues/50504>",
|
|
||||||
edition: None,
|
|
||||||
},
|
|
||||||
FutureIncompatibleInfo {
|
|
||||||
id: LintId::of(MACRO_EXPANDED_MACRO_EXPORTS_ACCESSED_BY_ABSOLUTE_PATHS),
|
|
||||||
reference: "issue #52234 <https://github.com/rust-lang/rust/issues/52234>",
|
|
||||||
edition: None,
|
|
||||||
},
|
|
||||||
FutureIncompatibleInfo {
|
|
||||||
id: LintId::of(ILL_FORMED_ATTRIBUTE_INPUT),
|
|
||||||
reference: "issue #57571 <https://github.com/rust-lang/rust/issues/57571>",
|
|
||||||
edition: None,
|
|
||||||
},
|
|
||||||
FutureIncompatibleInfo {
|
|
||||||
id: LintId::of(AMBIGUOUS_ASSOCIATED_ITEMS),
|
|
||||||
reference: "issue #57644 <https://github.com/rust-lang/rust/issues/57644>",
|
|
||||||
edition: None,
|
|
||||||
},
|
|
||||||
FutureIncompatibleInfo {
|
|
||||||
id: LintId::of(NESTED_IMPL_TRAIT),
|
|
||||||
reference: "issue #59014 <https://github.com/rust-lang/rust/issues/59014>",
|
|
||||||
edition: None,
|
|
||||||
},
|
|
||||||
FutureIncompatibleInfo {
|
|
||||||
id: LintId::of(MUTABLE_BORROW_RESERVATION_CONFLICT),
|
|
||||||
reference: "issue #59159 <https://github.com/rust-lang/rust/issues/59159>",
|
|
||||||
edition: None,
|
|
||||||
},
|
|
||||||
FutureIncompatibleInfo {
|
|
||||||
id: LintId::of(INDIRECT_STRUCTURAL_MATCH),
|
|
||||||
reference: "issue #62411 <https://github.com/rust-lang/rust/issues/62411>",
|
|
||||||
edition: None,
|
|
||||||
},
|
|
||||||
FutureIncompatibleInfo {
|
|
||||||
id: LintId::of(SOFT_UNSTABLE),
|
|
||||||
reference: "issue #64266 <https://github.com/rust-lang/rust/issues/64266>",
|
|
||||||
edition: None,
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
|
|
||||||
// Register renamed and removed lints.
|
// Register renamed and removed lints.
|
||||||
store.register_renamed("single_use_lifetime", "single_use_lifetimes");
|
store.register_renamed("single_use_lifetime", "single_use_lifetimes");
|
||||||
store.register_renamed("elided_lifetime_in_path", "elided_lifetimes_in_paths");
|
store.register_renamed("elided_lifetime_in_path", "elided_lifetimes_in_paths");
|
||||||
@ -496,12 +336,14 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
|
|||||||
"converted into hard error, see https://github.com/rust-lang/rust/issues/46205");
|
"converted into hard error, see https://github.com/rust-lang/rust/issues/46205");
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn register_internals(store: &mut lint::LintStore, sess: Option<&Session>) {
|
fn register_internals(store: &mut lint::LintStore) {
|
||||||
store.register_early_pass(sess, false, false, box DefaultHashTypes::new());
|
store.register_lints(&DefaultHashTypes::get_lints());
|
||||||
store.register_early_pass(sess, false, false, box LintPassImpl);
|
store.register_early_pass(|| box DefaultHashTypes::new());
|
||||||
store.register_late_pass(sess, false, false, false, box TyTyKind);
|
store.register_lints(&LintPassImpl::get_lints());
|
||||||
|
store.register_early_pass(|| box LintPassImpl);
|
||||||
|
store.register_lints(&TyTyKind::get_lints());
|
||||||
|
store.register_late_pass(|| box TyTyKind);
|
||||||
store.register_group(
|
store.register_group(
|
||||||
sess,
|
|
||||||
false,
|
false,
|
||||||
"rustc::internal",
|
"rustc::internal",
|
||||||
None,
|
None,
|
||||||
|
@ -25,7 +25,7 @@ declare_lint! {
|
|||||||
pub UNUSED_MUST_USE,
|
pub UNUSED_MUST_USE,
|
||||||
Warn,
|
Warn,
|
||||||
"unused result of a type flagged as `#[must_use]`",
|
"unused result of a type flagged as `#[must_use]`",
|
||||||
report_in_external_macro: true
|
report_in_external_macro
|
||||||
}
|
}
|
||||||
|
|
||||||
declare_lint! {
|
declare_lint! {
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
use crate::cstore::{self, CStore, MetadataBlob};
|
use crate::cstore::{self, CStore, MetadataBlob};
|
||||||
use crate::locator::{self, CratePaths};
|
use crate::locator::{self, CratePaths};
|
||||||
use crate::schema::{CrateRoot, CrateDep};
|
use crate::schema::{CrateRoot, CrateDep};
|
||||||
use rustc_data_structures::sync::{Lrc, RwLock, Lock, AtomicCell};
|
use rustc_data_structures::sync::{RwLock, Lock, AtomicCell};
|
||||||
|
|
||||||
use rustc::hir::def_id::CrateNum;
|
use rustc::hir::def_id::CrateNum;
|
||||||
use rustc_data_structures::svh::Svh;
|
use rustc_data_structures::svh::Svh;
|
||||||
@ -14,21 +14,20 @@ use rustc::session::{Session, CrateDisambiguator};
|
|||||||
use rustc::session::config::{Sanitizer, self};
|
use rustc::session::config::{Sanitizer, self};
|
||||||
use rustc_target::spec::{PanicStrategy, TargetTriple};
|
use rustc_target::spec::{PanicStrategy, TargetTriple};
|
||||||
use rustc::session::search_paths::PathKind;
|
use rustc::session::search_paths::PathKind;
|
||||||
use rustc::middle::cstore::{CrateSource, ExternCrate, ExternCrateSource};
|
use rustc::middle::cstore::{CrateSource, ExternCrate, ExternCrateSource, MetadataLoaderDyn};
|
||||||
use rustc::util::common::record_time;
|
use rustc::util::common::record_time;
|
||||||
use rustc::util::nodemap::FxHashSet;
|
use rustc::util::nodemap::FxHashSet;
|
||||||
use rustc::hir::map::Definitions;
|
use rustc::hir::map::Definitions;
|
||||||
use rustc::hir::def_id::LOCAL_CRATE;
|
use rustc::hir::def_id::LOCAL_CRATE;
|
||||||
|
|
||||||
use std::ops::Deref;
|
use std::path::Path;
|
||||||
use std::path::{Path, PathBuf};
|
|
||||||
use std::{cmp, fs};
|
use std::{cmp, fs};
|
||||||
|
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use syntax::attr;
|
use syntax::attr;
|
||||||
use syntax_expand::allocator::{global_allocator_spans, AllocatorKind};
|
use syntax_expand::allocator::{global_allocator_spans, AllocatorKind};
|
||||||
use syntax::symbol::{Symbol, sym};
|
use syntax::symbol::{Symbol, sym};
|
||||||
use syntax::{span_err, span_fatal};
|
use syntax::span_fatal;
|
||||||
use syntax_pos::{Span, DUMMY_SP};
|
use syntax_pos::{Span, DUMMY_SP};
|
||||||
use log::{debug, info, log_enabled};
|
use log::{debug, info, log_enabled};
|
||||||
use proc_macro::bridge::client::ProcMacro;
|
use proc_macro::bridge::client::ProcMacro;
|
||||||
@ -39,9 +38,12 @@ crate struct Library {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct CrateLoader<'a> {
|
pub struct CrateLoader<'a> {
|
||||||
|
// Immutable configuration.
|
||||||
sess: &'a Session,
|
sess: &'a Session,
|
||||||
cstore: &'a CStore,
|
metadata_loader: &'a MetadataLoaderDyn,
|
||||||
local_crate_name: Symbol,
|
local_crate_name: Symbol,
|
||||||
|
// Mutable output.
|
||||||
|
cstore: CStore,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn dump_crates(cstore: &CStore) {
|
fn dump_crates(cstore: &CStore) {
|
||||||
@ -58,29 +60,6 @@ fn dump_crates(cstore: &CStore) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extra info about a crate loaded for plugins or exported macros.
|
|
||||||
struct ExtensionCrate {
|
|
||||||
metadata: PMDSource,
|
|
||||||
dylib: Option<PathBuf>,
|
|
||||||
target_only: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
enum PMDSource {
|
|
||||||
Registered(Lrc<cstore::CrateMetadata>),
|
|
||||||
Owned(Library),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Deref for PMDSource {
|
|
||||||
type Target = MetadataBlob;
|
|
||||||
|
|
||||||
fn deref(&self) -> &MetadataBlob {
|
|
||||||
match *self {
|
|
||||||
PMDSource::Registered(ref cmd) => &cmd.blob,
|
|
||||||
PMDSource::Owned(ref lib) => &lib.metadata
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
enum LoadResult {
|
enum LoadResult {
|
||||||
Previous(CrateNum),
|
Previous(CrateNum),
|
||||||
Loaded(Library),
|
Loaded(Library),
|
||||||
@ -99,14 +78,27 @@ impl<'a> LoadError<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> CrateLoader<'a> {
|
impl<'a> CrateLoader<'a> {
|
||||||
pub fn new(sess: &'a Session, cstore: &'a CStore, local_crate_name: &str) -> Self {
|
pub fn new(
|
||||||
|
sess: &'a Session,
|
||||||
|
metadata_loader: &'a MetadataLoaderDyn,
|
||||||
|
local_crate_name: &str,
|
||||||
|
) -> Self {
|
||||||
CrateLoader {
|
CrateLoader {
|
||||||
sess,
|
sess,
|
||||||
cstore,
|
metadata_loader,
|
||||||
local_crate_name: Symbol::intern(local_crate_name),
|
local_crate_name: Symbol::intern(local_crate_name),
|
||||||
|
cstore: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn cstore(&self) -> &CStore {
|
||||||
|
&self.cstore
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn into_cstore(self) -> CStore {
|
||||||
|
self.cstore
|
||||||
|
}
|
||||||
|
|
||||||
fn existing_match(&self, name: Symbol, hash: Option<&Svh>, kind: PathKind)
|
fn existing_match(&self, name: Symbol, hash: Option<&Svh>, kind: PathKind)
|
||||||
-> Option<CrateNum> {
|
-> Option<CrateNum> {
|
||||||
let mut ret = None;
|
let mut ret = None;
|
||||||
@ -187,14 +179,14 @@ impl<'a> CrateLoader<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn register_crate(
|
fn register_crate(
|
||||||
&self,
|
&mut self,
|
||||||
host_lib: Option<Library>,
|
host_lib: Option<Library>,
|
||||||
root: Option<&CratePaths>,
|
root: Option<&CratePaths>,
|
||||||
span: Span,
|
span: Span,
|
||||||
lib: Library,
|
lib: Library,
|
||||||
dep_kind: DepKind,
|
dep_kind: DepKind,
|
||||||
name: Symbol
|
name: Symbol
|
||||||
) -> (CrateNum, Lrc<cstore::CrateMetadata>) {
|
) -> CrateNum {
|
||||||
let _prof_timer = self.sess.prof.generic_activity("metadata_register_crate");
|
let _prof_timer = self.sess.prof.generic_activity("metadata_register_crate");
|
||||||
|
|
||||||
let Library { source, metadata } = lib;
|
let Library { source, metadata } = lib;
|
||||||
@ -248,9 +240,9 @@ impl<'a> CrateLoader<'a> {
|
|||||||
crate_root.def_path_table.decode((&metadata, self.sess))
|
crate_root.def_path_table.decode((&metadata, self.sess))
|
||||||
});
|
});
|
||||||
|
|
||||||
let cmeta = cstore::CrateMetadata {
|
self.cstore.set_crate_data(cnum, cstore::CrateMetadata {
|
||||||
extern_crate: Lock::new(None),
|
extern_crate: Lock::new(None),
|
||||||
def_path_table: Lrc::new(def_path_table),
|
def_path_table,
|
||||||
trait_impls,
|
trait_impls,
|
||||||
root: crate_root,
|
root: crate_root,
|
||||||
blob: metadata,
|
blob: metadata,
|
||||||
@ -264,11 +256,9 @@ impl<'a> CrateLoader<'a> {
|
|||||||
private_dep,
|
private_dep,
|
||||||
raw_proc_macros,
|
raw_proc_macros,
|
||||||
dep_node_index: AtomicCell::new(DepNodeIndex::INVALID),
|
dep_node_index: AtomicCell::new(DepNodeIndex::INVALID),
|
||||||
};
|
});
|
||||||
|
|
||||||
let cmeta = Lrc::new(cmeta);
|
cnum
|
||||||
self.cstore.set_crate_data(cnum, cmeta.clone());
|
|
||||||
(cnum, cmeta)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load_proc_macro<'b>(
|
fn load_proc_macro<'b>(
|
||||||
@ -327,22 +317,22 @@ impl<'a> CrateLoader<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_crate<'b>(
|
fn resolve_crate<'b>(
|
||||||
&'b self,
|
&'b mut self,
|
||||||
name: Symbol,
|
name: Symbol,
|
||||||
span: Span,
|
span: Span,
|
||||||
dep_kind: DepKind,
|
dep_kind: DepKind,
|
||||||
dep: Option<(&'b CratePaths, &'b CrateDep)>,
|
dep: Option<(&'b CratePaths, &'b CrateDep)>,
|
||||||
) -> (CrateNum, Lrc<cstore::CrateMetadata>) {
|
) -> CrateNum {
|
||||||
self.maybe_resolve_crate(name, span, dep_kind, dep).unwrap_or_else(|err| err.report())
|
self.maybe_resolve_crate(name, span, dep_kind, dep).unwrap_or_else(|err| err.report())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn maybe_resolve_crate<'b>(
|
fn maybe_resolve_crate<'b>(
|
||||||
&'b self,
|
&'b mut self,
|
||||||
name: Symbol,
|
name: Symbol,
|
||||||
span: Span,
|
span: Span,
|
||||||
mut dep_kind: DepKind,
|
mut dep_kind: DepKind,
|
||||||
dep: Option<(&'b CratePaths, &'b CrateDep)>,
|
dep: Option<(&'b CratePaths, &'b CrateDep)>,
|
||||||
) -> Result<(CrateNum, Lrc<cstore::CrateMetadata>), LoadError<'b>> {
|
) -> Result<CrateNum, LoadError<'b>> {
|
||||||
info!("resolving crate `{}`", name);
|
info!("resolving crate `{}`", name);
|
||||||
let (root, hash, extra_filename, path_kind) = match dep {
|
let (root, hash, extra_filename, path_kind) = match dep {
|
||||||
Some((root, dep)) =>
|
Some((root, dep)) =>
|
||||||
@ -370,7 +360,7 @@ impl<'a> CrateLoader<'a> {
|
|||||||
rejected_via_filename: vec![],
|
rejected_via_filename: vec![],
|
||||||
should_match_name: true,
|
should_match_name: true,
|
||||||
is_proc_macro: Some(false),
|
is_proc_macro: Some(false),
|
||||||
metadata_loader: &*self.cstore.metadata_loader,
|
metadata_loader: self.metadata_loader,
|
||||||
};
|
};
|
||||||
|
|
||||||
self.load(&mut locate_ctxt).map(|r| (r, None)).or_else(|| {
|
self.load(&mut locate_ctxt).map(|r| (r, None)).or_else(|| {
|
||||||
@ -388,7 +378,7 @@ impl<'a> CrateLoader<'a> {
|
|||||||
data.dep_kind.with_lock(|data_dep_kind| {
|
data.dep_kind.with_lock(|data_dep_kind| {
|
||||||
*data_dep_kind = cmp::max(*data_dep_kind, dep_kind);
|
*data_dep_kind = cmp::max(*data_dep_kind, dep_kind);
|
||||||
});
|
});
|
||||||
Ok((cnum, data))
|
Ok(cnum)
|
||||||
}
|
}
|
||||||
(LoadResult::Loaded(library), host_library) => {
|
(LoadResult::Loaded(library), host_library) => {
|
||||||
Ok(self.register_crate(host_library, root, span, library, dep_kind, name))
|
Ok(self.register_crate(host_library, root, span, library, dep_kind, name))
|
||||||
@ -466,7 +456,7 @@ impl<'a> CrateLoader<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Go through the crate metadata and load any crates that it references
|
// Go through the crate metadata and load any crates that it references
|
||||||
fn resolve_crate_deps(&self,
|
fn resolve_crate_deps(&mut self,
|
||||||
root: &CratePaths,
|
root: &CratePaths,
|
||||||
crate_root: &CrateRoot<'_>,
|
crate_root: &CrateRoot<'_>,
|
||||||
metadata: &MetadataBlob,
|
metadata: &MetadataBlob,
|
||||||
@ -492,73 +482,10 @@ impl<'a> CrateLoader<'a> {
|
|||||||
DepKind::MacrosOnly => DepKind::MacrosOnly,
|
DepKind::MacrosOnly => DepKind::MacrosOnly,
|
||||||
_ => dep.kind,
|
_ => dep.kind,
|
||||||
};
|
};
|
||||||
self.resolve_crate(dep.name, span, dep_kind, Some((root, &dep))).0
|
self.resolve_crate(dep.name, span, dep_kind, Some((root, &dep)))
|
||||||
})).collect()
|
})).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_extension_crate(&self, name: Symbol, span: Span) -> ExtensionCrate {
|
|
||||||
info!("read extension crate `{}`", name);
|
|
||||||
let target_triple = self.sess.opts.target_triple.clone();
|
|
||||||
let host_triple = TargetTriple::from_triple(config::host_triple());
|
|
||||||
let is_cross = target_triple != host_triple;
|
|
||||||
let mut target_only = false;
|
|
||||||
let mut locate_ctxt = locator::Context {
|
|
||||||
sess: self.sess,
|
|
||||||
span,
|
|
||||||
crate_name: name,
|
|
||||||
hash: None,
|
|
||||||
extra_filename: None,
|
|
||||||
filesearch: self.sess.host_filesearch(PathKind::Crate),
|
|
||||||
target: &self.sess.host,
|
|
||||||
triple: host_triple,
|
|
||||||
root: None,
|
|
||||||
rejected_via_hash: vec![],
|
|
||||||
rejected_via_triple: vec![],
|
|
||||||
rejected_via_kind: vec![],
|
|
||||||
rejected_via_version: vec![],
|
|
||||||
rejected_via_filename: vec![],
|
|
||||||
should_match_name: true,
|
|
||||||
is_proc_macro: None,
|
|
||||||
metadata_loader: &*self.cstore.metadata_loader,
|
|
||||||
};
|
|
||||||
let library = self.load(&mut locate_ctxt).or_else(|| {
|
|
||||||
if !is_cross {
|
|
||||||
return None
|
|
||||||
}
|
|
||||||
// Try loading from target crates. This will abort later if we
|
|
||||||
// try to load a plugin registrar function,
|
|
||||||
target_only = true;
|
|
||||||
|
|
||||||
locate_ctxt.target = &self.sess.target.target;
|
|
||||||
locate_ctxt.triple = target_triple;
|
|
||||||
locate_ctxt.filesearch = self.sess.target_filesearch(PathKind::Crate);
|
|
||||||
|
|
||||||
self.load(&mut locate_ctxt)
|
|
||||||
});
|
|
||||||
let library = match library {
|
|
||||||
Some(l) => l,
|
|
||||||
None => locate_ctxt.report_errs(),
|
|
||||||
};
|
|
||||||
|
|
||||||
let (dylib, metadata) = match library {
|
|
||||||
LoadResult::Previous(cnum) => {
|
|
||||||
let data = self.cstore.get_crate_data(cnum);
|
|
||||||
(data.source.dylib.clone(), PMDSource::Registered(data))
|
|
||||||
}
|
|
||||||
LoadResult::Loaded(library) => {
|
|
||||||
let dylib = library.source.dylib.clone();
|
|
||||||
let metadata = PMDSource::Owned(library);
|
|
||||||
(dylib, metadata)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
ExtensionCrate {
|
|
||||||
metadata,
|
|
||||||
dylib: dylib.map(|p| p.0),
|
|
||||||
target_only,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn dlsym_proc_macros(&self,
|
fn dlsym_proc_macros(&self,
|
||||||
path: &Path,
|
path: &Path,
|
||||||
disambiguator: CrateDisambiguator,
|
disambiguator: CrateDisambiguator,
|
||||||
@ -590,42 +517,7 @@ impl<'a> CrateLoader<'a> {
|
|||||||
decls
|
decls
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Look for a plugin registrar. Returns library path, crate
|
fn inject_panic_runtime(&mut self, krate: &ast::Crate) {
|
||||||
/// SVH and DefIndex of the registrar function.
|
|
||||||
pub fn find_plugin_registrar(&self,
|
|
||||||
span: Span,
|
|
||||||
name: Symbol)
|
|
||||||
-> Option<(PathBuf, CrateDisambiguator)> {
|
|
||||||
let ekrate = self.read_extension_crate(name, span);
|
|
||||||
|
|
||||||
if ekrate.target_only {
|
|
||||||
// Need to abort before syntax expansion.
|
|
||||||
let message = format!("plugin `{}` is not available for triple `{}` \
|
|
||||||
(only found {})",
|
|
||||||
name,
|
|
||||||
config::host_triple(),
|
|
||||||
self.sess.opts.target_triple);
|
|
||||||
span_fatal!(self.sess, span, E0456, "{}", &message);
|
|
||||||
}
|
|
||||||
|
|
||||||
let root = ekrate.metadata.get_root();
|
|
||||||
match ekrate.dylib.as_ref() {
|
|
||||||
Some(dylib) => {
|
|
||||||
Some((dylib.to_path_buf(), root.disambiguator))
|
|
||||||
}
|
|
||||||
None => {
|
|
||||||
span_err!(self.sess, span, E0457,
|
|
||||||
"plugin `{}` only found in rlib format, but must be available \
|
|
||||||
in dylib format",
|
|
||||||
name);
|
|
||||||
// No need to abort because the loading code will just ignore this
|
|
||||||
// empty dylib.
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn inject_panic_runtime(&self, krate: &ast::Crate) {
|
|
||||||
// If we're only compiling an rlib, then there's no need to select a
|
// If we're only compiling an rlib, then there's no need to select a
|
||||||
// panic runtime, so we just skip this section entirely.
|
// panic runtime, so we just skip this section entirely.
|
||||||
let any_non_rlib = self.sess.crate_types.borrow().iter().any(|ct| {
|
let any_non_rlib = self.sess.crate_types.borrow().iter().any(|ct| {
|
||||||
@ -687,7 +579,8 @@ impl<'a> CrateLoader<'a> {
|
|||||||
};
|
};
|
||||||
info!("panic runtime not found -- loading {}", name);
|
info!("panic runtime not found -- loading {}", name);
|
||||||
|
|
||||||
let (cnum, data) = self.resolve_crate(name, DUMMY_SP, DepKind::Implicit, None);
|
let cnum = self.resolve_crate(name, DUMMY_SP, DepKind::Implicit, None);
|
||||||
|
let data = self.cstore.get_crate_data(cnum);
|
||||||
|
|
||||||
// Sanity check the loaded crate to ensure it is indeed a panic runtime
|
// Sanity check the loaded crate to ensure it is indeed a panic runtime
|
||||||
// and the panic strategy is indeed what we thought it was.
|
// and the panic strategy is indeed what we thought it was.
|
||||||
@ -706,7 +599,7 @@ impl<'a> CrateLoader<'a> {
|
|||||||
&|data| data.root.needs_panic_runtime);
|
&|data| data.root.needs_panic_runtime);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn inject_sanitizer_runtime(&self) {
|
fn inject_sanitizer_runtime(&mut self) {
|
||||||
if let Some(ref sanitizer) = self.sess.opts.debugging_opts.sanitizer {
|
if let Some(ref sanitizer) = self.sess.opts.debugging_opts.sanitizer {
|
||||||
// Sanitizers can only be used on some tested platforms with
|
// Sanitizers can only be used on some tested platforms with
|
||||||
// executables linked to `std`
|
// executables linked to `std`
|
||||||
@ -791,7 +684,8 @@ impl<'a> CrateLoader<'a> {
|
|||||||
});
|
});
|
||||||
info!("loading sanitizer: {}", name);
|
info!("loading sanitizer: {}", name);
|
||||||
|
|
||||||
let data = self.resolve_crate(name, DUMMY_SP, DepKind::Explicit, None).1;
|
let cnum = self.resolve_crate(name, DUMMY_SP, DepKind::Explicit, None);
|
||||||
|
let data = self.cstore.get_crate_data(cnum);
|
||||||
|
|
||||||
// Sanity check the loaded crate to ensure it is indeed a sanitizer runtime
|
// Sanity check the loaded crate to ensure it is indeed a sanitizer runtime
|
||||||
if !data.root.sanitizer_runtime {
|
if !data.root.sanitizer_runtime {
|
||||||
@ -804,14 +698,15 @@ impl<'a> CrateLoader<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn inject_profiler_runtime(&self) {
|
fn inject_profiler_runtime(&mut self) {
|
||||||
if self.sess.opts.debugging_opts.profile ||
|
if self.sess.opts.debugging_opts.profile ||
|
||||||
self.sess.opts.cg.profile_generate.enabled()
|
self.sess.opts.cg.profile_generate.enabled()
|
||||||
{
|
{
|
||||||
info!("loading profiler");
|
info!("loading profiler");
|
||||||
|
|
||||||
let name = Symbol::intern("profiler_builtins");
|
let name = Symbol::intern("profiler_builtins");
|
||||||
let data = self.resolve_crate(name, DUMMY_SP, DepKind::Implicit, None).1;
|
let cnum = self.resolve_crate(name, DUMMY_SP, DepKind::Implicit, None);
|
||||||
|
let data = self.cstore.get_crate_data(cnum);
|
||||||
|
|
||||||
// Sanity check the loaded crate to ensure it is indeed a profiler runtime
|
// Sanity check the loaded crate to ensure it is indeed a profiler runtime
|
||||||
if !data.root.profiler_runtime {
|
if !data.root.profiler_runtime {
|
||||||
@ -957,10 +852,8 @@ impl<'a> CrateLoader<'a> {
|
|||||||
data.dependencies.borrow_mut().push(krate);
|
data.dependencies.borrow_mut().push(krate);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> CrateLoader<'a> {
|
pub fn postprocess(&mut self, krate: &ast::Crate) {
|
||||||
pub fn postprocess(&self, krate: &ast::Crate) {
|
|
||||||
self.inject_sanitizer_runtime();
|
self.inject_sanitizer_runtime();
|
||||||
self.inject_profiler_runtime();
|
self.inject_profiler_runtime();
|
||||||
self.inject_allocator_crate(krate);
|
self.inject_allocator_crate(krate);
|
||||||
@ -971,7 +864,11 @@ impl<'a> CrateLoader<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn process_extern_crate(&self, item: &ast::Item, definitions: &Definitions) -> CrateNum {
|
pub fn process_extern_crate(
|
||||||
|
&mut self,
|
||||||
|
item: &ast::Item,
|
||||||
|
definitions: &Definitions,
|
||||||
|
) -> CrateNum {
|
||||||
match item.kind {
|
match item.kind {
|
||||||
ast::ItemKind::ExternCrate(orig_name) => {
|
ast::ItemKind::ExternCrate(orig_name) => {
|
||||||
debug!("resolving extern crate stmt. ident: {} orig_name: {:?}",
|
debug!("resolving extern crate stmt. ident: {} orig_name: {:?}",
|
||||||
@ -990,7 +887,7 @@ impl<'a> CrateLoader<'a> {
|
|||||||
DepKind::Explicit
|
DepKind::Explicit
|
||||||
};
|
};
|
||||||
|
|
||||||
let cnum = self.resolve_crate(name, item.span, dep_kind, None).0;
|
let cnum = self.resolve_crate(name, item.span, dep_kind, None);
|
||||||
|
|
||||||
let def_id = definitions.opt_local_def_id(item.id).unwrap();
|
let def_id = definitions.opt_local_def_id(item.id).unwrap();
|
||||||
let path_len = definitions.def_path(def_id.index).data.len();
|
let path_len = definitions.def_path(def_id.index).data.len();
|
||||||
@ -1010,8 +907,8 @@ impl<'a> CrateLoader<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn process_path_extern(&self, name: Symbol, span: Span) -> CrateNum {
|
pub fn process_path_extern(&mut self, name: Symbol, span: Span) -> CrateNum {
|
||||||
let cnum = self.resolve_crate(name, span, DepKind::Explicit, None).0;
|
let cnum = self.resolve_crate(name, span, DepKind::Explicit, None);
|
||||||
|
|
||||||
self.update_extern_crate(
|
self.update_extern_crate(
|
||||||
cnum,
|
cnum,
|
||||||
@ -1028,8 +925,8 @@ impl<'a> CrateLoader<'a> {
|
|||||||
cnum
|
cnum
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn maybe_process_path_extern(&self, name: Symbol, span: Span) -> Option<CrateNum> {
|
pub fn maybe_process_path_extern(&mut self, name: Symbol, span: Span) -> Option<CrateNum> {
|
||||||
let cnum = self.maybe_resolve_crate(name, span, DepKind::Explicit, None).ok()?.0;
|
let cnum = self.maybe_resolve_crate(name, span, DepKind::Explicit, None).ok()?;
|
||||||
|
|
||||||
self.update_extern_crate(
|
self.update_extern_crate(
|
||||||
cnum,
|
cnum,
|
||||||
|
@ -5,12 +5,13 @@ use crate::schema;
|
|||||||
use rustc::dep_graph::DepNodeIndex;
|
use rustc::dep_graph::DepNodeIndex;
|
||||||
use rustc::hir::def_id::{CrateNum, DefIndex};
|
use rustc::hir::def_id::{CrateNum, DefIndex};
|
||||||
use rustc::hir::map::definitions::DefPathTable;
|
use rustc::hir::map::definitions::DefPathTable;
|
||||||
use rustc::middle::cstore::{CrateSource, DepKind, ExternCrate, MetadataLoader};
|
use rustc::middle::cstore::{CrateSource, DepKind, ExternCrate};
|
||||||
use rustc::mir::interpret::AllocDecodingState;
|
use rustc::mir::interpret::AllocDecodingState;
|
||||||
use rustc_index::vec::IndexVec;
|
use rustc_index::vec::IndexVec;
|
||||||
use rustc::util::nodemap::FxHashMap;
|
use rustc::util::nodemap::FxHashMap;
|
||||||
use rustc_data_structures::sync::{Lrc, RwLock, Lock, MetadataRef, AtomicCell};
|
use rustc_data_structures::sync::{Lrc, RwLock, Lock, MetadataRef, AtomicCell};
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
|
use syntax::edition::Edition;
|
||||||
use syntax_expand::base::SyntaxExtension;
|
use syntax_expand::base::SyntaxExtension;
|
||||||
use syntax_pos;
|
use syntax_pos;
|
||||||
use proc_macro::bridge::client::ProcMacro;
|
use proc_macro::bridge::client::ProcMacro;
|
||||||
@ -36,7 +37,7 @@ crate struct ImportedSourceFile {
|
|||||||
pub translated_source_file: Lrc<syntax_pos::SourceFile>,
|
pub translated_source_file: Lrc<syntax_pos::SourceFile>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct CrateMetadata {
|
crate struct CrateMetadata {
|
||||||
/// The primary crate data - binary metadata blob.
|
/// The primary crate data - binary metadata blob.
|
||||||
crate blob: MetadataBlob,
|
crate blob: MetadataBlob,
|
||||||
|
|
||||||
@ -53,7 +54,7 @@ pub struct CrateMetadata {
|
|||||||
/// hashmap, which gives the reverse mapping. This allows us to
|
/// hashmap, which gives the reverse mapping. This allows us to
|
||||||
/// quickly retrace a `DefPath`, which is needed for incremental
|
/// quickly retrace a `DefPath`, which is needed for incremental
|
||||||
/// compilation support.
|
/// compilation support.
|
||||||
crate def_path_table: Lrc<DefPathTable>,
|
crate def_path_table: DefPathTable,
|
||||||
/// Trait impl data.
|
/// Trait impl data.
|
||||||
/// FIXME: Used only from queries and can use query cache,
|
/// FIXME: Used only from queries and can use query cache,
|
||||||
/// so pre-decoding can probably be avoided.
|
/// so pre-decoding can probably be avoided.
|
||||||
@ -94,50 +95,48 @@ pub struct CrateMetadata {
|
|||||||
crate extern_crate: Lock<Option<ExternCrate>>,
|
crate extern_crate: Lock<Option<ExternCrate>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
pub struct CStore {
|
pub struct CStore {
|
||||||
metas: RwLock<IndexVec<CrateNum, Option<Lrc<CrateMetadata>>>>,
|
metas: IndexVec<CrateNum, Option<Lrc<CrateMetadata>>>,
|
||||||
crate metadata_loader: Box<dyn MetadataLoader + Sync>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum LoadedMacro {
|
pub enum LoadedMacro {
|
||||||
MacroDef(ast::Item),
|
MacroDef(ast::Item, Edition),
|
||||||
ProcMacro(SyntaxExtension),
|
ProcMacro(SyntaxExtension),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CStore {
|
impl Default for CStore {
|
||||||
pub fn new(metadata_loader: Box<dyn MetadataLoader + Sync>) -> CStore {
|
fn default() -> Self {
|
||||||
CStore {
|
CStore {
|
||||||
// We add an empty entry for LOCAL_CRATE (which maps to zero) in
|
// We add an empty entry for LOCAL_CRATE (which maps to zero) in
|
||||||
// order to make array indices in `metas` match with the
|
// order to make array indices in `metas` match with the
|
||||||
// corresponding `CrateNum`. This first entry will always remain
|
// corresponding `CrateNum`. This first entry will always remain
|
||||||
// `None`.
|
// `None`.
|
||||||
metas: RwLock::new(IndexVec::from_elem_n(None, 1)),
|
metas: IndexVec::from_elem_n(None, 1),
|
||||||
metadata_loader,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
crate fn alloc_new_crate_num(&self) -> CrateNum {
|
impl CStore {
|
||||||
let mut metas = self.metas.borrow_mut();
|
crate fn alloc_new_crate_num(&mut self) -> CrateNum {
|
||||||
let cnum = CrateNum::new(metas.len());
|
self.metas.push(None);
|
||||||
metas.push(None);
|
CrateNum::new(self.metas.len() - 1)
|
||||||
cnum
|
|
||||||
}
|
}
|
||||||
|
|
||||||
crate fn get_crate_data(&self, cnum: CrateNum) -> Lrc<CrateMetadata> {
|
crate fn get_crate_data(&self, cnum: CrateNum) -> &CrateMetadata {
|
||||||
self.metas.borrow()[cnum].clone()
|
self.metas[cnum].as_ref()
|
||||||
.unwrap_or_else(|| panic!("Failed to get crate data for {:?}", cnum))
|
.unwrap_or_else(|| panic!("Failed to get crate data for {:?}", cnum))
|
||||||
}
|
}
|
||||||
|
|
||||||
crate fn set_crate_data(&self, cnum: CrateNum, data: Lrc<CrateMetadata>) {
|
crate fn set_crate_data(&mut self, cnum: CrateNum, data: CrateMetadata) {
|
||||||
let mut metas = self.metas.borrow_mut();
|
assert!(self.metas[cnum].is_none(), "Overwriting crate metadata entry");
|
||||||
assert!(metas[cnum].is_none(), "Overwriting crate metadata entry");
|
self.metas[cnum] = Some(Lrc::new(data));
|
||||||
metas[cnum] = Some(data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
crate fn iter_crate_data<I>(&self, mut i: I)
|
crate fn iter_crate_data<I>(&self, mut i: I)
|
||||||
where I: FnMut(CrateNum, &Lrc<CrateMetadata>)
|
where I: FnMut(CrateNum, &CrateMetadata)
|
||||||
{
|
{
|
||||||
for (k, v) in self.metas.borrow().iter_enumerated() {
|
for (k, v) in self.metas.iter_enumerated() {
|
||||||
if let &Some(ref v) = v {
|
if let &Some(ref v) = v {
|
||||||
i(k, v);
|
i(k, v);
|
||||||
}
|
}
|
||||||
@ -168,7 +167,7 @@ impl CStore {
|
|||||||
|
|
||||||
crate fn do_postorder_cnums_untracked(&self) -> Vec<CrateNum> {
|
crate fn do_postorder_cnums_untracked(&self) -> Vec<CrateNum> {
|
||||||
let mut ordering = Vec::new();
|
let mut ordering = Vec::new();
|
||||||
for (num, v) in self.metas.borrow().iter_enumerated() {
|
for (num, v) in self.metas.iter_enumerated() {
|
||||||
if let &Some(_) = v {
|
if let &Some(_) = v {
|
||||||
self.push_dependencies_in_postorder(&mut ordering, num);
|
self.push_dependencies_in_postorder(&mut ordering, num);
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,6 @@ use std::sync::Arc;
|
|||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use syntax::attr;
|
use syntax::attr;
|
||||||
use syntax::source_map;
|
use syntax::source_map;
|
||||||
use syntax::edition::Edition;
|
|
||||||
use syntax::parse::source_file_to_stream;
|
use syntax::parse::source_file_to_stream;
|
||||||
use syntax::parse::parser::emit_unclosed_delims;
|
use syntax::parse::parser::emit_unclosed_delims;
|
||||||
use syntax::source_map::Spanned;
|
use syntax::source_map::Spanned;
|
||||||
@ -54,7 +53,7 @@ macro_rules! provide {
|
|||||||
let ($def_id, $other) = def_id_arg.into_args();
|
let ($def_id, $other) = def_id_arg.into_args();
|
||||||
assert!(!$def_id.is_local());
|
assert!(!$def_id.is_local());
|
||||||
|
|
||||||
let $cdata = $tcx.crate_data_as_rc_any($def_id.krate);
|
let $cdata = $tcx.crate_data_as_any($def_id.krate);
|
||||||
let $cdata = $cdata.downcast_ref::<cstore::CrateMetadata>()
|
let $cdata = $cdata.downcast_ref::<cstore::CrateMetadata>()
|
||||||
.expect("CrateStore created data is not a CrateMetadata");
|
.expect("CrateStore created data is not a CrateMetadata");
|
||||||
|
|
||||||
@ -411,10 +410,6 @@ impl cstore::CStore {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn crate_edition_untracked(&self, cnum: CrateNum) -> Edition {
|
|
||||||
self.get_crate_data(cnum).root.edition
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn struct_field_names_untracked(&self, def: DefId, sess: &Session) -> Vec<Spanned<Symbol>> {
|
pub fn struct_field_names_untracked(&self, def: DefId, sess: &Session) -> Vec<Spanned<Symbol>> {
|
||||||
self.get_crate_data(def.krate).get_struct_field_names(def.index, sess)
|
self.get_crate_data(def.krate).get_struct_field_names(def.index, sess)
|
||||||
}
|
}
|
||||||
@ -460,7 +455,7 @@ impl cstore::CStore {
|
|||||||
|
|
||||||
LoadedMacro::MacroDef(ast::Item {
|
LoadedMacro::MacroDef(ast::Item {
|
||||||
// FIXME: cross-crate hygiene
|
// FIXME: cross-crate hygiene
|
||||||
ident: ast::Ident::with_dummy_span(name.as_symbol()),
|
ident: ast::Ident::with_dummy_span(name),
|
||||||
id: ast::DUMMY_NODE_ID,
|
id: ast::DUMMY_NODE_ID,
|
||||||
span: local_span,
|
span: local_span,
|
||||||
attrs: attrs.iter().cloned().collect(),
|
attrs: attrs.iter().cloned().collect(),
|
||||||
@ -470,7 +465,7 @@ impl cstore::CStore {
|
|||||||
}),
|
}),
|
||||||
vis: source_map::respan(local_span.shrink_to_lo(), ast::VisibilityKind::Inherited),
|
vis: source_map::respan(local_span.shrink_to_lo(), ast::VisibilityKind::Inherited),
|
||||||
tokens: None,
|
tokens: None,
|
||||||
})
|
}, data.root.edition)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn associated_item_cloned_untracked(&self, def: DefId) -> ty::AssocItem {
|
pub fn associated_item_cloned_untracked(&self, def: DefId) -> ty::AssocItem {
|
||||||
@ -483,8 +478,8 @@ impl cstore::CStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl CrateStore for cstore::CStore {
|
impl CrateStore for cstore::CStore {
|
||||||
fn crate_data_as_rc_any(&self, krate: CrateNum) -> Lrc<dyn Any> {
|
fn crate_data_as_any(&self, cnum: CrateNum) -> &dyn Any {
|
||||||
self.get_crate_data(krate)
|
self.get_crate_data(cnum)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn item_generics_cloned_untracked(&self, def: DefId, sess: &Session) -> ty::Generics {
|
fn item_generics_cloned_untracked(&self, def: DefId, sess: &Session) -> ty::Generics {
|
||||||
@ -525,8 +520,8 @@ impl CrateStore for cstore::CStore {
|
|||||||
self.get_crate_data(def.krate).def_path_hash(def.index)
|
self.get_crate_data(def.krate).def_path_hash(def.index)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn def_path_table(&self, cnum: CrateNum) -> Lrc<DefPathTable> {
|
fn def_path_table(&self, cnum: CrateNum) -> &DefPathTable {
|
||||||
self.get_crate_data(cnum).def_path_table.clone()
|
&self.get_crate_data(cnum).def_path_table
|
||||||
}
|
}
|
||||||
|
|
||||||
fn crates_untracked(&self) -> Vec<CrateNum>
|
fn crates_untracked(&self) -> Vec<CrateNum>
|
||||||
|
@ -35,7 +35,7 @@ use syntax::ast::{self, Ident};
|
|||||||
use syntax::source_map::{self, respan, Spanned};
|
use syntax::source_map::{self, respan, Spanned};
|
||||||
use syntax::symbol::{Symbol, sym};
|
use syntax::symbol::{Symbol, sym};
|
||||||
use syntax_expand::base::{MacroKind, SyntaxExtensionKind, SyntaxExtension};
|
use syntax_expand::base::{MacroKind, SyntaxExtensionKind, SyntaxExtension};
|
||||||
use syntax_pos::{self, Span, BytePos, Pos, DUMMY_SP, symbol::{InternedString}};
|
use syntax_pos::{self, Span, BytePos, Pos, DUMMY_SP};
|
||||||
use log::debug;
|
use log::debug;
|
||||||
use proc_macro::bridge::client::ProcMacro;
|
use proc_macro::bridge::client::ProcMacro;
|
||||||
use syntax_expand::proc_macro::{AttrProcMacro, ProcMacroDerive, BangProcMacro};
|
use syntax_expand::proc_macro::{AttrProcMacro, ProcMacroDerive, BangProcMacro};
|
||||||
@ -448,7 +448,7 @@ impl<'tcx> EntryKind<'tcx> {
|
|||||||
EntryKind::Mod(_) => DefKind::Mod,
|
EntryKind::Mod(_) => DefKind::Mod,
|
||||||
EntryKind::Variant(_) => DefKind::Variant,
|
EntryKind::Variant(_) => DefKind::Variant,
|
||||||
EntryKind::Trait(_) => DefKind::Trait,
|
EntryKind::Trait(_) => DefKind::Trait,
|
||||||
EntryKind::TraitAlias(_) => DefKind::TraitAlias,
|
EntryKind::TraitAlias => DefKind::TraitAlias,
|
||||||
EntryKind::Enum(..) => DefKind::Enum,
|
EntryKind::Enum(..) => DefKind::Enum,
|
||||||
EntryKind::MacroDef(_) => DefKind::Macro(MacroKind::Bang),
|
EntryKind::MacroDef(_) => DefKind::Macro(MacroKind::Bang),
|
||||||
EntryKind::ForeignType => DefKind::ForeignTy,
|
EntryKind::ForeignType => DefKind::ForeignTy,
|
||||||
@ -458,7 +458,7 @@ impl<'tcx> EntryKind<'tcx> {
|
|||||||
EntryKind::Impl(_) |
|
EntryKind::Impl(_) |
|
||||||
EntryKind::Field |
|
EntryKind::Field |
|
||||||
EntryKind::Generator(_) |
|
EntryKind::Generator(_) |
|
||||||
EntryKind::Closure(_) => return None,
|
EntryKind::Closure => return None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -514,7 +514,6 @@ impl<'a, 'tcx> CrateMetadata {
|
|||||||
.data
|
.data
|
||||||
.get_opt_name()
|
.get_opt_name()
|
||||||
.expect("no name in item_name")
|
.expect("no name in item_name")
|
||||||
.as_symbol()
|
|
||||||
} else {
|
} else {
|
||||||
Symbol::intern(self.raw_proc_macro(item_index).name())
|
Symbol::intern(self.raw_proc_macro(item_index).name())
|
||||||
}
|
}
|
||||||
@ -575,7 +574,7 @@ impl<'a, 'tcx> CrateMetadata {
|
|||||||
data.is_marker,
|
data.is_marker,
|
||||||
self.def_path_table.def_path_hash(item_id))
|
self.def_path_table.def_path_hash(item_id))
|
||||||
},
|
},
|
||||||
EntryKind::TraitAlias(_) => {
|
EntryKind::TraitAlias => {
|
||||||
ty::TraitDef::new(self.local_def_id(item_id),
|
ty::TraitDef::new(self.local_def_id(item_id),
|
||||||
hir::Unsafety::Normal,
|
hir::Unsafety::Normal,
|
||||||
false,
|
false,
|
||||||
@ -680,13 +679,7 @@ impl<'a, 'tcx> CrateMetadata {
|
|||||||
item_id: DefIndex,
|
item_id: DefIndex,
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
) -> ty::GenericPredicates<'tcx> {
|
) -> ty::GenericPredicates<'tcx> {
|
||||||
let super_predicates = match self.kind(item_id) {
|
self.root.per_def.super_predicates.get(self, item_id).unwrap().decode((self, tcx))
|
||||||
EntryKind::Trait(data) => data.decode(self).super_predicates,
|
|
||||||
EntryKind::TraitAlias(data) => data.decode(self).super_predicates,
|
|
||||||
_ => bug!("def-index does not refer to trait or trait alias"),
|
|
||||||
};
|
|
||||||
|
|
||||||
super_predicates.decode((self, tcx))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
crate fn get_generics(&self, item_id: DefIndex, sess: &Session) -> ty::Generics {
|
crate fn get_generics(&self, item_id: DefIndex, sess: &Session) -> ty::Generics {
|
||||||
@ -717,7 +710,7 @@ impl<'a, 'tcx> CrateMetadata {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_impl_data(&self, id: DefIndex) -> ImplData<'tcx> {
|
fn get_impl_data(&self, id: DefIndex) -> ImplData {
|
||||||
match self.kind(id) {
|
match self.kind(id) {
|
||||||
EntryKind::Impl(data) => data.decode(self),
|
EntryKind::Impl(data) => data.decode(self),
|
||||||
_ => bug!(),
|
_ => bug!(),
|
||||||
@ -744,7 +737,7 @@ impl<'a, 'tcx> CrateMetadata {
|
|||||||
}
|
}
|
||||||
|
|
||||||
crate fn get_impl_trait(&self, id: DefIndex, tcx: TyCtxt<'tcx>) -> Option<ty::TraitRef<'tcx>> {
|
crate fn get_impl_trait(&self, id: DefIndex, tcx: TyCtxt<'tcx>) -> Option<ty::TraitRef<'tcx>> {
|
||||||
self.get_impl_data(id).trait_ref.map(|tr| tr.decode((self, tcx)))
|
self.root.per_def.impl_trait_ref.get(self, id).map(|tr| tr.decode((self, tcx)))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Iterates over all the stability attributes in the given crate.
|
/// Iterates over all the stability attributes in the given crate.
|
||||||
@ -864,7 +857,7 @@ impl<'a, 'tcx> CrateMetadata {
|
|||||||
let span = self.get_span(child_index, sess);
|
let span = self.get_span(child_index, sess);
|
||||||
if let (Some(kind), Some(name)) =
|
if let (Some(kind), Some(name)) =
|
||||||
(self.def_kind(child_index), def_key.disambiguated_data.data.get_opt_name()) {
|
(self.def_kind(child_index), def_key.disambiguated_data.data.get_opt_name()) {
|
||||||
let ident = Ident::from_interned_str(name);
|
let ident = Ident::with_dummy_span(name);
|
||||||
let vis = self.get_visibility(child_index);
|
let vis = self.get_visibility(child_index);
|
||||||
let def_id = self.local_def_id(child_index);
|
let def_id = self.local_def_id(child_index);
|
||||||
let res = Res::Def(kind, def_id);
|
let res = Res::Def(kind, def_id);
|
||||||
@ -987,7 +980,7 @@ impl<'a, 'tcx> CrateMetadata {
|
|||||||
};
|
};
|
||||||
|
|
||||||
ty::AssocItem {
|
ty::AssocItem {
|
||||||
ident: Ident::from_interned_str(name),
|
ident: Ident::with_dummy_span(name),
|
||||||
kind,
|
kind,
|
||||||
vis: self.get_visibility(id),
|
vis: self.get_visibility(id),
|
||||||
defaultness: container.defaultness(),
|
defaultness: container.defaultness(),
|
||||||
@ -1118,7 +1111,7 @@ impl<'a, 'tcx> CrateMetadata {
|
|||||||
def_key.parent.and_then(|parent_index| {
|
def_key.parent.and_then(|parent_index| {
|
||||||
match self.kind(parent_index) {
|
match self.kind(parent_index) {
|
||||||
EntryKind::Trait(_) |
|
EntryKind::Trait(_) |
|
||||||
EntryKind::TraitAlias(_) => Some(self.local_def_id(parent_index)),
|
EntryKind::TraitAlias => Some(self.local_def_id(parent_index)),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -1245,16 +1238,7 @@ impl<'a, 'tcx> CrateMetadata {
|
|||||||
}
|
}
|
||||||
|
|
||||||
crate fn fn_sig(&self, id: DefIndex, tcx: TyCtxt<'tcx>) -> ty::PolyFnSig<'tcx> {
|
crate fn fn_sig(&self, id: DefIndex, tcx: TyCtxt<'tcx>) -> ty::PolyFnSig<'tcx> {
|
||||||
let sig = match self.kind(id) {
|
self.root.per_def.fn_sig.get(self, id).unwrap().decode((self, tcx))
|
||||||
EntryKind::Fn(data) |
|
|
||||||
EntryKind::ForeignFn(data) => data.decode(self).sig,
|
|
||||||
EntryKind::Method(data) => data.decode(self).fn_data.sig,
|
|
||||||
EntryKind::Variant(data) |
|
|
||||||
EntryKind::Struct(data, _) => data.decode(self).ctor_sig.unwrap(),
|
|
||||||
EntryKind::Closure(data) => data.decode(self).sig,
|
|
||||||
_ => bug!(),
|
|
||||||
};
|
|
||||||
sig.decode((self, tcx))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -1262,7 +1246,7 @@ impl<'a, 'tcx> CrateMetadata {
|
|||||||
let mut key = self.def_path_table.def_key(index);
|
let mut key = self.def_path_table.def_key(index);
|
||||||
if self.is_proc_macro(index) {
|
if self.is_proc_macro(index) {
|
||||||
let name = self.raw_proc_macro(index).name();
|
let name = self.raw_proc_macro(index).name();
|
||||||
key.disambiguated_data.data = DefPathData::MacroNs(InternedString::intern(name));
|
key.disambiguated_data.data = DefPathData::MacroNs(Symbol::intern(name));
|
||||||
}
|
}
|
||||||
key
|
key
|
||||||
}
|
}
|
||||||
|
@ -71,11 +71,14 @@ struct PerDefTables<'tcx> {
|
|||||||
deprecation: PerDefTable<Lazy<attr::Deprecation>>,
|
deprecation: PerDefTable<Lazy<attr::Deprecation>>,
|
||||||
|
|
||||||
ty: PerDefTable<Lazy<Ty<'tcx>>>,
|
ty: PerDefTable<Lazy<Ty<'tcx>>>,
|
||||||
|
fn_sig: PerDefTable<Lazy<ty::PolyFnSig<'tcx>>>,
|
||||||
|
impl_trait_ref: PerDefTable<Lazy<ty::TraitRef<'tcx>>>,
|
||||||
inherent_impls: PerDefTable<Lazy<[DefIndex]>>,
|
inherent_impls: PerDefTable<Lazy<[DefIndex]>>,
|
||||||
variances: PerDefTable<Lazy<[ty::Variance]>>,
|
variances: PerDefTable<Lazy<[ty::Variance]>>,
|
||||||
generics: PerDefTable<Lazy<ty::Generics>>,
|
generics: PerDefTable<Lazy<ty::Generics>>,
|
||||||
predicates: PerDefTable<Lazy<ty::GenericPredicates<'tcx>>>,
|
predicates: PerDefTable<Lazy<ty::GenericPredicates<'tcx>>>,
|
||||||
predicates_defined_on: PerDefTable<Lazy<ty::GenericPredicates<'tcx>>>,
|
predicates_defined_on: PerDefTable<Lazy<ty::GenericPredicates<'tcx>>>,
|
||||||
|
super_predicates: PerDefTable<Lazy<ty::GenericPredicates<'tcx>>>,
|
||||||
|
|
||||||
mir: PerDefTable<Lazy<mir::Body<'tcx>>>,
|
mir: PerDefTable<Lazy<mir::Body<'tcx>>>,
|
||||||
promoted_mir: PerDefTable<Lazy<IndexVec<mir::Promoted, mir::Body<'tcx>>>>,
|
promoted_mir: PerDefTable<Lazy<IndexVec<mir::Promoted, mir::Body<'tcx>>>>,
|
||||||
@ -508,11 +511,14 @@ impl<'tcx> EncodeContext<'tcx> {
|
|||||||
deprecation: self.per_def.deprecation.encode(&mut self.opaque),
|
deprecation: self.per_def.deprecation.encode(&mut self.opaque),
|
||||||
|
|
||||||
ty: self.per_def.ty.encode(&mut self.opaque),
|
ty: self.per_def.ty.encode(&mut self.opaque),
|
||||||
|
fn_sig: self.per_def.fn_sig.encode(&mut self.opaque),
|
||||||
|
impl_trait_ref: self.per_def.impl_trait_ref.encode(&mut self.opaque),
|
||||||
inherent_impls: self.per_def.inherent_impls.encode(&mut self.opaque),
|
inherent_impls: self.per_def.inherent_impls.encode(&mut self.opaque),
|
||||||
variances: self.per_def.variances.encode(&mut self.opaque),
|
variances: self.per_def.variances.encode(&mut self.opaque),
|
||||||
generics: self.per_def.generics.encode(&mut self.opaque),
|
generics: self.per_def.generics.encode(&mut self.opaque),
|
||||||
predicates: self.per_def.predicates.encode(&mut self.opaque),
|
predicates: self.per_def.predicates.encode(&mut self.opaque),
|
||||||
predicates_defined_on: self.per_def.predicates_defined_on.encode(&mut self.opaque),
|
predicates_defined_on: self.per_def.predicates_defined_on.encode(&mut self.opaque),
|
||||||
|
super_predicates: self.per_def.super_predicates.encode(&mut self.opaque),
|
||||||
|
|
||||||
mir: self.per_def.mir.encode(&mut self.opaque),
|
mir: self.per_def.mir.encode(&mut self.opaque),
|
||||||
promoted_mir: self.per_def.promoted_mir.encode(&mut self.opaque),
|
promoted_mir: self.per_def.promoted_mir.encode(&mut self.opaque),
|
||||||
@ -635,13 +641,7 @@ impl EncodeContext<'tcx> {
|
|||||||
let data = VariantData {
|
let data = VariantData {
|
||||||
ctor_kind: variant.ctor_kind,
|
ctor_kind: variant.ctor_kind,
|
||||||
discr: variant.discr,
|
discr: variant.discr,
|
||||||
// FIXME(eddyb) deduplicate these with `encode_enum_variant_ctor`.
|
|
||||||
ctor: variant.ctor_def_id.map(|did| did.index),
|
ctor: variant.ctor_def_id.map(|did| did.index),
|
||||||
ctor_sig: if variant.ctor_kind == CtorKind::Fn {
|
|
||||||
variant.ctor_def_id.map(|ctor_def_id| self.lazy(&tcx.fn_sig(ctor_def_id)))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let enum_id = tcx.hir().as_local_hir_id(enum_did).unwrap();
|
let enum_id = tcx.hir().as_local_hir_id(enum_did).unwrap();
|
||||||
@ -660,6 +660,11 @@ impl EncodeContext<'tcx> {
|
|||||||
self.encode_deprecation(def_id);
|
self.encode_deprecation(def_id);
|
||||||
self.encode_item_type(def_id);
|
self.encode_item_type(def_id);
|
||||||
if variant.ctor_kind == CtorKind::Fn {
|
if variant.ctor_kind == CtorKind::Fn {
|
||||||
|
// FIXME(eddyb) encode signature only in `encode_enum_variant_ctor`.
|
||||||
|
if let Some(ctor_def_id) = variant.ctor_def_id {
|
||||||
|
record!(self.per_def.fn_sig[def_id] <- tcx.fn_sig(ctor_def_id));
|
||||||
|
}
|
||||||
|
// FIXME(eddyb) is this ever used?
|
||||||
self.encode_variances_of(def_id);
|
self.encode_variances_of(def_id);
|
||||||
}
|
}
|
||||||
self.encode_generics(def_id);
|
self.encode_generics(def_id);
|
||||||
@ -679,15 +684,11 @@ impl EncodeContext<'tcx> {
|
|||||||
let def_id = variant.ctor_def_id.unwrap();
|
let def_id = variant.ctor_def_id.unwrap();
|
||||||
debug!("EncodeContext::encode_enum_variant_ctor({:?})", def_id);
|
debug!("EncodeContext::encode_enum_variant_ctor({:?})", def_id);
|
||||||
|
|
||||||
|
// FIXME(eddyb) encode only the `CtorKind` for constructors.
|
||||||
let data = VariantData {
|
let data = VariantData {
|
||||||
ctor_kind: variant.ctor_kind,
|
ctor_kind: variant.ctor_kind,
|
||||||
discr: variant.discr,
|
discr: variant.discr,
|
||||||
ctor: Some(def_id.index),
|
ctor: Some(def_id.index),
|
||||||
ctor_sig: if variant.ctor_kind == CtorKind::Fn {
|
|
||||||
Some(self.lazy(tcx.fn_sig(def_id)))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Variant constructors have the same visibility as the parent enums, unless marked as
|
// Variant constructors have the same visibility as the parent enums, unless marked as
|
||||||
@ -706,6 +707,7 @@ impl EncodeContext<'tcx> {
|
|||||||
self.encode_deprecation(def_id);
|
self.encode_deprecation(def_id);
|
||||||
self.encode_item_type(def_id);
|
self.encode_item_type(def_id);
|
||||||
if variant.ctor_kind == CtorKind::Fn {
|
if variant.ctor_kind == CtorKind::Fn {
|
||||||
|
record!(self.per_def.fn_sig[def_id] <- tcx.fn_sig(def_id));
|
||||||
self.encode_variances_of(def_id);
|
self.encode_variances_of(def_id);
|
||||||
}
|
}
|
||||||
self.encode_generics(def_id);
|
self.encode_generics(def_id);
|
||||||
@ -780,11 +782,6 @@ impl EncodeContext<'tcx> {
|
|||||||
ctor_kind: variant.ctor_kind,
|
ctor_kind: variant.ctor_kind,
|
||||||
discr: variant.discr,
|
discr: variant.discr,
|
||||||
ctor: Some(def_id.index),
|
ctor: Some(def_id.index),
|
||||||
ctor_sig: if variant.ctor_kind == CtorKind::Fn {
|
|
||||||
Some(self.lazy(tcx.fn_sig(def_id)))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let struct_id = tcx.hir().as_local_hir_id(adt_def_id).unwrap();
|
let struct_id = tcx.hir().as_local_hir_id(adt_def_id).unwrap();
|
||||||
@ -811,6 +808,7 @@ impl EncodeContext<'tcx> {
|
|||||||
self.encode_deprecation(def_id);
|
self.encode_deprecation(def_id);
|
||||||
self.encode_item_type(def_id);
|
self.encode_item_type(def_id);
|
||||||
if variant.ctor_kind == CtorKind::Fn {
|
if variant.ctor_kind == CtorKind::Fn {
|
||||||
|
record!(self.per_def.fn_sig[def_id] <- tcx.fn_sig(def_id));
|
||||||
self.encode_variances_of(def_id);
|
self.encode_variances_of(def_id);
|
||||||
}
|
}
|
||||||
self.encode_generics(def_id);
|
self.encode_generics(def_id);
|
||||||
@ -835,6 +833,11 @@ impl EncodeContext<'tcx> {
|
|||||||
self.tcx.predicates_defined_on(def_id))
|
self.tcx.predicates_defined_on(def_id))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn encode_super_predicates(&mut self, def_id: DefId) {
|
||||||
|
debug!("EncodeContext::encode_super_predicates({:?})", def_id);
|
||||||
|
record!(self.per_def.super_predicates[def_id] <- self.tcx.super_predicates_of(def_id));
|
||||||
|
}
|
||||||
|
|
||||||
fn encode_info_for_trait_item(&mut self, def_id: DefId) {
|
fn encode_info_for_trait_item(&mut self, def_id: DefId) {
|
||||||
debug!("EncodeContext::encode_info_for_trait_item({:?})", def_id);
|
debug!("EncodeContext::encode_info_for_trait_item({:?})", def_id);
|
||||||
let tcx = self.tcx;
|
let tcx = self.tcx;
|
||||||
@ -874,7 +877,6 @@ impl EncodeContext<'tcx> {
|
|||||||
asyncness: m_sig.header.asyncness,
|
asyncness: m_sig.header.asyncness,
|
||||||
constness: hir::Constness::NotConst,
|
constness: hir::Constness::NotConst,
|
||||||
param_names,
|
param_names,
|
||||||
sig: self.lazy(tcx.fn_sig(def_id)),
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
bug!()
|
bug!()
|
||||||
@ -906,6 +908,7 @@ impl EncodeContext<'tcx> {
|
|||||||
ty::AssocKind::OpaqueTy => unreachable!(),
|
ty::AssocKind::OpaqueTy => unreachable!(),
|
||||||
}
|
}
|
||||||
if trait_item.kind == ty::AssocKind::Method {
|
if trait_item.kind == ty::AssocKind::Method {
|
||||||
|
record!(self.per_def.fn_sig[def_id] <- tcx.fn_sig(def_id));
|
||||||
self.encode_variances_of(def_id);
|
self.encode_variances_of(def_id);
|
||||||
}
|
}
|
||||||
self.encode_generics(def_id);
|
self.encode_generics(def_id);
|
||||||
@ -952,7 +955,6 @@ impl EncodeContext<'tcx> {
|
|||||||
asyncness: sig.header.asyncness,
|
asyncness: sig.header.asyncness,
|
||||||
constness: sig.header.constness,
|
constness: sig.header.constness,
|
||||||
param_names: self.encode_fn_param_names_for_body(body),
|
param_names: self.encode_fn_param_names_for_body(body),
|
||||||
sig: self.lazy(tcx.fn_sig(def_id)),
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
bug!()
|
bug!()
|
||||||
@ -973,6 +975,7 @@ impl EncodeContext<'tcx> {
|
|||||||
self.encode_deprecation(def_id);
|
self.encode_deprecation(def_id);
|
||||||
self.encode_item_type(def_id);
|
self.encode_item_type(def_id);
|
||||||
if impl_item.kind == ty::AssocKind::Method {
|
if impl_item.kind == ty::AssocKind::Method {
|
||||||
|
record!(self.per_def.fn_sig[def_id] <- tcx.fn_sig(def_id));
|
||||||
self.encode_variances_of(def_id);
|
self.encode_variances_of(def_id);
|
||||||
}
|
}
|
||||||
self.encode_generics(def_id);
|
self.encode_generics(def_id);
|
||||||
@ -1081,7 +1084,6 @@ impl EncodeContext<'tcx> {
|
|||||||
asyncness: header.asyncness,
|
asyncness: header.asyncness,
|
||||||
constness: header.constness,
|
constness: header.constness,
|
||||||
param_names: self.encode_fn_param_names_for_body(body),
|
param_names: self.encode_fn_param_names_for_body(body),
|
||||||
sig: self.lazy(tcx.fn_sig(def_id)),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
EntryKind::Fn(self.lazy(data))
|
EntryKind::Fn(self.lazy(data))
|
||||||
@ -1109,7 +1111,6 @@ impl EncodeContext<'tcx> {
|
|||||||
ctor_kind: variant.ctor_kind,
|
ctor_kind: variant.ctor_kind,
|
||||||
discr: variant.discr,
|
discr: variant.discr,
|
||||||
ctor,
|
ctor,
|
||||||
ctor_sig: None,
|
|
||||||
}), adt_def.repr)
|
}), adt_def.repr)
|
||||||
}
|
}
|
||||||
hir::ItemKind::Union(..) => {
|
hir::ItemKind::Union(..) => {
|
||||||
@ -1120,7 +1121,6 @@ impl EncodeContext<'tcx> {
|
|||||||
ctor_kind: variant.ctor_kind,
|
ctor_kind: variant.ctor_kind,
|
||||||
discr: variant.discr,
|
discr: variant.discr,
|
||||||
ctor: None,
|
ctor: None,
|
||||||
ctor_sig: None,
|
|
||||||
}), adt_def.repr)
|
}), adt_def.repr)
|
||||||
}
|
}
|
||||||
hir::ItemKind::Impl(_, _, defaultness, ..) => {
|
hir::ItemKind::Impl(_, _, defaultness, ..) => {
|
||||||
@ -1154,7 +1154,6 @@ impl EncodeContext<'tcx> {
|
|||||||
defaultness,
|
defaultness,
|
||||||
parent_impl: parent,
|
parent_impl: parent,
|
||||||
coerce_unsized_info,
|
coerce_unsized_info,
|
||||||
trait_ref: trait_ref.map(|trait_ref| self.lazy(trait_ref)),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
EntryKind::Impl(self.lazy(data))
|
EntryKind::Impl(self.lazy(data))
|
||||||
@ -1166,18 +1165,11 @@ impl EncodeContext<'tcx> {
|
|||||||
paren_sugar: trait_def.paren_sugar,
|
paren_sugar: trait_def.paren_sugar,
|
||||||
has_auto_impl: self.tcx.trait_is_auto(def_id),
|
has_auto_impl: self.tcx.trait_is_auto(def_id),
|
||||||
is_marker: trait_def.is_marker,
|
is_marker: trait_def.is_marker,
|
||||||
super_predicates: self.lazy(tcx.super_predicates_of(def_id)),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
EntryKind::Trait(self.lazy(data))
|
EntryKind::Trait(self.lazy(data))
|
||||||
}
|
}
|
||||||
hir::ItemKind::TraitAlias(..) => {
|
hir::ItemKind::TraitAlias(..) => EntryKind::TraitAlias,
|
||||||
let data = TraitAliasData {
|
|
||||||
super_predicates: self.lazy(tcx.super_predicates_of(def_id)),
|
|
||||||
};
|
|
||||||
|
|
||||||
EntryKind::TraitAlias(self.lazy(data))
|
|
||||||
}
|
|
||||||
hir::ItemKind::ExternCrate(_) |
|
hir::ItemKind::ExternCrate(_) |
|
||||||
hir::ItemKind::Use(..) => bug!("cannot encode info for item {:?}", item),
|
hir::ItemKind::Use(..) => bug!("cannot encode info for item {:?}", item),
|
||||||
});
|
});
|
||||||
@ -1232,6 +1224,14 @@ impl EncodeContext<'tcx> {
|
|||||||
hir::ItemKind::Impl(..) => self.encode_item_type(def_id),
|
hir::ItemKind::Impl(..) => self.encode_item_type(def_id),
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
if let hir::ItemKind::Fn(..) = item.kind {
|
||||||
|
record!(self.per_def.fn_sig[def_id] <- tcx.fn_sig(def_id));
|
||||||
|
}
|
||||||
|
if let hir::ItemKind::Impl(..) = item.kind {
|
||||||
|
if let Some(trait_ref) = self.tcx.impl_trait_ref(def_id) {
|
||||||
|
record!(self.per_def.impl_trait_ref[def_id] <- trait_ref);
|
||||||
|
}
|
||||||
|
}
|
||||||
self.encode_inherent_implementations(def_id);
|
self.encode_inherent_implementations(def_id);
|
||||||
match item.kind {
|
match item.kind {
|
||||||
hir::ItemKind::Enum(..) |
|
hir::ItemKind::Enum(..) |
|
||||||
@ -1269,6 +1269,13 @@ impl EncodeContext<'tcx> {
|
|||||||
}
|
}
|
||||||
_ => {} // not *wrong* for other kinds of items, but not needed
|
_ => {} // not *wrong* for other kinds of items, but not needed
|
||||||
}
|
}
|
||||||
|
match item.kind {
|
||||||
|
hir::ItemKind::Trait(..) |
|
||||||
|
hir::ItemKind::TraitAlias(..) => {
|
||||||
|
self.encode_super_predicates(def_id);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
|
||||||
let mir = match item.kind {
|
let mir = match item.kind {
|
||||||
hir::ItemKind::Static(..) | hir::ItemKind::Const(..) => true,
|
hir::ItemKind::Static(..) | hir::ItemKind::Const(..) => true,
|
||||||
@ -1321,10 +1328,12 @@ impl EncodeContext<'tcx> {
|
|||||||
fn encode_info_for_closure(&mut self, def_id: DefId) {
|
fn encode_info_for_closure(&mut self, def_id: DefId) {
|
||||||
debug!("EncodeContext::encode_info_for_closure({:?})", def_id);
|
debug!("EncodeContext::encode_info_for_closure({:?})", def_id);
|
||||||
|
|
||||||
let tables = self.tcx.typeck_tables_of(def_id);
|
// NOTE(eddyb) `tcx.type_of(def_id)` isn't used because it's fully generic,
|
||||||
|
// including on the signature, which is inferred in `typeck_tables_of.
|
||||||
let hir_id = self.tcx.hir().as_local_hir_id(def_id).unwrap();
|
let hir_id = self.tcx.hir().as_local_hir_id(def_id).unwrap();
|
||||||
|
let ty = self.tcx.typeck_tables_of(def_id).node_type(hir_id);
|
||||||
|
|
||||||
record!(self.per_def.kind[def_id] <- match tables.node_type(hir_id).kind {
|
record!(self.per_def.kind[def_id] <- match ty.kind {
|
||||||
ty::Generator(def_id, ..) => {
|
ty::Generator(def_id, ..) => {
|
||||||
let layout = self.tcx.generator_layout(def_id);
|
let layout = self.tcx.generator_layout(def_id);
|
||||||
let data = GeneratorData {
|
let data = GeneratorData {
|
||||||
@ -1333,11 +1342,7 @@ impl EncodeContext<'tcx> {
|
|||||||
EntryKind::Generator(self.lazy(data))
|
EntryKind::Generator(self.lazy(data))
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::Closure(def_id, substs) => {
|
ty::Closure(..) => EntryKind::Closure,
|
||||||
let sig = substs.as_closure().sig(def_id, self.tcx);
|
|
||||||
let data = ClosureData { sig: self.lazy(sig) };
|
|
||||||
EntryKind::Closure(self.lazy(data))
|
|
||||||
}
|
|
||||||
|
|
||||||
_ => bug!("closure that is neither generator nor closure"),
|
_ => bug!("closure that is neither generator nor closure"),
|
||||||
});
|
});
|
||||||
@ -1345,6 +1350,9 @@ impl EncodeContext<'tcx> {
|
|||||||
record!(self.per_def.span[def_id] <- self.tcx.def_span(def_id));
|
record!(self.per_def.span[def_id] <- self.tcx.def_span(def_id));
|
||||||
record!(self.per_def.attributes[def_id] <- &self.tcx.get_attrs(def_id)[..]);
|
record!(self.per_def.attributes[def_id] <- &self.tcx.get_attrs(def_id)[..]);
|
||||||
self.encode_item_type(def_id);
|
self.encode_item_type(def_id);
|
||||||
|
if let ty::Closure(def_id, substs) = ty.kind {
|
||||||
|
record!(self.per_def.fn_sig[def_id] <- substs.as_closure().sig(def_id, self.tcx));
|
||||||
|
}
|
||||||
self.encode_generics(def_id);
|
self.encode_generics(def_id);
|
||||||
self.encode_optimized_mir(def_id);
|
self.encode_optimized_mir(def_id);
|
||||||
self.encode_promoted_mir(def_id);
|
self.encode_promoted_mir(def_id);
|
||||||
@ -1553,7 +1561,6 @@ impl EncodeContext<'tcx> {
|
|||||||
asyncness: hir::IsAsync::NotAsync,
|
asyncness: hir::IsAsync::NotAsync,
|
||||||
constness: hir::Constness::NotConst,
|
constness: hir::Constness::NotConst,
|
||||||
param_names: self.encode_fn_param_names(names),
|
param_names: self.encode_fn_param_names(names),
|
||||||
sig: self.lazy(tcx.fn_sig(def_id)),
|
|
||||||
};
|
};
|
||||||
EntryKind::ForeignFn(self.lazy(data))
|
EntryKind::ForeignFn(self.lazy(data))
|
||||||
}
|
}
|
||||||
@ -1569,6 +1576,7 @@ impl EncodeContext<'tcx> {
|
|||||||
self.encode_deprecation(def_id);
|
self.encode_deprecation(def_id);
|
||||||
self.encode_item_type(def_id);
|
self.encode_item_type(def_id);
|
||||||
if let hir::ForeignItemKind::Fn(..) = nitem.kind {
|
if let hir::ForeignItemKind::Fn(..) = nitem.kind {
|
||||||
|
record!(self.per_def.fn_sig[def_id] <- tcx.fn_sig(def_id));
|
||||||
self.encode_variances_of(def_id);
|
self.encode_variances_of(def_id);
|
||||||
}
|
}
|
||||||
self.encode_generics(def_id);
|
self.encode_generics(def_id);
|
||||||
|
@ -212,7 +212,7 @@
|
|||||||
//! no means all of the necessary details. Take a look at the rest of
|
//! no means all of the necessary details. Take a look at the rest of
|
||||||
//! metadata::locator or metadata::creader for all the juicy details!
|
//! metadata::locator or metadata::creader for all the juicy details!
|
||||||
|
|
||||||
use crate::cstore::{MetadataBlob, CStore};
|
use crate::cstore::MetadataBlob;
|
||||||
use crate::creader::Library;
|
use crate::creader::Library;
|
||||||
use crate::schema::{METADATA_HEADER, rustc_version};
|
use crate::schema::{METADATA_HEADER, rustc_version};
|
||||||
|
|
||||||
@ -220,12 +220,13 @@ use rustc_data_structures::fx::FxHashSet;
|
|||||||
use rustc_data_structures::svh::Svh;
|
use rustc_data_structures::svh::Svh;
|
||||||
use rustc_data_structures::sync::MetadataRef;
|
use rustc_data_structures::sync::MetadataRef;
|
||||||
use rustc::middle::cstore::{CrateSource, MetadataLoader};
|
use rustc::middle::cstore::{CrateSource, MetadataLoader};
|
||||||
use rustc::session::{config, Session};
|
use rustc::session::{config, Session, CrateDisambiguator};
|
||||||
use rustc::session::filesearch::{FileSearch, FileMatches, FileDoesntMatch};
|
use rustc::session::filesearch::{FileSearch, FileMatches, FileDoesntMatch};
|
||||||
use rustc::session::search_paths::PathKind;
|
use rustc::session::search_paths::PathKind;
|
||||||
use rustc::util::nodemap::FxHashMap;
|
use rustc::util::nodemap::FxHashMap;
|
||||||
|
|
||||||
use errors::DiagnosticBuilder;
|
use errors::DiagnosticBuilder;
|
||||||
|
use syntax::{span_err, span_fatal};
|
||||||
use syntax::symbol::{Symbol, sym};
|
use syntax::symbol::{Symbol, sym};
|
||||||
use syntax::struct_span_err;
|
use syntax::struct_span_err;
|
||||||
use syntax_pos::Span;
|
use syntax_pos::Span;
|
||||||
@ -911,10 +912,87 @@ fn get_metadata_section_imp(target: &Target,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Look for a plugin registrar. Returns its library path and crate disambiguator.
|
||||||
|
pub fn find_plugin_registrar(
|
||||||
|
sess: &Session,
|
||||||
|
metadata_loader: &dyn MetadataLoader,
|
||||||
|
span: Span,
|
||||||
|
name: Symbol,
|
||||||
|
) -> Option<(PathBuf, CrateDisambiguator)> {
|
||||||
|
info!("find plugin registrar `{}`", name);
|
||||||
|
let target_triple = sess.opts.target_triple.clone();
|
||||||
|
let host_triple = TargetTriple::from_triple(config::host_triple());
|
||||||
|
let is_cross = target_triple != host_triple;
|
||||||
|
let mut target_only = false;
|
||||||
|
let mut locate_ctxt = Context {
|
||||||
|
sess,
|
||||||
|
span,
|
||||||
|
crate_name: name,
|
||||||
|
hash: None,
|
||||||
|
extra_filename: None,
|
||||||
|
filesearch: sess.host_filesearch(PathKind::Crate),
|
||||||
|
target: &sess.host,
|
||||||
|
triple: host_triple,
|
||||||
|
root: None,
|
||||||
|
rejected_via_hash: vec![],
|
||||||
|
rejected_via_triple: vec![],
|
||||||
|
rejected_via_kind: vec![],
|
||||||
|
rejected_via_version: vec![],
|
||||||
|
rejected_via_filename: vec![],
|
||||||
|
should_match_name: true,
|
||||||
|
is_proc_macro: None,
|
||||||
|
metadata_loader,
|
||||||
|
};
|
||||||
|
|
||||||
|
let library = locate_ctxt.maybe_load_library_crate().or_else(|| {
|
||||||
|
if !is_cross {
|
||||||
|
return None
|
||||||
|
}
|
||||||
|
// Try loading from target crates. This will abort later if we
|
||||||
|
// try to load a plugin registrar function,
|
||||||
|
target_only = true;
|
||||||
|
|
||||||
|
locate_ctxt.target = &sess.target.target;
|
||||||
|
locate_ctxt.triple = target_triple;
|
||||||
|
locate_ctxt.filesearch = sess.target_filesearch(PathKind::Crate);
|
||||||
|
|
||||||
|
locate_ctxt.maybe_load_library_crate()
|
||||||
|
});
|
||||||
|
let library = match library {
|
||||||
|
Some(l) => l,
|
||||||
|
None => locate_ctxt.report_errs(),
|
||||||
|
};
|
||||||
|
|
||||||
|
if target_only {
|
||||||
|
// Need to abort before syntax expansion.
|
||||||
|
let message = format!("plugin `{}` is not available for triple `{}` \
|
||||||
|
(only found {})",
|
||||||
|
name,
|
||||||
|
config::host_triple(),
|
||||||
|
sess.opts.target_triple);
|
||||||
|
span_fatal!(sess, span, E0456, "{}", &message);
|
||||||
|
}
|
||||||
|
|
||||||
|
match library.source.dylib {
|
||||||
|
Some(dylib) => {
|
||||||
|
Some((dylib.0, library.metadata.get_root().disambiguator))
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
span_err!(sess, span, E0457,
|
||||||
|
"plugin `{}` only found in rlib format, but must be available \
|
||||||
|
in dylib format",
|
||||||
|
name);
|
||||||
|
// No need to abort because the loading code will just ignore this
|
||||||
|
// empty dylib.
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// A diagnostic function for dumping crate metadata to an output stream.
|
/// A diagnostic function for dumping crate metadata to an output stream.
|
||||||
pub fn list_file_metadata(target: &Target,
|
pub fn list_file_metadata(target: &Target,
|
||||||
path: &Path,
|
path: &Path,
|
||||||
cstore: &CStore,
|
metadata_loader: &dyn MetadataLoader,
|
||||||
out: &mut dyn io::Write)
|
out: &mut dyn io::Write)
|
||||||
-> io::Result<()> {
|
-> io::Result<()> {
|
||||||
let filename = path.file_name().unwrap().to_str().unwrap();
|
let filename = path.file_name().unwrap().to_str().unwrap();
|
||||||
@ -925,7 +1003,7 @@ pub fn list_file_metadata(target: &Target,
|
|||||||
} else {
|
} else {
|
||||||
CrateFlavor::Dylib
|
CrateFlavor::Dylib
|
||||||
};
|
};
|
||||||
match get_metadata_section(target, flavor, path, &*cstore.metadata_loader) {
|
match get_metadata_section(target, flavor, path, metadata_loader) {
|
||||||
Ok(metadata) => metadata.list_crate_metadata(out),
|
Ok(metadata) => metadata.list_crate_metadata(out),
|
||||||
Err(msg) => write!(out, "{}\n", msg),
|
Err(msg) => write!(out, "{}\n", msg),
|
||||||
}
|
}
|
||||||
|
@ -238,11 +238,14 @@ crate struct LazyPerDefTables<'tcx> {
|
|||||||
pub deprecation: Lazy!(PerDefTable<Lazy<attr::Deprecation>>),
|
pub deprecation: Lazy!(PerDefTable<Lazy<attr::Deprecation>>),
|
||||||
|
|
||||||
pub ty: Lazy!(PerDefTable<Lazy!(Ty<'tcx>)>),
|
pub ty: Lazy!(PerDefTable<Lazy!(Ty<'tcx>)>),
|
||||||
|
pub fn_sig: Lazy!(PerDefTable<Lazy!(ty::PolyFnSig<'tcx>)>),
|
||||||
|
pub impl_trait_ref: Lazy!(PerDefTable<Lazy!(ty::TraitRef<'tcx>)>),
|
||||||
pub inherent_impls: Lazy!(PerDefTable<Lazy<[DefIndex]>>),
|
pub inherent_impls: Lazy!(PerDefTable<Lazy<[DefIndex]>>),
|
||||||
pub variances: Lazy!(PerDefTable<Lazy<[ty::Variance]>>),
|
pub variances: Lazy!(PerDefTable<Lazy<[ty::Variance]>>),
|
||||||
pub generics: Lazy!(PerDefTable<Lazy<ty::Generics>>),
|
pub generics: Lazy!(PerDefTable<Lazy<ty::Generics>>),
|
||||||
pub predicates: Lazy!(PerDefTable<Lazy!(ty::GenericPredicates<'tcx>)>),
|
pub predicates: Lazy!(PerDefTable<Lazy!(ty::GenericPredicates<'tcx>)>),
|
||||||
pub predicates_defined_on: Lazy!(PerDefTable<Lazy!(ty::GenericPredicates<'tcx>)>),
|
pub predicates_defined_on: Lazy!(PerDefTable<Lazy!(ty::GenericPredicates<'tcx>)>),
|
||||||
|
pub super_predicates: Lazy!(PerDefTable<Lazy!(ty::GenericPredicates<'tcx>)>),
|
||||||
|
|
||||||
pub mir: Lazy!(PerDefTable<Lazy!(mir::Body<'tcx>)>),
|
pub mir: Lazy!(PerDefTable<Lazy!(mir::Body<'tcx>)>),
|
||||||
pub promoted_mir: Lazy!(PerDefTable<Lazy!(IndexVec<mir::Promoted, mir::Body<'tcx>>)>),
|
pub promoted_mir: Lazy!(PerDefTable<Lazy!(IndexVec<mir::Promoted, mir::Body<'tcx>>)>),
|
||||||
@ -264,22 +267,22 @@ crate enum EntryKind<'tcx> {
|
|||||||
OpaqueTy,
|
OpaqueTy,
|
||||||
Enum(ReprOptions),
|
Enum(ReprOptions),
|
||||||
Field,
|
Field,
|
||||||
Variant(Lazy!(VariantData<'tcx>)),
|
Variant(Lazy<VariantData>),
|
||||||
Struct(Lazy!(VariantData<'tcx>), ReprOptions),
|
Struct(Lazy<VariantData>, ReprOptions),
|
||||||
Union(Lazy!(VariantData<'tcx>), ReprOptions),
|
Union(Lazy<VariantData>, ReprOptions),
|
||||||
Fn(Lazy!(FnData<'tcx>)),
|
Fn(Lazy<FnData>),
|
||||||
ForeignFn(Lazy!(FnData<'tcx>)),
|
ForeignFn(Lazy<FnData>),
|
||||||
Mod(Lazy<ModData>),
|
Mod(Lazy<ModData>),
|
||||||
MacroDef(Lazy<MacroDef>),
|
MacroDef(Lazy<MacroDef>),
|
||||||
Closure(Lazy!(ClosureData<'tcx>)),
|
Closure,
|
||||||
Generator(Lazy!(GeneratorData<'tcx>)),
|
Generator(Lazy!(GeneratorData<'tcx>)),
|
||||||
Trait(Lazy!(TraitData<'tcx>)),
|
Trait(Lazy<TraitData>),
|
||||||
Impl(Lazy!(ImplData<'tcx>)),
|
Impl(Lazy<ImplData>),
|
||||||
Method(Lazy!(MethodData<'tcx>)),
|
Method(Lazy<MethodData>),
|
||||||
AssocType(AssocContainer),
|
AssocType(AssocContainer),
|
||||||
AssocOpaqueTy(AssocContainer),
|
AssocOpaqueTy(AssocContainer),
|
||||||
AssocConst(AssocContainer, ConstQualif, Lazy<RenderedConst>),
|
AssocConst(AssocContainer, ConstQualif, Lazy<RenderedConst>),
|
||||||
TraitAlias(Lazy!(TraitAliasData<'tcx>)),
|
TraitAlias,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Additional data for EntryKind::Const and EntryKind::AssocConst
|
/// Additional data for EntryKind::Const and EntryKind::AssocConst
|
||||||
@ -305,47 +308,37 @@ crate struct MacroDef {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(RustcEncodable, RustcDecodable)]
|
#[derive(RustcEncodable, RustcDecodable)]
|
||||||
crate struct FnData<'tcx> {
|
crate struct FnData {
|
||||||
pub asyncness: hir::IsAsync,
|
pub asyncness: hir::IsAsync,
|
||||||
pub constness: hir::Constness,
|
pub constness: hir::Constness,
|
||||||
pub param_names: Lazy<[ast::Name]>,
|
pub param_names: Lazy<[ast::Name]>,
|
||||||
pub sig: Lazy!(ty::PolyFnSig<'tcx>),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(RustcEncodable, RustcDecodable)]
|
#[derive(RustcEncodable, RustcDecodable)]
|
||||||
crate struct VariantData<'tcx> {
|
crate struct VariantData {
|
||||||
pub ctor_kind: CtorKind,
|
pub ctor_kind: CtorKind,
|
||||||
pub discr: ty::VariantDiscr,
|
pub discr: ty::VariantDiscr,
|
||||||
/// If this is unit or tuple-variant/struct, then this is the index of the ctor id.
|
/// If this is unit or tuple-variant/struct, then this is the index of the ctor id.
|
||||||
pub ctor: Option<DefIndex>,
|
pub ctor: Option<DefIndex>,
|
||||||
/// If this is a tuple struct or variant
|
|
||||||
/// ctor, this is its "function" signature.
|
|
||||||
pub ctor_sig: Option<Lazy!(ty::PolyFnSig<'tcx>)>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(RustcEncodable, RustcDecodable)]
|
#[derive(RustcEncodable, RustcDecodable)]
|
||||||
crate struct TraitData<'tcx> {
|
crate struct TraitData {
|
||||||
pub unsafety: hir::Unsafety,
|
pub unsafety: hir::Unsafety,
|
||||||
pub paren_sugar: bool,
|
pub paren_sugar: bool,
|
||||||
pub has_auto_impl: bool,
|
pub has_auto_impl: bool,
|
||||||
pub is_marker: bool,
|
pub is_marker: bool,
|
||||||
pub super_predicates: Lazy!(ty::GenericPredicates<'tcx>),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(RustcEncodable, RustcDecodable)]
|
#[derive(RustcEncodable, RustcDecodable)]
|
||||||
crate struct TraitAliasData<'tcx> {
|
crate struct ImplData {
|
||||||
pub super_predicates: Lazy!(ty::GenericPredicates<'tcx>),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(RustcEncodable, RustcDecodable)]
|
|
||||||
crate struct ImplData<'tcx> {
|
|
||||||
pub polarity: ty::ImplPolarity,
|
pub polarity: ty::ImplPolarity,
|
||||||
pub defaultness: hir::Defaultness,
|
pub defaultness: hir::Defaultness,
|
||||||
pub parent_impl: Option<DefId>,
|
pub parent_impl: Option<DefId>,
|
||||||
|
|
||||||
/// This is `Some` only for impls of `CoerceUnsized`.
|
/// This is `Some` only for impls of `CoerceUnsized`.
|
||||||
|
// FIXME(eddyb) perhaps compute this on the fly if cheap enough?
|
||||||
pub coerce_unsized_info: Option<ty::adjustment::CoerceUnsizedInfo>,
|
pub coerce_unsized_info: Option<ty::adjustment::CoerceUnsizedInfo>,
|
||||||
pub trait_ref: Option<Lazy!(ty::TraitRef<'tcx>)>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -388,17 +381,12 @@ impl AssocContainer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(RustcEncodable, RustcDecodable)]
|
#[derive(RustcEncodable, RustcDecodable)]
|
||||||
crate struct MethodData<'tcx> {
|
crate struct MethodData {
|
||||||
pub fn_data: FnData<'tcx>,
|
pub fn_data: FnData,
|
||||||
pub container: AssocContainer,
|
pub container: AssocContainer,
|
||||||
pub has_self: bool,
|
pub has_self: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(RustcEncodable, RustcDecodable)]
|
|
||||||
crate struct ClosureData<'tcx> {
|
|
||||||
pub sig: Lazy!(ty::PolyFnSig<'tcx>),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(RustcEncodable, RustcDecodable)]
|
#[derive(RustcEncodable, RustcDecodable)]
|
||||||
crate struct GeneratorData<'tcx> {
|
crate struct GeneratorData<'tcx> {
|
||||||
pub layout: mir::GeneratorLayout<'tcx>,
|
pub layout: mir::GeneratorLayout<'tcx>,
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user