mirror of
https://github.com/rust-lang/rust.git
synced 2025-05-14 02:49:40 +00:00
Merge branch 'master' into rusty-hermit, resolve conflicts
This commit is contained in:
commit
d349e32fc7
@ -128,6 +128,14 @@ the master branch to your feature branch.
|
||||
Also, please make sure that fixup commits are squashed into other related
|
||||
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
|
||||
guidelines by running
|
||||
|
||||
|
12
Cargo.lock
12
Cargo.lock
@ -556,9 +556,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "compiletest_rs"
|
||||
version = "0.3.24"
|
||||
version = "0.3.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "676a74b493d50ac33cacd83fd536597e6b52c0b46b9856f7b9c809d82fef4ac0"
|
||||
checksum = "f75b10a18fb53549fdd090846eb01c7f8593914494d1faabc4d3005c436e417a"
|
||||
dependencies = [
|
||||
"diff",
|
||||
"filetime",
|
||||
@ -1297,9 +1297,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.6.1"
|
||||
version = "0.6.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6587d09be37fb98a11cb08b9000a3f592451c1b1b613ca69d949160e313a430a"
|
||||
checksum = "3cd9867f119b19fecb08cd5c326ad4488d7a1da4bf75b4d95d71db742525aaab"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"compiler_builtins",
|
||||
@ -3494,6 +3494,7 @@ dependencies = [
|
||||
"rustc_data_structures",
|
||||
"rustc_errors",
|
||||
"rustc_interface",
|
||||
"rustc_lint",
|
||||
"rustc_metadata",
|
||||
"rustc_mir",
|
||||
"rustc_plugin",
|
||||
@ -4156,9 +4157,8 @@ dependencies = [
|
||||
"core",
|
||||
"dlmalloc",
|
||||
"fortanix-sgx-abi",
|
||||
"hashbrown 0.6.1",
|
||||
"hashbrown 0.6.2",
|
||||
"hermit-abi",
|
||||
"libc",
|
||||
"panic_abort",
|
||||
"panic_unwind",
|
||||
"profiler_builtins",
|
||||
|
@ -443,6 +443,7 @@ impl<'a> Builder<'a> {
|
||||
dist::Rustc,
|
||||
dist::DebuggerScripts,
|
||||
dist::Std,
|
||||
dist::RustcDev,
|
||||
dist::Analysis,
|
||||
dist::Src,
|
||||
dist::PlainSourceTarball,
|
||||
|
@ -55,6 +55,7 @@ impl Step for Std {
|
||||
cargo,
|
||||
args(builder.kind),
|
||||
&libstd_stamp(builder, compiler, target),
|
||||
vec![],
|
||||
true);
|
||||
|
||||
let libdir = builder.sysroot_libdir(compiler, target);
|
||||
@ -103,6 +104,7 @@ impl Step for Rustc {
|
||||
cargo,
|
||||
args(builder.kind),
|
||||
&librustc_stamp(builder, compiler, target),
|
||||
vec![],
|
||||
true);
|
||||
|
||||
let libdir = builder.sysroot_libdir(compiler, target);
|
||||
@ -155,6 +157,7 @@ impl Step for CodegenBackend {
|
||||
cargo,
|
||||
args(builder.kind),
|
||||
&codegen_backend_stamp(builder, compiler, target, backend),
|
||||
vec![],
|
||||
true);
|
||||
}
|
||||
}
|
||||
@ -199,6 +202,7 @@ impl Step for Rustdoc {
|
||||
cargo,
|
||||
args(builder.kind),
|
||||
&rustdoc_stamp(builder, compiler, target),
|
||||
vec![],
|
||||
true);
|
||||
|
||||
let libdir = builder.sysroot_libdir(compiler, target);
|
||||
|
@ -69,7 +69,7 @@ impl Step for Std {
|
||||
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);
|
||||
if compiler_to_use != compiler {
|
||||
@ -91,7 +91,7 @@ impl Step for Std {
|
||||
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");
|
||||
std_cargo(builder, &compiler, target, &mut cargo);
|
||||
@ -102,6 +102,7 @@ impl Step for Std {
|
||||
cargo,
|
||||
vec![],
|
||||
&libstd_stamp(builder, compiler, target),
|
||||
target_deps,
|
||||
false);
|
||||
|
||||
builder.ensure(StdLink {
|
||||
@ -113,9 +114,22 @@ impl Step for Std {
|
||||
}
|
||||
|
||||
/// 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 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
|
||||
//
|
||||
// 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
|
||||
// musl so we have them on linux-gnu hosts.
|
||||
if target.contains("musl") {
|
||||
let srcdir = builder.musl_root(target).unwrap().join("lib");
|
||||
for &obj in &["crt1.o", "crti.o", "crtn.o"] {
|
||||
builder.copy(
|
||||
&builder.musl_root(target).unwrap().join("lib").join(obj),
|
||||
&libdir.join(obj),
|
||||
);
|
||||
copy_and_stamp(&srcdir, obj);
|
||||
}
|
||||
} else if target.ends_with("-wasi") {
|
||||
for &obj in &["crt1.o"] {
|
||||
builder.copy(
|
||||
&builder.wasi_root(target).unwrap().join("lib/wasm32-wasi").join(obj),
|
||||
&libdir.join(obj),
|
||||
);
|
||||
}
|
||||
let srcdir = builder.wasi_root(target).unwrap().join("lib/wasm32-wasi");
|
||||
copy_and_stamp(&srcdir, "crt1.o");
|
||||
}
|
||||
|
||||
// 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.
|
||||
if target == "x86_64-fortanix-unknown-sgx" {
|
||||
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 = Path::new(&src).join(obj);
|
||||
builder.copy(&src, &libdir.join(obj));
|
||||
copy_and_stamp(Path::new(&src), "libunwind.a");
|
||||
}
|
||||
|
||||
target_deps
|
||||
}
|
||||
|
||||
/// Configure cargo to compile the standard library, adding appropriate env vars
|
||||
@ -306,7 +314,7 @@ pub struct StartupObjects {
|
||||
}
|
||||
|
||||
impl Step for StartupObjects {
|
||||
type Output = ();
|
||||
type Output = Vec<PathBuf>;
|
||||
|
||||
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
|
||||
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
|
||||
/// files, so we just use the nightly snapshot compiler to always build them (as
|
||||
/// 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 target = self.target;
|
||||
if !target.contains("windows-gnu") {
|
||||
return
|
||||
return vec![]
|
||||
}
|
||||
|
||||
let mut target_deps = vec![];
|
||||
|
||||
let src_dir = &builder.src.join("src/rtstartup");
|
||||
let dst_dir = &builder.native_dir(target).join("rtstartup");
|
||||
let sysroot_dir = &builder.sysroot_libdir(for_compiler, target);
|
||||
@ -350,7 +360,9 @@ impl Step for StartupObjects {
|
||||
.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() {
|
||||
@ -358,8 +370,12 @@ impl Step for StartupObjects {
|
||||
builder.cc(target),
|
||||
target,
|
||||
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,
|
||||
vec![],
|
||||
&librustc_stamp(builder, compiler, target),
|
||||
vec![],
|
||||
false);
|
||||
|
||||
builder.ensure(RustcLink {
|
||||
@ -585,7 +602,7 @@ impl Step for CodegenBackend {
|
||||
|
||||
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 {
|
||||
return;
|
||||
}
|
||||
@ -941,6 +958,7 @@ pub fn run_cargo(builder: &Builder<'_>,
|
||||
cargo: Cargo,
|
||||
tail_args: Vec<String>,
|
||||
stamp: &Path,
|
||||
additional_target_deps: Vec<PathBuf>,
|
||||
is_check: bool)
|
||||
-> Vec<PathBuf>
|
||||
{
|
||||
@ -1057,6 +1075,7 @@ pub fn run_cargo(builder: &Builder<'_>,
|
||||
deps.push((path_to_add.into(), false));
|
||||
}
|
||||
|
||||
deps.extend(additional_target_deps.into_iter().map(|d| (d, false)));
|
||||
deps.sort();
|
||||
let mut new_contents = Vec::new();
|
||||
for (dep, proc_macro) in deps.iter() {
|
||||
|
@ -637,6 +637,28 @@ impl Step for DebuggerScripts {
|
||||
}
|
||||
}
|
||||
|
||||
fn skip_host_target_lib(builder: &Builder<'_>, compiler: Compiler) -> bool {
|
||||
// The only true set of target libraries came from the build triple, so
|
||||
// let's reduce redundant work by only producing archives from that host.
|
||||
if compiler.host != builder.config.build {
|
||||
builder.info("\tskipping, not a build host");
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
/// Copy stamped files into an image's `target/lib` directory.
|
||||
fn copy_target_libs(builder: &Builder<'_>, target: &str, image: &Path, stamp: &Path) {
|
||||
let dst = image.join("lib/rustlib").join(target).join("lib");
|
||||
t!(fs::create_dir_all(&dst));
|
||||
for (path, host) in builder.read_stamp_file(stamp) {
|
||||
if !host || builder.config.build == target {
|
||||
builder.copy(&path, &dst.join(path.file_name().unwrap()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)]
|
||||
pub struct Std {
|
||||
pub compiler: Compiler,
|
||||
@ -667,44 +689,19 @@ impl Step for Std {
|
||||
let target = self.target;
|
||||
|
||||
let name = pkgname(builder, "rust-std");
|
||||
|
||||
// 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");
|
||||
return distdir(builder).join(format!("{}-{}.tar.gz", name, target));
|
||||
let archive = distdir(builder).join(format!("{}-{}.tar.gz", name, target));
|
||||
if skip_host_target_lib(builder, compiler) {
|
||||
return archive;
|
||||
}
|
||||
|
||||
// We want to package up as many target libraries as possible
|
||||
// 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 });
|
||||
}
|
||||
builder.ensure(compile::Std { compiler, target });
|
||||
|
||||
let image = tmpdir(builder).join(format!("{}-{}-image", name, target));
|
||||
let _ = fs::remove_dir_all(&image);
|
||||
|
||||
let dst = image.join("lib/rustlib").join(target);
|
||||
t!(fs::create_dir_all(&dst));
|
||||
let mut src = builder.sysroot_libdir(compiler, target).to_path_buf();
|
||||
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 compiler_to_use = builder.compiler_for(compiler.stage, compiler.host, target);
|
||||
let stamp = compile::libstd_stamp(builder, compiler_to_use, target);
|
||||
copy_target_libs(builder, &target, &image, &stamp);
|
||||
|
||||
let mut cmd = rust_installer(builder);
|
||||
cmd.arg("generate")
|
||||
@ -723,7 +720,73 @@ impl Step for Std {
|
||||
let _time = timeit(builder);
|
||||
builder.run(&mut cmd);
|
||||
builder.remove_dir(&image);
|
||||
distdir(builder).join(format!("{}-{}.tar.gz", name, target))
|
||||
archive
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)]
|
||||
pub struct RustcDev {
|
||||
pub compiler: Compiler,
|
||||
pub target: Interned<String>,
|
||||
}
|
||||
|
||||
impl Step for RustcDev {
|
||||
type Output = PathBuf;
|
||||
const DEFAULT: bool = true;
|
||||
const ONLY_HOSTS: bool = true;
|
||||
|
||||
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
|
||||
run.path("rustc-dev")
|
||||
}
|
||||
|
||||
fn make_run(run: RunConfig<'_>) {
|
||||
run.builder.ensure(RustcDev {
|
||||
compiler: run.builder.compiler_for(
|
||||
run.builder.top_stage,
|
||||
run.builder.config.build,
|
||||
run.target,
|
||||
),
|
||||
target: run.target,
|
||||
});
|
||||
}
|
||||
|
||||
fn run(self, builder: &Builder<'_>) -> PathBuf {
|
||||
let compiler = self.compiler;
|
||||
let target = self.target;
|
||||
|
||||
let name = pkgname(builder, "rustc-dev");
|
||||
let archive = distdir(builder).join(format!("{}-{}.tar.gz", name, target));
|
||||
if skip_host_target_lib(builder, compiler) {
|
||||
return archive;
|
||||
}
|
||||
|
||||
builder.ensure(compile::Rustc { compiler, target });
|
||||
|
||||
let image = tmpdir(builder).join(format!("{}-{}-image", name, target));
|
||||
let _ = fs::remove_dir_all(&image);
|
||||
|
||||
let compiler_to_use = builder.compiler_for(compiler.stage, compiler.host, target);
|
||||
let stamp = compile::librustc_stamp(builder, compiler_to_use, target);
|
||||
copy_target_libs(builder, &target, &image, &stamp);
|
||||
|
||||
let mut cmd = rust_installer(builder);
|
||||
cmd.arg("generate")
|
||||
.arg("--product-name=Rust")
|
||||
.arg("--rel-manifest-dir=rustlib")
|
||||
.arg("--success-message=Rust-is-ready-to-develop.")
|
||||
.arg("--image-dir").arg(&image)
|
||||
.arg("--work-dir").arg(&tmpdir(builder))
|
||||
.arg("--output-dir").arg(&distdir(builder))
|
||||
.arg(format!("--package-name={}-{}", name, target))
|
||||
.arg(format!("--component-name=rustc-dev-{}", target))
|
||||
.arg("--legacy-manifest-dirs=rustlib,cargo");
|
||||
|
||||
builder.info(&format!("Dist rustc-dev stage{} ({} -> {})",
|
||||
compiler.stage, &compiler.host, target));
|
||||
let _time = timeit(builder);
|
||||
builder.run(&mut cmd);
|
||||
builder.remove_dir(&image);
|
||||
archive
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1137,6 +1137,7 @@ impl Build {
|
||||
pub fn copy(&self, src: &Path, dst: &Path) {
|
||||
if self.config.dry_run { return; }
|
||||
self.verbose_than(1, &format!("Copy {:?} to {:?}", src, dst));
|
||||
if src == dst { return; }
|
||||
let _ = fs::remove_file(&dst);
|
||||
let metadata = t!(src.symlink_metadata());
|
||||
if metadata.file_type().is_symlink() {
|
||||
|
@ -84,6 +84,17 @@ steps:
|
||||
condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'), ne(variables['MINGW_URL'],''))
|
||||
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`
|
||||
- bash: |
|
||||
set -e
|
||||
@ -96,6 +107,18 @@ steps:
|
||||
condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'), eq(variables['MINGW_URL'],''))
|
||||
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
|
||||
# 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
|
||||
|
@ -14,6 +14,7 @@
|
||||
- [Targets](targets/index.md)
|
||||
- [Built-in Targets](targets/built-in.md)
|
||||
- [Custom Targets](targets/custom.md)
|
||||
- [Known Issues](targets/known-issues.md)
|
||||
- [Profile-guided Optimization](profile-guided-optimization.md)
|
||||
- [Linker-plugin based LTO](linker-plugin-lto.md)
|
||||
- [Contributing to `rustc`](contributing.md)
|
||||
|
@ -61,6 +61,8 @@ enabling or disabling a feature.
|
||||
To see the valid options and an example of use, run `rustc --print
|
||||
target-features`.
|
||||
|
||||
Using this flag is unsafe and might result in [undefined runtime behavior](../targets/known-issues.md).
|
||||
|
||||
## passes
|
||||
|
||||
This flag can be used to add extra LLVM passes to the compilation.
|
||||
|
@ -145,7 +145,7 @@ of print values are:
|
||||
target CPU may be selected with the `-C target-cpu=val` flag.
|
||||
- `target-features` — List of available target features for the current
|
||||
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
|
||||
selected with the `-C relocation-model=val` flag.
|
||||
- `code-models` — List of code models. Code models may be selected with the
|
||||
|
@ -11,3 +11,9 @@ To compile to a particular target, use the `--target` flag:
|
||||
```bash
|
||||
$ rustc src/main.rs --target=wasm32-unknown-unknown
|
||||
```
|
||||
## Target Features
|
||||
`x86`, and `ARMv8` are two popular CPU architectures. Their instruction sets form a common baseline across most CPUs. However, some CPUs extend these with custom instruction sets, e.g. vector (`AVX`), bitwise manipulation (`BMI`) or cryptographic (`AES`).
|
||||
|
||||
Developers, who know on which CPUs their compiled code is going to run can choose to add (or remove) CPU specific instruction sets via the `-C target-feature=val` flag.
|
||||
|
||||
Please note, that this flag is generally considered as unsafe. More details can be found in [this section](known-issues.md).
|
||||
|
13
src/doc/rustc/src/targets/known-issues.md
Normal file
13
src/doc/rustc/src/targets/known-issues.md
Normal file
@ -0,0 +1,13 @@
|
||||
# Known Issues
|
||||
This section informs you about known "gotchas". Keep in mind, that this section is (and always will be) incomplete. For suggestions and amendments, feel free to [contribute](../contributing.md) to this guide.
|
||||
|
||||
## Target Features
|
||||
Most target-feature problems arise, when mixing code that have the target-feature _enabled_ with code that have it _disabled_. If you want to avoid undefined behavior, it is recommended to build _all code_ (including the standard library and imported crates) with a common set of target-features.
|
||||
|
||||
By default, compiling your code with the `-C target-feature` flag will not recompile the entire standard library and/or imported crates with matching target features. Therefore, target features are generally considered as unsafe. Using `#[target_feature]` on individual functions makes the function unsafe.
|
||||
|
||||
Examples:
|
||||
|
||||
| Target-Feature | Issue | Seen on | Description | Details |
|
||||
| -------------- | ----- | ------- | ----------- | ------- |
|
||||
| `+soft-float` <br> and <br> `-sse` | Segfaults and ABI mismatches | `x86` and `x86-64` | The `x86` and `x86_64` architecture uses SSE registers (aka `xmm`) for floating point operations. Using software emulated floats ("soft-floats") disables usage of `xmm` registers, but parts of Rust's core libraries (e.g. `std::f32` or `std::f64`) are compiled without soft-floats and expect parameters to be passed in `xmm` registers. This leads to ABI mismatches. <br><br> Attempting to compile with disabled SSE causes the same error, too. | [#63466](https://github.com/rust-lang/rust/issues/63466) |
|
@ -207,6 +207,47 @@ impl<B: ?Sized + ToOwned> Clone for Cow<'_, B> {
|
||||
}
|
||||
|
||||
impl<B: ?Sized + ToOwned> Cow<'_, B> {
|
||||
/// 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.
|
||||
///
|
||||
/// Clones the data if it is not already owned.
|
||||
|
@ -1817,7 +1817,7 @@ impl<T> VecDeque<T> {
|
||||
}
|
||||
}
|
||||
|
||||
return elem;
|
||||
elem
|
||||
}
|
||||
|
||||
/// Splits the `VecDeque` into two at the given index.
|
||||
|
@ -85,6 +85,7 @@
|
||||
#![feature(const_generic_impls_guard)]
|
||||
#![feature(const_generics)]
|
||||
#![feature(const_in_array_repeat_expressions)]
|
||||
#![feature(cow_is_borrowed)]
|
||||
#![feature(dispatch_from_dyn)]
|
||||
#![feature(core_intrinsics)]
|
||||
#![feature(container_error_extra)]
|
||||
|
@ -456,7 +456,7 @@ impl str {
|
||||
}
|
||||
}
|
||||
}
|
||||
return s;
|
||||
s
|
||||
}
|
||||
|
||||
/// Converts a [`Box<str>`] into a [`String`] without copying or allocating.
|
||||
|
@ -1638,7 +1638,7 @@ impl<T: ?Sized> Clone for Weak<T> {
|
||||
}
|
||||
}
|
||||
|
||||
return Weak { ptr: self.ptr };
|
||||
Weak { ptr: self.ptr }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2025,7 +2025,7 @@ impl<T: ?Sized> Pointer for *const T {
|
||||
if f.alternate() {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -238,6 +238,33 @@ macro_rules! debug_assert_ne {
|
||||
($($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.
|
||||
///
|
||||
/// The `?` operator was added to replace `try!` and should be used instead.
|
||||
|
@ -143,13 +143,12 @@ pub fn fast_path<T: RawFloat>(integral: &[u8], fractional: &[u8], e: i64) -> Opt
|
||||
/// > not a bound for the true error, but bounds the difference between the approximation z and
|
||||
/// > the best possible approximation that uses p bits of significand.)
|
||||
pub fn bellerophon<T: RawFloat>(f: &Big, e: i16) -> T {
|
||||
let slop;
|
||||
if f <= &Big::from_u64(T::MAX_SIG) {
|
||||
let slop = if f <= &Big::from_u64(T::MAX_SIG) {
|
||||
// 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 {
|
||||
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 exp_p_n = 1 << (P - T::SIG_BITS as u32);
|
||||
let lowbits: i64 = (z.f % exp_p_n) as i64;
|
||||
|
@ -837,9 +837,8 @@ impl<T> Option<T> {
|
||||
#[inline]
|
||||
#[stable(feature = "option_entry", since = "1.20.0")]
|
||||
pub fn get_or_insert_with<F: FnOnce() -> T>(&mut self, f: F) -> &mut T {
|
||||
match *self {
|
||||
None => *self = Some(f()),
|
||||
_ => (),
|
||||
if let None = *self {
|
||||
*self = Some(f());
|
||||
}
|
||||
|
||||
match *self {
|
||||
|
@ -156,21 +156,21 @@ unsafe extern "C" fn rust_eh_personality(version: c_int,
|
||||
if actions as i32 & uw::_UA_SEARCH_PHASE as i32 != 0 {
|
||||
match eh_action {
|
||||
EHAction::None |
|
||||
EHAction::Cleanup(_) => return uw::_URC_CONTINUE_UNWIND,
|
||||
EHAction::Catch(_) => return uw::_URC_HANDLER_FOUND,
|
||||
EHAction::Terminate => return uw::_URC_FATAL_PHASE1_ERROR,
|
||||
EHAction::Cleanup(_) => uw::_URC_CONTINUE_UNWIND,
|
||||
EHAction::Catch(_) => uw::_URC_HANDLER_FOUND,
|
||||
EHAction::Terminate => uw::_URC_FATAL_PHASE1_ERROR,
|
||||
}
|
||||
} else {
|
||||
match eh_action {
|
||||
EHAction::None => return uw::_URC_CONTINUE_UNWIND,
|
||||
EHAction::None => uw::_URC_CONTINUE_UNWIND,
|
||||
EHAction::Cleanup(lpad) |
|
||||
EHAction::Catch(lpad) => {
|
||||
uw::_Unwind_SetGR(context, UNWIND_DATA_REG.0, exception_object as uintptr_t);
|
||||
uw::_Unwind_SetGR(context, UNWIND_DATA_REG.1, 0);
|
||||
uw::_Unwind_SetIP(context, lpad);
|
||||
return uw::_URC_INSTALL_CONTEXT;
|
||||
uw::_URC_INSTALL_CONTEXT
|
||||
}
|
||||
EHAction::Terminate => return uw::_URC_FATAL_PHASE2_ERROR,
|
||||
EHAction::Terminate => uw::_URC_FATAL_PHASE2_ERROR,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ pub fn payload() -> *mut u8 {
|
||||
|
||||
pub unsafe fn cleanup(ptr: *mut u8) -> Box<dyn Any + Send> {
|
||||
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
|
||||
|
@ -59,7 +59,7 @@ use crate::ich::{Fingerprint, StableHashingContext};
|
||||
use rustc_data_structures::stable_hasher::{StableHasher, HashStable};
|
||||
use std::fmt;
|
||||
use std::hash::Hash;
|
||||
use syntax_pos::symbol::InternedString;
|
||||
use syntax_pos::symbol::Symbol;
|
||||
use crate::traits;
|
||||
use crate::traits::query::{
|
||||
CanonicalProjectionGoal, CanonicalTyGoal, CanonicalTypeOpAscribeUserTypeGoal,
|
||||
@ -426,7 +426,7 @@ rustc_dep_node_append!([define_dep_nodes!][ <'tcx>
|
||||
|
||||
[anon] TraitSelect,
|
||||
|
||||
[] CompileCodegenUnit(InternedString),
|
||||
[] CompileCodegenUnit(Symbol),
|
||||
|
||||
[eval_always] Analysis(CrateNum),
|
||||
]);
|
||||
|
@ -2045,8 +2045,8 @@ so that a generator can then be constructed:
|
||||
async fn bar<T>() -> () {}
|
||||
|
||||
async fn foo() {
|
||||
bar::<String>().await;
|
||||
// ^^^^^^^^ specify type explicitly
|
||||
bar::<String>().await;
|
||||
// ^^^^^^^^ 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##"
|
||||
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
|
||||
E0726, // non-explicit (not `'_`) elided lifetime in unsupported position
|
||||
E0727, // `async` generators are not yet supported
|
||||
E0728, // `await` must be in an `async` function or block
|
||||
E0739, // invalid track_caller application/syntax
|
||||
}
|
||||
|
@ -83,8 +83,6 @@ pub struct LoweringContext<'a> {
|
||||
/// Used to assign IDs to HIR nodes that do not directly correspond to AST nodes.
|
||||
sess: &'a Session,
|
||||
|
||||
cstore: &'a dyn CrateStore,
|
||||
|
||||
resolver: &'a mut dyn Resolver,
|
||||
|
||||
/// HACK(Centril): there is a cyclic dependency between the parser and lowering
|
||||
@ -160,6 +158,8 @@ pub struct LoweringContext<'a> {
|
||||
}
|
||||
|
||||
pub trait Resolver {
|
||||
fn cstore(&self) -> &dyn CrateStore;
|
||||
|
||||
/// Obtains resolution for a `NodeId` with a single resolution.
|
||||
fn get_partial_res(&mut self, id: NodeId) -> Option<PartialRes>;
|
||||
|
||||
@ -240,7 +240,6 @@ impl<'a> ImplTraitContext<'a> {
|
||||
|
||||
pub fn lower_crate(
|
||||
sess: &Session,
|
||||
cstore: &dyn CrateStore,
|
||||
dep_graph: &DepGraph,
|
||||
krate: &Crate,
|
||||
resolver: &mut dyn Resolver,
|
||||
@ -256,7 +255,6 @@ pub fn lower_crate(
|
||||
LoweringContext {
|
||||
crate_root: sess.parse_sess.injected_crate_name.try_get().copied(),
|
||||
sess,
|
||||
cstore,
|
||||
resolver,
|
||||
nt_to_tokenstream,
|
||||
items: BTreeMap::new(),
|
||||
@ -792,15 +790,15 @@ impl<'a> LoweringContext<'a> {
|
||||
// really show up for end-user.
|
||||
let (str_name, kind) = match hir_name {
|
||||
ParamName::Plain(ident) => (
|
||||
ident.as_interned_str(),
|
||||
ident.name,
|
||||
hir::LifetimeParamKind::InBand,
|
||||
),
|
||||
ParamName::Fresh(_) => (
|
||||
kw::UnderscoreLifetime.as_interned_str(),
|
||||
kw::UnderscoreLifetime,
|
||||
hir::LifetimeParamKind::Elided,
|
||||
),
|
||||
ParamName::Error => (
|
||||
kw::UnderscoreLifetime.as_interned_str(),
|
||||
kw::UnderscoreLifetime,
|
||||
hir::LifetimeParamKind::Error,
|
||||
),
|
||||
};
|
||||
@ -980,7 +978,7 @@ impl<'a> LoweringContext<'a> {
|
||||
if id.is_local() {
|
||||
self.resolver.definitions().def_key(id.index)
|
||||
} 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.parent,
|
||||
def_node_id,
|
||||
DefPathData::LifetimeNs(name.ident().as_interned_str()),
|
||||
DefPathData::LifetimeNs(name.ident().name),
|
||||
ExpnId::root(),
|
||||
lifetime.span);
|
||||
|
||||
@ -1727,8 +1725,8 @@ impl<'a> LoweringContext<'a> {
|
||||
return n;
|
||||
}
|
||||
assert!(!def_id.is_local());
|
||||
let item_generics =
|
||||
self.cstore.item_generics_cloned_untracked(def_id, self.sess);
|
||||
let item_generics = self.resolver.cstore()
|
||||
.item_generics_cloned_untracked(def_id, self.sess);
|
||||
let n = item_generics.own_counts().lifetimes;
|
||||
self.type_def_lifetime_params.insert(def_id, n);
|
||||
n
|
||||
|
@ -186,13 +186,13 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
|
||||
});
|
||||
|
||||
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 hash = cstore.crate_hash_untracked(cnum);
|
||||
(name, disambiguator, hash)
|
||||
}).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
|
||||
// don't have to include the path prefix remapping commandline args.
|
||||
|
@ -57,7 +57,7 @@ impl<'a> DefCollector<'a> {
|
||||
|
||||
// For async functions, we need to create their inner defs inside of a
|
||||
// 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);
|
||||
return self.with_parent(fn_def, |this| {
|
||||
this.create_def(return_impl_trait_id, DefPathData::ImplTrait, span);
|
||||
@ -83,8 +83,7 @@ impl<'a> DefCollector<'a> {
|
||||
.unwrap_or_else(|| {
|
||||
let node_id = NodeId::placeholder_from_expn_id(self.expansion);
|
||||
sym::integer(self.definitions.placeholder_field_indices[&node_id])
|
||||
})
|
||||
.as_interned_str();
|
||||
});
|
||||
let def = self.create_def(field.id, DefPathData::ValueNs(name), field.span);
|
||||
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::Enum(..) | ItemKind::Struct(..) | ItemKind::Union(..) |
|
||||
ItemKind::OpaqueTy(..) | ItemKind::ExternCrate(..) | ItemKind::ForeignMod(..) |
|
||||
ItemKind::TyAlias(..) => DefPathData::TypeNs(i.ident.as_interned_str()),
|
||||
ItemKind::TyAlias(..) => DefPathData::TypeNs(i.ident.name),
|
||||
ItemKind::Fn(
|
||||
ref decl,
|
||||
ref header,
|
||||
@ -127,8 +126,8 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
|
||||
)
|
||||
}
|
||||
ItemKind::Static(..) | ItemKind::Const(..) | ItemKind::Fn(..) =>
|
||||
DefPathData::ValueNs(i.ident.as_interned_str()),
|
||||
ItemKind::MacroDef(..) => DefPathData::MacroNs(i.ident.as_interned_str()),
|
||||
DefPathData::ValueNs(i.ident.name),
|
||||
ItemKind::MacroDef(..) => DefPathData::MacroNs(i.ident.name),
|
||||
ItemKind::Mac(..) => return self.visit_macro_invoc(i.id),
|
||||
ItemKind::GlobalAsm(..) => DefPathData::Misc,
|
||||
ItemKind::Use(..) => {
|
||||
@ -162,7 +161,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
self.with_parent(def, |this| {
|
||||
@ -175,7 +174,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
|
||||
return self.visit_macro_invoc(v.id);
|
||||
}
|
||||
let def = self.create_def(v.id,
|
||||
DefPathData::TypeNs(v.ident.as_interned_str()),
|
||||
DefPathData::TypeNs(v.ident.name),
|
||||
v.span);
|
||||
self.with_parent(def, |this| {
|
||||
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);
|
||||
return;
|
||||
}
|
||||
let name = param.ident.as_interned_str();
|
||||
let name = param.ident.name;
|
||||
let def_path_data = match param.kind {
|
||||
GenericParamKind::Lifetime { .. } => DefPathData::LifetimeNs(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) {
|
||||
let def_data = match ti.kind {
|
||||
TraitItemKind::Method(..) | TraitItemKind::Const(..) =>
|
||||
DefPathData::ValueNs(ti.ident.as_interned_str()),
|
||||
DefPathData::ValueNs(ti.ident.name),
|
||||
TraitItemKind::Type(..) => {
|
||||
DefPathData::TypeNs(ti.ident.as_interned_str())
|
||||
DefPathData::TypeNs(ti.ident.name)
|
||||
},
|
||||
TraitItemKind::Macro(..) => return self.visit_macro_invoc(ti.id),
|
||||
};
|
||||
@ -243,12 +242,10 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
|
||||
body,
|
||||
)
|
||||
}
|
||||
ImplItemKind::Method(..) | ImplItemKind::Const(..) =>
|
||||
DefPathData::ValueNs(ii.ident.as_interned_str()),
|
||||
ImplItemKind::Method(..) |
|
||||
ImplItemKind::Const(..) => DefPathData::ValueNs(ii.ident.name),
|
||||
ImplItemKind::TyAlias(..) |
|
||||
ImplItemKind::OpaqueTy(..) => {
|
||||
DefPathData::TypeNs(ii.ident.as_interned_str())
|
||||
},
|
||||
ImplItemKind::OpaqueTy(..) => DefPathData::TypeNs(ii.ident.name),
|
||||
ImplItemKind::Macro(..) => return self.visit_macro_invoc(ii.id),
|
||||
};
|
||||
|
||||
|
@ -18,7 +18,7 @@ use std::fmt::Write;
|
||||
use std::hash::Hash;
|
||||
use syntax::ast;
|
||||
use syntax_expand::hygiene::ExpnId;
|
||||
use syntax::symbol::{Symbol, sym, InternedString};
|
||||
use syntax::symbol::{Symbol, sym};
|
||||
use syntax_pos::{Span, DUMMY_SP};
|
||||
|
||||
/// The `DefPathTable` maps `DefIndex`es to `DefKey`s and vice versa.
|
||||
@ -136,7 +136,9 @@ impl DefKey {
|
||||
|
||||
::std::mem::discriminant(data).hash(&mut hasher);
|
||||
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);
|
||||
@ -218,7 +220,7 @@ impl DefPath {
|
||||
for component in &self.data {
|
||||
write!(s,
|
||||
"::{}[{}]",
|
||||
component.data.as_interned_str(),
|
||||
component.data.as_symbol(),
|
||||
component.disambiguator)
|
||||
.unwrap();
|
||||
}
|
||||
@ -238,11 +240,11 @@ impl DefPath {
|
||||
|
||||
for component in &self.data {
|
||||
if component.disambiguator == 0 {
|
||||
write!(s, "::{}", component.data.as_interned_str()).unwrap();
|
||||
write!(s, "::{}", component.data.as_symbol()).unwrap();
|
||||
} else {
|
||||
write!(s,
|
||||
"{}[{}]",
|
||||
component.data.as_interned_str(),
|
||||
component.data.as_symbol(),
|
||||
component.disambiguator)
|
||||
.unwrap();
|
||||
}
|
||||
@ -262,11 +264,11 @@ impl DefPath {
|
||||
opt_delimiter.map(|d| s.push(d));
|
||||
opt_delimiter = Some('-');
|
||||
if component.disambiguator == 0 {
|
||||
write!(s, "{}", component.data.as_interned_str()).unwrap();
|
||||
write!(s, "{}", component.data.as_symbol()).unwrap();
|
||||
} else {
|
||||
write!(s,
|
||||
"{}[{}]",
|
||||
component.data.as_interned_str(),
|
||||
component.data.as_symbol(),
|
||||
component.disambiguator)
|
||||
.unwrap();
|
||||
}
|
||||
@ -290,13 +292,13 @@ pub enum DefPathData {
|
||||
/// An impl.
|
||||
Impl,
|
||||
/// Something in the type namespace.
|
||||
TypeNs(InternedString),
|
||||
TypeNs(Symbol),
|
||||
/// Something in the value namespace.
|
||||
ValueNs(InternedString),
|
||||
ValueNs(Symbol),
|
||||
/// Something in the macro namespace.
|
||||
MacroNs(InternedString),
|
||||
MacroNs(Symbol),
|
||||
/// Something in the lifetime namespace.
|
||||
LifetimeNs(InternedString),
|
||||
LifetimeNs(Symbol),
|
||||
/// A closure expression.
|
||||
ClosureExpr,
|
||||
|
||||
@ -311,7 +313,7 @@ pub enum DefPathData {
|
||||
/// Identifies a piece of crate metadata that is global to a whole crate
|
||||
/// (as opposed to just one item). `GlobalMetaData` components are only
|
||||
/// supposed to show up right below the crate root.
|
||||
GlobalMetaData(InternedString),
|
||||
GlobalMetaData(Symbol),
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord, Debug,
|
||||
@ -545,7 +547,7 @@ impl Definitions {
|
||||
}
|
||||
|
||||
impl DefPathData {
|
||||
pub fn get_opt_name(&self) -> Option<InternedString> {
|
||||
pub fn get_opt_name(&self) -> Option<Symbol> {
|
||||
use self::DefPathData::*;
|
||||
match *self {
|
||||
TypeNs(name) |
|
||||
@ -564,15 +566,15 @@ impl DefPathData {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_interned_str(&self) -> InternedString {
|
||||
pub fn as_symbol(&self) -> Symbol {
|
||||
use self::DefPathData::*;
|
||||
let s = match *self {
|
||||
match *self {
|
||||
TypeNs(name) |
|
||||
ValueNs(name) |
|
||||
MacroNs(name) |
|
||||
LifetimeNs(name) |
|
||||
GlobalMetaData(name) => {
|
||||
return name
|
||||
name
|
||||
}
|
||||
// Note that this does not show up in user print-outs.
|
||||
CrateRoot => sym::double_braced_crate,
|
||||
@ -582,13 +584,11 @@ impl DefPathData {
|
||||
Ctor => sym::double_braced_constructor,
|
||||
AnonConst => sym::double_braced_constant,
|
||||
ImplTrait => sym::double_braced_opaque,
|
||||
};
|
||||
|
||||
s.as_interned_str()
|
||||
}
|
||||
}
|
||||
|
||||
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(
|
||||
CRATE_DEF_INDEX,
|
||||
ast::DUMMY_NODE_ID,
|
||||
DefPathData::GlobalMetaData(instance.name().as_interned_str()),
|
||||
DefPathData::GlobalMetaData(instance.name()),
|
||||
ExpnId::root(),
|
||||
DUMMY_SP
|
||||
);
|
||||
@ -624,7 +624,7 @@ macro_rules! define_global_metadata_kind {
|
||||
let def_key = DefKey {
|
||||
parent: Some(CRATE_DEF_INDEX),
|
||||
disambiguated_data: DisambiguatedDefPathData {
|
||||
data: DefPathData::GlobalMetaData(self.name().as_interned_str()),
|
||||
data: DefPathData::GlobalMetaData(self.name()),
|
||||
disambiguator: 0,
|
||||
}
|
||||
};
|
||||
|
@ -19,7 +19,7 @@ use crate::ty::query::Providers;
|
||||
use crate::util::nodemap::{NodeMap, FxHashSet};
|
||||
|
||||
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::ast::{self, CrateSugar, Ident, Name, NodeId, AsmDialect};
|
||||
use syntax::ast::{Attribute, Label, LitKind, StrStyle, FloatTy, IntTy, UintTy};
|
||||
@ -628,9 +628,9 @@ impl Generics {
|
||||
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 {
|
||||
if name == param.name.ident().as_interned_str() {
|
||||
if name == param.name.ident().name {
|
||||
return Some(param);
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ use std::mem;
|
||||
use syntax::ast;
|
||||
use syntax::feature_gate;
|
||||
use syntax::parse::token;
|
||||
use syntax::symbol::InternedString;
|
||||
use syntax::symbol::LocalInternedString;
|
||||
use syntax::tokenstream;
|
||||
use syntax_pos::SourceFile;
|
||||
|
||||
@ -18,20 +18,21 @@ use crate::hir::def_id::{DefId, CrateNum, CRATE_DEF_INDEX};
|
||||
use smallvec::SmallVec;
|
||||
use rustc_data_structures::stable_hasher::{HashStable, ToStableHashKey, StableHasher};
|
||||
|
||||
impl<'a> HashStable<StableHashingContext<'a>> for InternedString {
|
||||
impl<'a> HashStable<StableHashingContext<'a>> for LocalInternedString {
|
||||
#[inline]
|
||||
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 {
|
||||
type KeyType = InternedString;
|
||||
impl<'a> ToStableHashKey<StableHashingContext<'a>> for LocalInternedString {
|
||||
type KeyType = LocalInternedString;
|
||||
|
||||
#[inline]
|
||||
fn to_stable_hash_key(&self,
|
||||
_: &StableHashingContext<'a>)
|
||||
-> InternedString {
|
||||
-> LocalInternedString {
|
||||
self.clone()
|
||||
}
|
||||
}
|
||||
@ -44,13 +45,13 @@ impl<'a> HashStable<StableHashingContext<'a>> for ast::Name {
|
||||
}
|
||||
|
||||
impl<'a> ToStableHashKey<StableHashingContext<'a>> for ast::Name {
|
||||
type KeyType = InternedString;
|
||||
type KeyType = LocalInternedString;
|
||||
|
||||
#[inline]
|
||||
fn to_stable_hash_key(&self,
|
||||
_: &StableHashingContext<'a>)
|
||||
-> InternedString {
|
||||
self.as_interned_str()
|
||||
-> LocalInternedString {
|
||||
self.as_str()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -494,7 +494,7 @@ impl TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
|
||||
if sub_vid == self.for_vid_sub_root {
|
||||
// If sub-roots are equal, then `for_vid` and
|
||||
// `vid` are related via subtyping.
|
||||
return Err(TypeError::CyclicTy(self.root_ty));
|
||||
Err(TypeError::CyclicTy(self.root_ty))
|
||||
} else {
|
||||
match variables.probe(vid) {
|
||||
TypeVariableValue::Known { value: u } => {
|
||||
@ -527,7 +527,7 @@ impl TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
|
||||
let u = self.tcx().mk_ty_var(new_var_id);
|
||||
debug!("generalize: replacing original vid={:?} with new={:?}",
|
||||
vid, u);
|
||||
return Ok(u);
|
||||
Ok(u)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -602,19 +602,26 @@ impl TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
|
||||
) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
|
||||
assert_eq!(c, c2); // we are abusing TypeRelation here; both LHS and RHS ought to be ==
|
||||
|
||||
match c {
|
||||
ty::Const { val: ConstValue::Infer(InferConst::Var(vid)), .. } => {
|
||||
match c.val {
|
||||
ConstValue::Infer(InferConst::Var(vid)) => {
|
||||
let mut variable_table = self.infcx.const_unification_table.borrow_mut();
|
||||
match variable_table.probe_value(*vid).val.known() {
|
||||
Some(u) => {
|
||||
self.relate(&u, &u)
|
||||
let var_value = variable_table.probe_value(vid);
|
||||
match var_value.val {
|
||||
ConstVariableValue::Known { value: u } => self.relate(&u, &u),
|
||||
ConstVariableValue::Unknown { universe } => {
|
||||
if self.for_universe.can_name(universe) {
|
||||
Ok(c)
|
||||
} else {
|
||||
let new_var_id = variable_table.new_key(ConstVarValue {
|
||||
origin: var_value.origin,
|
||||
val: ConstVariableValue::Unknown { universe: self.for_universe },
|
||||
});
|
||||
Ok(self.tcx().mk_const_var(new_var_id, c.ty))
|
||||
}
|
||||
}
|
||||
None => Ok(c),
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
relate::super_relate_consts(self, c, c)
|
||||
}
|
||||
_ => relate::super_relate_consts(self, c, c),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -542,7 +542,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
disambiguated_data: &DisambiguatedDefPathData,
|
||||
) -> Result<Self::Path, Self::Error> {
|
||||
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)
|
||||
}
|
||||
fn path_generic_args(
|
||||
@ -1146,10 +1146,17 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
|
||||
let span = cause.span(self.tcx);
|
||||
|
||||
diag.span_label(span, terr.to_string());
|
||||
if let Some((sp, msg)) = secondary_span {
|
||||
diag.span_label(sp, msg);
|
||||
}
|
||||
// Ignore msg for object safe coercion
|
||||
// since E0038 message will be printed
|
||||
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 {
|
||||
match (terr, is_simple_error, expected == found) {
|
||||
@ -1169,6 +1176,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
&sort_string(values.found),
|
||||
);
|
||||
}
|
||||
(TypeError::ObjectUnsafeCoercion(_), ..) => {
|
||||
diag.note_unsuccessfull_coercion(found, expected);
|
||||
}
|
||||
(_, false, _) => {
|
||||
if let Some(exp_found) = exp_found {
|
||||
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 failure_code = trace.cause.as_failure_code(terr);
|
||||
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) => {
|
||||
struct_span_err!(self.tcx.sess, span, E0317, "{}", failure_str)
|
||||
}
|
||||
@ -1628,6 +1642,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
}
|
||||
|
||||
enum FailureCode {
|
||||
Error0038(DefId),
|
||||
Error0317(&'static str),
|
||||
Error0580(&'static str),
|
||||
Error0308(&'static str),
|
||||
@ -1666,6 +1681,7 @@ impl<'tcx> ObligationCause<'tcx> {
|
||||
TypeError::IntrinsicCast => {
|
||||
Error0308("cannot coerce intrinsics to function pointers")
|
||||
}
|
||||
TypeError::ObjectUnsafeCoercion(did) => Error0038(did.clone()),
|
||||
_ => Error0308("mismatched types"),
|
||||
},
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ use std::cell::{Cell, Ref, RefCell, RefMut};
|
||||
use std::collections::BTreeMap;
|
||||
use std::fmt;
|
||||
use syntax::ast;
|
||||
use syntax_pos::symbol::InternedString;
|
||||
use syntax_pos::symbol::Symbol;
|
||||
use syntax_pos::Span;
|
||||
|
||||
use self::combine::CombineFields;
|
||||
@ -392,7 +392,7 @@ pub enum RegionVariableOrigin {
|
||||
Coercion(Span),
|
||||
|
||||
/// Region variables created as the values for early-bound regions
|
||||
EarlyBoundRegion(Span, InternedString),
|
||||
EarlyBoundRegion(Span, Symbol),
|
||||
|
||||
/// Region variables created for bound regions
|
||||
/// in a function or method that is called
|
||||
|
@ -27,7 +27,8 @@ use crate::ty::error::TypeError;
|
||||
use crate::ty::fold::{TypeFoldable, TypeVisitor};
|
||||
use crate::ty::relate::{self, Relate, RelateResult, TypeRelation};
|
||||
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 rustc_data_structures::fx::FxHashMap;
|
||||
use std::fmt::Debug;
|
||||
@ -324,7 +325,7 @@ where
|
||||
let vid = pair.vid();
|
||||
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
|
||||
// doesn't permit type variables to appear on both sides (and
|
||||
// doesn't use lazy norm).
|
||||
@ -616,15 +617,21 @@ where
|
||||
fn consts(
|
||||
&mut self,
|
||||
a: &'tcx ty::Const<'tcx>,
|
||||
b: &'tcx ty::Const<'tcx>,
|
||||
mut b: &'tcx ty::Const<'tcx>,
|
||||
) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
|
||||
if let ty::Const { val: ConstValue::Bound(..), .. } = a {
|
||||
// FIXME(const_generics): I'm unsure how this branch should actually be handled,
|
||||
// so this is probably not correct.
|
||||
self.infcx.super_combine_consts(self, a, b)
|
||||
} else {
|
||||
debug!("consts(a={:?}, b={:?}, variance={:?})", a, b, self.ambient_variance);
|
||||
relate::super_relate_consts(self, a, b)
|
||||
let a = self.infcx.shallow_resolve(a);
|
||||
|
||||
if !D::forbid_inference_vars() {
|
||||
b = self.infcx.shallow_resolve(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>,
|
||||
_: &'tcx ty::Const<'tcx>,
|
||||
) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
|
||||
debug!("TypeGeneralizer::consts(a={:?})", a);
|
||||
|
||||
if let ty::Const { val: ConstValue::Bound(..), .. } = a {
|
||||
bug!(
|
||||
"unexpected inference variable encountered in NLL generalization: {:?}",
|
||||
a
|
||||
);
|
||||
} else {
|
||||
relate::super_relate_consts(self, a, a)
|
||||
match a.val {
|
||||
ConstValue::Infer(InferConst::Var(_)) if D::forbid_inference_vars() => {
|
||||
bug!(
|
||||
"unexpected inference variable encountered in NLL generalization: {:?}",
|
||||
a
|
||||
);
|
||||
}
|
||||
ConstValue::Infer(InferConst::Var(vid)) => {
|
||||
let mut variable_table = self.infcx.const_unification_table.borrow_mut();
|
||||
let var_value = variable_table.probe_value(vid);
|
||||
match var_value.val.known() {
|
||||
Some(u) => self.relate(&u, &u),
|
||||
None => {
|
||||
let new_var_id = variable_table.new_key(ConstVarValue {
|
||||
origin: var_value.origin,
|
||||
val: ConstVariableValue::Unknown { universe: self.universe },
|
||||
});
|
||||
Ok(self.tcx().mk_const_var(new_var_id, a.ty))
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => relate::super_relate_consts(self, a, a),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
use syntax::symbol::InternedString;
|
||||
use syntax::symbol::Symbol;
|
||||
use syntax_pos::Span;
|
||||
use crate::ty::{self, Ty, TyVid};
|
||||
|
||||
@ -49,7 +49,7 @@ pub enum TypeVariableOriginKind {
|
||||
MiscVariable,
|
||||
NormalizeProjectionType,
|
||||
TypeInference,
|
||||
TypeParameterDefinition(InternedString),
|
||||
TypeParameterDefinition(Symbol),
|
||||
|
||||
/// One of the upvars or closure kind parameters in a `ClosureSubsts`
|
||||
/// (before it has been determined).
|
||||
|
@ -3,7 +3,7 @@ use crate::mir::interpret::ConstValue;
|
||||
use rustc_data_structures::unify::{NoError, EqUnifyValue, UnifyKey, UnifyValue, UnificationTable};
|
||||
use rustc_data_structures::unify::InPlace;
|
||||
use syntax_pos::{Span, DUMMY_SP};
|
||||
use syntax::symbol::InternedString;
|
||||
use syntax::symbol::Symbol;
|
||||
|
||||
use std::cmp;
|
||||
use std::marker::PhantomData;
|
||||
@ -90,7 +90,7 @@ pub struct ConstVariableOrigin {
|
||||
pub enum ConstVariableOriginKind {
|
||||
MiscVariable,
|
||||
ConstInference,
|
||||
ConstParameterDefinition(InternedString),
|
||||
ConstParameterDefinition(Symbol),
|
||||
SubstitutionPlaceholder,
|
||||
}
|
||||
|
||||
|
@ -4,11 +4,12 @@
|
||||
//! compiler code, rather than using their own custom pass. Those
|
||||
//! 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::session::Session;
|
||||
use errors::{Applicability, DiagnosticBuilder, pluralise};
|
||||
use syntax::ast;
|
||||
use syntax::edition::Edition;
|
||||
use syntax::source_map::Span;
|
||||
use syntax::symbol::Symbol;
|
||||
|
||||
@ -22,7 +23,7 @@ declare_lint! {
|
||||
pub CONST_ERR,
|
||||
Deny,
|
||||
"constant evaluation detected erroneous expression",
|
||||
report_in_external_macro: true
|
||||
report_in_external_macro
|
||||
}
|
||||
|
||||
declare_lint! {
|
||||
@ -71,7 +72,7 @@ declare_lint! {
|
||||
pub UNREACHABLE_CODE,
|
||||
Warn,
|
||||
"detects unreachable code paths",
|
||||
report_in_external_macro: true
|
||||
report_in_external_macro
|
||||
}
|
||||
|
||||
declare_lint! {
|
||||
@ -131,7 +132,11 @@ declare_lint! {
|
||||
declare_lint! {
|
||||
pub PRIVATE_IN_PUBLIC,
|
||||
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! {
|
||||
@ -143,13 +148,21 @@ declare_lint! {
|
||||
declare_lint! {
|
||||
pub PUB_USE_OF_PRIVATE_EXTERN_CRATE,
|
||||
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! {
|
||||
pub INVALID_TYPE_PARAM_DEFAULT,
|
||||
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! {
|
||||
@ -161,63 +174,99 @@ declare_lint! {
|
||||
declare_lint! {
|
||||
pub SAFE_EXTERN_STATICS,
|
||||
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! {
|
||||
pub SAFE_PACKED_BORROWS,
|
||||
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! {
|
||||
pub PATTERNS_IN_FNS_WITHOUT_BODY,
|
||||
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! {
|
||||
pub LEGACY_DIRECTORY_OWNERSHIP,
|
||||
Deny,
|
||||
"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! {
|
||||
pub LEGACY_CONSTRUCTOR_VISIBILITY,
|
||||
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! {
|
||||
pub MISSING_FRAGMENT_SPECIFIER,
|
||||
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! {
|
||||
pub PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES,
|
||||
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! {
|
||||
pub LATE_BOUND_LIFETIME_ARGUMENTS,
|
||||
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! {
|
||||
pub ORDER_DEPENDENT_TRAIT_OBJECTS,
|
||||
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! {
|
||||
pub DEPRECATED,
|
||||
Warn,
|
||||
"detects use of deprecated items",
|
||||
report_in_external_macro: true
|
||||
report_in_external_macro
|
||||
}
|
||||
|
||||
declare_lint! {
|
||||
@ -253,7 +302,11 @@ declare_lint! {
|
||||
declare_lint! {
|
||||
pub TYVAR_BEHIND_RAW_POINTER,
|
||||
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! {
|
||||
@ -272,19 +325,33 @@ declare_lint! {
|
||||
pub ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE,
|
||||
Allow,
|
||||
"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! {
|
||||
pub ILLEGAL_FLOATING_POINT_LITERAL_PATTERN,
|
||||
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! {
|
||||
pub UNSTABLE_NAME_COLLISIONS,
|
||||
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! {
|
||||
@ -302,7 +369,11 @@ declare_lint! {
|
||||
declare_lint! {
|
||||
pub DUPLICATE_MACRO_EXPORTS,
|
||||
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! {
|
||||
@ -326,13 +397,21 @@ declare_lint! {
|
||||
declare_lint! {
|
||||
pub WHERE_CLAUSES_OBJECT_SAFETY,
|
||||
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! {
|
||||
pub PROC_MACRO_DERIVE_RESOLUTION_FALLBACK,
|
||||
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! {
|
||||
@ -346,7 +425,11 @@ declare_lint! {
|
||||
pub MACRO_EXPANDED_MACRO_EXPORTS_ACCESSED_BY_ABSOLUTE_PATHS,
|
||||
Deny,
|
||||
"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! {
|
||||
@ -359,7 +442,11 @@ declare_lint! {
|
||||
pub INDIRECT_STRUCTURAL_MATCH,
|
||||
// defaulting to allow until rust-lang/rust#62614 is fixed.
|
||||
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`.
|
||||
@ -367,7 +454,11 @@ pub mod parser {
|
||||
declare_lint! {
|
||||
pub ILL_FORMED_ATTRIBUTE_INPUT,
|
||||
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! {
|
||||
@ -387,31 +478,47 @@ declare_lint! {
|
||||
pub DEPRECATED_IN_FUTURE,
|
||||
Allow,
|
||||
"detects use of items that will be deprecated in a future version",
|
||||
report_in_external_macro: true
|
||||
report_in_external_macro
|
||||
}
|
||||
|
||||
declare_lint! {
|
||||
pub AMBIGUOUS_ASSOCIATED_ITEMS,
|
||||
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! {
|
||||
pub NESTED_IMPL_TRAIT,
|
||||
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! {
|
||||
pub MUTABLE_BORROW_RESERVATION_CONFLICT,
|
||||
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! {
|
||||
pub SOFT_UNSTABLE,
|
||||
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! {
|
||||
|
@ -22,11 +22,11 @@ use crate::hir::intravisit as hir_visit;
|
||||
use crate::hir::intravisit::Visitor;
|
||||
use crate::hir::map::{definitions::DisambiguatedDefPathData, DefPathData};
|
||||
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::levels::{LintLevelSets, LintLevelsBuilder};
|
||||
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::layout::{LayoutError, LayoutOf, TyLayout};
|
||||
use crate::util::nodemap::FxHashMap;
|
||||
@ -35,10 +35,9 @@ use crate::util::common::time;
|
||||
use errors::DiagnosticBuilder;
|
||||
use std::slice;
|
||||
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 syntax::ast;
|
||||
use syntax::edition;
|
||||
use syntax::util::lev_distance::find_best_match_for_name;
|
||||
use syntax::visit as ast_visit;
|
||||
use syntax_pos::{MultiSpan, Span, symbol::Symbol};
|
||||
@ -50,24 +49,25 @@ use syntax_pos::{MultiSpan, Span, symbol::Symbol};
|
||||
pub struct LintStore {
|
||||
/// Registered lints. The bool is true if the lint was
|
||||
/// added by a plugin.
|
||||
lints: Vec<(&'static Lint, bool)>,
|
||||
lints: Vec<&'static Lint>,
|
||||
|
||||
/// Trait objects for each lint pass.
|
||||
/// This is only `None` while performing a lint pass.
|
||||
pre_expansion_passes: Option<Vec<EarlyLintPassObject>>,
|
||||
early_passes: Option<Vec<EarlyLintPassObject>>,
|
||||
late_passes: Lock<Option<Vec<LateLintPassObject>>>,
|
||||
late_module_passes: Vec<LateLintPassObject>,
|
||||
/// Constructor functions for each variety of lint pass.
|
||||
///
|
||||
/// These should only be called once, but since we want to avoid locks or
|
||||
/// interior mutability, we don't enforce this (and lints should, in theory,
|
||||
/// be compatible with being constructed more than once, though not
|
||||
/// 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.
|
||||
by_name: FxHashMap<String, TargetLint>,
|
||||
|
||||
/// Map of registered lint groups to what lints they expand to.
|
||||
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
|
||||
@ -81,18 +81,6 @@ pub struct BufferedEarlyLint {
|
||||
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.
|
||||
enum TargetLint {
|
||||
/// A direct lint target
|
||||
@ -142,17 +130,16 @@ impl LintStore {
|
||||
pub fn new() -> LintStore {
|
||||
LintStore {
|
||||
lints: vec![],
|
||||
pre_expansion_passes: Some(vec![]),
|
||||
early_passes: Some(vec![]),
|
||||
late_passes: Lock::new(Some(vec![])),
|
||||
pre_expansion_passes: vec![],
|
||||
early_passes: vec![],
|
||||
late_passes: vec![],
|
||||
late_module_passes: vec![],
|
||||
by_name: Default::default(),
|
||||
future_incompatible: 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
|
||||
}
|
||||
|
||||
@ -168,101 +155,66 @@ impl LintStore {
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn register_early_pass(&mut self,
|
||||
sess: Option<&Session>,
|
||||
from_plugin: bool,
|
||||
register_only: bool,
|
||||
pass: EarlyLintPassObject) {
|
||||
self.push_pass(sess, from_plugin, &pass);
|
||||
if !register_only {
|
||||
self.early_passes.as_mut().unwrap().push(pass);
|
||||
}
|
||||
pub fn register_early_pass(
|
||||
&mut self,
|
||||
pass: impl Fn() -> EarlyLintPassObject + 'static + sync::Send + sync::Sync
|
||||
) {
|
||||
self.early_passes.push(Box::new(pass));
|
||||
}
|
||||
|
||||
pub fn register_pre_expansion_pass(
|
||||
&mut self,
|
||||
sess: Option<&Session>,
|
||||
from_plugin: bool,
|
||||
register_only: bool,
|
||||
pass: EarlyLintPassObject,
|
||||
pass: impl Fn() -> EarlyLintPassObject + 'static + sync::Send + sync::Sync,
|
||||
) {
|
||||
self.push_pass(sess, from_plugin, &pass);
|
||||
if !register_only {
|
||||
self.pre_expansion_passes.as_mut().unwrap().push(pass);
|
||||
}
|
||||
self.pre_expansion_passes.push(Box::new(pass));
|
||||
}
|
||||
|
||||
pub fn register_late_pass(&mut self,
|
||||
sess: Option<&Session>,
|
||||
from_plugin: bool,
|
||||
register_only: bool,
|
||||
per_module: bool,
|
||||
pass: LateLintPassObject) {
|
||||
self.push_pass(sess, from_plugin, &pass);
|
||||
if !register_only {
|
||||
if per_module {
|
||||
self.late_module_passes.push(pass);
|
||||
} else {
|
||||
self.late_passes.lock().as_mut().unwrap().push(pass);
|
||||
}
|
||||
}
|
||||
pub fn register_late_pass(
|
||||
&mut self,
|
||||
pass: impl Fn() -> LateLintPassObject + 'static + sync::Send + sync::Sync,
|
||||
) {
|
||||
self.late_passes.push(Box::new(pass));
|
||||
}
|
||||
|
||||
pub fn register_late_mod_pass(
|
||||
&mut self,
|
||||
pass: impl Fn() -> LateLintPassObject + 'static + sync::Send + sync::Sync,
|
||||
) {
|
||||
self.late_module_passes.push(Box::new(pass));
|
||||
}
|
||||
|
||||
// Helper method for register_early/late_pass
|
||||
fn push_pass<P: LintPass + ?Sized + 'static>(&mut self,
|
||||
sess: Option<&Session>,
|
||||
from_plugin: bool,
|
||||
pass: &Box<P>) {
|
||||
for lint in pass.get_lints() {
|
||||
self.lints.push((lint, from_plugin));
|
||||
pub fn register_lints(&mut self, lints: &[&'static Lint]) {
|
||||
for lint in lints {
|
||||
self.lints.push(lint);
|
||||
|
||||
let id = LintId::of(lint);
|
||||
if self.by_name.insert(lint.name_lower(), Id(id)).is_some() {
|
||||
let msg = format!("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),
|
||||
bug!("duplicate specification of lint {}", lint.name_lower())
|
||||
}
|
||||
|
||||
// A duplicate name from a plugin is a user error.
|
||||
(Some(sess), true) => sess.err(&msg[..]),
|
||||
if let Some(FutureIncompatibleInfo { edition, .. }) = lint.future_incompatible {
|
||||
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(
|
||||
&mut self,
|
||||
lint_name: &'static str,
|
||||
@ -277,7 +229,6 @@ impl LintStore {
|
||||
|
||||
pub fn register_group(
|
||||
&mut self,
|
||||
sess: Option<&Session>,
|
||||
from_plugin: bool,
|
||||
name: &'static str,
|
||||
deprecated_name: Option<&'static str>,
|
||||
@ -300,16 +251,7 @@ impl LintStore {
|
||||
}
|
||||
|
||||
if !new {
|
||||
let msg = format!("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[..]),
|
||||
}
|
||||
bug!("duplicate specification of lint group {}", name);
|
||||
}
|
||||
}
|
||||
|
||||
@ -522,7 +464,7 @@ pub struct LateContext<'a, 'tcx> {
|
||||
pub access_levels: &'a AccessLevels,
|
||||
|
||||
/// 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,
|
||||
|
||||
@ -550,7 +492,7 @@ pub struct EarlyContext<'a> {
|
||||
builder: LintLevelsBuilder<'a>,
|
||||
|
||||
/// The store of registered lints and the lint levels.
|
||||
lint_store: ReadGuard<'a, LintStore>,
|
||||
lint_store: &'a LintStore,
|
||||
|
||||
buffered: LintBuffer,
|
||||
}
|
||||
@ -639,14 +581,15 @@ pub trait LintContext: Sized {
|
||||
impl<'a> EarlyContext<'a> {
|
||||
fn new(
|
||||
sess: &'a Session,
|
||||
lint_store: &'a LintStore,
|
||||
krate: &'a ast::Crate,
|
||||
buffered: LintBuffer,
|
||||
) -> EarlyContext<'a> {
|
||||
EarlyContext {
|
||||
sess,
|
||||
krate,
|
||||
lint_store: sess.lint_store.borrow(),
|
||||
builder: LintLevelSets::builder(sess),
|
||||
lint_store,
|
||||
builder: LintLevelSets::builder(sess, lint_store),
|
||||
buffered,
|
||||
}
|
||||
}
|
||||
@ -681,7 +624,7 @@ impl<'a, T: EarlyLintPass> EarlyContextAndPass<'a, T> {
|
||||
f: F)
|
||||
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.enter_attrs(attrs);
|
||||
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)
|
||||
}
|
||||
|
||||
@ -1355,10 +1298,6 @@ impl LintPass for LateLintPassObjects<'_> {
|
||||
fn name(&self) -> &'static str {
|
||||
panic!()
|
||||
}
|
||||
|
||||
fn get_lints(&self) -> LintArray {
|
||||
panic!()
|
||||
}
|
||||
}
|
||||
|
||||
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),
|
||||
param_env: ty::ParamEnv::empty(),
|
||||
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(),
|
||||
generics: None,
|
||||
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);
|
||||
|
||||
let mut passes: Vec<_> = tcx.sess.lint_store.borrow().late_module_passes
|
||||
.iter().map(|pass| pass.fresh_late_pass()).collect();
|
||||
let mut passes: Vec<_> = tcx.lint_store.late_module_passes
|
||||
.iter().map(|pass| (pass)()).collect();
|
||||
|
||||
if !passes.is_empty() {
|
||||
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),
|
||||
param_env: ty::ParamEnv::empty(),
|
||||
access_levels,
|
||||
lint_store: tcx.sess.lint_store.borrow(),
|
||||
lint_store: &tcx.lint_store,
|
||||
last_node_with_lint_attrs: hir::CRATE_HIR_ID,
|
||||
generics: None,
|
||||
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) {
|
||||
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 !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
|
||||
.iter().map(|pass| pass.fresh_late_pass()).collect();
|
||||
let mut passes: Vec<_> = tcx.lint_store.late_module_passes
|
||||
.iter().map(|pass| (pass)()).collect();
|
||||
|
||||
for pass in &mut passes {
|
||||
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.
|
||||
@ -1525,10 +1462,6 @@ impl LintPass for EarlyLintPassObjects<'_> {
|
||||
fn name(&self) -> &'static str {
|
||||
panic!()
|
||||
}
|
||||
|
||||
fn get_lints(&self) -> LintArray {
|
||||
panic!()
|
||||
}
|
||||
}
|
||||
|
||||
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>(
|
||||
sess: &Session,
|
||||
lint_store: &LintStore,
|
||||
krate: &ast::Crate,
|
||||
pass: T,
|
||||
buffered: LintBuffer,
|
||||
) -> LintBuffer {
|
||||
let mut cx = EarlyContextAndPass {
|
||||
context: EarlyContext::new(sess, krate, buffered),
|
||||
context: EarlyContext::new(sess, lint_store, krate, buffered),
|
||||
pass,
|
||||
};
|
||||
|
||||
@ -1577,28 +1511,30 @@ fn early_lint_crate<T: EarlyLintPass>(
|
||||
|
||||
pub fn check_ast_crate<T: EarlyLintPass>(
|
||||
sess: &Session,
|
||||
lint_store: &LintStore,
|
||||
krate: &ast::Crate,
|
||||
pre_expansion: bool,
|
||||
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(),
|
||||
)
|
||||
} 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(),
|
||||
)
|
||||
};
|
||||
|
||||
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() {
|
||||
buffered = early_lint_crate(
|
||||
sess,
|
||||
lint_store,
|
||||
krate,
|
||||
EarlyLintPassObjects { lints: &mut passes[..] },
|
||||
buffered,
|
||||
@ -1609,6 +1545,7 @@ pub fn check_ast_crate<T: EarlyLintPass>(
|
||||
buffered = time(sess, &format!("running lint: {}", pass.name()), || {
|
||||
early_lint_crate(
|
||||
sess,
|
||||
lint_store,
|
||||
krate,
|
||||
EarlyLintPassObjects { lints: slice::from_mut(pass) },
|
||||
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.
|
||||
// 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.
|
||||
@ -1653,7 +1583,7 @@ impl Decodable for LintId {
|
||||
fn decode<D: Decoder>(d: &mut D) -> Result<LintId, D::Error> {
|
||||
let s = d.read_str()?;
|
||||
ty::tls::with(|tcx| {
|
||||
match tcx.sess.lint_store.borrow().find_lints(&s) {
|
||||
match tcx.lint_store.find_lints(&s) {
|
||||
Ok(ids) => {
|
||||
if ids.len() != 0 {
|
||||
panic!("invalid lint-id `{}`", s);
|
||||
|
@ -3,7 +3,7 @@ use std::cmp;
|
||||
use crate::hir::HirId;
|
||||
use crate::ich::StableHashingContext;
|
||||
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::session::Session;
|
||||
use crate::util::nodemap::FxHashMap;
|
||||
@ -35,21 +35,20 @@ enum LintSet {
|
||||
}
|
||||
|
||||
impl LintLevelSets {
|
||||
pub fn new(sess: &Session) -> LintLevelSets {
|
||||
pub fn new(sess: &Session, lint_store: &LintStore) -> LintLevelSets {
|
||||
let mut me = LintLevelSets {
|
||||
list: Vec::new(),
|
||||
lint_cap: Level::Forbid,
|
||||
};
|
||||
me.process_command_line(sess);
|
||||
me.process_command_line(sess, lint_store);
|
||||
return me
|
||||
}
|
||||
|
||||
pub fn builder(sess: &Session) -> LintLevelsBuilder<'_> {
|
||||
LintLevelsBuilder::new(sess, LintLevelSets::new(sess))
|
||||
pub fn builder<'a>(sess: &'a Session, store: &LintStore) -> LintLevelsBuilder<'a> {
|
||||
LintLevelsBuilder::new(sess, LintLevelSets::new(sess, store))
|
||||
}
|
||||
|
||||
fn process_command_line(&mut self, sess: &Session) {
|
||||
let store = sess.lint_store.borrow();
|
||||
fn process_command_line(&mut self, sess: &Session, store: &LintStore) {
|
||||
let mut specs = FxHashMap::default();
|
||||
self.lint_cap = sess.opts.lint_cap.unwrap_or(Level::Forbid);
|
||||
|
||||
@ -186,9 +185,8 @@ impl<'a> LintLevelsBuilder<'a> {
|
||||
/// #[allow]
|
||||
///
|
||||
/// 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 store = self.sess.lint_store.borrow();
|
||||
let sess = self.sess;
|
||||
let bad_attr = |span| {
|
||||
struct_span_err!(sess, span, E0452, "malformed lint attribute input")
|
||||
|
@ -45,7 +45,7 @@ use syntax_pos::Span;
|
||||
|
||||
pub use crate::lint::context::{LateContext, EarlyContext, LintContext, LintStore,
|
||||
check_crate, check_ast_crate, late_lint_mod, CheckLintNameResult,
|
||||
FutureIncompatibleInfo, BufferedEarlyLint,};
|
||||
BufferedEarlyLint,};
|
||||
|
||||
/// Specification of a single lint.
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
@ -76,9 +76,35 @@ pub struct Lint {
|
||||
|
||||
/// `true` if this lint is reported even inside expansions of external macros.
|
||||
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 {
|
||||
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`.
|
||||
pub fn from_parser_lint_id(lint_id: BufferedEarlyLintId) -> &'static Self {
|
||||
match lint_id {
|
||||
@ -105,18 +131,21 @@ impl Lint {
|
||||
#[macro_export]
|
||||
macro_rules! declare_lint {
|
||||
($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) => (
|
||||
declare_lint!{$vis $NAME, $Level, $desc, $rep}
|
||||
);
|
||||
($vis: vis $NAME: ident, $Level: ident, $desc: expr, $external: expr) => (
|
||||
($vis: vis $NAME: ident, $Level: ident, $desc: expr,
|
||||
$(@future_incompatible = $fi:expr;)? $($v:ident),*) => (
|
||||
$vis static $NAME: &$crate::lint::Lint = &$crate::lint::Lint {
|
||||
name: stringify!($NAME),
|
||||
default_level: $crate::lint::$Level,
|
||||
desc: $desc,
|
||||
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,
|
||||
@ -128,6 +157,7 @@ macro_rules! declare_lint {
|
||||
desc: $desc,
|
||||
edition_lint_opts: Some(($lint_edition, $crate::lint::Level::$edition_level)),
|
||||
report_in_external_macro: false,
|
||||
is_plugin: false,
|
||||
};
|
||||
);
|
||||
}
|
||||
@ -156,6 +186,8 @@ macro_rules! declare_tool_lint {
|
||||
desc: $desc,
|
||||
edition_lint_opts: None,
|
||||
report_in_external_macro: $external,
|
||||
future_incompatible: None,
|
||||
is_plugin: true,
|
||||
};
|
||||
);
|
||||
}
|
||||
@ -173,14 +205,6 @@ pub type LintArray = Vec<&'static Lint>;
|
||||
|
||||
pub trait LintPass {
|
||||
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.
|
||||
@ -189,7 +213,9 @@ macro_rules! impl_lint_pass {
|
||||
($name:ident => [$($lint:expr),* $(,)?]) => {
|
||||
impl LintPass for $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 {
|
||||
([], [$hir:tt], [$($methods:tt)*]) => (
|
||||
pub trait LateLintPass<'a, $hir>: LintPass {
|
||||
fn fresh_late_pass(&self) -> LateLintPassObject {
|
||||
panic!()
|
||||
}
|
||||
expand_lint_pass_methods!(&LateContext<'a, $hir>, [$($methods)*]);
|
||||
}
|
||||
)
|
||||
@ -327,6 +350,12 @@ macro_rules! declare_combined_late_lint_pass {
|
||||
$($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 {
|
||||
@ -337,12 +366,6 @@ macro_rules! declare_combined_late_lint_pass {
|
||||
fn name(&self) -> &'static str {
|
||||
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,)*
|
||||
}
|
||||
}
|
||||
|
||||
$v fn get_lints() -> LintArray {
|
||||
let mut lints = Vec::new();
|
||||
$(lints.extend_from_slice(&$passes::get_lints());)*
|
||||
lints
|
||||
}
|
||||
}
|
||||
|
||||
impl EarlyLintPass for $name {
|
||||
@ -464,12 +493,6 @@ macro_rules! declare_combined_early_lint_pass {
|
||||
fn name(&self) -> &'static str {
|
||||
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.
|
||||
let lints = sess.lint_store.borrow();
|
||||
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
|
||||
// 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 {
|
||||
assert_eq!(cnum, LOCAL_CRATE);
|
||||
let store = &tcx.lint_store;
|
||||
let mut builder = LintLevelMapBuilder {
|
||||
levels: LintLevelSets::builder(tcx.sess),
|
||||
levels: LintLevelSets::builder(tcx.sess, &store),
|
||||
tcx: tcx,
|
||||
store: store,
|
||||
};
|
||||
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);
|
||||
for macro_def in &krate.exported_macros {
|
||||
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())
|
||||
}
|
||||
|
||||
struct LintLevelMapBuilder<'tcx> {
|
||||
struct LintLevelMapBuilder<'a, 'tcx> {
|
||||
levels: levels::LintLevelsBuilder<'tcx>,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
store: &'a LintStore,
|
||||
}
|
||||
|
||||
impl LintLevelMapBuilder<'tcx> {
|
||||
impl LintLevelMapBuilder<'_, '_> {
|
||||
fn with_lint_attrs<F>(&mut self,
|
||||
id: hir::HirId,
|
||||
attrs: &[ast::Attribute],
|
||||
f: F)
|
||||
where F: FnOnce(&mut Self)
|
||||
{
|
||||
let push = self.levels.push(attrs);
|
||||
let push = self.levels.push(attrs, self.store);
|
||||
if push.changed {
|
||||
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> {
|
||||
intravisit::NestedVisitorMap::All(&self.tcx.hir())
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ use syntax::ast;
|
||||
use syntax::symbol::Symbol;
|
||||
use syntax_pos::Span;
|
||||
use rustc_target::spec::Target;
|
||||
use rustc_data_structures::sync::{self, MetadataRef, Lrc};
|
||||
use rustc_data_structures::sync::{self, MetadataRef};
|
||||
use rustc_macros::HashStable;
|
||||
|
||||
pub use self::NativeLibraryKind::*;
|
||||
@ -191,6 +191,8 @@ pub trait MetadataLoader {
|
||||
-> Result<MetadataRef, String>;
|
||||
}
|
||||
|
||||
pub type MetadataLoaderDyn = dyn MetadataLoader + Sync;
|
||||
|
||||
/// A store of Rust crates, through which their metadata can be accessed.
|
||||
///
|
||||
/// 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.
|
||||
/// during resolve)
|
||||
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
|
||||
fn def_key(&self, def: DefId) -> DefKey;
|
||||
fn def_path(&self, def: DefId) -> hir_map::DefPath;
|
||||
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
|
||||
fn crate_name_untracked(&self, cnum: CrateNum) -> Symbol;
|
||||
|
@ -353,11 +353,14 @@ impl<'tcx, Tag: Copy, Extra: AllocationExtra<Tag>> Allocation<Tag, Extra> {
|
||||
&mut self,
|
||||
cx: &impl HasDataLayout,
|
||||
ptr: Pointer<Tag>,
|
||||
src: impl IntoIterator<Item=u8, IntoIter: iter::ExactSizeIterator>,
|
||||
src: impl IntoIterator<Item=u8>,
|
||||
) -> InterpResult<'tcx>
|
||||
{
|
||||
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
|
||||
// cover all of `bytes`.
|
||||
for dest in bytes {
|
||||
|
@ -37,7 +37,7 @@ use std::slice;
|
||||
use std::vec::IntoIter;
|
||||
use std::{iter, mem, option, u32};
|
||||
use syntax::ast::Name;
|
||||
use syntax::symbol::{InternedString, Symbol};
|
||||
use syntax::symbol::Symbol;
|
||||
use syntax_pos::{Span, DUMMY_SP};
|
||||
|
||||
pub use crate::mir::interpret::AssertMessage;
|
||||
@ -2736,8 +2736,8 @@ pub enum UnsafetyViolationKind {
|
||||
#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, HashStable)]
|
||||
pub struct UnsafetyViolation {
|
||||
pub source_info: SourceInfo,
|
||||
pub description: InternedString,
|
||||
pub details: InternedString,
|
||||
pub description: Symbol,
|
||||
pub details: Symbol,
|
||||
pub kind: UnsafetyViolationKind,
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::hir::def_id::{DefId, CrateNum, LOCAL_CRATE};
|
||||
use crate::hir::HirId;
|
||||
use syntax::symbol::InternedString;
|
||||
use syntax::symbol::Symbol;
|
||||
use syntax::attr::InlineAttr;
|
||||
use syntax::source_map::Span;
|
||||
use crate::ty::{Instance, InstanceDef, TyCtxt, SymbolName, subst::InternalSubsts};
|
||||
@ -80,7 +80,7 @@ impl<'tcx> MonoItem<'tcx> {
|
||||
MonoItem::GlobalAsm(hir_id) => {
|
||||
let def_id = tcx.hir().local_def_id(hir_id);
|
||||
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
|
||||
/// contain something unique to this crate (e.g., a module path)
|
||||
/// as well as the crate name and disambiguator.
|
||||
name: InternedString,
|
||||
name: Symbol,
|
||||
items: FxHashMap<MonoItem<'tcx>, (Linkage, Visibility)>,
|
||||
size_estimate: Option<usize>,
|
||||
}
|
||||
@ -294,7 +294,7 @@ impl_stable_hash_for!(enum self::Visibility {
|
||||
});
|
||||
|
||||
impl<'tcx> CodegenUnit<'tcx> {
|
||||
pub fn new(name: InternedString) -> CodegenUnit<'tcx> {
|
||||
pub fn new(name: Symbol) -> CodegenUnit<'tcx> {
|
||||
CodegenUnit {
|
||||
name: name,
|
||||
items: Default::default(),
|
||||
@ -302,11 +302,11 @@ impl<'tcx> CodegenUnit<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn name(&self) -> &InternedString {
|
||||
&self.name
|
||||
pub fn name(&self) -> Symbol {
|
||||
self.name
|
||||
}
|
||||
|
||||
pub fn set_name(&mut self, name: InternedString) {
|
||||
pub fn set_name(&mut self, name: Symbol) {
|
||||
self.name = name;
|
||||
}
|
||||
|
||||
@ -474,7 +474,7 @@ impl CodegenUnitNameBuilder<'tcx> {
|
||||
cnum: CrateNum,
|
||||
components: I,
|
||||
special_suffix: Option<S>)
|
||||
-> InternedString
|
||||
-> Symbol
|
||||
where I: IntoIterator<Item=C>,
|
||||
C: fmt::Display,
|
||||
S: fmt::Display,
|
||||
@ -487,7 +487,7 @@ impl CodegenUnitNameBuilder<'tcx> {
|
||||
cgu_name
|
||||
} else {
|
||||
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,
|
||||
components: I,
|
||||
special_suffix: Option<S>)
|
||||
-> InternedString
|
||||
-> Symbol
|
||||
where I: IntoIterator<Item=C>,
|
||||
C: fmt::Display,
|
||||
S: fmt::Display,
|
||||
@ -543,6 +543,6 @@ impl CodegenUnitNameBuilder<'tcx> {
|
||||
write!(cgu_name, ".{}", special_suffix).unwrap();
|
||||
}
|
||||
|
||||
InternedString::intern(&cgu_name[..])
|
||||
Symbol::intern(&cgu_name[..])
|
||||
}
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ use crate::traits::query::{
|
||||
};
|
||||
|
||||
use std::borrow::Cow;
|
||||
use syntax_pos::symbol::InternedString;
|
||||
use syntax_pos::symbol::Symbol;
|
||||
|
||||
// Each of these queries corresponds to a function pointer field in the
|
||||
// `Providers` struct for requesting a value of that type, and a method
|
||||
@ -924,7 +924,7 @@ rustc_queries! {
|
||||
desc { "collect_and_partition_mono_items" }
|
||||
}
|
||||
query is_codegened_item(_: DefId) -> bool {}
|
||||
query codegen_unit(_: InternedString) -> Arc<CodegenUnit<'tcx>> {
|
||||
query codegen_unit(_: Symbol) -> Arc<CodegenUnit<'tcx>> {
|
||||
no_force
|
||||
desc { "codegen_unit" }
|
||||
}
|
||||
|
@ -1149,7 +1149,8 @@ options! {CodegenOptions, CodegenSetter, basic_codegen_options,
|
||||
target_cpu: Option<String> = (None, parse_opt_string, [TRACKED],
|
||||
"select target processor (`rustc --print target-cpus` for details)"),
|
||||
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],
|
||||
"a list of extra LLVM passes to run (space separated)"),
|
||||
llvm_args: Vec<String> = (Vec::new(), parse_list, [TRACKED],
|
||||
|
@ -14,7 +14,7 @@ use crate::util::common::{duration_to_secs_str, ErrorReported};
|
||||
|
||||
use rustc_data_structures::base_n;
|
||||
use rustc_data_structures::sync::{
|
||||
self, Lrc, Lock, OneThread, Once, RwLock, AtomicU64, AtomicUsize, Ordering,
|
||||
self, Lrc, Lock, OneThread, Once, AtomicU64, AtomicUsize, Ordering,
|
||||
Ordering::SeqCst,
|
||||
};
|
||||
|
||||
@ -77,9 +77,11 @@ pub struct Session {
|
||||
/// if the value stored here has been affected by path remapping.
|
||||
pub working_dir: (PathBuf, bool),
|
||||
|
||||
// FIXME: `lint_store` and `buffered_lints` are not thread-safe,
|
||||
// but are only used in a single thread.
|
||||
pub lint_store: RwLock<lint::LintStore>,
|
||||
/// This is intended to be used from a single thread.
|
||||
///
|
||||
/// 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>>,
|
||||
|
||||
/// Set of `(DiagnosticId, Option<Span>, message)` tuples tracking
|
||||
@ -1213,7 +1215,6 @@ fn build_session_(
|
||||
sysroot,
|
||||
local_crate_source_file,
|
||||
working_dir,
|
||||
lint_store: RwLock::new(lint::LintStore::new()),
|
||||
buffered_lints: Lock::new(Some(Default::default())),
|
||||
one_time_diagnostics: Default::default(),
|
||||
plugin_llvm_passes: OneThread::new(RefCell::new(Vec::new())),
|
||||
|
@ -406,7 +406,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
},
|
||||
GenericParamDefKind::Lifetime => continue,
|
||||
};
|
||||
let name = param.name.as_symbol();
|
||||
let name = param.name;
|
||||
flags.push((name, Some(value)));
|
||||
}
|
||||
|
||||
@ -793,15 +793,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
|
||||
ty::Predicate::ObjectSafe(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,
|
||||
trait_def_id,
|
||||
violations,
|
||||
) {
|
||||
err
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
ty::Predicate::ClosureKind(closure_def_id, closure_substs, kind) => {
|
||||
@ -937,11 +933,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
|
||||
TraitNotObjectSafe(did) => {
|
||||
let violations = self.tcx.object_safety_violations(did);
|
||||
if let Some(err) = self.tcx.report_object_safety_error(span, did, violations) {
|
||||
err
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
self.tcx.report_object_safety_error(span, did, violations)
|
||||
}
|
||||
|
||||
// already reported in the query
|
||||
@ -1665,11 +1657,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
span: Span,
|
||||
trait_def_id: DefId,
|
||||
violations: Vec<ObjectSafetyViolation>,
|
||||
) -> Option<DiagnosticBuilder<'tcx>> {
|
||||
if self.sess.trait_methods_not_found.borrow().contains(&span) {
|
||||
// Avoid emitting error caused by non-existing method (#58734)
|
||||
return None;
|
||||
}
|
||||
) -> DiagnosticBuilder<'tcx> {
|
||||
let trait_str = self.def_path_str(trait_def_id);
|
||||
let span = self.sess.source_map().def_span(span);
|
||||
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 `{}`",
|
||||
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 => {
|
||||
err.note("the `Copy` trait is required because the \
|
||||
repeated element will be copied");
|
||||
|
@ -188,6 +188,9 @@ pub enum ObligationCauseCode<'tcx> {
|
||||
/// Obligation incurred due to an object cast.
|
||||
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:
|
||||
/// L = X implies that L is Sized
|
||||
AssignmentLhsSized,
|
||||
|
@ -19,7 +19,7 @@ use crate::ty::subst::{Subst, InternalSubsts};
|
||||
use std::borrow::Cow;
|
||||
use std::iter::{self};
|
||||
use syntax::ast::{self};
|
||||
use syntax::symbol::InternedString;
|
||||
use syntax::symbol::Symbol;
|
||||
use syntax_pos::{Span, DUMMY_SP};
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
|
||||
@ -560,7 +560,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
// are implemented
|
||||
let unsized_self_ty: Ty<'tcx> = self.mk_ty_param(
|
||||
::std::u32::MAX,
|
||||
InternedString::intern("RustaceansAreAwesome"),
|
||||
Symbol::intern("RustaceansAreAwesome"),
|
||||
);
|
||||
|
||||
// `Receiver[Self => U]`
|
||||
|
@ -250,7 +250,7 @@ impl<'tcx> OnUnimplementedFormatString {
|
||||
Position::ArgumentNamed(s) if s == sym::from_desugaring => (),
|
||||
// So is `{A}` if A is a type parameter
|
||||
Position::ArgumentNamed(s) => match generics.params.iter().find(|param| {
|
||||
param.name.as_symbol() == s
|
||||
param.name == s
|
||||
}) {
|
||||
Some(_) => (),
|
||||
None => {
|
||||
@ -289,7 +289,7 @@ impl<'tcx> OnUnimplementedFormatString {
|
||||
},
|
||||
GenericParamDefKind::Lifetime => return None
|
||||
};
|
||||
let name = param.name.as_symbol();
|
||||
let name = param.name;
|
||||
Some((name, value))
|
||||
}).collect::<FxHashMap<Symbol, String>>();
|
||||
let empty_string = String::new();
|
||||
|
@ -2246,7 +2246,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
}
|
||||
|
||||
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 {
|
||||
// Only auto-trait bounds exist.
|
||||
return;
|
||||
|
@ -4,7 +4,7 @@ use crate::traits;
|
||||
use crate::traits::project::Normalized;
|
||||
use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
|
||||
use crate::ty::{self, Lift, Ty, TyCtxt};
|
||||
use syntax::symbol::InternedString;
|
||||
use syntax::symbol::Symbol;
|
||||
|
||||
use std::fmt;
|
||||
use std::rc::Rc;
|
||||
@ -261,11 +261,11 @@ impl fmt::Display for traits::QuantifierKind {
|
||||
/// for debug output in tests anyway.
|
||||
struct BoundNamesCollector {
|
||||
// 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
|
||||
// by the list of type parameters.
|
||||
types: BTreeMap<u32, InternedString>,
|
||||
types: BTreeMap<u32, Symbol>,
|
||||
|
||||
binder_index: ty::DebruijnIndex,
|
||||
}
|
||||
@ -319,7 +319,7 @@ impl<'tcx> TypeVisitor<'tcx> for BoundNamesCollector {
|
||||
match bound_ty.kind {
|
||||
ty::BoundTyKind::Param(name) => name,
|
||||
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) => {
|
||||
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)))
|
||||
),
|
||||
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::TupleInitializerSized => Some(super::TupleInitializerSized),
|
||||
super::StructInitializerSized => Some(super::StructInitializerSized),
|
||||
|
@ -72,7 +72,7 @@ use syntax::ast;
|
||||
use syntax::attr;
|
||||
use syntax::source_map::MultiSpan;
|
||||
use syntax::feature_gate;
|
||||
use syntax::symbol::{Symbol, InternedString, kw, sym};
|
||||
use syntax::symbol::{Symbol, kw, sym};
|
||||
use syntax_pos::Span;
|
||||
|
||||
pub struct AllArenas {
|
||||
@ -949,7 +949,7 @@ impl<'tcx> CommonTypes<'tcx> {
|
||||
f64: mk(Float(ast::FloatTy::F64)),
|
||||
self_param: mk(ty::Param(ty::ParamTy {
|
||||
index: 0,
|
||||
name: kw::SelfUpper.as_interned_str(),
|
||||
name: kw::SelfUpper,
|
||||
})),
|
||||
|
||||
trait_object_dummy_self: mk(Infer(ty::FreshTy(0))),
|
||||
@ -1027,10 +1027,12 @@ pub struct GlobalCtxt<'tcx> {
|
||||
|
||||
interners: CtxtInterners<'tcx>,
|
||||
|
||||
cstore: &'tcx CrateStoreDyn,
|
||||
cstore: Box<CrateStoreDyn>,
|
||||
|
||||
pub sess: &'tcx Session,
|
||||
|
||||
pub lint_store: Lrc<lint::LintStore>,
|
||||
|
||||
pub dep_graph: DepGraph,
|
||||
|
||||
pub prof: SelfProfilerRef,
|
||||
@ -1192,11 +1194,11 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
/// reference to the context, to allow formatting values that need it.
|
||||
pub fn create_global_ctxt(
|
||||
s: &'tcx Session,
|
||||
cstore: &'tcx CrateStoreDyn,
|
||||
lint_store: Lrc<lint::LintStore>,
|
||||
local_providers: ty::query::Providers<'tcx>,
|
||||
extern_providers: ty::query::Providers<'tcx>,
|
||||
arenas: &'tcx AllArenas,
|
||||
resolutions: ty::Resolutions,
|
||||
resolutions: ty::ResolverOutputs,
|
||||
hir: hir_map::Map<'tcx>,
|
||||
on_disk_query_result_cache: query::OnDiskCache<'tcx>,
|
||||
crate_name: &str,
|
||||
@ -1210,34 +1212,28 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
let common_lifetimes = CommonLifetimes::new(&interners);
|
||||
let common_consts = CommonConsts::new(&interners, &common_types);
|
||||
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);
|
||||
providers[LOCAL_CRATE] = local_providers;
|
||||
|
||||
let def_path_hash_to_def_id = if s.opts.build_dep_graph() {
|
||||
let upstream_def_path_tables: Vec<(CrateNum, Lrc<_>)> = cstore
|
||||
.crates_untracked()
|
||||
let def_path_tables = crates
|
||||
.iter()
|
||||
.map(|&cnum| (cnum, cstore.def_path_table(cnum)))
|
||||
.collect();
|
||||
|
||||
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())))
|
||||
};
|
||||
.chain(iter::once((LOCAL_CRATE, hir.definitions().def_path_table())));
|
||||
|
||||
// Precompute the capacity of the hashmap so we don't have to
|
||||
// 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(
|
||||
capacity,
|
||||
::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);
|
||||
}
|
||||
|
||||
@ -1255,6 +1251,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
|
||||
GlobalCtxt {
|
||||
sess: s,
|
||||
lint_store,
|
||||
cstore,
|
||||
arena: WorkerLocal::new(|_| Arena::default()),
|
||||
interners,
|
||||
@ -1413,8 +1410,8 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
|
||||
// Note that this is *untracked* and should only be used within the query
|
||||
// system if the result is otherwise tracked through queries
|
||||
pub fn crate_data_as_rc_any(self, cnum: CrateNum) -> Lrc<dyn Any> {
|
||||
self.cstore.crate_data_as_rc_any(cnum)
|
||||
pub fn crate_data_as_any(self, cnum: CrateNum) -> &'tcx dyn Any {
|
||||
self.cstore.crate_data_as_any(cnum)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
@ -1424,7 +1421,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
StableHashingContext::new(self.sess,
|
||||
krate,
|
||||
self.hir().definitions(),
|
||||
self.cstore)
|
||||
&*self.cstore)
|
||||
}
|
||||
|
||||
// This method makes sure that we have a DepNode and a Fingerprint for
|
||||
@ -2552,7 +2549,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
}
|
||||
|
||||
#[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 }))
|
||||
}
|
||||
|
||||
@ -2560,7 +2557,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
pub fn mk_const_param(
|
||||
self,
|
||||
index: u32,
|
||||
name: InternedString,
|
||||
name: Symbol,
|
||||
ty: Ty<'tcx>
|
||||
) -> &'tcx Const<'tcx> {
|
||||
self.mk_const(ty::Const {
|
||||
|
@ -45,7 +45,7 @@ pub enum TypeError<'tcx> {
|
||||
ProjectionMismatched(ExpectedFound<DefId>),
|
||||
ProjectionBoundsLength(ExpectedFound<usize>),
|
||||
ExistentialMismatch(ExpectedFound<&'tcx ty::List<ty::ExistentialPredicate<'tcx>>>),
|
||||
|
||||
ObjectUnsafeCoercion(DefId),
|
||||
ConstMismatch(ExpectedFound<&'tcx ty::Const<'tcx>>),
|
||||
|
||||
IntrinsicCast,
|
||||
@ -178,6 +178,7 @@ impl<'tcx> fmt::Display for TypeError<'tcx> {
|
||||
IntrinsicCast => {
|
||||
write!(f, "cannot coerce intrinsics to function pointers")
|
||||
}
|
||||
ObjectUnsafeCoercion(_) => write!(f, "coercion to object-unsafe trait object"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ pub use self::Variance::*;
|
||||
pub use self::AssocItemContainer::*;
|
||||
pub use self::BorrowKind::*;
|
||||
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::Node;
|
||||
@ -15,6 +15,7 @@ use rustc_macros::HashStable;
|
||||
use crate::ich::Fingerprint;
|
||||
use crate::ich::StableHashingContext;
|
||||
use crate::infer::canonical::Canonical;
|
||||
use crate::middle::cstore::CrateStoreDyn;
|
||||
use crate::middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem, FnOnceTraitLangItem};
|
||||
use crate::middle::resolve_lifetime::ObjectLifetimeDefault;
|
||||
use crate::mir::Body;
|
||||
@ -46,11 +47,11 @@ use std::ops::Range;
|
||||
use syntax::ast::{self, Name, Ident, NodeId};
|
||||
use syntax::attr;
|
||||
use syntax_expand::hygiene::ExpnId;
|
||||
use syntax::symbol::{kw, sym, Symbol, InternedString};
|
||||
use syntax::symbol::{kw, sym, Symbol};
|
||||
use syntax_pos::Span;
|
||||
|
||||
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_index::vec::{Idx, IndexVec};
|
||||
|
||||
@ -119,8 +120,9 @@ mod sty;
|
||||
|
||||
// Data types
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Resolutions {
|
||||
pub struct ResolverOutputs {
|
||||
pub definitions: hir_map::Definitions,
|
||||
pub cstore: Box<CrateStoreDyn>,
|
||||
pub extern_crate_map: NodeMap<CrateNum>,
|
||||
pub trait_map: TraitMap,
|
||||
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
|
||||
/// always have names except when using anonymous lifetimes (`'_`).
|
||||
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)]
|
||||
pub struct GenericParamDef {
|
||||
pub name: InternedString,
|
||||
pub name: Symbol,
|
||||
pub def_id: DefId,
|
||||
pub index: u32,
|
||||
|
||||
@ -3019,7 +3021,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
}),
|
||||
_ => def_key.disambiguated_data.data.get_opt_name().unwrap_or_else(|| {
|
||||
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()
|
||||
}
|
||||
|
||||
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<'_>) {
|
||||
context::provide(providers);
|
||||
@ -3429,11 +3554,11 @@ pub struct CrateInherentImpls {
|
||||
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 {
|
||||
// FIXME: we don't rely on interning or equality here - better have
|
||||
// this be a `&'tcx str`.
|
||||
pub name: InternedString
|
||||
pub name: Symbol
|
||||
}
|
||||
|
||||
impl_stable_hash_for!(struct self::SymbolName {
|
||||
@ -3443,11 +3568,24 @@ impl_stable_hash_for!(struct self::SymbolName {
|
||||
impl SymbolName {
|
||||
pub fn new(name: &str) -> 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 {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
fmt::Display::fmt(&self.name, fmt)
|
||||
|
@ -218,9 +218,9 @@ impl DefPathBasedNames<'tcx> {
|
||||
// foo::bar::ItemName::
|
||||
for part in self.tcx.def_path(def_id).data {
|
||||
if self.omit_disambiguators {
|
||||
write!(output, "{}::", part.data.as_interned_str()).unwrap();
|
||||
write!(output, "{}::", part.data.as_symbol()).unwrap();
|
||||
} else {
|
||||
write!(output, "{}[{}]::", part.data.as_interned_str(), part.disambiguator)
|
||||
write!(output, "{}[{}]::", part.data.as_symbol(), part.disambiguator)
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ use rustc_apfloat::Float;
|
||||
use rustc_target::spec::abi::Abi;
|
||||
use syntax::ast;
|
||||
use syntax::attr::{SignedInt, UnsignedInt};
|
||||
use syntax::symbol::{kw, InternedString};
|
||||
use syntax::symbol::{kw, Symbol};
|
||||
|
||||
use std::cell::Cell;
|
||||
use std::fmt::{self, Write as _};
|
||||
@ -384,7 +384,7 @@ pub trait PrettyPrinter<'tcx>:
|
||||
let reexport = self.tcx().item_children(visible_parent)
|
||||
.iter()
|
||||
.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 {
|
||||
*name = reexport;
|
||||
}
|
||||
@ -392,7 +392,7 @@ pub trait PrettyPrinter<'tcx>:
|
||||
// Re-exported `extern crate` (#43189).
|
||||
DefPathData::CrateRoot => {
|
||||
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,
|
||||
in_value: bool,
|
||||
|
||||
used_region_names: FxHashSet<InternedString>,
|
||||
used_region_names: FxHashSet<Symbol>,
|
||||
region_index: 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
|
||||
// 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 !self.empty_path {
|
||||
write!(self, "::")?;
|
||||
@ -1332,16 +1332,16 @@ impl<F: fmt::Write> PrettyPrinter<'tcx> for FmtPrinter<'_, 'tcx, F> {
|
||||
|
||||
match *region {
|
||||
ty::ReEarlyBound(ref data) => {
|
||||
data.name.as_symbol() != kw::Invalid &&
|
||||
data.name.as_symbol() != kw::UnderscoreLifetime
|
||||
data.name != kw::Invalid &&
|
||||
data.name != kw::UnderscoreLifetime
|
||||
}
|
||||
|
||||
ty::ReLateBound(_, br) |
|
||||
ty::ReFree(ty::FreeRegion { bound_region: br, .. }) |
|
||||
ty::RePlaceholder(ty::Placeholder { name: br, .. }) => {
|
||||
if let ty::BrNamed(_, name) = br {
|
||||
if name.as_symbol() != kw::Invalid &&
|
||||
name.as_symbol() != kw::UnderscoreLifetime {
|
||||
if name != kw::Invalid &&
|
||||
name != kw::UnderscoreLifetime {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -1397,7 +1397,7 @@ impl<F: fmt::Write> FmtPrinter<'_, '_, F> {
|
||||
// `explain_region()` or `note_and_explain_region()`.
|
||||
match *region {
|
||||
ty::ReEarlyBound(ref data) => {
|
||||
if data.name.as_symbol() != kw::Invalid {
|
||||
if data.name != kw::Invalid {
|
||||
p!(write("{}", data.name));
|
||||
return Ok(self);
|
||||
}
|
||||
@ -1406,8 +1406,8 @@ impl<F: fmt::Write> FmtPrinter<'_, '_, F> {
|
||||
ty::ReFree(ty::FreeRegion { bound_region: br, .. }) |
|
||||
ty::RePlaceholder(ty::Placeholder { name: br, .. }) => {
|
||||
if let ty::BrNamed(_, name) = br {
|
||||
if name.as_symbol() != kw::Invalid &&
|
||||
name.as_symbol() != kw::UnderscoreLifetime {
|
||||
if name != kw::Invalid &&
|
||||
name != kw::UnderscoreLifetime {
|
||||
p!(write("{}", name));
|
||||
return Ok(self);
|
||||
}
|
||||
@ -1474,11 +1474,11 @@ impl<F: fmt::Write> FmtPrinter<'_, 'tcx, F> {
|
||||
where
|
||||
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 {
|
||||
0 => InternedString::intern("'r"),
|
||||
1 => InternedString::intern("'s"),
|
||||
i => InternedString::intern(&format!("'t{}", i-2)),
|
||||
0 => Symbol::intern("'r"),
|
||||
1 => Symbol::intern("'s"),
|
||||
i => Symbol::intern(&format!("'t{}", i-2)),
|
||||
}
|
||||
}
|
||||
|
||||
@ -1541,7 +1541,7 @@ impl<F: fmt::Write> FmtPrinter<'_, 'tcx, F> {
|
||||
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<'_> {
|
||||
fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
|
||||
match *r {
|
||||
|
@ -9,7 +9,7 @@ use crate::ty::fast_reject::SimplifiedType;
|
||||
use crate::mir;
|
||||
|
||||
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
|
||||
/// 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 {
|
||||
LOCAL_CRATE
|
||||
}
|
||||
|
@ -55,7 +55,6 @@ use std::ops::Deref;
|
||||
use std::sync::Arc;
|
||||
use std::any::type_name;
|
||||
use syntax_pos::{Span, DUMMY_SP};
|
||||
use syntax_pos::symbol::InternedString;
|
||||
use syntax::attr;
|
||||
use syntax::ast;
|
||||
use syntax::feature_gate;
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::ty::{self, Ty, TyCtxt, AdtSizedConstraint};
|
||||
use crate::ty::util::NeedsDrop;
|
||||
|
||||
use syntax::symbol::InternedString;
|
||||
use syntax::symbol::Symbol;
|
||||
|
||||
pub(super) trait Value<'tcx>: Sized {
|
||||
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 {
|
||||
fn from_cycle_error(_: TyCtxt<'tcx>) -> Self {
|
||||
ty::SymbolName { name: InternedString::intern("<error>") }
|
||||
ty::SymbolName { name: Symbol::intern("<error>") }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -557,10 +557,9 @@ pub fn super_relate_consts<R: TypeRelation<'tcx>>(
|
||||
x.val
|
||||
};
|
||||
|
||||
// Currently, the values that can be unified are those that
|
||||
// implement both `PartialEq` and `Eq`, corresponding to
|
||||
// `structural_match` types.
|
||||
// FIXME(const_generics): check for `structural_match` synthetic attribute.
|
||||
// Currently, the values that can be unified are primitive types,
|
||||
// and those that derive both `PartialEq` and `Eq`, corresponding
|
||||
// to `structural_match` types.
|
||||
let new_const_val = match (eagerly_eval(a), eagerly_eval(b)) {
|
||||
(ConstValue::Infer(_), _) | (_, ConstValue::Infer(_)) => {
|
||||
// The caller should handle these cases!
|
||||
|
@ -749,6 +749,7 @@ impl<'a, 'tcx> Lift<'tcx> for ty::error::TypeError<'a> {
|
||||
ExistentialMismatch(ref x) => return tcx.lift(x).map(ExistentialMismatch),
|
||||
ConstMismatch(ref x) => return tcx.lift(x).map(ConstMismatch),
|
||||
IntrinsicCast => IntrinsicCast,
|
||||
ObjectUnsafeCoercion(ref x) => return tcx.lift(x).map(ObjectUnsafeCoercion),
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -1350,6 +1351,7 @@ EnumTypeFoldableImpl! {
|
||||
(ty::error::TypeError::ExistentialMismatch)(x),
|
||||
(ty::error::TypeError::ConstMismatch)(x),
|
||||
(ty::error::TypeError::IntrinsicCast),
|
||||
(ty::error::TypeError::ObjectUnsafeCoercion)(x),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24,7 +24,7 @@ use std::marker::PhantomData;
|
||||
use std::ops::Range;
|
||||
use rustc_target::spec::abi;
|
||||
use syntax::ast::{self, Ident};
|
||||
use syntax::symbol::{kw, InternedString};
|
||||
use syntax::symbol::{kw, Symbol};
|
||||
|
||||
use self::InferTy::*;
|
||||
use self::TyKind::*;
|
||||
@ -55,7 +55,7 @@ pub enum BoundRegion {
|
||||
///
|
||||
/// The `DefId` is needed to distinguish free regions in
|
||||
/// the event of shadowing.
|
||||
BrNamed(DefId, InternedString),
|
||||
BrNamed(DefId, Symbol),
|
||||
|
||||
/// Anonymous region for the implicit env pointer parameter
|
||||
/// to a closure
|
||||
@ -1121,16 +1121,16 @@ pub type CanonicalPolyFnSig<'tcx> = Canonical<'tcx, Binder<FnSig<'tcx>>>;
|
||||
Hash, RustcEncodable, RustcDecodable, HashStable)]
|
||||
pub struct ParamTy {
|
||||
pub index: u32,
|
||||
pub name: InternedString,
|
||||
pub name: Symbol,
|
||||
}
|
||||
|
||||
impl<'tcx> ParamTy {
|
||||
pub fn new(index: u32, name: InternedString) -> ParamTy {
|
||||
pub fn new(index: u32, name: Symbol) -> ParamTy {
|
||||
ParamTy { index, name: name }
|
||||
}
|
||||
|
||||
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 {
|
||||
@ -1146,11 +1146,11 @@ impl<'tcx> ParamTy {
|
||||
Eq, PartialEq, Ord, PartialOrd, HashStable)]
|
||||
pub struct ParamConst {
|
||||
pub index: u32,
|
||||
pub name: InternedString,
|
||||
pub name: Symbol,
|
||||
}
|
||||
|
||||
impl<'tcx> ParamConst {
|
||||
pub fn new(index: u32, name: InternedString) -> ParamConst {
|
||||
pub fn new(index: u32, name: Symbol) -> ParamConst {
|
||||
ParamConst { index, name }
|
||||
}
|
||||
|
||||
@ -1323,7 +1323,7 @@ impl<'tcx> rustc_serialize::UseSpecializedDecodable for Region<'tcx> {}
|
||||
pub struct EarlyBoundRegion {
|
||||
pub def_id: DefId,
|
||||
pub index: u32,
|
||||
pub name: InternedString,
|
||||
pub name: Symbol,
|
||||
}
|
||||
|
||||
#[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)]
|
||||
pub enum BoundTyKind {
|
||||
Anon,
|
||||
Param(InternedString),
|
||||
Param(Symbol),
|
||||
}
|
||||
|
||||
impl_stable_hash_for!(struct BoundTy { var, kind });
|
||||
|
@ -380,16 +380,21 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
|
||||
// obligations that don't refer to Self and
|
||||
// checking those
|
||||
|
||||
let cause = self.cause(traits::MiscObligation);
|
||||
let component_traits =
|
||||
data.auto_traits().chain(data.principal_def_id());
|
||||
self.out.extend(
|
||||
component_traits.map(|did| traits::Obligation::new(
|
||||
cause.clone(),
|
||||
param_env,
|
||||
ty::Predicate::ObjectSafe(did)
|
||||
))
|
||||
);
|
||||
let defer_to_coercion =
|
||||
self.infcx.tcx.features().object_safe_for_dispatch;
|
||||
|
||||
if !defer_to_coercion {
|
||||
let cause = self.cause(traits::MiscObligation);
|
||||
let component_traits =
|
||||
data.auto_traits().chain(data.principal_def_id());
|
||||
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
|
||||
|
@ -36,7 +36,7 @@ use rustc_codegen_ssa::back::write::submit_codegened_module_to_llvm;
|
||||
|
||||
use std::ffi::CString;
|
||||
use std::time::Instant;
|
||||
use syntax_pos::symbol::InternedString;
|
||||
use syntax_pos::symbol::Symbol;
|
||||
use rustc::hir::CodegenFnAttrs;
|
||||
|
||||
use crate::value::Value;
|
||||
@ -105,7 +105,7 @@ pub fn iter_globals(llmod: &'ll llvm::Module) -> ValueIter<'ll> {
|
||||
|
||||
pub fn compile_codegen_unit(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
cgu_name: InternedString,
|
||||
cgu_name: Symbol,
|
||||
tx_to_llvm_workers: &std::sync::mpsc::Sender<Box<dyn std::any::Any + Send>>,
|
||||
) {
|
||||
let prof_timer = tcx.prof.generic_activity("codegen_module");
|
||||
@ -131,7 +131,7 @@ pub fn compile_codegen_unit(
|
||||
|
||||
fn module_codegen(
|
||||
tcx: TyCtxt<'_>,
|
||||
cgu_name: InternedString,
|
||||
cgu_name: Symbol,
|
||||
) -> ModuleCodegen<ModuleLlvm> {
|
||||
let cgu = tcx.codegen_unit(cgu_name);
|
||||
// Instantiate monomorphizations without filling out definitions yet...
|
||||
|
@ -221,7 +221,7 @@ impl CodegenCx<'ll, 'tcx> {
|
||||
def_id);
|
||||
|
||||
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);
|
||||
|
||||
|
@ -46,7 +46,7 @@ use std::iter;
|
||||
use std::ptr;
|
||||
use std::path::{Path, PathBuf};
|
||||
use syntax::ast;
|
||||
use syntax::symbol::{Interner, InternedString};
|
||||
use syntax::symbol::{Interner, Symbol};
|
||||
use syntax_pos::{self, Span, FileName};
|
||||
|
||||
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<'_, '_>,
|
||||
generics: &ty::Generics)
|
||||
-> Vec<InternedString> {
|
||||
-> Vec<Symbol> {
|
||||
let mut names = generics.parent.map_or(vec![], |def_id| {
|
||||
get_parameter_names(cx, cx.tcx.generics_of(def_id))
|
||||
});
|
||||
|
@ -36,7 +36,7 @@ use std::ffi::{CStr, CString};
|
||||
|
||||
use syntax_pos::{self, Span, Pos};
|
||||
use syntax::ast;
|
||||
use syntax::symbol::InternedString;
|
||||
use syntax::symbol::Symbol;
|
||||
use rustc::ty::layout::{self, LayoutOf, HasTyCtxt};
|
||||
use rustc_codegen_ssa::traits::*;
|
||||
|
||||
@ -490,7 +490,7 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
|
||||
|
||||
fn get_parameter_names(cx: &CodegenCx<'_, '_>,
|
||||
generics: &ty::Generics)
|
||||
-> Vec<InternedString> {
|
||||
-> Vec<Symbol> {
|
||||
let mut names = generics.parent.map_or(vec![], |def_id| {
|
||||
get_parameter_names(cx, cx.tcx.generics_of(def_id))
|
||||
});
|
||||
|
@ -35,7 +35,7 @@ pub fn item_namespace(cx: &CodegenCx<'ll, '_>, def_id: DefId) -> &'ll DIScope {
|
||||
|
||||
let namespace_name = match def_key.disambiguated_data.data {
|
||||
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);
|
||||
|
@ -50,14 +50,13 @@ use rustc_codegen_ssa::CompiledModule;
|
||||
use errors::{FatalError, Handler};
|
||||
use rustc::dep_graph::WorkProduct;
|
||||
use syntax_expand::allocator::AllocatorKind;
|
||||
use syntax_pos::symbol::InternedString;
|
||||
pub use llvm_util::target_features;
|
||||
use std::any::Any;
|
||||
use std::sync::Arc;
|
||||
use std::ffi::CStr;
|
||||
|
||||
use rustc::dep_graph::DepGraph;
|
||||
use rustc::middle::cstore::{EncodedMetadata, MetadataLoader};
|
||||
use rustc::middle::cstore::{EncodedMetadata, MetadataLoaderDyn};
|
||||
use rustc::session::Session;
|
||||
use rustc::session::config::{OutputFilenames, OutputType, PrintRequest, OptLevel};
|
||||
use rustc::ty::{self, TyCtxt};
|
||||
@ -123,7 +122,7 @@ impl ExtraBackendMethods for LlvmCodegenBackend {
|
||||
}
|
||||
fn compile_codegen_unit(
|
||||
&self, tcx: TyCtxt<'_>,
|
||||
cgu_name: InternedString,
|
||||
cgu_name: Symbol,
|
||||
tx: &std::sync::mpsc::Sender<Box<dyn Any + Send>>,
|
||||
) {
|
||||
base::compile_codegen_unit(tcx, cgu_name, tx);
|
||||
@ -261,7 +260,7 @@ impl CodegenBackend for LlvmCodegenBackend {
|
||||
target_features(sess)
|
||||
}
|
||||
|
||||
fn metadata_loader(&self) -> Box<dyn MetadataLoader + Sync> {
|
||||
fn metadata_loader(&self) -> Box<MetadataLoaderDyn> {
|
||||
box metadata::LlvmMetadataLoader
|
||||
}
|
||||
|
||||
|
@ -259,7 +259,7 @@ fn generate_lto_work<B: ExtraBackendMethods>(
|
||||
needs_thin_lto: Vec<(String, B::ThinBuffer)>,
|
||||
import_only_modules: Vec<(SerializedModule<B::ModuleBuffer>, WorkProduct)>
|
||||
) -> 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() {
|
||||
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 {
|
||||
WorkItem::Optimize(ref m) => format!("optimize: {}", m.name),
|
||||
WorkItem::CopyPostLtoArtifacts(ref m) => format!("copy post LTO artifacts: {}", m.name),
|
||||
WorkItem::LTO(ref m) => format!("lto: {}", m.name()),
|
||||
WorkItem::Optimize(_) => "codegen_module_optimize",
|
||||
WorkItem::CopyPostLtoArtifacts(_) => "codegen_copy_artifacts_from_incr_cache",
|
||||
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
|
||||
// surface that there was an error in this worker.
|
||||
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()
|
||||
};
|
||||
});
|
||||
|
@ -406,6 +406,8 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(cx: &'
|
||||
rust_main_def_id: DefId,
|
||||
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 {
|
||||
cx.type_func(&[cx.type_int(), cx.type_ptr_to(cx.type_i8p())], cx.type_int())
|
||||
} 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();
|
||||
|
||||
let (arg_argc, arg_argv) = 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)
|
||||
};
|
||||
let (arg_argc, arg_argv) = get_argc_argv(cx, &mut bx);
|
||||
|
||||
let (start_fn, args) = if use_start_lang_item {
|
||||
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 fn codegen_crate<B: ExtraBackendMethods>(
|
||||
@ -515,7 +526,7 @@ pub fn codegen_crate<B: ExtraBackendMethods>(
|
||||
// unnecessarily.
|
||||
if tcx.dep_graph.is_fully_enabled() {
|
||||
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 {
|
||||
CguReuse::No => {
|
||||
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();
|
||||
false
|
||||
}
|
||||
|
@ -221,7 +221,7 @@ pub fn push_debuginfo_type_name<'tcx>(
|
||||
output.push_str(&tcx.crate_name(def_id.krate).as_str());
|
||||
for path_element in tcx.def_path(def_id).data {
|
||||
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 {
|
||||
output.push_str(&tcx.item_name(def_id).as_str());
|
||||
|
@ -10,7 +10,7 @@ use rustc_codegen_utils::codegen_backend::CodegenBackend;
|
||||
use std::sync::Arc;
|
||||
use std::sync::mpsc;
|
||||
use syntax_expand::allocator::AllocatorKind;
|
||||
use syntax_pos::symbol::InternedString;
|
||||
use syntax_pos::symbol::Symbol;
|
||||
|
||||
pub trait BackendTypes {
|
||||
type Value: CodegenObject;
|
||||
@ -50,7 +50,7 @@ pub trait ExtraBackendMethods: CodegenBackend + WriteBackendMethods + Sized + Se
|
||||
fn compile_codegen_unit(
|
||||
&self,
|
||||
tcx: TyCtxt<'_>,
|
||||
cgu_name: InternedString,
|
||||
cgu_name: Symbol,
|
||||
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
|
||||
|
@ -14,7 +14,7 @@ use rustc::util::common::ErrorReported;
|
||||
use rustc::session::config::{OutputFilenames, PrintRequest};
|
||||
use rustc::ty::TyCtxt;
|
||||
use rustc::ty::query::Providers;
|
||||
use rustc::middle::cstore::{EncodedMetadata, MetadataLoader};
|
||||
use rustc::middle::cstore::{EncodedMetadata, MetadataLoaderDyn};
|
||||
use rustc::dep_graph::DepGraph;
|
||||
|
||||
pub use rustc_data_structures::sync::MetadataRef;
|
||||
@ -26,7 +26,7 @@ pub trait CodegenBackend {
|
||||
fn print_passes(&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_extern(&self, _providers: &mut Providers<'_>);
|
||||
fn codegen_crate<'tcx>(
|
||||
|
@ -95,7 +95,7 @@ use rustc::ty::query::Providers;
|
||||
use rustc::ty::{self, TyCtxt, Instance};
|
||||
use rustc::mir::mono::{MonoItem, InstantiationMode};
|
||||
|
||||
use syntax_pos::symbol::InternedString;
|
||||
use syntax_pos::symbol::Symbol;
|
||||
|
||||
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 substs = instance.substs;
|
||||
|
||||
@ -123,13 +123,11 @@ fn symbol_name(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> InternedString {
|
||||
if def_id.is_local() {
|
||||
if tcx.plugin_registrar_fn(LOCAL_CRATE) == Some(def_id) {
|
||||
let disambiguator = tcx.sess.local_crate_disambiguator();
|
||||
return
|
||||
InternedString::intern(&tcx.sess.generate_plugin_registrar_symbol(disambiguator));
|
||||
return Symbol::intern(&tcx.sess.generate_plugin_registrar_symbol(disambiguator));
|
||||
}
|
||||
if tcx.proc_macro_decls_static(LOCAL_CRATE) == Some(def_id) {
|
||||
let disambiguator = tcx.sess.local_crate_disambiguator();
|
||||
return
|
||||
InternedString::intern(&tcx.sess.generate_proc_macro_decls_symbol(disambiguator));
|
||||
return Symbol::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);
|
||||
if is_foreign {
|
||||
if let Some(name) = attrs.link_name {
|
||||
return name.as_interned_str();
|
||||
return name;
|
||||
}
|
||||
// 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
|
||||
return name.as_interned_str();
|
||||
return name;
|
||||
}
|
||||
|
||||
if attrs.flags.contains(CodegenFnAttrFlags::NO_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 avoid_cross_crate_conflicts =
|
||||
// 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),
|
||||
};
|
||||
|
||||
InternedString::intern(&mangled)
|
||||
Symbol::intern(&mangled)
|
||||
}
|
||||
|
@ -335,7 +335,7 @@ impl Printer<'tcx> for SymbolPrinter<'tcx> {
|
||||
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)
|
||||
}
|
||||
fn path_generic_args(
|
||||
|
@ -17,7 +17,7 @@ pub fn dominators<G: ControlFlowGraph>(graph: &G) -> Dominators<G::Node> {
|
||||
dominators_given_rpo(graph, &rpo)
|
||||
}
|
||||
|
||||
pub fn dominators_given_rpo<G: ControlFlowGraph>(
|
||||
fn dominators_given_rpo<G: ControlFlowGraph>(
|
||||
graph: &G,
|
||||
rpo: &[G::Node],
|
||||
) -> Dominators<G::Node> {
|
||||
@ -43,14 +43,12 @@ pub fn dominators_given_rpo<G: ControlFlowGraph>(
|
||||
let mut new_idom = None;
|
||||
for pred in graph.predecessors(node) {
|
||||
if immediate_dominators[pred].is_some() {
|
||||
// (*)
|
||||
// (*) dominators for `pred` have been calculated
|
||||
new_idom = intersect_opt(
|
||||
&post_order_rank,
|
||||
&immediate_dominators,
|
||||
new_idom,
|
||||
Some(pred),
|
||||
);
|
||||
new_idom = Some(if let Some(new_idom) = new_idom {
|
||||
intersect(&post_order_rank, &immediate_dominators, new_idom, pred)
|
||||
} else {
|
||||
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>(
|
||||
post_order_rank: &IndexVec<Node, usize>,
|
||||
immediate_dominators: &IndexVec<Node, Option<Node>>,
|
||||
|
@ -16,6 +16,7 @@ log = "0.4"
|
||||
env_logger = { version = "0.7", default-features = false }
|
||||
rustc = { path = "../librustc" }
|
||||
rustc_target = { path = "../librustc_target" }
|
||||
rustc_lint = { path = "../librustc_lint" }
|
||||
rustc_data_structures = { path = "../librustc_data_structures" }
|
||||
errors = { path = "../librustc_errors", package = "rustc_errors" }
|
||||
rustc_metadata = { path = "../librustc_metadata" }
|
||||
|
@ -36,11 +36,11 @@ use rustc::session::config::nightly_options;
|
||||
use rustc::session::{early_error, early_warn};
|
||||
use rustc::lint::Lint;
|
||||
use rustc::lint;
|
||||
use rustc::middle::cstore::MetadataLoader;
|
||||
use rustc::hir::def_id::LOCAL_CRATE;
|
||||
use rustc::ty::TyCtxt;
|
||||
use rustc::util::common::{set_time_depth, time, print_time_passes_entry, ErrorReported};
|
||||
use rustc_metadata::locator;
|
||||
use rustc_metadata::cstore::CStore;
|
||||
use rustc_codegen_utils::codegen_backend::CodegenBackend;
|
||||
use rustc_interface::interface;
|
||||
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 {
|
||||
/// Called before creating the compiler instance
|
||||
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
|
||||
/// continue the compilation afterwards (defaults to `Compilation::Continue`)
|
||||
fn after_parsing(&mut self, _compiler: &interface::Compiler) -> Compilation {
|
||||
@ -182,6 +184,7 @@ pub fn run_compiler(
|
||||
stderr: None,
|
||||
crate_name: None,
|
||||
lint_caps: Default::default(),
|
||||
register_lints: None,
|
||||
};
|
||||
callbacks.config(&mut config);
|
||||
config
|
||||
@ -202,9 +205,13 @@ pub fn run_compiler(
|
||||
interface::run_compiler(config, |compiler| {
|
||||
let sopts = &compiler.session().opts;
|
||||
if sopts.describe_lints {
|
||||
let lint_store = rustc_lint::new_lint_store(
|
||||
sopts.debugging_opts.no_interleave_lints,
|
||||
compiler.session().unstable_options(),
|
||||
);
|
||||
describe_lints(
|
||||
compiler.session(),
|
||||
&*compiler.session().lint_store.borrow(),
|
||||
&lint_store,
|
||||
false
|
||||
);
|
||||
return;
|
||||
@ -255,6 +262,7 @@ pub fn run_compiler(
|
||||
stderr: None,
|
||||
crate_name: None,
|
||||
lint_caps: Default::default(),
|
||||
register_lints: None,
|
||||
};
|
||||
|
||||
callbacks.config(&mut config);
|
||||
@ -269,7 +277,7 @@ pub fn run_compiler(
|
||||
compiler.output_file(),
|
||||
).and_then(|| RustcDefaultCalls::list_metadata(
|
||||
sess,
|
||||
compiler.cstore(),
|
||||
&*compiler.codegen_backend().metadata_loader(),
|
||||
&matches,
|
||||
compiler.input()
|
||||
));
|
||||
@ -321,12 +329,14 @@ pub fn run_compiler(
|
||||
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.
|
||||
if sess.opts.describe_lints {
|
||||
describe_lints(&sess, &sess.lint_store.borrow(), true);
|
||||
return sess.compile_status();
|
||||
// Lint plugins are registered; now we can process command line flags.
|
||||
if sess.opts.describe_lints {
|
||||
describe_lints(&sess, &lint_store, true);
|
||||
return sess.compile_status();
|
||||
}
|
||||
}
|
||||
|
||||
compiler.expansion()?;
|
||||
@ -604,7 +614,7 @@ fn show_content_with_pager(content: &String) {
|
||||
|
||||
impl RustcDefaultCalls {
|
||||
pub fn list_metadata(sess: &Session,
|
||||
cstore: &CStore,
|
||||
metadata_loader: &dyn MetadataLoader,
|
||||
matches: &getopts::Matches,
|
||||
input: &Input)
|
||||
-> Compilation {
|
||||
@ -616,7 +626,7 @@ impl RustcDefaultCalls {
|
||||
let mut v = Vec::new();
|
||||
locator::list_file_metadata(&sess.target.target,
|
||||
path,
|
||||
cstore,
|
||||
metadata_loader,
|
||||
&mut 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> {
|
||||
let mut lints: Vec<_> = lints.into_iter().map(|(x, _)| x).collect();
|
||||
fn sort_lints(sess: &Session, mut lints: Vec<&'static Lint>) -> Vec<&'static Lint> {
|
||||
// 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
|
||||
@ -852,7 +861,7 @@ Available lint options:
|
||||
let (plugin, builtin): (Vec<_>, _) = lint_store.get_lints()
|
||||
.iter()
|
||||
.cloned()
|
||||
.partition(|&(_, p)| p);
|
||||
.partition(|&lint| lint.is_plugin);
|
||||
let plugin = sort_lints(sess, plugin);
|
||||
let builtin = sort_lints(sess, builtin);
|
||||
|
||||
|
@ -152,6 +152,32 @@ impl Diagnostic {
|
||||
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,
|
||||
label: &dyn fmt::Display,
|
||||
expected: DiagnosticStyledString,
|
||||
|
@ -209,6 +209,11 @@ impl<'a> DiagnosticBuilder<'a> {
|
||||
found_extra: &dyn fmt::Display,
|
||||
) -> &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 span_note<S: Into<MultiSpan>>(&mut self,
|
||||
sp: S,
|
||||
|
@ -27,7 +27,7 @@ use rustc::mir::mono::CodegenUnitNameBuilder;
|
||||
use rustc::ty::TyCtxt;
|
||||
use std::collections::BTreeSet;
|
||||
use syntax::ast;
|
||||
use syntax::symbol::{InternedString, Symbol, sym};
|
||||
use syntax::symbol::{Symbol, sym};
|
||||
use rustc::ich::{ATTR_PARTITION_REUSED, ATTR_PARTITION_CODEGENED,
|
||||
ATTR_EXPECTED_CGU_REUSE};
|
||||
|
||||
@ -45,8 +45,8 @@ pub fn assert_module_sources(tcx: TyCtxt<'_>) {
|
||||
.collect_and_partition_mono_items(LOCAL_CRATE)
|
||||
.1
|
||||
.iter()
|
||||
.map(|cgu| *cgu.name())
|
||||
.collect::<BTreeSet<InternedString>>();
|
||||
.map(|cgu| cgu.name())
|
||||
.collect::<BTreeSet<Symbol>>();
|
||||
|
||||
let ams = AssertModuleSource {
|
||||
tcx,
|
||||
@ -61,7 +61,7 @@ pub fn assert_module_sources(tcx: TyCtxt<'_>) {
|
||||
|
||||
struct AssertModuleSource<'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
available_cgus: BTreeSet<InternedString>,
|
||||
available_cgus: BTreeSet<Symbol>,
|
||||
}
|
||||
|
||||
impl AssertModuleSource<'tcx> {
|
||||
|
@ -11,7 +11,6 @@ use rustc_codegen_utils::codegen_backend::CodegenBackend;
|
||||
use rustc_data_structures::OnDrop;
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
use rustc_data_structures::fx::{FxHashSet, FxHashMap};
|
||||
use rustc_metadata::cstore::CStore;
|
||||
use std::path::PathBuf;
|
||||
use std::result;
|
||||
use std::sync::{Arc, Mutex};
|
||||
@ -37,8 +36,8 @@ pub struct Compiler {
|
||||
pub(crate) output_dir: Option<PathBuf>,
|
||||
pub(crate) output_file: Option<PathBuf>,
|
||||
pub(crate) queries: Queries,
|
||||
pub(crate) cstore: Lrc<CStore>,
|
||||
pub(crate) crate_name: Option<String>,
|
||||
pub(crate) register_lints: Option<Box<dyn Fn(&Session, &mut lint::LintStore) + Send + Sync>>,
|
||||
}
|
||||
|
||||
impl Compiler {
|
||||
@ -48,9 +47,6 @@ impl Compiler {
|
||||
pub fn codegen_backend(&self) -> &Lrc<Box<dyn CodegenBackend>> {
|
||||
&self.codegen_backend
|
||||
}
|
||||
pub fn cstore(&self) -> &Lrc<CStore> {
|
||||
&self.cstore
|
||||
}
|
||||
pub fn source_map(&self) -> &Lrc<SourceMap> {
|
||||
&self.source_map
|
||||
}
|
||||
@ -137,6 +133,13 @@ pub struct Config {
|
||||
|
||||
pub crate_name: Option<String>,
|
||||
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
|
||||
@ -152,19 +155,17 @@ where
|
||||
config.lint_caps,
|
||||
);
|
||||
|
||||
let cstore = Lrc::new(CStore::new(codegen_backend.metadata_loader()));
|
||||
|
||||
let compiler = Compiler {
|
||||
sess,
|
||||
codegen_backend,
|
||||
source_map,
|
||||
cstore,
|
||||
input: config.input,
|
||||
input_path: config.input_path,
|
||||
output_dir: config.output_dir,
|
||||
output_file: config.output_file,
|
||||
queries: Default::default(),
|
||||
crate_name: config.crate_name,
|
||||
register_lints: config.register_lints,
|
||||
};
|
||||
|
||||
let _sess_abort_error = OnDrop(|| {
|
||||
|
@ -9,8 +9,8 @@ use rustc::hir::lowering::lower_crate;
|
||||
use rustc::hir::def_id::{CrateNum, LOCAL_CRATE};
|
||||
use rustc::lint;
|
||||
use rustc::middle::{self, reachable, resolve_lifetime, stability};
|
||||
use rustc::middle::cstore::CrateStore;
|
||||
use rustc::ty::{self, AllArenas, Resolutions, TyCtxt, GlobalCtxt};
|
||||
use rustc::middle::cstore::{CrateStore, MetadataLoader, MetadataLoaderDyn};
|
||||
use rustc::ty::{self, AllArenas, ResolverOutputs, TyCtxt, GlobalCtxt};
|
||||
use rustc::ty::steal::Steal;
|
||||
use rustc::traits;
|
||||
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::sync::{Lrc, ParallelIterator, par_iter};
|
||||
use rustc_incremental;
|
||||
use rustc_metadata::creader::CrateLoader;
|
||||
use rustc_metadata::cstore::{self, CStore};
|
||||
use rustc_metadata::cstore;
|
||||
use rustc_mir as mir;
|
||||
use rustc_passes::{self, ast_validation, hir_stats, layout_test};
|
||||
use rustc_plugin as plugin;
|
||||
@ -46,12 +45,10 @@ use syntax_ext;
|
||||
use rustc_serialize::json;
|
||||
use tempfile::Builder as TempFileBuilder;
|
||||
|
||||
use std::{env, fs, iter, mem};
|
||||
use std::any::Any;
|
||||
use std::env;
|
||||
use std::ffi::OsString;
|
||||
use std::fs;
|
||||
use std::io::{self, Write};
|
||||
use std::iter;
|
||||
use std::path::PathBuf;
|
||||
use std::cell::RefCell;
|
||||
use std::rc::Rc;
|
||||
@ -105,7 +102,7 @@ fn count_nodes(krate: &ast::Crate) -> usize {
|
||||
declare_box_region_type!(
|
||||
pub BoxedResolver,
|
||||
for(),
|
||||
(&mut Resolver<'_>) -> (Result<ast::Crate>, ExpansionResult)
|
||||
(&mut Resolver<'_>) -> (Result<ast::Crate>, ResolverOutputs)
|
||||
);
|
||||
|
||||
/// 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.
|
||||
pub fn configure_and_expand(
|
||||
sess: Lrc<Session>,
|
||||
cstore: Lrc<CStore>,
|
||||
lint_store: Lrc<lint::LintStore>,
|
||||
metadata_loader: Box<MetadataLoaderDyn>,
|
||||
krate: ast::Crate,
|
||||
crate_name: &str,
|
||||
plugin_info: PluginInfo,
|
||||
@ -130,15 +128,14 @@ pub fn configure_and_expand(
|
||||
let crate_name = crate_name.to_string();
|
||||
let (result, resolver) = BoxedResolver::new(static move || {
|
||||
let sess = &*sess;
|
||||
let crate_loader = CrateLoader::new(sess, &*cstore, &crate_name);
|
||||
let resolver_arenas = Resolver::arenas();
|
||||
let res = configure_and_expand_inner(
|
||||
sess,
|
||||
&*cstore,
|
||||
&lint_store,
|
||||
krate,
|
||||
&crate_name,
|
||||
&resolver_arenas,
|
||||
&crate_loader,
|
||||
&*metadata_loader,
|
||||
plugin_info,
|
||||
);
|
||||
let mut resolver = match res {
|
||||
@ -152,68 +149,16 @@ pub fn configure_and_expand(
|
||||
}
|
||||
};
|
||||
box_region_allow_access!(for(), (&mut Resolver<'_>), (&mut resolver));
|
||||
ExpansionResult::from_owned_resolver(resolver)
|
||||
resolver.into_outputs()
|
||||
});
|
||||
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 {
|
||||
pub fn to_expansion_result(
|
||||
resolver: Rc<RefCell<BoxedResolver>>,
|
||||
) -> ExpansionResult {
|
||||
pub fn to_resolver_outputs(resolver: Rc<RefCell<BoxedResolver>>) -> ResolverOutputs {
|
||||
match Rc::try_unwrap(resolver) {
|
||||
Ok(resolver) => resolver.into_inner().complete(),
|
||||
Err(resolver) => {
|
||||
let resolver = &*resolver;
|
||||
resolver.borrow_mut().access(|resolver| {
|
||||
ExpansionResult::from_resolver_ref(resolver)
|
||||
})
|
||||
}
|
||||
Err(resolver) => resolver.borrow_mut().access(|resolver| resolver.clone_outputs()),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -224,10 +169,11 @@ pub struct PluginInfo {
|
||||
|
||||
pub fn register_plugins<'a>(
|
||||
sess: &'a Session,
|
||||
cstore: &'a CStore,
|
||||
metadata_loader: &'a dyn MetadataLoader,
|
||||
register_lints: impl Fn(&Session, &mut lint::LintStore),
|
||||
mut krate: ast::Crate,
|
||||
crate_name: &str,
|
||||
) -> Result<(ast::Crate, PluginInfo)> {
|
||||
) -> Result<(ast::Crate, PluginInfo, Lrc<lint::LintStore>)> {
|
||||
krate = time(sess, "attributes injection", || {
|
||||
syntax_ext::cmdline_attrs::inject(
|
||||
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", || {
|
||||
plugin::load::load_plugins(
|
||||
sess,
|
||||
&cstore,
|
||||
metadata_loader,
|
||||
&krate,
|
||||
crate_name,
|
||||
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", || {
|
||||
for registrar in registrars {
|
||||
@ -289,44 +241,30 @@ pub fn register_plugins<'a>(
|
||||
|
||||
let Registry {
|
||||
syntax_exts,
|
||||
early_lint_passes,
|
||||
late_lint_passes,
|
||||
lint_groups,
|
||||
llvm_passes,
|
||||
attributes,
|
||||
..
|
||||
} = 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_attributes.borrow_mut() = attributes;
|
||||
|
||||
Ok((krate, PluginInfo { syntax_exts }))
|
||||
Ok((krate, PluginInfo { syntax_exts }, Lrc::new(lint_store)))
|
||||
}
|
||||
|
||||
fn configure_and_expand_inner<'a>(
|
||||
sess: &'a Session,
|
||||
cstore: &'a CStore,
|
||||
lint_store: &'a lint::LintStore,
|
||||
mut krate: ast::Crate,
|
||||
crate_name: &str,
|
||||
resolver_arenas: &'a ResolverArenas<'a>,
|
||||
crate_loader: &'a CrateLoader<'a>,
|
||||
metadata_loader: &'a MetadataLoaderDyn,
|
||||
plugin_info: PluginInfo,
|
||||
) -> Result<(ast::Crate, Resolver<'a>)> {
|
||||
time(sess, "pre-AST-expansion lint checks", || {
|
||||
lint::check_ast_crate(
|
||||
sess,
|
||||
lint_store,
|
||||
&krate,
|
||||
true,
|
||||
rustc_lint::BuiltinCombinedPreExpansionLintPass::new());
|
||||
@ -334,10 +272,9 @@ fn configure_and_expand_inner<'a>(
|
||||
|
||||
let mut resolver = Resolver::new(
|
||||
sess,
|
||||
cstore,
|
||||
&krate,
|
||||
crate_name,
|
||||
crate_loader,
|
||||
metadata_loader,
|
||||
&resolver_arenas,
|
||||
);
|
||||
syntax_ext::register_builtin_macros(&mut resolver, sess.edition());
|
||||
@ -536,7 +473,7 @@ fn configure_and_expand_inner<'a>(
|
||||
|
||||
pub fn lower_to_hir(
|
||||
sess: &Session,
|
||||
cstore: &CStore,
|
||||
lint_store: &lint::LintStore,
|
||||
resolver: &mut Resolver<'_>,
|
||||
dep_graph: &DepGraph,
|
||||
krate: &ast::Crate,
|
||||
@ -544,7 +481,7 @@ pub fn lower_to_hir(
|
||||
// Lower AST to HIR.
|
||||
let hir_forest = time(sess, "lowering AST -> HIR", || {
|
||||
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 {
|
||||
hir_stats::print_hir_stats(&hir_crate);
|
||||
@ -554,7 +491,13 @@ pub fn lower_to_hir(
|
||||
});
|
||||
|
||||
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.
|
||||
@ -644,8 +587,12 @@ fn escape_dep_filename(filename: &FileName) -> String {
|
||||
filename.to_string().replace(" ", "\\ ")
|
||||
}
|
||||
|
||||
fn write_out_deps(compiler: &Compiler, outputs: &OutputFilenames, out_filenames: &[PathBuf]) {
|
||||
let sess = &compiler.sess;
|
||||
fn write_out_deps(
|
||||
sess: &Session,
|
||||
boxed_resolver: &Steal<Rc<RefCell<BoxedResolver>>>,
|
||||
outputs: &OutputFilenames,
|
||||
out_filenames: &[PathBuf],
|
||||
) {
|
||||
// Write out dependency rules to the dep-info file if requested
|
||||
if !sess.opts.output_types.contains_key(&OutputType::DepInfo) {
|
||||
return;
|
||||
@ -664,18 +611,20 @@ fn write_out_deps(compiler: &Compiler, outputs: &OutputFilenames, out_filenames:
|
||||
.collect();
|
||||
|
||||
if sess.binary_dep_depinfo() {
|
||||
for cnum in compiler.cstore.crates_untracked() {
|
||||
let source = compiler.cstore.crate_source_untracked(cnum);
|
||||
if let Some((path, _)) = source.dylib {
|
||||
files.push(escape_dep_filename(&FileName::Real(path)));
|
||||
boxed_resolver.borrow().borrow_mut().access(|resolver| {
|
||||
for cnum in resolver.cstore().crates_untracked() {
|
||||
let source = resolver.cstore().crate_source_untracked(cnum);
|
||||
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)?;
|
||||
@ -713,6 +662,7 @@ pub fn prepare_outputs(
|
||||
sess: &Session,
|
||||
compiler: &Compiler,
|
||||
krate: &ast::Crate,
|
||||
boxed_resolver: &Steal<Rc<RefCell<BoxedResolver>>>,
|
||||
crate_name: &str
|
||||
) -> Result<OutputFilenames> {
|
||||
// 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)
|
||||
&& sess.opts.output_types.len() == 1;
|
||||
@ -817,27 +767,26 @@ impl BoxedGlobalCtxt {
|
||||
|
||||
pub fn create_global_ctxt(
|
||||
compiler: &Compiler,
|
||||
lint_store: Lrc<lint::LintStore>,
|
||||
mut hir_forest: hir::map::Forest,
|
||||
defs: hir::map::Definitions,
|
||||
resolutions: Resolutions,
|
||||
mut resolver_outputs: ResolverOutputs,
|
||||
outputs: OutputFilenames,
|
||||
crate_name: &str,
|
||||
) -> BoxedGlobalCtxt {
|
||||
let sess = compiler.session().clone();
|
||||
let cstore = compiler.cstore.clone();
|
||||
let codegen_backend = compiler.codegen_backend().clone();
|
||||
let crate_name = crate_name.to_string();
|
||||
let defs = mem::take(&mut resolver_outputs.definitions);
|
||||
|
||||
let ((), result) = BoxedGlobalCtxt::new(static move || {
|
||||
let sess = &*sess;
|
||||
let cstore = &*cstore;
|
||||
|
||||
let global_ctxt: Option<GlobalCtxt<'_>>;
|
||||
let arenas = AllArenas::new();
|
||||
|
||||
// Construct the HIR map.
|
||||
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", || {
|
||||
@ -854,11 +803,11 @@ pub fn create_global_ctxt(
|
||||
|
||||
let gcx = TyCtxt::create_global_ctxt(
|
||||
sess,
|
||||
cstore,
|
||||
lint_store,
|
||||
local_providers,
|
||||
extern_providers,
|
||||
&arenas,
|
||||
resolutions,
|
||||
resolver_outputs,
|
||||
hir_map,
|
||||
query_result_on_disk_cache,
|
||||
&crate_name,
|
||||
|
@ -1,12 +1,17 @@
|
||||
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_data_structures::sync::Lrc;
|
||||
use rustc::session::config::{OutputFilenames, OutputType};
|
||||
use rustc::util::common::{time, ErrorReported};
|
||||
use rustc::hir;
|
||||
use rustc::lint;
|
||||
use rustc::session::Session;
|
||||
use rustc::lint::LintStore;
|
||||
use rustc::hir::def_id::LOCAL_CRATE;
|
||||
use rustc::ty::steal::Steal;
|
||||
use rustc::ty::ResolverOutputs;
|
||||
use rustc::dep_graph::DepGraph;
|
||||
use std::cell::{Ref, RefMut, RefCell};
|
||||
use std::rc::Rc;
|
||||
@ -74,10 +79,10 @@ pub(crate) struct Queries {
|
||||
dep_graph_future: Query<Option<DepGraphFuture>>,
|
||||
parse: Query<ast::Crate>,
|
||||
crate_name: Query<String>,
|
||||
register_plugins: Query<(ast::Crate, PluginInfo)>,
|
||||
expansion: Query<(ast::Crate, Steal<Rc<RefCell<BoxedResolver>>>)>,
|
||||
register_plugins: Query<(ast::Crate, PluginInfo, Lrc<LintStore>)>,
|
||||
expansion: Query<(ast::Crate, Steal<Rc<RefCell<BoxedResolver>>>, Lrc<LintStore>)>,
|
||||
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>,
|
||||
global_ctxt: Query<BoxedGlobalCtxt>,
|
||||
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(|| {
|
||||
let crate_name = self.crate_name()?.peek().clone();
|
||||
let krate = self.parse()?.take();
|
||||
|
||||
let empty: &(dyn Fn(&Session, &mut lint::LintStore) + Sync + Send) = &|_, _| {};
|
||||
let result = passes::register_plugins(
|
||||
self.session(),
|
||||
self.cstore(),
|
||||
&*self.codegen_backend().metadata_loader(),
|
||||
self.register_lints
|
||||
.as_ref()
|
||||
.map(|p| &**p)
|
||||
.unwrap_or_else(|| empty),
|
||||
krate,
|
||||
&crate_name,
|
||||
);
|
||||
@ -148,17 +158,20 @@ impl Compiler {
|
||||
|
||||
pub fn expansion(
|
||||
&self
|
||||
) -> Result<&Query<(ast::Crate, Steal<Rc<RefCell<BoxedResolver>>>)>> {
|
||||
) -> Result<&Query<(ast::Crate, Steal<Rc<RefCell<BoxedResolver>>>, Lrc<LintStore>)>> {
|
||||
self.queries.expansion.compute(|| {
|
||||
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(
|
||||
self.sess.clone(),
|
||||
self.cstore().clone(),
|
||||
lint_store.clone(),
|
||||
self.codegen_backend().metadata_loader(),
|
||||
krate,
|
||||
&crate_name,
|
||||
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(|| {
|
||||
let expansion_result = self.expansion()?;
|
||||
let peeked = expansion_result.peek();
|
||||
let krate = &peeked.0;
|
||||
let resolver = peeked.1.steal();
|
||||
let lint_store = &peeked.2;
|
||||
let hir = Steal::new(resolver.borrow_mut().access(|resolver| {
|
||||
passes::lower_to_hir(
|
||||
self.session(),
|
||||
self.cstore(),
|
||||
lint_store,
|
||||
resolver,
|
||||
&*self.dep_graph()?.peek(),
|
||||
&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>> {
|
||||
self.queries.prepare_outputs.compute(|| {
|
||||
let krate = self.expansion()?;
|
||||
let krate = krate.peek();
|
||||
let expansion_result = self.expansion()?;
|
||||
let (krate, boxed_resolver, _) = &*expansion_result.peek();
|
||||
let crate_name = self.crate_name()?;
|
||||
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(|| {
|
||||
let crate_name = self.crate_name()?.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 = hir.peek();
|
||||
let (ref hir_forest, ref expansion) = *hir;
|
||||
let (hir_forest, resolver_outputs) = &*hir;
|
||||
Ok(passes::create_global_ctxt(
|
||||
self,
|
||||
lint_store,
|
||||
hir_forest.steal(),
|
||||
expansion.defs.steal(),
|
||||
expansion.resolutions.steal(),
|
||||
resolver_outputs.steal(),
|
||||
outputs,
|
||||
&crate_name))
|
||||
})
|
||||
|
@ -13,7 +13,6 @@ use rustc_data_structures::fingerprint::Fingerprint;
|
||||
use rustc_data_structures::thin_vec::ThinVec;
|
||||
use rustc_data_structures::fx::{FxHashSet, FxHashMap};
|
||||
use rustc_errors::registry::Registry;
|
||||
use rustc_lint;
|
||||
use rustc_metadata::dynamic_lib::DynamicLibrary;
|
||||
use rustc_mir;
|
||||
use rustc_passes;
|
||||
@ -108,11 +107,6 @@ pub fn create_session(
|
||||
|
||||
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));
|
||||
add_configuration(&mut cfg, &sess, &*codegen_backend);
|
||||
sess.parse_sess.config = cfg;
|
||||
|
@ -27,6 +27,7 @@ use rustc::hir::def::{Res, DefKind};
|
||||
use rustc::hir::def_id::{DefId, LOCAL_CRATE};
|
||||
use rustc::ty::{self, Ty, TyCtxt, layout::VariantIdx};
|
||||
use rustc::{lint, util};
|
||||
use rustc::lint::FutureIncompatibleInfo;
|
||||
use hir::Node;
|
||||
use util::nodemap::HirIdSet;
|
||||
use lint::{LateContext, LintContext, LintArray};
|
||||
@ -280,7 +281,7 @@ declare_lint! {
|
||||
pub MISSING_DOCS,
|
||||
Allow,
|
||||
"detects missing documentation for public members",
|
||||
report_in_external_macro: true
|
||||
report_in_external_macro
|
||||
}
|
||||
|
||||
pub struct MissingDoc {
|
||||
@ -601,7 +602,11 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingDebugImplementations {
|
||||
declare_lint! {
|
||||
pub ANONYMOUS_PARAMETERS,
|
||||
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!(
|
||||
@ -1344,7 +1349,7 @@ declare_lint! {
|
||||
UNNAMEABLE_TEST_ITEMS,
|
||||
Warn,
|
||||
"detects an item that cannot be named being marked as `#[test_case]`",
|
||||
report_in_external_macro: true
|
||||
report_in_external_macro
|
||||
}
|
||||
|
||||
pub struct UnnameableTestItems {
|
||||
@ -1393,7 +1398,11 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnnameableTestItems {
|
||||
declare_lint! {
|
||||
pub KEYWORD_IDENTS,
|
||||
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!(
|
||||
|
@ -33,27 +33,21 @@ use rustc::lint;
|
||||
use rustc::lint::{EarlyContext, LateContext, LateLintPass, EarlyLintPass, LintPass, LintArray};
|
||||
use rustc::lint::builtin::{
|
||||
BARE_TRAIT_OBJECTS,
|
||||
ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE,
|
||||
ELIDED_LIFETIMES_IN_PATHS,
|
||||
EXPLICIT_OUTLIVES_REQUIREMENTS,
|
||||
INTRA_DOC_LINK_RESOLUTION_FAILURE,
|
||||
MISSING_DOC_CODE_EXAMPLES,
|
||||
PRIVATE_DOC_TESTS,
|
||||
parser::ILL_FORMED_ATTRIBUTE_INPUT,
|
||||
};
|
||||
use rustc::session;
|
||||
use rustc::hir;
|
||||
use rustc::hir::def_id::DefId;
|
||||
use rustc::ty::query::Providers;
|
||||
use rustc::ty::TyCtxt;
|
||||
|
||||
use syntax::ast;
|
||||
use syntax::edition::Edition;
|
||||
use syntax_pos::Span;
|
||||
|
||||
use session::Session;
|
||||
use lint::LintId;
|
||||
use lint::FutureIncompatibleInfo;
|
||||
|
||||
use redundant_semicolon::*;
|
||||
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]);
|
||||
|
||||
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
|
||||
/// defined in this crate and the ones defined in
|
||||
/// `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 {
|
||||
($sess:ident, $name:expr, $($lint:ident),*) => (
|
||||
store.register_group($sess, false, $name, None, vec![$(LintId::of($lint)),*]);
|
||||
($name:expr, $($lint:ident),*) => (
|
||||
store.register_group(false, $name, None, vec![$(LintId::of($lint)),*]);
|
||||
)
|
||||
}
|
||||
|
||||
macro_rules! register_pass {
|
||||
($method:ident, $constructor:expr, [$($args:expr),*]) => (
|
||||
store.$method(sess, false, false, $($args,)* box $constructor);
|
||||
($method:ident, $ty:ident, $constructor:expr) => (
|
||||
store.register_lints(&$ty::get_lints());
|
||||
store.$method(|| box $constructor);
|
||||
)
|
||||
}
|
||||
|
||||
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) {
|
||||
pre_expansion_lint_passes!(register_passes, [register_pre_expansion_pass, []]);
|
||||
early_lint_passes!(register_passes, [register_early_pass, []]);
|
||||
late_lint_passes!(register_passes, [register_late_pass, [false]]);
|
||||
late_lint_mod_passes!(register_passes, [register_late_pass, [true]]);
|
||||
if no_interleave_lints {
|
||||
pre_expansion_lint_passes!(register_passes, register_pre_expansion_pass);
|
||||
early_lint_passes!(register_passes, register_early_pass);
|
||||
late_lint_passes!(register_passes, register_late_pass);
|
||||
late_lint_mod_passes!(register_passes, register_late_mod_pass);
|
||||
} else {
|
||||
store.register_pre_expansion_pass(
|
||||
sess,
|
||||
false,
|
||||
true,
|
||||
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()
|
||||
);
|
||||
store.register_lints(&BuiltinCombinedPreExpansionLintPass::get_lints());
|
||||
store.register_lints(&BuiltinCombinedEarlyLintPass::get_lints());
|
||||
store.register_lints(&BuiltinCombinedModuleLateLintPass::get_lints());
|
||||
store.register_lints(&BuiltinCombinedLateLintPass::get_lints());
|
||||
}
|
||||
|
||||
add_lint_group!(sess,
|
||||
"nonstandard_style",
|
||||
add_lint_group!("nonstandard_style",
|
||||
NON_CAMEL_CASE_TYPES,
|
||||
NON_SNAKE_CASE,
|
||||
NON_UPPER_CASE_GLOBALS);
|
||||
|
||||
add_lint_group!(sess,
|
||||
"unused",
|
||||
add_lint_group!("unused",
|
||||
UNUSED_IMPORTS,
|
||||
UNUSED_VARIABLES,
|
||||
UNUSED_ASSIGNMENTS,
|
||||
@ -265,8 +260,7 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
|
||||
UNUSED_LABELS,
|
||||
UNUSED_PARENS);
|
||||
|
||||
add_lint_group!(sess,
|
||||
"rust_2018_idioms",
|
||||
add_lint_group!("rust_2018_idioms",
|
||||
BARE_TRAIT_OBJECTS,
|
||||
UNUSED_EXTERN_CRATES,
|
||||
ELLIPSIS_INCLUSIVE_RANGE_PATTERNS,
|
||||
@ -282,165 +276,11 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
|
||||
// MACRO_USE_EXTERN_CRATE,
|
||||
);
|
||||
|
||||
add_lint_group!(sess,
|
||||
"rustdoc",
|
||||
add_lint_group!("rustdoc",
|
||||
INTRA_DOC_LINK_RESOLUTION_FAILURE,
|
||||
MISSING_DOC_CODE_EXAMPLES,
|
||||
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.
|
||||
store.register_renamed("single_use_lifetime", "single_use_lifetimes");
|
||||
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");
|
||||
}
|
||||
|
||||
pub fn register_internals(store: &mut lint::LintStore, sess: Option<&Session>) {
|
||||
store.register_early_pass(sess, false, false, box DefaultHashTypes::new());
|
||||
store.register_early_pass(sess, false, false, box LintPassImpl);
|
||||
store.register_late_pass(sess, false, false, false, box TyTyKind);
|
||||
fn register_internals(store: &mut lint::LintStore) {
|
||||
store.register_lints(&DefaultHashTypes::get_lints());
|
||||
store.register_early_pass(|| box DefaultHashTypes::new());
|
||||
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(
|
||||
sess,
|
||||
false,
|
||||
"rustc::internal",
|
||||
None,
|
||||
|
@ -25,7 +25,7 @@ declare_lint! {
|
||||
pub UNUSED_MUST_USE,
|
||||
Warn,
|
||||
"unused result of a type flagged as `#[must_use]`",
|
||||
report_in_external_macro: true
|
||||
report_in_external_macro
|
||||
}
|
||||
|
||||
declare_lint! {
|
||||
|
@ -3,7 +3,7 @@
|
||||
use crate::cstore::{self, CStore, MetadataBlob};
|
||||
use crate::locator::{self, CratePaths};
|
||||
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_data_structures::svh::Svh;
|
||||
@ -14,21 +14,20 @@ use rustc::session::{Session, CrateDisambiguator};
|
||||
use rustc::session::config::{Sanitizer, self};
|
||||
use rustc_target::spec::{PanicStrategy, TargetTriple};
|
||||
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::nodemap::FxHashSet;
|
||||
use rustc::hir::map::Definitions;
|
||||
use rustc::hir::def_id::LOCAL_CRATE;
|
||||
|
||||
use std::ops::Deref;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::path::Path;
|
||||
use std::{cmp, fs};
|
||||
|
||||
use syntax::ast;
|
||||
use syntax::attr;
|
||||
use syntax_expand::allocator::{global_allocator_spans, AllocatorKind};
|
||||
use syntax::symbol::{Symbol, sym};
|
||||
use syntax::{span_err, span_fatal};
|
||||
use syntax::span_fatal;
|
||||
use syntax_pos::{Span, DUMMY_SP};
|
||||
use log::{debug, info, log_enabled};
|
||||
use proc_macro::bridge::client::ProcMacro;
|
||||
@ -39,9 +38,12 @@ crate struct Library {
|
||||
}
|
||||
|
||||
pub struct CrateLoader<'a> {
|
||||
// Immutable configuration.
|
||||
sess: &'a Session,
|
||||
cstore: &'a CStore,
|
||||
metadata_loader: &'a MetadataLoaderDyn,
|
||||
local_crate_name: Symbol,
|
||||
// Mutable output.
|
||||
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 {
|
||||
Previous(CrateNum),
|
||||
Loaded(Library),
|
||||
@ -99,14 +78,27 @@ impl<'a> LoadError<'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 {
|
||||
sess,
|
||||
cstore,
|
||||
metadata_loader,
|
||||
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)
|
||||
-> Option<CrateNum> {
|
||||
let mut ret = None;
|
||||
@ -187,14 +179,14 @@ impl<'a> CrateLoader<'a> {
|
||||
}
|
||||
|
||||
fn register_crate(
|
||||
&self,
|
||||
&mut self,
|
||||
host_lib: Option<Library>,
|
||||
root: Option<&CratePaths>,
|
||||
span: Span,
|
||||
lib: Library,
|
||||
dep_kind: DepKind,
|
||||
name: Symbol
|
||||
) -> (CrateNum, Lrc<cstore::CrateMetadata>) {
|
||||
) -> CrateNum {
|
||||
let _prof_timer = self.sess.prof.generic_activity("metadata_register_crate");
|
||||
|
||||
let Library { source, metadata } = lib;
|
||||
@ -248,9 +240,9 @@ impl<'a> CrateLoader<'a> {
|
||||
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),
|
||||
def_path_table: Lrc::new(def_path_table),
|
||||
def_path_table,
|
||||
trait_impls,
|
||||
root: crate_root,
|
||||
blob: metadata,
|
||||
@ -264,11 +256,9 @@ impl<'a> CrateLoader<'a> {
|
||||
private_dep,
|
||||
raw_proc_macros,
|
||||
dep_node_index: AtomicCell::new(DepNodeIndex::INVALID),
|
||||
};
|
||||
});
|
||||
|
||||
let cmeta = Lrc::new(cmeta);
|
||||
self.cstore.set_crate_data(cnum, cmeta.clone());
|
||||
(cnum, cmeta)
|
||||
cnum
|
||||
}
|
||||
|
||||
fn load_proc_macro<'b>(
|
||||
@ -327,22 +317,22 @@ impl<'a> CrateLoader<'a> {
|
||||
}
|
||||
|
||||
fn resolve_crate<'b>(
|
||||
&'b self,
|
||||
&'b mut self,
|
||||
name: Symbol,
|
||||
span: Span,
|
||||
dep_kind: DepKind,
|
||||
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())
|
||||
}
|
||||
|
||||
fn maybe_resolve_crate<'b>(
|
||||
&'b self,
|
||||
&'b mut self,
|
||||
name: Symbol,
|
||||
span: Span,
|
||||
mut dep_kind: DepKind,
|
||||
dep: Option<(&'b CratePaths, &'b CrateDep)>,
|
||||
) -> Result<(CrateNum, Lrc<cstore::CrateMetadata>), LoadError<'b>> {
|
||||
) -> Result<CrateNum, LoadError<'b>> {
|
||||
info!("resolving crate `{}`", name);
|
||||
let (root, hash, extra_filename, path_kind) = match dep {
|
||||
Some((root, dep)) =>
|
||||
@ -370,7 +360,7 @@ impl<'a> CrateLoader<'a> {
|
||||
rejected_via_filename: vec![],
|
||||
should_match_name: true,
|
||||
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(|| {
|
||||
@ -388,7 +378,7 @@ impl<'a> CrateLoader<'a> {
|
||||
data.dep_kind.with_lock(|data_dep_kind| {
|
||||
*data_dep_kind = cmp::max(*data_dep_kind, dep_kind);
|
||||
});
|
||||
Ok((cnum, data))
|
||||
Ok(cnum)
|
||||
}
|
||||
(LoadResult::Loaded(library), host_library) => {
|
||||
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
|
||||
fn resolve_crate_deps(&self,
|
||||
fn resolve_crate_deps(&mut self,
|
||||
root: &CratePaths,
|
||||
crate_root: &CrateRoot<'_>,
|
||||
metadata: &MetadataBlob,
|
||||
@ -492,73 +482,10 @@ impl<'a> CrateLoader<'a> {
|
||||
DepKind::MacrosOnly => DepKind::MacrosOnly,
|
||||
_ => 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()
|
||||
}
|
||||
|
||||
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,
|
||||
path: &Path,
|
||||
disambiguator: CrateDisambiguator,
|
||||
@ -590,42 +517,7 @@ impl<'a> CrateLoader<'a> {
|
||||
decls
|
||||
}
|
||||
|
||||
/// Look for a plugin registrar. Returns library path, 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) {
|
||||
fn inject_panic_runtime(&mut self, krate: &ast::Crate) {
|
||||
// If we're only compiling an rlib, then there's no need to select a
|
||||
// panic runtime, so we just skip this section entirely.
|
||||
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);
|
||||
|
||||
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
|
||||
// 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);
|
||||
}
|
||||
|
||||
fn inject_sanitizer_runtime(&self) {
|
||||
fn inject_sanitizer_runtime(&mut self) {
|
||||
if let Some(ref sanitizer) = self.sess.opts.debugging_opts.sanitizer {
|
||||
// Sanitizers can only be used on some tested platforms with
|
||||
// executables linked to `std`
|
||||
@ -791,7 +684,8 @@ impl<'a> CrateLoader<'a> {
|
||||
});
|
||||
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
|
||||
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 ||
|
||||
self.sess.opts.cg.profile_generate.enabled()
|
||||
{
|
||||
info!("loading profiler");
|
||||
|
||||
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
|
||||
if !data.root.profiler_runtime {
|
||||
@ -957,10 +852,8 @@ impl<'a> CrateLoader<'a> {
|
||||
data.dependencies.borrow_mut().push(krate);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> CrateLoader<'a> {
|
||||
pub fn postprocess(&self, krate: &ast::Crate) {
|
||||
pub fn postprocess(&mut self, krate: &ast::Crate) {
|
||||
self.inject_sanitizer_runtime();
|
||||
self.inject_profiler_runtime();
|
||||
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 {
|
||||
ast::ItemKind::ExternCrate(orig_name) => {
|
||||
debug!("resolving extern crate stmt. ident: {} orig_name: {:?}",
|
||||
@ -990,7 +887,7 @@ impl<'a> CrateLoader<'a> {
|
||||
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 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 {
|
||||
let cnum = self.resolve_crate(name, span, DepKind::Explicit, None).0;
|
||||
pub fn process_path_extern(&mut self, name: Symbol, span: Span) -> CrateNum {
|
||||
let cnum = self.resolve_crate(name, span, DepKind::Explicit, None);
|
||||
|
||||
self.update_extern_crate(
|
||||
cnum,
|
||||
@ -1028,8 +925,8 @@ impl<'a> CrateLoader<'a> {
|
||||
cnum
|
||||
}
|
||||
|
||||
pub fn maybe_process_path_extern(&self, name: Symbol, span: Span) -> Option<CrateNum> {
|
||||
let cnum = self.maybe_resolve_crate(name, span, DepKind::Explicit, None).ok()?.0;
|
||||
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()?;
|
||||
|
||||
self.update_extern_crate(
|
||||
cnum,
|
||||
|
@ -5,12 +5,13 @@ use crate::schema;
|
||||
use rustc::dep_graph::DepNodeIndex;
|
||||
use rustc::hir::def_id::{CrateNum, DefIndex};
|
||||
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_index::vec::IndexVec;
|
||||
use rustc::util::nodemap::FxHashMap;
|
||||
use rustc_data_structures::sync::{Lrc, RwLock, Lock, MetadataRef, AtomicCell};
|
||||
use syntax::ast;
|
||||
use syntax::edition::Edition;
|
||||
use syntax_expand::base::SyntaxExtension;
|
||||
use syntax_pos;
|
||||
use proc_macro::bridge::client::ProcMacro;
|
||||
@ -36,7 +37,7 @@ crate struct ImportedSourceFile {
|
||||
pub translated_source_file: Lrc<syntax_pos::SourceFile>,
|
||||
}
|
||||
|
||||
pub struct CrateMetadata {
|
||||
crate struct CrateMetadata {
|
||||
/// The primary crate data - binary metadata blob.
|
||||
crate blob: MetadataBlob,
|
||||
|
||||
@ -53,7 +54,7 @@ pub struct CrateMetadata {
|
||||
/// hashmap, which gives the reverse mapping. This allows us to
|
||||
/// quickly retrace a `DefPath`, which is needed for incremental
|
||||
/// compilation support.
|
||||
crate def_path_table: Lrc<DefPathTable>,
|
||||
crate def_path_table: DefPathTable,
|
||||
/// Trait impl data.
|
||||
/// FIXME: Used only from queries and can use query cache,
|
||||
/// so pre-decoding can probably be avoided.
|
||||
@ -94,50 +95,48 @@ pub struct CrateMetadata {
|
||||
crate extern_crate: Lock<Option<ExternCrate>>,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct CStore {
|
||||
metas: RwLock<IndexVec<CrateNum, Option<Lrc<CrateMetadata>>>>,
|
||||
crate metadata_loader: Box<dyn MetadataLoader + Sync>,
|
||||
metas: IndexVec<CrateNum, Option<Lrc<CrateMetadata>>>,
|
||||
}
|
||||
|
||||
pub enum LoadedMacro {
|
||||
MacroDef(ast::Item),
|
||||
MacroDef(ast::Item, Edition),
|
||||
ProcMacro(SyntaxExtension),
|
||||
}
|
||||
|
||||
impl CStore {
|
||||
pub fn new(metadata_loader: Box<dyn MetadataLoader + Sync>) -> CStore {
|
||||
impl Default for CStore {
|
||||
fn default() -> Self {
|
||||
CStore {
|
||||
// We add an empty entry for LOCAL_CRATE (which maps to zero) in
|
||||
// order to make array indices in `metas` match with the
|
||||
// corresponding `CrateNum`. This first entry will always remain
|
||||
// `None`.
|
||||
metas: RwLock::new(IndexVec::from_elem_n(None, 1)),
|
||||
metadata_loader,
|
||||
metas: IndexVec::from_elem_n(None, 1),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
crate fn alloc_new_crate_num(&self) -> CrateNum {
|
||||
let mut metas = self.metas.borrow_mut();
|
||||
let cnum = CrateNum::new(metas.len());
|
||||
metas.push(None);
|
||||
cnum
|
||||
impl CStore {
|
||||
crate fn alloc_new_crate_num(&mut self) -> CrateNum {
|
||||
self.metas.push(None);
|
||||
CrateNum::new(self.metas.len() - 1)
|
||||
}
|
||||
|
||||
crate fn get_crate_data(&self, cnum: CrateNum) -> Lrc<CrateMetadata> {
|
||||
self.metas.borrow()[cnum].clone()
|
||||
crate fn get_crate_data(&self, cnum: CrateNum) -> &CrateMetadata {
|
||||
self.metas[cnum].as_ref()
|
||||
.unwrap_or_else(|| panic!("Failed to get crate data for {:?}", cnum))
|
||||
}
|
||||
|
||||
crate fn set_crate_data(&self, cnum: CrateNum, data: Lrc<CrateMetadata>) {
|
||||
let mut metas = self.metas.borrow_mut();
|
||||
assert!(metas[cnum].is_none(), "Overwriting crate metadata entry");
|
||||
metas[cnum] = Some(data);
|
||||
crate fn set_crate_data(&mut self, cnum: CrateNum, data: CrateMetadata) {
|
||||
assert!(self.metas[cnum].is_none(), "Overwriting crate metadata entry");
|
||||
self.metas[cnum] = Some(Lrc::new(data));
|
||||
}
|
||||
|
||||
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 {
|
||||
i(k, v);
|
||||
}
|
||||
@ -168,7 +167,7 @@ impl CStore {
|
||||
|
||||
crate fn do_postorder_cnums_untracked(&self) -> Vec<CrateNum> {
|
||||
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 {
|
||||
self.push_dependencies_in_postorder(&mut ordering, num);
|
||||
}
|
||||
|
@ -29,7 +29,6 @@ use std::sync::Arc;
|
||||
use syntax::ast;
|
||||
use syntax::attr;
|
||||
use syntax::source_map;
|
||||
use syntax::edition::Edition;
|
||||
use syntax::parse::source_file_to_stream;
|
||||
use syntax::parse::parser::emit_unclosed_delims;
|
||||
use syntax::source_map::Spanned;
|
||||
@ -54,7 +53,7 @@ macro_rules! provide {
|
||||
let ($def_id, $other) = def_id_arg.into_args();
|
||||
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>()
|
||||
.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>> {
|
||||
self.get_crate_data(def.krate).get_struct_field_names(def.index, sess)
|
||||
}
|
||||
@ -460,7 +455,7 @@ impl cstore::CStore {
|
||||
|
||||
LoadedMacro::MacroDef(ast::Item {
|
||||
// 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,
|
||||
span: local_span,
|
||||
attrs: attrs.iter().cloned().collect(),
|
||||
@ -470,7 +465,7 @@ impl cstore::CStore {
|
||||
}),
|
||||
vis: source_map::respan(local_span.shrink_to_lo(), ast::VisibilityKind::Inherited),
|
||||
tokens: None,
|
||||
})
|
||||
}, data.root.edition)
|
||||
}
|
||||
|
||||
pub fn associated_item_cloned_untracked(&self, def: DefId) -> ty::AssocItem {
|
||||
@ -483,8 +478,8 @@ impl cstore::CStore {
|
||||
}
|
||||
|
||||
impl CrateStore for cstore::CStore {
|
||||
fn crate_data_as_rc_any(&self, krate: CrateNum) -> Lrc<dyn Any> {
|
||||
self.get_crate_data(krate)
|
||||
fn crate_data_as_any(&self, cnum: CrateNum) -> &dyn Any {
|
||||
self.get_crate_data(cnum)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
fn def_path_table(&self, cnum: CrateNum) -> Lrc<DefPathTable> {
|
||||
self.get_crate_data(cnum).def_path_table.clone()
|
||||
fn def_path_table(&self, cnum: CrateNum) -> &DefPathTable {
|
||||
&self.get_crate_data(cnum).def_path_table
|
||||
}
|
||||
|
||||
fn crates_untracked(&self) -> Vec<CrateNum>
|
||||
|
@ -35,7 +35,7 @@ use syntax::ast::{self, Ident};
|
||||
use syntax::source_map::{self, respan, Spanned};
|
||||
use syntax::symbol::{Symbol, sym};
|
||||
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 proc_macro::bridge::client::ProcMacro;
|
||||
use syntax_expand::proc_macro::{AttrProcMacro, ProcMacroDerive, BangProcMacro};
|
||||
@ -448,7 +448,7 @@ impl<'tcx> EntryKind<'tcx> {
|
||||
EntryKind::Mod(_) => DefKind::Mod,
|
||||
EntryKind::Variant(_) => DefKind::Variant,
|
||||
EntryKind::Trait(_) => DefKind::Trait,
|
||||
EntryKind::TraitAlias(_) => DefKind::TraitAlias,
|
||||
EntryKind::TraitAlias => DefKind::TraitAlias,
|
||||
EntryKind::Enum(..) => DefKind::Enum,
|
||||
EntryKind::MacroDef(_) => DefKind::Macro(MacroKind::Bang),
|
||||
EntryKind::ForeignType => DefKind::ForeignTy,
|
||||
@ -458,7 +458,7 @@ impl<'tcx> EntryKind<'tcx> {
|
||||
EntryKind::Impl(_) |
|
||||
EntryKind::Field |
|
||||
EntryKind::Generator(_) |
|
||||
EntryKind::Closure(_) => return None,
|
||||
EntryKind::Closure => return None,
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -514,7 +514,6 @@ impl<'a, 'tcx> CrateMetadata {
|
||||
.data
|
||||
.get_opt_name()
|
||||
.expect("no name in item_name")
|
||||
.as_symbol()
|
||||
} else {
|
||||
Symbol::intern(self.raw_proc_macro(item_index).name())
|
||||
}
|
||||
@ -575,7 +574,7 @@ impl<'a, 'tcx> CrateMetadata {
|
||||
data.is_marker,
|
||||
self.def_path_table.def_path_hash(item_id))
|
||||
},
|
||||
EntryKind::TraitAlias(_) => {
|
||||
EntryKind::TraitAlias => {
|
||||
ty::TraitDef::new(self.local_def_id(item_id),
|
||||
hir::Unsafety::Normal,
|
||||
false,
|
||||
@ -680,13 +679,7 @@ impl<'a, 'tcx> CrateMetadata {
|
||||
item_id: DefIndex,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
) -> ty::GenericPredicates<'tcx> {
|
||||
let super_predicates = match self.kind(item_id) {
|
||||
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))
|
||||
self.root.per_def.super_predicates.get(self, item_id).unwrap().decode((self, tcx))
|
||||
}
|
||||
|
||||
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) {
|
||||
EntryKind::Impl(data) => data.decode(self),
|
||||
_ => bug!(),
|
||||
@ -744,7 +737,7 @@ impl<'a, 'tcx> CrateMetadata {
|
||||
}
|
||||
|
||||
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.
|
||||
@ -864,7 +857,7 @@ impl<'a, 'tcx> CrateMetadata {
|
||||
let span = self.get_span(child_index, sess);
|
||||
if let (Some(kind), Some(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 def_id = self.local_def_id(child_index);
|
||||
let res = Res::Def(kind, def_id);
|
||||
@ -987,7 +980,7 @@ impl<'a, 'tcx> CrateMetadata {
|
||||
};
|
||||
|
||||
ty::AssocItem {
|
||||
ident: Ident::from_interned_str(name),
|
||||
ident: Ident::with_dummy_span(name),
|
||||
kind,
|
||||
vis: self.get_visibility(id),
|
||||
defaultness: container.defaultness(),
|
||||
@ -1118,7 +1111,7 @@ impl<'a, 'tcx> CrateMetadata {
|
||||
def_key.parent.and_then(|parent_index| {
|
||||
match self.kind(parent_index) {
|
||||
EntryKind::Trait(_) |
|
||||
EntryKind::TraitAlias(_) => Some(self.local_def_id(parent_index)),
|
||||
EntryKind::TraitAlias => Some(self.local_def_id(parent_index)),
|
||||
_ => None,
|
||||
}
|
||||
})
|
||||
@ -1245,16 +1238,7 @@ impl<'a, 'tcx> CrateMetadata {
|
||||
}
|
||||
|
||||
crate fn fn_sig(&self, id: DefIndex, tcx: TyCtxt<'tcx>) -> ty::PolyFnSig<'tcx> {
|
||||
let sig = match self.kind(id) {
|
||||
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))
|
||||
self.root.per_def.fn_sig.get(self, id).unwrap().decode((self, tcx))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@ -1262,7 +1246,7 @@ impl<'a, 'tcx> CrateMetadata {
|
||||
let mut key = self.def_path_table.def_key(index);
|
||||
if self.is_proc_macro(index) {
|
||||
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
|
||||
}
|
||||
|
@ -71,11 +71,14 @@ struct PerDefTables<'tcx> {
|
||||
deprecation: PerDefTable<Lazy<attr::Deprecation>>,
|
||||
|
||||
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]>>,
|
||||
variances: PerDefTable<Lazy<[ty::Variance]>>,
|
||||
generics: PerDefTable<Lazy<ty::Generics>>,
|
||||
predicates: 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>>>,
|
||||
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),
|
||||
|
||||
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),
|
||||
variances: self.per_def.variances.encode(&mut self.opaque),
|
||||
generics: self.per_def.generics.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),
|
||||
super_predicates: self.per_def.super_predicates.encode(&mut self.opaque),
|
||||
|
||||
mir: self.per_def.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 {
|
||||
ctor_kind: variant.ctor_kind,
|
||||
discr: variant.discr,
|
||||
// FIXME(eddyb) deduplicate these with `encode_enum_variant_ctor`.
|
||||
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();
|
||||
@ -660,6 +660,11 @@ impl EncodeContext<'tcx> {
|
||||
self.encode_deprecation(def_id);
|
||||
self.encode_item_type(def_id);
|
||||
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_generics(def_id);
|
||||
@ -679,15 +684,11 @@ impl EncodeContext<'tcx> {
|
||||
let def_id = variant.ctor_def_id.unwrap();
|
||||
debug!("EncodeContext::encode_enum_variant_ctor({:?})", def_id);
|
||||
|
||||
// FIXME(eddyb) encode only the `CtorKind` for constructors.
|
||||
let data = VariantData {
|
||||
ctor_kind: variant.ctor_kind,
|
||||
discr: variant.discr,
|
||||
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
|
||||
@ -706,6 +707,7 @@ impl EncodeContext<'tcx> {
|
||||
self.encode_deprecation(def_id);
|
||||
self.encode_item_type(def_id);
|
||||
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_generics(def_id);
|
||||
@ -780,11 +782,6 @@ impl EncodeContext<'tcx> {
|
||||
ctor_kind: variant.ctor_kind,
|
||||
discr: variant.discr,
|
||||
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();
|
||||
@ -811,6 +808,7 @@ impl EncodeContext<'tcx> {
|
||||
self.encode_deprecation(def_id);
|
||||
self.encode_item_type(def_id);
|
||||
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_generics(def_id);
|
||||
@ -835,6 +833,11 @@ impl EncodeContext<'tcx> {
|
||||
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) {
|
||||
debug!("EncodeContext::encode_info_for_trait_item({:?})", def_id);
|
||||
let tcx = self.tcx;
|
||||
@ -874,7 +877,6 @@ impl EncodeContext<'tcx> {
|
||||
asyncness: m_sig.header.asyncness,
|
||||
constness: hir::Constness::NotConst,
|
||||
param_names,
|
||||
sig: self.lazy(tcx.fn_sig(def_id)),
|
||||
}
|
||||
} else {
|
||||
bug!()
|
||||
@ -906,6 +908,7 @@ impl EncodeContext<'tcx> {
|
||||
ty::AssocKind::OpaqueTy => unreachable!(),
|
||||
}
|
||||
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_generics(def_id);
|
||||
@ -952,7 +955,6 @@ impl EncodeContext<'tcx> {
|
||||
asyncness: sig.header.asyncness,
|
||||
constness: sig.header.constness,
|
||||
param_names: self.encode_fn_param_names_for_body(body),
|
||||
sig: self.lazy(tcx.fn_sig(def_id)),
|
||||
}
|
||||
} else {
|
||||
bug!()
|
||||
@ -973,6 +975,7 @@ impl EncodeContext<'tcx> {
|
||||
self.encode_deprecation(def_id);
|
||||
self.encode_item_type(def_id);
|
||||
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_generics(def_id);
|
||||
@ -1081,7 +1084,6 @@ impl EncodeContext<'tcx> {
|
||||
asyncness: header.asyncness,
|
||||
constness: header.constness,
|
||||
param_names: self.encode_fn_param_names_for_body(body),
|
||||
sig: self.lazy(tcx.fn_sig(def_id)),
|
||||
};
|
||||
|
||||
EntryKind::Fn(self.lazy(data))
|
||||
@ -1109,7 +1111,6 @@ impl EncodeContext<'tcx> {
|
||||
ctor_kind: variant.ctor_kind,
|
||||
discr: variant.discr,
|
||||
ctor,
|
||||
ctor_sig: None,
|
||||
}), adt_def.repr)
|
||||
}
|
||||
hir::ItemKind::Union(..) => {
|
||||
@ -1120,7 +1121,6 @@ impl EncodeContext<'tcx> {
|
||||
ctor_kind: variant.ctor_kind,
|
||||
discr: variant.discr,
|
||||
ctor: None,
|
||||
ctor_sig: None,
|
||||
}), adt_def.repr)
|
||||
}
|
||||
hir::ItemKind::Impl(_, _, defaultness, ..) => {
|
||||
@ -1154,7 +1154,6 @@ impl EncodeContext<'tcx> {
|
||||
defaultness,
|
||||
parent_impl: parent,
|
||||
coerce_unsized_info,
|
||||
trait_ref: trait_ref.map(|trait_ref| self.lazy(trait_ref)),
|
||||
};
|
||||
|
||||
EntryKind::Impl(self.lazy(data))
|
||||
@ -1166,18 +1165,11 @@ impl EncodeContext<'tcx> {
|
||||
paren_sugar: trait_def.paren_sugar,
|
||||
has_auto_impl: self.tcx.trait_is_auto(def_id),
|
||||
is_marker: trait_def.is_marker,
|
||||
super_predicates: self.lazy(tcx.super_predicates_of(def_id)),
|
||||
};
|
||||
|
||||
EntryKind::Trait(self.lazy(data))
|
||||
}
|
||||
hir::ItemKind::TraitAlias(..) => {
|
||||
let data = TraitAliasData {
|
||||
super_predicates: self.lazy(tcx.super_predicates_of(def_id)),
|
||||
};
|
||||
|
||||
EntryKind::TraitAlias(self.lazy(data))
|
||||
}
|
||||
hir::ItemKind::TraitAlias(..) => EntryKind::TraitAlias,
|
||||
hir::ItemKind::ExternCrate(_) |
|
||||
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),
|
||||
_ => {}
|
||||
}
|
||||
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);
|
||||
match item.kind {
|
||||
hir::ItemKind::Enum(..) |
|
||||
@ -1269,6 +1269,13 @@ impl EncodeContext<'tcx> {
|
||||
}
|
||||
_ => {} // 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 {
|
||||
hir::ItemKind::Static(..) | hir::ItemKind::Const(..) => true,
|
||||
@ -1321,10 +1328,12 @@ impl EncodeContext<'tcx> {
|
||||
fn encode_info_for_closure(&mut self, def_id: DefId) {
|
||||
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 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, ..) => {
|
||||
let layout = self.tcx.generator_layout(def_id);
|
||||
let data = GeneratorData {
|
||||
@ -1333,11 +1342,7 @@ impl EncodeContext<'tcx> {
|
||||
EntryKind::Generator(self.lazy(data))
|
||||
}
|
||||
|
||||
ty::Closure(def_id, substs) => {
|
||||
let sig = substs.as_closure().sig(def_id, self.tcx);
|
||||
let data = ClosureData { sig: self.lazy(sig) };
|
||||
EntryKind::Closure(self.lazy(data))
|
||||
}
|
||||
ty::Closure(..) => EntryKind::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.attributes[def_id] <- &self.tcx.get_attrs(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_optimized_mir(def_id);
|
||||
self.encode_promoted_mir(def_id);
|
||||
@ -1553,7 +1561,6 @@ impl EncodeContext<'tcx> {
|
||||
asyncness: hir::IsAsync::NotAsync,
|
||||
constness: hir::Constness::NotConst,
|
||||
param_names: self.encode_fn_param_names(names),
|
||||
sig: self.lazy(tcx.fn_sig(def_id)),
|
||||
};
|
||||
EntryKind::ForeignFn(self.lazy(data))
|
||||
}
|
||||
@ -1569,6 +1576,7 @@ impl EncodeContext<'tcx> {
|
||||
self.encode_deprecation(def_id);
|
||||
self.encode_item_type(def_id);
|
||||
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_generics(def_id);
|
||||
|
@ -212,7 +212,7 @@
|
||||
//! no means all of the necessary details. Take a look at the rest of
|
||||
//! 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::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::sync::MetadataRef;
|
||||
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::search_paths::PathKind;
|
||||
use rustc::util::nodemap::FxHashMap;
|
||||
|
||||
use errors::DiagnosticBuilder;
|
||||
use syntax::{span_err, span_fatal};
|
||||
use syntax::symbol::{Symbol, sym};
|
||||
use syntax::struct_span_err;
|
||||
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.
|
||||
pub fn list_file_metadata(target: &Target,
|
||||
path: &Path,
|
||||
cstore: &CStore,
|
||||
metadata_loader: &dyn MetadataLoader,
|
||||
out: &mut dyn io::Write)
|
||||
-> io::Result<()> {
|
||||
let filename = path.file_name().unwrap().to_str().unwrap();
|
||||
@ -925,7 +1003,7 @@ pub fn list_file_metadata(target: &Target,
|
||||
} else {
|
||||
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),
|
||||
Err(msg) => write!(out, "{}\n", msg),
|
||||
}
|
||||
|
@ -238,11 +238,14 @@ crate struct LazyPerDefTables<'tcx> {
|
||||
pub deprecation: Lazy!(PerDefTable<Lazy<attr::Deprecation>>),
|
||||
|
||||
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 variances: Lazy!(PerDefTable<Lazy<[ty::Variance]>>),
|
||||
pub generics: Lazy!(PerDefTable<Lazy<ty::Generics>>),
|
||||
pub predicates: 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 promoted_mir: Lazy!(PerDefTable<Lazy!(IndexVec<mir::Promoted, mir::Body<'tcx>>)>),
|
||||
@ -264,22 +267,22 @@ crate enum EntryKind<'tcx> {
|
||||
OpaqueTy,
|
||||
Enum(ReprOptions),
|
||||
Field,
|
||||
Variant(Lazy!(VariantData<'tcx>)),
|
||||
Struct(Lazy!(VariantData<'tcx>), ReprOptions),
|
||||
Union(Lazy!(VariantData<'tcx>), ReprOptions),
|
||||
Fn(Lazy!(FnData<'tcx>)),
|
||||
ForeignFn(Lazy!(FnData<'tcx>)),
|
||||
Variant(Lazy<VariantData>),
|
||||
Struct(Lazy<VariantData>, ReprOptions),
|
||||
Union(Lazy<VariantData>, ReprOptions),
|
||||
Fn(Lazy<FnData>),
|
||||
ForeignFn(Lazy<FnData>),
|
||||
Mod(Lazy<ModData>),
|
||||
MacroDef(Lazy<MacroDef>),
|
||||
Closure(Lazy!(ClosureData<'tcx>)),
|
||||
Closure,
|
||||
Generator(Lazy!(GeneratorData<'tcx>)),
|
||||
Trait(Lazy!(TraitData<'tcx>)),
|
||||
Impl(Lazy!(ImplData<'tcx>)),
|
||||
Method(Lazy!(MethodData<'tcx>)),
|
||||
Trait(Lazy<TraitData>),
|
||||
Impl(Lazy<ImplData>),
|
||||
Method(Lazy<MethodData>),
|
||||
AssocType(AssocContainer),
|
||||
AssocOpaqueTy(AssocContainer),
|
||||
AssocConst(AssocContainer, ConstQualif, Lazy<RenderedConst>),
|
||||
TraitAlias(Lazy!(TraitAliasData<'tcx>)),
|
||||
TraitAlias,
|
||||
}
|
||||
|
||||
/// Additional data for EntryKind::Const and EntryKind::AssocConst
|
||||
@ -305,47 +308,37 @@ crate struct MacroDef {
|
||||
}
|
||||
|
||||
#[derive(RustcEncodable, RustcDecodable)]
|
||||
crate struct FnData<'tcx> {
|
||||
crate struct FnData {
|
||||
pub asyncness: hir::IsAsync,
|
||||
pub constness: hir::Constness,
|
||||
pub param_names: Lazy<[ast::Name]>,
|
||||
pub sig: Lazy!(ty::PolyFnSig<'tcx>),
|
||||
}
|
||||
|
||||
#[derive(RustcEncodable, RustcDecodable)]
|
||||
crate struct VariantData<'tcx> {
|
||||
crate struct VariantData {
|
||||
pub ctor_kind: CtorKind,
|
||||
pub discr: ty::VariantDiscr,
|
||||
/// If this is unit or tuple-variant/struct, then this is the index of the ctor id.
|
||||
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)]
|
||||
crate struct TraitData<'tcx> {
|
||||
crate struct TraitData {
|
||||
pub unsafety: hir::Unsafety,
|
||||
pub paren_sugar: bool,
|
||||
pub has_auto_impl: bool,
|
||||
pub is_marker: bool,
|
||||
pub super_predicates: Lazy!(ty::GenericPredicates<'tcx>),
|
||||
}
|
||||
|
||||
#[derive(RustcEncodable, RustcDecodable)]
|
||||
crate struct TraitAliasData<'tcx> {
|
||||
pub super_predicates: Lazy!(ty::GenericPredicates<'tcx>),
|
||||
}
|
||||
|
||||
#[derive(RustcEncodable, RustcDecodable)]
|
||||
crate struct ImplData<'tcx> {
|
||||
crate struct ImplData {
|
||||
pub polarity: ty::ImplPolarity,
|
||||
pub defaultness: hir::Defaultness,
|
||||
pub parent_impl: Option<DefId>,
|
||||
|
||||
/// 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 trait_ref: Option<Lazy!(ty::TraitRef<'tcx>)>,
|
||||
}
|
||||
|
||||
|
||||
@ -388,17 +381,12 @@ impl AssocContainer {
|
||||
}
|
||||
|
||||
#[derive(RustcEncodable, RustcDecodable)]
|
||||
crate struct MethodData<'tcx> {
|
||||
pub fn_data: FnData<'tcx>,
|
||||
crate struct MethodData {
|
||||
pub fn_data: FnData,
|
||||
pub container: AssocContainer,
|
||||
pub has_self: bool,
|
||||
}
|
||||
|
||||
#[derive(RustcEncodable, RustcDecodable)]
|
||||
crate struct ClosureData<'tcx> {
|
||||
pub sig: Lazy!(ty::PolyFnSig<'tcx>),
|
||||
}
|
||||
|
||||
#[derive(RustcEncodable, RustcDecodable)]
|
||||
crate struct GeneratorData<'tcx> {
|
||||
pub layout: mir::GeneratorLayout<'tcx>,
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user