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

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

View File

@ -128,6 +128,14 @@ the master branch to your feature branch.
Also, please make sure that fixup commits are squashed into other related
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

View File

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

View File

@ -443,6 +443,7 @@ impl<'a> Builder<'a> {
dist::Rustc,
dist::DebuggerScripts,
dist::Std,
dist::RustcDev,
dist::Analysis,
dist::Src,
dist::PlainSourceTarball,

View File

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

View File

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

View File

@ -637,6 +637,28 @@ impl Step for DebuggerScripts {
}
}
fn skip_host_target_lib(builder: &Builder<'_>, compiler: Compiler) -> bool {
// The only true set of target libraries came from the build triple, so
// let's reduce redundant work by only producing archives from that host.
if compiler.host != builder.config.build {
builder.info("\tskipping, not a build host");
true
} else {
false
}
}
/// Copy stamped files into an image's `target/lib` directory.
fn copy_target_libs(builder: &Builder<'_>, target: &str, image: &Path, stamp: &Path) {
let dst = image.join("lib/rustlib").join(target).join("lib");
t!(fs::create_dir_all(&dst));
for (path, host) in builder.read_stamp_file(stamp) {
if !host || builder.config.build == target {
builder.copy(&path, &dst.join(path.file_name().unwrap()));
}
}
}
#[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)]
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
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,13 @@
# Known Issues
This section informs you about known "gotchas". Keep in mind, that this section is (and always will be) incomplete. For suggestions and amendments, feel free to [contribute](../contributing.md) to this guide.
## Target Features
Most target-feature problems arise, when mixing code that have the target-feature _enabled_ with code that have it _disabled_. If you want to avoid undefined behavior, it is recommended to build _all code_ (including the standard library and imported crates) with a common set of target-features.
By default, compiling your code with the `-C target-feature` flag will not recompile the entire standard library and/or imported crates with matching target features. Therefore, target features are generally considered as unsafe. Using `#[target_feature]` on individual functions makes the function unsafe.
Examples:
| Target-Feature | Issue | Seen on | Description | Details |
| -------------- | ----- | ------- | ----------- | ------- |
| `+soft-float` <br> and <br> `-sse` | Segfaults and ABI mismatches | `x86` and `x86-64` | The `x86` and `x86_64` architecture uses SSE registers (aka `xmm`) for floating point operations. Using software emulated floats ("soft-floats") disables usage of `xmm` registers, but parts of Rust's core libraries (e.g. `std::f32` or `std::f64`) are compiled without soft-floats and expect parameters to be passed in `xmm` registers. This leads to ABI mismatches. <br><br> Attempting to compile with disabled SSE causes the same error, too. | [#63466](https://github.com/rust-lang/rust/issues/63466) |

View File

@ -207,6 +207,47 @@ impl<B: ?Sized + ToOwned> Clone for Cow<'_, B> {
}
impl<B: ?Sized + ToOwned> Cow<'_, B> {
/// 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.

View File

@ -1817,7 +1817,7 @@ impl<T> VecDeque<T> {
}
}
return elem;
elem
}
/// Splits the `VecDeque` into two at the given index.

View File

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

View File

@ -456,7 +456,7 @@ impl str {
}
}
}
return s;
s
}
/// Converts a [`Box<str>`] into a [`String`] without copying or allocating.

View File

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

View File

@ -2025,7 +2025,7 @@ impl<T: ?Sized> Pointer for *const T {
if f.alternate() {
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);
}
}

View File

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

View File

@ -143,13 +143,12 @@ pub fn fast_path<T: RawFloat>(integral: &[u8], fractional: &[u8], e: i64) -> Opt
/// > not a bound for the true error, but bounds the difference between the approximation z and
/// > 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;

View File

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

View File

@ -156,21 +156,21 @@ unsafe extern "C" fn rust_eh_personality(version: c_int,
if actions as i32 & uw::_UA_SEARCH_PHASE as i32 != 0 {
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,
}
}
}

View File

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

View File

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

View File

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

View File

@ -83,8 +83,6 @@ pub struct LoweringContext<'a> {
/// Used to assign IDs to HIR nodes that do not directly correspond to AST nodes.
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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -3,7 +3,7 @@ use crate::mir::interpret::ConstValue;
use rustc_data_structures::unify::{NoError, EqUnifyValue, UnifyKey, UnifyValue, UnificationTable};
use rustc_data_structures::unify::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,
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -14,7 +14,7 @@ use crate::util::common::{duration_to_secs_str, ErrorReported};
use rustc_data_structures::base_n;
use rustc_data_structures::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())),

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -749,6 +749,7 @@ impl<'a, 'tcx> Lift<'tcx> for ty::error::TypeError<'a> {
ExistentialMismatch(ref x) => return tcx.lift(x).map(ExistentialMismatch),
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),
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -35,7 +35,7 @@ pub fn item_namespace(cx: &CodegenCx<'ll, '_>, def_id: DefId) -> &'ll DIScope {
let namespace_name = match def_key.disambiguated_data.data {
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);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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