Merge branch 'master' into rusty-hermit, resolve conflicts

This commit is contained in:
Stefan Lankes 2019-10-25 09:09:55 +02:00
commit d349e32fc7
277 changed files with 3583 additions and 2737 deletions

View File

@ -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

View File

@ -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",

View File

@ -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,

View File

@ -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);

View File

@ -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() {

View File

@ -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
} }
} }

View File

@ -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() {

View File

@ -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

View File

@ -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)

View File

@ -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.

View File

@ -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

View File

@ -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).

View 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) |

View File

@ -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.

View File

@ -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.

View File

@ -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)]

View File

@ -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.

View File

@ -1638,7 +1638,7 @@ impl<T: ?Sized> Clone for Weak<T> {
} }
} }
return Weak { ptr: self.ptr }; Weak { ptr: self.ptr }
} }
} }

View File

@ -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);
} }
} }

View File

@ -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.

View File

@ -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;

View File

@ -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 {

View File

@ -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,
} }
} }
} }

View File

@ -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

View File

@ -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),
]); ]);

View File

@ -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
} }

View File

@ -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

View File

@ -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.

View File

@ -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),
}; };

View File

@ -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,
} }
}; };

View File

@ -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);
} }
} }

View File

@ -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()
} }
} }

View File

@ -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)
}
} }
} }
} }

View File

@ -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"),
}, },
} }

View File

@ -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

View File

@ -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),
} }
} }

View File

@ -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).

View File

@ -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,
} }

View File

@ -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! {

View File

@ -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);

View File

@ -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")

View File

@ -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())
} }

View File

@ -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;

View File

@ -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 {

View File

@ -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,
} }

View File

@ -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[..])
} }
} }

View File

@ -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" }
} }

View File

@ -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],

View File

@ -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())),

View File

@ -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");

View File

@ -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,

View File

@ -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]`

View File

@ -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();

View File

@ -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;

View File

@ -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),

View File

@ -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 {

View File

@ -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"),
} }
} }
} }

View File

@ -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)

View File

@ -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();
} }
} }

View File

@ -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 {

View File

@ -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
} }

View File

@ -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;

View File

@ -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>") }
} }
} }

View File

@ -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!

View File

@ -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),
} }
} }

View File

@ -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 });

View File

@ -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

View File

@ -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...

View File

@ -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);

View File

@ -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))
}); });

View File

@ -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))
}); });

View File

@ -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);

View File

@ -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
} }

View File

@ -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()
}; };
}); });

View File

@ -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
} }

View File

@ -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());

View File

@ -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

View File

@ -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>(

View File

@ -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)
} }

View File

@ -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(

View File

@ -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>>,

View File

@ -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" }

View File

@ -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);

View File

@ -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,

View File

@ -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,

View File

@ -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> {

View File

@ -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(|| {

View File

@ -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,

View File

@ -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))
}) })

View File

@ -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;

View File

@ -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!(

View File

@ -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,

View File

@ -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! {

View File

@ -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,

View File

@ -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);
} }

View File

@ -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>

View File

@ -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
} }

View File

@ -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);

View File

@ -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),
} }

View File

@ -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