diff options
| author | Tim Diekmann <21277928+TimDiekmann@users.noreply.github.com> | 2020-08-03 02:18:20 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-08-03 02:18:20 +0200 |
| commit | 24ddf76ed7bc453826e6e843cd0ca289e02185f1 (patch) | |
| tree | 2833654479a3749e6646890af4bdbc071b181f3b /src | |
| parent | db7d07b83bee302be977468caa6931f651b4f77a (diff) | |
| parent | 81e754c359c471f91263813c46c67955071716a7 (diff) | |
| download | rust-24ddf76ed7bc453826e6e843cd0ca289e02185f1.tar.gz rust-24ddf76ed7bc453826e6e843cd0ca289e02185f1.zip | |
Merge branch 'master' into remove-in-place-alloc
Diffstat (limited to 'src')
764 files changed, 7300 insertions, 5413 deletions
diff --git a/src/README.md b/src/README.md index b69a92a7237..2f8e9da179a 100644 --- a/src/README.md +++ b/src/README.md @@ -1,6 +1,6 @@ This directory contains the source code of the rust project, including: - `rustc` and its tests -- `libstd` +- The bootstrapping build system - Various submodules for tools, like rustdoc, rls, etc. For more information on how various parts of the compiler work, see the [rustc dev guide]. diff --git a/src/bootstrap/bin/rustc.rs b/src/bootstrap/bin/rustc.rs index d6649d0521c..4dd71ebade1 100644 --- a/src/bootstrap/bin/rustc.rs +++ b/src/bootstrap/bin/rustc.rs @@ -171,7 +171,9 @@ fn main() { // note: everything below here is unreachable. do not put code that // should run on success, after this block. } - println!("\nDid not run successfully: {}\n{:?}\n-------------", status, cmd); + if verbose > 0 { + println!("\nDid not run successfully: {}\n{:?}\n-------------", status, cmd); + } if let Some(mut on_fail) = on_fail { on_fail.status().expect("Could not run the on_fail command"); diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index c1e56347ab1..144e146685f 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -232,7 +232,7 @@ impl StepDescription { } if !attempted_run { - panic!("Error: no rules matched {}.", path.display()); + panic!("error: no rules matched {}", path.display()); } } } @@ -501,16 +501,7 @@ impl<'a> Builder<'a> { _ => return None, }; - let builder = Builder { - build, - top_stage: build.config.stage.unwrap_or(2), - kind, - cache: Cache::new(), - stack: RefCell::new(Vec::new()), - time_spent_on_dependencies: Cell::new(Duration::new(0, 0)), - paths: vec![], - }; - + let builder = Self::new_internal(build, kind, vec![]); let builder = &builder; let mut should_run = ShouldRun::new(builder); for desc in Builder::get_step_descriptions(builder.kind) { @@ -535,6 +526,32 @@ impl<'a> Builder<'a> { Some(help) } + fn new_internal(build: &Build, kind: Kind, paths: Vec<PathBuf>) -> Builder<'_> { + let top_stage = if let Some(explicit_stage) = build.config.stage { + explicit_stage + } else { + // See https://github.com/rust-lang/compiler-team/issues/326 + match kind { + Kind::Doc => 0, + Kind::Build | Kind::Test => 1, + Kind::Bench | Kind::Dist | Kind::Install => 2, + // These are all bootstrap tools, which don't depend on the compiler. + // The stage we pass shouldn't matter, but use 0 just in case. + Kind::Check | Kind::Clippy | Kind::Fix | Kind::Run | Kind::Format => 0, + } + }; + + Builder { + build, + top_stage, + kind, + cache: Cache::new(), + stack: RefCell::new(Vec::new()), + time_spent_on_dependencies: Cell::new(Duration::new(0, 0)), + paths, + } + } + pub fn new(build: &Build) -> Builder<'_> { let (kind, paths) = match build.config.cmd { Subcommand::Build { ref paths } => (Kind::Build, &paths[..]), @@ -550,15 +567,20 @@ impl<'a> Builder<'a> { Subcommand::Format { .. } | Subcommand::Clean { .. } => panic!(), }; - Builder { - build, - top_stage: build.config.stage.unwrap_or(2), - kind, - cache: Cache::new(), - stack: RefCell::new(Vec::new()), - time_spent_on_dependencies: Cell::new(Duration::new(0, 0)), - paths: paths.to_owned(), + let this = Self::new_internal(build, kind, paths.to_owned()); + + // CI should always run stage 2 builds, unless it specifically states otherwise + #[cfg(not(test))] + if build.config.stage.is_none() && build.ci_env != crate::CiEnv::None { + match kind { + Kind::Test | Kind::Doc | Kind::Build | Kind::Bench | Kind::Dist | Kind::Install => { + assert_eq!(this.top_stage, 2) + } + Kind::Check | Kind::Clippy | Kind::Fix | Kind::Run | Kind::Format => {} + } } + + this } pub fn execute_cli(&self) { diff --git a/src/bootstrap/builder/tests.rs b/src/bootstrap/builder/tests.rs index 6684ca82c27..111971534ba 100644 --- a/src/bootstrap/builder/tests.rs +++ b/src/bootstrap/builder/tests.rs @@ -2,8 +2,6 @@ use super::*; use crate::config::{Config, TargetSelection}; use std::thread; -use pretty_assertions::assert_eq; - fn configure(host: &[&str], target: &[&str]) -> Config { let mut config = Config::default_opts(); // don't save toolstates @@ -35,463 +33,562 @@ fn first<A, B>(v: Vec<(A, B)>) -> Vec<A> { v.into_iter().map(|(a, _)| a).collect::<Vec<_>>() } -#[test] -fn dist_baseline() { - let build = Build::new(configure(&[], &[])); - let mut builder = Builder::new(&build); - builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Dist), &[]); - - let a = TargetSelection::from_user("A"); - - assert_eq!(first(builder.cache.all::<dist::Docs>()), &[dist::Docs { host: a },]); - assert_eq!(first(builder.cache.all::<dist::Mingw>()), &[dist::Mingw { host: a },]); - assert_eq!( - first(builder.cache.all::<dist::Rustc>()), - &[dist::Rustc { compiler: Compiler { host: a, stage: 2 } },] - ); - assert_eq!( - first(builder.cache.all::<dist::Std>()), - &[dist::Std { compiler: Compiler { host: a, stage: 1 }, target: a },] - ); - assert_eq!(first(builder.cache.all::<dist::Src>()), &[dist::Src]); - // Make sure rustdoc is only built once. - assert_eq!( - first(builder.cache.all::<tool::Rustdoc>()), - &[tool::Rustdoc { compiler: Compiler { host: a, stage: 2 } },] - ); -} - -#[test] -fn dist_with_targets() { - let build = Build::new(configure(&[], &["B"])); - let mut builder = Builder::new(&build); - builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Dist), &[]); - - let a = TargetSelection::from_user("A"); - let b = TargetSelection::from_user("B"); - - assert_eq!( - first(builder.cache.all::<dist::Docs>()), - &[dist::Docs { host: a }, dist::Docs { host: b },] - ); - assert_eq!( - first(builder.cache.all::<dist::Mingw>()), - &[dist::Mingw { host: a }, dist::Mingw { host: b },] - ); - assert_eq!( - first(builder.cache.all::<dist::Rustc>()), - &[dist::Rustc { compiler: Compiler { host: a, stage: 2 } },] - ); - assert_eq!( - first(builder.cache.all::<dist::Std>()), - &[ - dist::Std { compiler: Compiler { host: a, stage: 1 }, target: a }, - dist::Std { compiler: Compiler { host: a, stage: 2 }, target: b }, - ] - ); - assert_eq!(first(builder.cache.all::<dist::Src>()), &[dist::Src]); -} - -#[test] -fn dist_with_hosts() { - let build = Build::new(configure(&["B"], &[])); - let mut builder = Builder::new(&build); - builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Dist), &[]); - - let a = TargetSelection::from_user("A"); - let b = TargetSelection::from_user("B"); - - assert_eq!( - first(builder.cache.all::<dist::Docs>()), - &[dist::Docs { host: a }, dist::Docs { host: b },] - ); - assert_eq!( - first(builder.cache.all::<dist::Mingw>()), - &[dist::Mingw { host: a }, dist::Mingw { host: b },] - ); - assert_eq!( - first(builder.cache.all::<dist::Rustc>()), - &[ - dist::Rustc { compiler: Compiler { host: a, stage: 2 } }, - dist::Rustc { compiler: Compiler { host: b, stage: 2 } }, - ] - ); - assert_eq!( - first(builder.cache.all::<dist::Std>()), - &[ - dist::Std { compiler: Compiler { host: a, stage: 1 }, target: a }, - dist::Std { compiler: Compiler { host: a, stage: 1 }, target: b }, - ] - ); - assert_eq!(first(builder.cache.all::<dist::Src>()), &[dist::Src]); -} - -#[test] -fn dist_only_cross_host() { - let a = TargetSelection::from_user("A"); - let b = TargetSelection::from_user("B"); - let mut build = Build::new(configure(&["B"], &[])); - build.config.docs = false; - build.config.extended = true; - build.hosts = vec![b]; - let mut builder = Builder::new(&build); - builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Dist), &[]); - - assert_eq!( - first(builder.cache.all::<dist::Rustc>()), - &[dist::Rustc { compiler: Compiler { host: b, stage: 2 } },] - ); - assert_eq!( - first(builder.cache.all::<compile::Rustc>()), - &[ - compile::Rustc { compiler: Compiler { host: a, stage: 0 }, target: a }, - compile::Rustc { compiler: Compiler { host: a, stage: 1 }, target: b }, - ] - ); -} - -#[test] -fn dist_with_targets_and_hosts() { - let build = Build::new(configure(&["B"], &["C"])); - let mut builder = Builder::new(&build); - builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Dist), &[]); - - let a = TargetSelection::from_user("A"); - let b = TargetSelection::from_user("B"); - let c = TargetSelection::from_user("C"); - - assert_eq!( - first(builder.cache.all::<dist::Docs>()), - &[dist::Docs { host: a }, dist::Docs { host: b }, dist::Docs { host: c },] - ); - assert_eq!( - first(builder.cache.all::<dist::Mingw>()), - &[dist::Mingw { host: a }, dist::Mingw { host: b }, dist::Mingw { host: c },] - ); - assert_eq!( - first(builder.cache.all::<dist::Rustc>()), - &[ - dist::Rustc { compiler: Compiler { host: a, stage: 2 } }, - dist::Rustc { compiler: Compiler { host: b, stage: 2 } }, - ] - ); - assert_eq!( - first(builder.cache.all::<dist::Std>()), - &[ - dist::Std { compiler: Compiler { host: a, stage: 1 }, target: a }, - dist::Std { compiler: Compiler { host: a, stage: 1 }, target: b }, - dist::Std { compiler: Compiler { host: a, stage: 2 }, target: c }, - ] - ); - assert_eq!(first(builder.cache.all::<dist::Src>()), &[dist::Src]); -} - -#[test] -fn dist_with_target_flag() { - let mut config = configure(&["B"], &["C"]); - config.skip_only_host_steps = true; // as-if --target=C was passed - let build = Build::new(config); - let mut builder = Builder::new(&build); - builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Dist), &[]); - - let a = TargetSelection::from_user("A"); - let b = TargetSelection::from_user("B"); - let c = TargetSelection::from_user("C"); - - assert_eq!( - first(builder.cache.all::<dist::Docs>()), - &[dist::Docs { host: a }, dist::Docs { host: b }, dist::Docs { host: c },] - ); - assert_eq!( - first(builder.cache.all::<dist::Mingw>()), - &[dist::Mingw { host: a }, dist::Mingw { host: b }, dist::Mingw { host: c },] - ); - assert_eq!(first(builder.cache.all::<dist::Rustc>()), &[]); - assert_eq!( - first(builder.cache.all::<dist::Std>()), - &[ - dist::Std { compiler: Compiler { host: a, stage: 1 }, target: a }, - dist::Std { compiler: Compiler { host: a, stage: 1 }, target: b }, - dist::Std { compiler: Compiler { host: a, stage: 2 }, target: c }, - ] - ); - assert_eq!(first(builder.cache.all::<dist::Src>()), &[]); -} - -#[test] -fn dist_with_same_targets_and_hosts() { - let build = Build::new(configure(&["B"], &["B"])); - let mut builder = Builder::new(&build); - builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Dist), &[]); - - let a = TargetSelection::from_user("A"); - let b = TargetSelection::from_user("B"); - - assert_eq!( - first(builder.cache.all::<dist::Docs>()), - &[dist::Docs { host: a }, dist::Docs { host: b },] - ); - assert_eq!( - first(builder.cache.all::<dist::Mingw>()), - &[dist::Mingw { host: a }, dist::Mingw { host: b },] - ); - assert_eq!( - first(builder.cache.all::<dist::Rustc>()), - &[ - dist::Rustc { compiler: Compiler { host: a, stage: 2 } }, - dist::Rustc { compiler: Compiler { host: b, stage: 2 } }, - ] - ); - assert_eq!( - first(builder.cache.all::<dist::Std>()), - &[ - dist::Std { compiler: Compiler { host: a, stage: 1 }, target: a }, - dist::Std { compiler: Compiler { host: a, stage: 1 }, target: b }, - ] - ); - assert_eq!(first(builder.cache.all::<dist::Src>()), &[dist::Src]); - assert_eq!( - first(builder.cache.all::<compile::Std>()), - &[ - compile::Std { compiler: Compiler { host: a, stage: 0 }, target: a }, - compile::Std { compiler: Compiler { host: a, stage: 1 }, target: a }, - compile::Std { compiler: Compiler { host: a, stage: 2 }, target: a }, - compile::Std { compiler: Compiler { host: a, stage: 1 }, target: b }, - compile::Std { compiler: Compiler { host: a, stage: 2 }, target: b }, - ] - ); - assert_eq!( - first(builder.cache.all::<compile::Assemble>()), - &[ - compile::Assemble { target_compiler: Compiler { host: a, stage: 0 } }, - compile::Assemble { target_compiler: Compiler { host: a, stage: 1 } }, - compile::Assemble { target_compiler: Compiler { host: a, stage: 2 } }, - compile::Assemble { target_compiler: Compiler { host: b, stage: 2 } }, - ] - ); -} - -#[test] -fn build_default() { - let build = Build::new(configure(&["B"], &["C"])); - let mut builder = Builder::new(&build); - builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Build), &[]); - - let a = TargetSelection::from_user("A"); - let b = TargetSelection::from_user("B"); - let c = TargetSelection::from_user("C"); - - assert_eq!( - first(builder.cache.all::<compile::Std>()), - &[ - compile::Std { compiler: Compiler { host: a, stage: 0 }, target: a }, - compile::Std { compiler: Compiler { host: a, stage: 1 }, target: a }, - compile::Std { compiler: Compiler { host: a, stage: 2 }, target: a }, - compile::Std { compiler: Compiler { host: b, stage: 2 }, target: a }, - compile::Std { compiler: Compiler { host: a, stage: 1 }, target: b }, - compile::Std { compiler: Compiler { host: a, stage: 2 }, target: b }, - compile::Std { compiler: Compiler { host: b, stage: 2 }, target: b }, - compile::Std { compiler: Compiler { host: a, stage: 2 }, target: c }, - compile::Std { compiler: Compiler { host: b, stage: 2 }, target: c }, - ] - ); - assert!(!builder.cache.all::<compile::Assemble>().is_empty()); - assert_eq!( - first(builder.cache.all::<compile::Rustc>()), - &[ - compile::Rustc { compiler: Compiler { host: a, stage: 0 }, target: a }, - compile::Rustc { compiler: Compiler { host: a, stage: 1 }, target: a }, - compile::Rustc { compiler: Compiler { host: a, stage: 2 }, target: a }, - compile::Rustc { compiler: Compiler { host: b, stage: 2 }, target: a }, - compile::Rustc { compiler: Compiler { host: a, stage: 1 }, target: b }, - compile::Rustc { compiler: Compiler { host: a, stage: 2 }, target: b }, - compile::Rustc { compiler: Compiler { host: b, stage: 2 }, target: b }, - ] - ); -} - -#[test] -fn build_with_target_flag() { - let mut config = configure(&["B"], &["C"]); - config.skip_only_host_steps = true; - let build = Build::new(config); - let mut builder = Builder::new(&build); - builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Build), &[]); - - let a = TargetSelection::from_user("A"); - let b = TargetSelection::from_user("B"); - let c = TargetSelection::from_user("C"); - - assert_eq!( - first(builder.cache.all::<compile::Std>()), - &[ - compile::Std { compiler: Compiler { host: a, stage: 0 }, target: a }, - compile::Std { compiler: Compiler { host: a, stage: 1 }, target: a }, - compile::Std { compiler: Compiler { host: a, stage: 2 }, target: a }, - compile::Std { compiler: Compiler { host: b, stage: 2 }, target: a }, - compile::Std { compiler: Compiler { host: a, stage: 1 }, target: b }, - compile::Std { compiler: Compiler { host: a, stage: 2 }, target: b }, - compile::Std { compiler: Compiler { host: b, stage: 2 }, target: b }, - compile::Std { compiler: Compiler { host: a, stage: 2 }, target: c }, - compile::Std { compiler: Compiler { host: b, stage: 2 }, target: c }, - ] - ); - assert_eq!( - first(builder.cache.all::<compile::Assemble>()), - &[ - compile::Assemble { target_compiler: Compiler { host: a, stage: 0 } }, - compile::Assemble { target_compiler: Compiler { host: a, stage: 1 } }, - compile::Assemble { target_compiler: Compiler { host: a, stage: 2 } }, - compile::Assemble { target_compiler: Compiler { host: b, stage: 2 } }, - ] - ); - assert_eq!( - first(builder.cache.all::<compile::Rustc>()), - &[ - compile::Rustc { compiler: Compiler { host: a, stage: 0 }, target: a }, - compile::Rustc { compiler: Compiler { host: a, stage: 1 }, target: a }, - compile::Rustc { compiler: Compiler { host: a, stage: 1 }, target: b }, - ] - ); -} - -#[test] -fn test_with_no_doc_stage0() { - let mut config = configure(&[], &[]); - config.stage = Some(0); - config.cmd = Subcommand::Test { - paths: vec!["library/std".into()], - test_args: vec![], - rustc_args: vec![], - fail_fast: true, - doc_tests: DocTests::No, - bless: false, - compare_mode: None, - rustfix_coverage: false, - pass: None, - }; - - let build = Build::new(config); - let mut builder = Builder::new(&build); - - let host = TargetSelection::from_user("A"); - - builder - .run_step_descriptions(&[StepDescription::from::<test::Crate>()], &["library/std".into()]); - - // Ensure we don't build any compiler artifacts. - assert!(!builder.cache.contains::<compile::Rustc>()); - assert_eq!( - first(builder.cache.all::<test::Crate>()), - &[test::Crate { - compiler: Compiler { host, stage: 0 }, - target: host, - mode: Mode::Std, - test_kind: test::TestKind::Test, - krate: INTERNER.intern_str("std"), - },] - ); -} - -#[test] -fn test_exclude() { - let mut config = configure(&[], &[]); - config.exclude = vec!["src/tools/tidy".into()]; - config.cmd = Subcommand::Test { - paths: Vec::new(), - test_args: Vec::new(), - rustc_args: Vec::new(), - fail_fast: true, - doc_tests: DocTests::No, - bless: false, - compare_mode: None, - rustfix_coverage: false, - pass: None, - }; - - let build = Build::new(config); - let builder = Builder::new(&build); - builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Test), &[]); - - // Ensure we have really excluded tidy - assert!(!builder.cache.contains::<test::Tidy>()); - - // Ensure other tests are not affected. - assert!(builder.cache.contains::<test::RustdocUi>()); -} - -#[test] -fn doc_default() { - let mut config = configure(&[], &[]); - config.compiler_docs = true; - config.cmd = Subcommand::Doc { paths: Vec::new(), open: false }; - let build = Build::new(config); - let mut builder = Builder::new(&build); - builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Doc), &[]); - let a = TargetSelection::from_user("A"); - - // error_index_generator uses stage 1 to share rustdoc artifacts with the - // rustdoc tool. - assert_eq!( - first(builder.cache.all::<doc::ErrorIndex>()), - &[doc::ErrorIndex { compiler: Compiler { host: a, stage: 1 }, target: a },] - ); - assert_eq!( - first(builder.cache.all::<tool::ErrorIndex>()), - &[tool::ErrorIndex { compiler: Compiler { host: a, stage: 1 } }] - ); - // This is actually stage 1, but Rustdoc::run swaps out the compiler with - // stage minus 1 if --stage is not 0. Very confusing! - assert_eq!( - first(builder.cache.all::<tool::Rustdoc>()), - &[tool::Rustdoc { compiler: Compiler { host: a, stage: 2 } },] - ); +mod defaults { + use super::{configure, first}; + use crate::builder::*; + use crate::Config; + use pretty_assertions::assert_eq; + + #[test] + fn build_default() { + let build = Build::new(configure(&[], &[])); + let mut builder = Builder::new(&build); + builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Build), &[]); + + let a = TargetSelection::from_user("A"); + assert_eq!( + first(builder.cache.all::<compile::Std>()), + &[ + compile::Std { compiler: Compiler { host: a, stage: 0 }, target: a }, + compile::Std { compiler: Compiler { host: a, stage: 1 }, target: a }, + ] + ); + assert!(!builder.cache.all::<compile::Assemble>().is_empty()); + // Make sure rustdoc is only built once. + assert_eq!( + first(builder.cache.all::<tool::Rustdoc>()), + // Recall that rustdoc stages are off-by-one + // - this is the compiler it's _linked_ to, not built with. + &[tool::Rustdoc { compiler: Compiler { host: a, stage: 1 } }], + ); + assert_eq!( + first(builder.cache.all::<compile::Rustc>()), + &[compile::Rustc { compiler: Compiler { host: a, stage: 0 }, target: a },] + ); + } + + #[test] + fn build_stage_0() { + let config = Config { stage: Some(0), ..configure(&[], &[]) }; + let build = Build::new(config); + let mut builder = Builder::new(&build); + builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Build), &[]); + + let a = TargetSelection::from_user("A"); + assert_eq!( + first(builder.cache.all::<compile::Std>()), + &[compile::Std { compiler: Compiler { host: a, stage: 0 }, target: a },] + ); + assert!(!builder.cache.all::<compile::Assemble>().is_empty()); + assert_eq!( + first(builder.cache.all::<tool::Rustdoc>()), + // This is the beta rustdoc. + // Add an assert here to make sure this is the only rustdoc built. + &[tool::Rustdoc { compiler: Compiler { host: a, stage: 0 } }], + ); + assert!(builder.cache.all::<compile::Rustc>().is_empty()); + } + + #[test] + fn doc_default() { + let mut config = configure(&[], &[]); + config.compiler_docs = true; + config.cmd = Subcommand::Doc { paths: Vec::new(), open: false }; + let build = Build::new(config); + let mut builder = Builder::new(&build); + builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Doc), &[]); + let a = TargetSelection::from_user("A"); + + // error_index_generator uses stage 0 to share rustdoc artifacts with the + // rustdoc tool. + assert_eq!( + first(builder.cache.all::<doc::ErrorIndex>()), + &[doc::ErrorIndex { compiler: Compiler { host: a, stage: 0 }, target: a },] + ); + assert_eq!( + first(builder.cache.all::<tool::ErrorIndex>()), + &[tool::ErrorIndex { compiler: Compiler { host: a, stage: 0 } }] + ); + // docs should be built with the beta compiler, not with the stage0 artifacts. + // recall that rustdoc is off-by-one: `stage` is the compiler rustdoc is _linked_ to, + // not the one it was built by. + assert_eq!( + first(builder.cache.all::<tool::Rustdoc>()), + &[tool::Rustdoc { compiler: Compiler { host: a, stage: 0 } },] + ); + } } -//FIXME(mark-i-m): reinstate this test when things are fixed... -//#[test] -#[allow(dead_code)] -fn test_docs() { - // Behavior of `x.py test` doing various documentation tests. - let mut config = configure(&[], &[]); - config.cmd = Subcommand::Test { - paths: vec![], - test_args: vec![], - rustc_args: vec![], - fail_fast: true, - doc_tests: DocTests::Yes, - bless: false, - compare_mode: None, - rustfix_coverage: false, - pass: None, - }; - let build = Build::new(config); - let mut builder = Builder::new(&build); - builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Test), &[]); - let a = TargetSelection::from_user("A"); - - // error_index_generator uses stage 1 to share rustdoc artifacts with the - // rustdoc tool. - assert_eq!( - first(builder.cache.all::<doc::ErrorIndex>()), - &[doc::ErrorIndex { compiler: Compiler { host: a, stage: 1 }, target: a },] - ); - assert_eq!( - first(builder.cache.all::<tool::ErrorIndex>()), - &[tool::ErrorIndex { compiler: Compiler { host: a, stage: 1 } }] - ); - // Unfortunately rustdoc is built twice. Once from stage1 for compiletest - // (and other things), and once from stage0 for std crates. Ideally it - // would only be built once. If someone wants to fix this, it might be - // worth investigating if it would be possible to test std from stage1. - // Note that the stages here are +1 than what they actually are because - // Rustdoc::run swaps out the compiler with stage minus 1 if --stage is - // not 0. - assert_eq!( - first(builder.cache.all::<tool::Rustdoc>()), - &[ - tool::Rustdoc { compiler: Compiler { host: a, stage: 1 } }, - tool::Rustdoc { compiler: Compiler { host: a, stage: 2 } }, - ] - ); +mod dist { + use super::{first, Config}; + use crate::builder::*; + use pretty_assertions::assert_eq; + + fn configure(host: &[&str], target: &[&str]) -> Config { + Config { stage: Some(2), ..super::configure(host, target) } + } + + #[test] + fn dist_baseline() { + let build = Build::new(configure(&[], &[])); + let mut builder = Builder::new(&build); + builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Dist), &[]); + + let a = TargetSelection::from_user("A"); + + assert_eq!(first(builder.cache.all::<dist::Docs>()), &[dist::Docs { host: a },]); + assert_eq!(first(builder.cache.all::<dist::Mingw>()), &[dist::Mingw { host: a },]); + assert_eq!( + first(builder.cache.all::<dist::Rustc>()), + &[dist::Rustc { compiler: Compiler { host: a, stage: 2 } },] + ); + assert_eq!( + first(builder.cache.all::<dist::Std>()), + &[dist::Std { compiler: Compiler { host: a, stage: 1 }, target: a },] + ); + assert_eq!(first(builder.cache.all::<dist::Src>()), &[dist::Src]); + // Make sure rustdoc is only built once. + assert_eq!( + first(builder.cache.all::<tool::Rustdoc>()), + &[tool::Rustdoc { compiler: Compiler { host: a, stage: 2 } },] + ); + } + + #[test] + fn dist_with_targets() { + let build = Build::new(configure(&[], &["B"])); + let mut builder = Builder::new(&build); + builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Dist), &[]); + + let a = TargetSelection::from_user("A"); + let b = TargetSelection::from_user("B"); + + assert_eq!( + first(builder.cache.all::<dist::Docs>()), + &[dist::Docs { host: a }, dist::Docs { host: b },] + ); + assert_eq!( + first(builder.cache.all::<dist::Mingw>()), + &[dist::Mingw { host: a }, dist::Mingw { host: b },] + ); + assert_eq!( + first(builder.cache.all::<dist::Rustc>()), + &[dist::Rustc { compiler: Compiler { host: a, stage: 2 } },] + ); + assert_eq!( + first(builder.cache.all::<dist::Std>()), + &[ + dist::Std { compiler: Compiler { host: a, stage: 1 }, target: a }, + dist::Std { compiler: Compiler { host: a, stage: 2 }, target: b }, + ] + ); + assert_eq!(first(builder.cache.all::<dist::Src>()), &[dist::Src]); + } + + #[test] + fn dist_with_hosts() { + let build = Build::new(configure(&["B"], &[])); + let mut builder = Builder::new(&build); + builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Dist), &[]); + + let a = TargetSelection::from_user("A"); + let b = TargetSelection::from_user("B"); + + assert_eq!( + first(builder.cache.all::<dist::Docs>()), + &[dist::Docs { host: a }, dist::Docs { host: b },] + ); + assert_eq!( + first(builder.cache.all::<dist::Mingw>()), + &[dist::Mingw { host: a }, dist::Mingw { host: b },] + ); + assert_eq!( + first(builder.cache.all::<dist::Rustc>()), + &[ + dist::Rustc { compiler: Compiler { host: a, stage: 2 } }, + dist::Rustc { compiler: Compiler { host: b, stage: 2 } }, + ] + ); + assert_eq!( + first(builder.cache.all::<dist::Std>()), + &[ + dist::Std { compiler: Compiler { host: a, stage: 1 }, target: a }, + dist::Std { compiler: Compiler { host: a, stage: 1 }, target: b }, + ] + ); + assert_eq!(first(builder.cache.all::<dist::Src>()), &[dist::Src]); + } + + #[test] + fn dist_only_cross_host() { + let a = TargetSelection::from_user("A"); + let b = TargetSelection::from_user("B"); + let mut build = Build::new(configure(&["B"], &[])); + build.config.docs = false; + build.config.extended = true; + build.hosts = vec![b]; + let mut builder = Builder::new(&build); + builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Dist), &[]); + + assert_eq!( + first(builder.cache.all::<dist::Rustc>()), + &[dist::Rustc { compiler: Compiler { host: b, stage: 2 } },] + ); + assert_eq!( + first(builder.cache.all::<compile::Rustc>()), + &[ + compile::Rustc { compiler: Compiler { host: a, stage: 0 }, target: a }, + compile::Rustc { compiler: Compiler { host: a, stage: 1 }, target: b }, + ] + ); + } + + #[test] + fn dist_with_targets_and_hosts() { + let build = Build::new(configure(&["B"], &["C"])); + let mut builder = Builder::new(&build); + builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Dist), &[]); + + let a = TargetSelection::from_user("A"); + let b = TargetSelection::from_user("B"); + let c = TargetSelection::from_user("C"); + + assert_eq!( + first(builder.cache.all::<dist::Docs>()), + &[dist::Docs { host: a }, dist::Docs { host: b }, dist::Docs { host: c },] + ); + assert_eq!( + first(builder.cache.all::<dist::Mingw>()), + &[dist::Mingw { host: a }, dist::Mingw { host: b }, dist::Mingw { host: c },] + ); + assert_eq!( + first(builder.cache.all::<dist::Rustc>()), + &[ + dist::Rustc { compiler: Compiler { host: a, stage: 2 } }, + dist::Rustc { compiler: Compiler { host: b, stage: 2 } }, + ] + ); + assert_eq!( + first(builder.cache.all::<dist::Std>()), + &[ + dist::Std { compiler: Compiler { host: a, stage: 1 }, target: a }, + dist::Std { compiler: Compiler { host: a, stage: 1 }, target: b }, + dist::Std { compiler: Compiler { host: a, stage: 2 }, target: c }, + ] + ); + assert_eq!(first(builder.cache.all::<dist::Src>()), &[dist::Src]); + } + + #[test] + fn dist_with_target_flag() { + let mut config = configure(&["B"], &["C"]); + config.skip_only_host_steps = true; // as-if --target=C was passed + let build = Build::new(config); + let mut builder = Builder::new(&build); + builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Dist), &[]); + + let a = TargetSelection::from_user("A"); + let b = TargetSelection::from_user("B"); + let c = TargetSelection::from_user("C"); + + assert_eq!( + first(builder.cache.all::<dist::Docs>()), + &[dist::Docs { host: a }, dist::Docs { host: b }, dist::Docs { host: c },] + ); + assert_eq!( + first(builder.cache.all::<dist::Mingw>()), + &[dist::Mingw { host: a }, dist::Mingw { host: b }, dist::Mingw { host: c },] + ); + assert_eq!(first(builder.cache.all::<dist::Rustc>()), &[]); + assert_eq!( + first(builder.cache.all::<dist::Std>()), + &[ + dist::Std { compiler: Compiler { host: a, stage: 1 }, target: a }, + dist::Std { compiler: Compiler { host: a, stage: 1 }, target: b }, + dist::Std { compiler: Compiler { host: a, stage: 2 }, target: c }, + ] + ); + assert_eq!(first(builder.cache.all::<dist::Src>()), &[]); + } + + #[test] + fn dist_with_same_targets_and_hosts() { + let build = Build::new(configure(&["B"], &["B"])); + let mut builder = Builder::new(&build); + builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Dist), &[]); + + let a = TargetSelection::from_user("A"); + let b = TargetSelection::from_user("B"); + + assert_eq!( + first(builder.cache.all::<dist::Docs>()), + &[dist::Docs { host: a }, dist::Docs { host: b },] + ); + assert_eq!( + first(builder.cache.all::<dist::Mingw>()), + &[dist::Mingw { host: a }, dist::Mingw { host: b },] + ); + assert_eq!( + first(builder.cache.all::<dist::Rustc>()), + &[ + dist::Rustc { compiler: Compiler { host: a, stage: 2 } }, + dist::Rustc { compiler: Compiler { host: b, stage: 2 } }, + ] + ); + assert_eq!( + first(builder.cache.all::<dist::Std>()), + &[ + dist::Std { compiler: Compiler { host: a, stage: 1 }, target: a }, + dist::Std { compiler: Compiler { host: a, stage: 1 }, target: b }, + ] + ); + assert_eq!(first(builder.cache.all::<dist::Src>()), &[dist::Src]); + assert_eq!( + first(builder.cache.all::<compile::Std>()), + &[ + compile::Std { compiler: Compiler { host: a, stage: 0 }, target: a }, + compile::Std { compiler: Compiler { host: a, stage: 1 }, target: a }, + compile::Std { compiler: Compiler { host: a, stage: 2 }, target: a }, + compile::Std { compiler: Compiler { host: a, stage: 1 }, target: b }, + compile::Std { compiler: Compiler { host: a, stage: 2 }, target: b }, + ] + ); + assert_eq!( + first(builder.cache.all::<compile::Assemble>()), + &[ + compile::Assemble { target_compiler: Compiler { host: a, stage: 0 } }, + compile::Assemble { target_compiler: Compiler { host: a, stage: 1 } }, + compile::Assemble { target_compiler: Compiler { host: a, stage: 2 } }, + compile::Assemble { target_compiler: Compiler { host: b, stage: 2 } }, + ] + ); + } + + #[test] + fn build_all() { + let build = Build::new(configure(&["B"], &["C"])); + let mut builder = Builder::new(&build); + builder.run_step_descriptions( + &Builder::get_step_descriptions(Kind::Build), + &["src/rustc".into(), "library/std".into()], + ); + + let a = TargetSelection::from_user("A"); + let b = TargetSelection::from_user("B"); + let c = TargetSelection::from_user("C"); + + assert_eq!( + first(builder.cache.all::<compile::Std>()), + &[ + compile::Std { compiler: Compiler { host: a, stage: 0 }, target: a }, + compile::Std { compiler: Compiler { host: a, stage: 1 }, target: a }, + compile::Std { compiler: Compiler { host: a, stage: 2 }, target: a }, + compile::Std { compiler: Compiler { host: b, stage: 2 }, target: a }, + compile::Std { compiler: Compiler { host: a, stage: 1 }, target: b }, + compile::Std { compiler: Compiler { host: a, stage: 2 }, target: b }, + compile::Std { compiler: Compiler { host: b, stage: 2 }, target: b }, + compile::Std { compiler: Compiler { host: a, stage: 2 }, target: c }, + compile::Std { compiler: Compiler { host: b, stage: 2 }, target: c }, + ] + ); + assert!(!builder.cache.all::<compile::Assemble>().is_empty()); + assert_eq!( + first(builder.cache.all::<compile::Rustc>()), + &[ + compile::Rustc { compiler: Compiler { host: a, stage: 0 }, target: a }, + compile::Rustc { compiler: Compiler { host: a, stage: 1 }, target: a }, + compile::Rustc { compiler: Compiler { host: a, stage: 2 }, target: a }, + compile::Rustc { compiler: Compiler { host: b, stage: 2 }, target: a }, + compile::Rustc { compiler: Compiler { host: a, stage: 1 }, target: b }, + compile::Rustc { compiler: Compiler { host: a, stage: 2 }, target: b }, + compile::Rustc { compiler: Compiler { host: b, stage: 2 }, target: b }, + ] + ); + } + + #[test] + fn build_with_target_flag() { + let mut config = configure(&["B"], &["C"]); + config.skip_only_host_steps = true; + let build = Build::new(config); + let mut builder = Builder::new(&build); + builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Build), &[]); + + let a = TargetSelection::from_user("A"); + let b = TargetSelection::from_user("B"); + let c = TargetSelection::from_user("C"); + + assert_eq!( + first(builder.cache.all::<compile::Std>()), + &[ + compile::Std { compiler: Compiler { host: a, stage: 0 }, target: a }, + compile::Std { compiler: Compiler { host: a, stage: 1 }, target: a }, + compile::Std { compiler: Compiler { host: a, stage: 2 }, target: a }, + compile::Std { compiler: Compiler { host: b, stage: 2 }, target: a }, + compile::Std { compiler: Compiler { host: a, stage: 1 }, target: b }, + compile::Std { compiler: Compiler { host: a, stage: 2 }, target: b }, + compile::Std { compiler: Compiler { host: b, stage: 2 }, target: b }, + compile::Std { compiler: Compiler { host: a, stage: 2 }, target: c }, + compile::Std { compiler: Compiler { host: b, stage: 2 }, target: c }, + ] + ); + assert_eq!( + first(builder.cache.all::<compile::Assemble>()), + &[ + compile::Assemble { target_compiler: Compiler { host: a, stage: 0 } }, + compile::Assemble { target_compiler: Compiler { host: a, stage: 1 } }, + compile::Assemble { target_compiler: Compiler { host: a, stage: 2 } }, + compile::Assemble { target_compiler: Compiler { host: b, stage: 2 } }, + ] + ); + assert_eq!( + first(builder.cache.all::<compile::Rustc>()), + &[ + compile::Rustc { compiler: Compiler { host: a, stage: 0 }, target: a }, + compile::Rustc { compiler: Compiler { host: a, stage: 1 }, target: a }, + compile::Rustc { compiler: Compiler { host: a, stage: 1 }, target: b }, + ] + ); + } + + #[test] + fn test_with_no_doc_stage0() { + let mut config = configure(&[], &[]); + config.stage = Some(0); + config.cmd = Subcommand::Test { + paths: vec!["library/std".into()], + test_args: vec![], + rustc_args: vec![], + fail_fast: true, + doc_tests: DocTests::No, + bless: false, + compare_mode: None, + rustfix_coverage: false, + pass: None, + }; + + let build = Build::new(config); + let mut builder = Builder::new(&build); + + let host = TargetSelection::from_user("A"); + + builder.run_step_descriptions( + &[StepDescription::from::<test::Crate>()], + &["library/std".into()], + ); + + // Ensure we don't build any compiler artifacts. + assert!(!builder.cache.contains::<compile::Rustc>()); + assert_eq!( + first(builder.cache.all::<test::Crate>()), + &[test::Crate { + compiler: Compiler { host, stage: 0 }, + target: host, + mode: Mode::Std, + test_kind: test::TestKind::Test, + krate: INTERNER.intern_str("std"), + },] + ); + } + + #[test] + fn test_exclude() { + let mut config = configure(&[], &[]); + config.exclude = vec!["src/tools/tidy".into()]; + config.cmd = Subcommand::Test { + paths: Vec::new(), + test_args: Vec::new(), + rustc_args: Vec::new(), + fail_fast: true, + doc_tests: DocTests::No, + bless: false, + compare_mode: None, + rustfix_coverage: false, + pass: None, + }; + + let build = Build::new(config); + let builder = Builder::new(&build); + builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Test), &[]); + + // Ensure we have really excluded tidy + assert!(!builder.cache.contains::<test::Tidy>()); + + // Ensure other tests are not affected. + assert!(builder.cache.contains::<test::RustdocUi>()); + } + + #[test] + fn doc_ci() { + let mut config = configure(&[], &[]); + config.compiler_docs = true; + config.cmd = Subcommand::Doc { paths: Vec::new(), open: false }; + let build = Build::new(config); + let mut builder = Builder::new(&build); + builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Doc), &[]); + let a = TargetSelection::from_user("A"); + + // error_index_generator uses stage 1 to share rustdoc artifacts with the + // rustdoc tool. + assert_eq!( + first(builder.cache.all::<doc::ErrorIndex>()), + &[doc::ErrorIndex { compiler: Compiler { host: a, stage: 1 }, target: a },] + ); + assert_eq!( + first(builder.cache.all::<tool::ErrorIndex>()), + &[tool::ErrorIndex { compiler: Compiler { host: a, stage: 1 } }] + ); + // This is actually stage 1, but Rustdoc::run swaps out the compiler with + // stage minus 1 if --stage is not 0. Very confusing! + assert_eq!( + first(builder.cache.all::<tool::Rustdoc>()), + &[tool::Rustdoc { compiler: Compiler { host: a, stage: 2 } },] + ); + } + + #[test] + fn test_docs() { + // Behavior of `x.py test` doing various documentation tests. + let mut config = configure(&[], &[]); + config.cmd = Subcommand::Test { + paths: vec![], + test_args: vec![], + rustc_args: vec![], + fail_fast: true, + doc_tests: DocTests::Yes, + bless: false, + compare_mode: None, + rustfix_coverage: false, + pass: None, + }; + let build = Build::new(config); + let mut builder = Builder::new(&build); + builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Test), &[]); + let a = TargetSelection::from_user("A"); + + // error_index_generator uses stage 1 to share rustdoc artifacts with the + // rustdoc tool. + assert_eq!( + first(builder.cache.all::<doc::ErrorIndex>()), + &[doc::ErrorIndex { compiler: Compiler { host: a, stage: 1 }, target: a },] + ); + assert_eq!( + first(builder.cache.all::<tool::ErrorIndex>()), + &[tool::ErrorIndex { compiler: Compiler { host: a, stage: 1 } }] + ); + // Unfortunately rustdoc is built twice. Once from stage1 for compiletest + // (and other things), and once from stage0 for std crates. Ideally it + // would only be built once. If someone wants to fix this, it might be + // worth investigating if it would be possible to test std from stage1. + // Note that the stages here are +1 than what they actually are because + // Rustdoc::run swaps out the compiler with stage minus 1 if --stage is + // not 0. + assert_eq!( + first(builder.cache.all::<tool::Rustdoc>()), + &[ + tool::Rustdoc { compiler: Compiler { host: a, stage: 1 } }, + tool::Rustdoc { compiler: Compiler { host: a, stage: 2 } }, + ] + ); + } } diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index e3d1e005373..373e240cb8e 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -446,10 +446,10 @@ pub struct Rustc { impl Step for Rustc { type Output = (); const ONLY_HOSTS: bool = true; - const DEFAULT: bool = true; + const DEFAULT: bool = false; fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { - run.all_krates("rustc-main") + run.path("src/rustc") } fn make_run(run: RunConfig<'_>) { diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index d71f3170420..d64ca95d243 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -734,7 +734,7 @@ impl Config { let with_defaults = |debuginfo_level_specific: Option<u32>| { debuginfo_level_specific.or(debuginfo_level).unwrap_or(if debug == Some(true) { - 2 + 1 } else { 0 }) diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 7f10d7895a5..a4a1d5193b9 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -1016,7 +1016,17 @@ impl Step for Src { let src_files = ["Cargo.lock"]; // This is the reduced set of paths which will become the rust-src component // (essentially libstd and all of its path dependencies). - copy_src_dirs(builder, &builder.src, &["library"], &[], &dst_src); + copy_src_dirs( + builder, + &builder.src, + &["library"], + &[ + // not needed and contains symlinks which rustup currently + // chokes on when unpacking. + "library/backtrace/crates", + ], + &dst_src, + ); for file in src_files.iter() { builder.copy(&builder.src.join(file), &dst_src.join(file)); } diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index b43108ccaf9..a1b5ca2ea2f 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -460,7 +460,7 @@ impl Step for Std { // open the corresponding rendered docs. for path in builder.paths.iter().map(components_simplified) { if path.get(0) == Some(&"library") { - let requested_crate = &path[1][3..]; + let requested_crate = &path[1]; if krates.contains(&requested_crate) { let index = out.join(requested_crate).join("index.html"); open(builder, &index); @@ -693,6 +693,7 @@ impl Step for UnstableBookGen { builder.create_dir(&out); builder.remove_dir(&out); let mut cmd = builder.tool_cmd(Tool::UnstableBookGen); + cmd.arg(builder.src.join("library")); cmd.arg(builder.src.join("src")); cmd.arg(out); diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs index a298b299667..56e4f0467cc 100644 --- a/src/bootstrap/flags.rs +++ b/src/bootstrap/flags.rs @@ -425,7 +425,7 @@ Arguments: This subcommand accepts a number of paths to tools to build and run. For example: - ./x.py run src/tool/expand-yaml-anchors + ./x.py run src/tools/expand-yaml-anchors At least a tool needs to be called.", ); diff --git a/src/bootstrap/mk/Makefile.in b/src/bootstrap/mk/Makefile.in index e5b9f27c258..1564cfb0619 100644 --- a/src/bootstrap/mk/Makefile.in +++ b/src/bootstrap/mk/Makefile.in @@ -9,8 +9,8 @@ endif BOOTSTRAP := $(CFG_PYTHON) $(CFG_SRC_DIR)src/bootstrap/bootstrap.py all: - $(Q)$(BOOTSTRAP) build $(BOOTSTRAP_ARGS) - $(Q)$(BOOTSTRAP) doc $(BOOTSTRAP_ARGS) + $(Q)$(BOOTSTRAP) build --stage 2 $(BOOTSTRAP_ARGS) + $(Q)$(BOOTSTRAP) doc --stage 2 $(BOOTSTRAP_ARGS) help: $(Q)echo 'Welcome to the rustbuild build system!' @@ -31,17 +31,17 @@ rustc-stage2: docs: doc doc: - $(Q)$(BOOTSTRAP) doc $(BOOTSTRAP_ARGS) + $(Q)$(BOOTSTRAP) doc --stage 2 $(BOOTSTRAP_ARGS) nomicon: - $(Q)$(BOOTSTRAP) doc src/doc/nomicon $(BOOTSTRAP_ARGS) + $(Q)$(BOOTSTRAP) doc --stage 2 src/doc/nomicon $(BOOTSTRAP_ARGS) book: - $(Q)$(BOOTSTRAP) doc src/doc/book $(BOOTSTRAP_ARGS) + $(Q)$(BOOTSTRAP) doc --stage 2 src/doc/book $(BOOTSTRAP_ARGS) standalone-docs: - $(Q)$(BOOTSTRAP) doc src/doc $(BOOTSTRAP_ARGS) + $(Q)$(BOOTSTRAP) doc --stage 2 src/doc $(BOOTSTRAP_ARGS) check: - $(Q)$(BOOTSTRAP) test $(BOOTSTRAP_ARGS) + $(Q)$(BOOTSTRAP) test --stage 2 $(BOOTSTRAP_ARGS) check-aux: - $(Q)$(BOOTSTRAP) test \ + $(Q)$(BOOTSTRAP) test --stage 2 \ src/tools/cargo \ src/tools/cargotest \ $(BOOTSTRAP_ARGS) @@ -51,18 +51,18 @@ dist: $(Q)$(BOOTSTRAP) dist $(BOOTSTRAP_ARGS) distcheck: $(Q)$(BOOTSTRAP) dist $(BOOTSTRAP_ARGS) - $(Q)$(BOOTSTRAP) test distcheck $(BOOTSTRAP_ARGS) + $(Q)$(BOOTSTRAP) test --stage 2 distcheck $(BOOTSTRAP_ARGS) install: $(Q)$(BOOTSTRAP) install $(BOOTSTRAP_ARGS) tidy: - $(Q)$(BOOTSTRAP) test src/tools/tidy $(BOOTSTRAP_ARGS) + $(Q)$(BOOTSTRAP) test --stage 2 src/tools/tidy $(BOOTSTRAP_ARGS) prepare: - $(Q)$(BOOTSTRAP) build nonexistent/path/to/trigger/cargo/metadata + $(Q)$(BOOTSTRAP) build --stage 2 nonexistent/path/to/trigger/cargo/metadata check-stage2-T-arm-linux-androideabi-H-x86_64-unknown-linux-gnu: - $(Q)$(BOOTSTRAP) test --target arm-linux-androideabi + $(Q)$(BOOTSTRAP) test --stage 2 --target arm-linux-androideabi check-stage2-T-x86_64-unknown-linux-musl-H-x86_64-unknown-linux-gnu: - $(Q)$(BOOTSTRAP) test --target x86_64-unknown-linux-musl + $(Q)$(BOOTSTRAP) test --stage 2 --target x86_64-unknown-linux-musl TESTS_IN_2 := \ src/test/ui \ @@ -70,18 +70,18 @@ TESTS_IN_2 := \ src/tools/linkchecker ci-subset-1: - $(Q)$(BOOTSTRAP) test $(TESTS_IN_2:%=--exclude %) + $(Q)$(BOOTSTRAP) test --stage 2 $(TESTS_IN_2:%=--exclude %) ci-subset-2: - $(Q)$(BOOTSTRAP) test $(TESTS_IN_2) + $(Q)$(BOOTSTRAP) test --stage 2 $(TESTS_IN_2) TESTS_IN_MINGW_2 := \ src/test/ui \ src/test/compile-fail ci-mingw-subset-1: - $(Q)$(BOOTSTRAP) test $(TESTS_IN_MINGW_2:%=--exclude %) + $(Q)$(BOOTSTRAP) test --stage 2 $(TESTS_IN_MINGW_2:%=--exclude %) ci-mingw-subset-2: - $(Q)$(BOOTSTRAP) test $(TESTS_IN_MINGW_2) + $(Q)$(BOOTSTRAP) test --stage 2 $(TESTS_IN_MINGW_2) .PHONY: dist diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index addc51faa5e..bb5b9296c0a 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -106,19 +106,18 @@ impl Step for Linkcheck { /// /// This tool in `src/tools` will verify the validity of all our links in the /// documentation to ensure we don't have a bunch of dead ones. - fn run(self, _builder: &Builder<'_>) { - // FIXME(mark-i-m): uncomment this after we fix the links... - // let host = self.host; + fn run(self, builder: &Builder<'_>) { + let host = self.host; - // builder.info(&format!("Linkcheck ({})", host)); + builder.info(&format!("Linkcheck ({})", host)); - // builder.default_doc(None); + builder.default_doc(None); - // let _time = util::timeit(&builder); - // try_run( - // builder, - // builder.tool_cmd(Tool::Linkchecker).arg(builder.out.join(host.triple).join("doc")), - // ); + let _time = util::timeit(&builder); + try_run( + builder, + builder.tool_cmd(Tool::Linkchecker).arg(builder.out.join(host.triple).join("doc")), + ); } fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { @@ -394,7 +393,7 @@ impl Step for Miri { cargo.arg("--").arg("miri").arg("setup"); // Tell `cargo miri setup` where to find the sources. - cargo.env("XARGO_RUST_SRC", builder.src.join("src")); + cargo.env("XARGO_RUST_SRC", builder.src.join("library")); // Tell it where to find Miri. cargo.env("MIRI", &miri); // Debug things. @@ -1159,13 +1158,19 @@ impl Step for Compiletest { cmd.arg("--quiet"); } + let mut llvm_components_passed = false; + let mut copts_passed = false; if builder.config.llvm_enabled() { let llvm_config = builder.ensure(native::Llvm { target: builder.config.build }); if !builder.config.dry_run { let llvm_version = output(Command::new(&llvm_config).arg("--version")); + let llvm_components = output(Command::new(&llvm_config).arg("--components")); // Remove trailing newline from llvm-config output. - let llvm_version = llvm_version.trim_end(); - cmd.arg("--llvm-version").arg(llvm_version); + cmd.arg("--llvm-version") + .arg(llvm_version.trim()) + .arg("--llvm-components") + .arg(llvm_components.trim()); + llvm_components_passed = true; } if !builder.is_rust_llvm(target) { cmd.arg("--system-llvm"); @@ -1183,15 +1188,13 @@ impl Step for Compiletest { // Only pass correct values for these flags for the `run-make` suite as it // requires that a C++ compiler was configured which isn't always the case. if !builder.config.dry_run && suite == "run-make-fulldeps" { - let llvm_components = output(Command::new(&llvm_config).arg("--components")); cmd.arg("--cc") .arg(builder.cc(target)) .arg("--cxx") .arg(builder.cxx(target).unwrap()) .arg("--cflags") - .arg(builder.cflags(target, GitRepo::Rustc).join(" ")) - .arg("--llvm-components") - .arg(llvm_components.trim()); + .arg(builder.cflags(target, GitRepo::Rustc).join(" ")); + copts_passed = true; if let Some(ar) = builder.ar(target) { cmd.arg("--ar").arg(ar); } @@ -1221,15 +1224,11 @@ impl Step for Compiletest { } } - if suite != "run-make-fulldeps" { - cmd.arg("--cc") - .arg("") - .arg("--cxx") - .arg("") - .arg("--cflags") - .arg("") - .arg("--llvm-components") - .arg(""); + if !llvm_components_passed { + cmd.arg("--llvm-components").arg(""); + } + if !copts_passed { + cmd.arg("--cc").arg("").arg("--cxx").arg("").arg("--cflags").arg(""); } if builder.remote_tested(target) { diff --git a/src/ci/azure-pipelines/auto.yml b/src/ci/azure-pipelines/auto.yml index 06e284c763c..2185b0d30db 100644 --- a/src/ci/azure-pipelines/auto.yml +++ b/src/ci/azure-pipelines/auto.yml @@ -36,7 +36,7 @@ jobs: # Note that the compiler is compiled to target 10.8 here because the Xcode # version that we're using, 8.2, cannot compile LLVM for OSX 10.7. x86_64-apple: - SCRIPT: ./x.py test + SCRIPT: ./x.py --stage 2 test INITIAL_RUST_CONFIGURE_ARGS: --build=x86_64-apple-darwin --enable-sanitizers --enable-profiler --set rust.jemalloc RUSTC_RETRY_LINKER_ON_SEGFAULT: 1 MACOSX_DEPLOYMENT_TARGET: 10.8 diff --git a/src/ci/docker/host-aarch64/aarch64-gnu/Dockerfile b/src/ci/docker/host-aarch64/aarch64-gnu/Dockerfile index 114ac832cf5..b6cf60a5e15 100644 --- a/src/ci/docker/host-aarch64/aarch64-gnu/Dockerfile +++ b/src/ci/docker/host-aarch64/aarch64-gnu/Dockerfile @@ -23,4 +23,4 @@ ENV RUST_CONFIGURE_ARGS \ --enable-sanitizers \ --enable-profiler \ --enable-compiler-docs -ENV SCRIPT python3 ../x.py test +ENV SCRIPT python3 ../x.py --stage 2 test diff --git a/src/ci/docker/host-x86_64/arm-android/Dockerfile b/src/ci/docker/host-x86_64/arm-android/Dockerfile index aa9335c473b..add2647fa1e 100644 --- a/src/ci/docker/host-x86_64/arm-android/Dockerfile +++ b/src/ci/docker/host-x86_64/arm-android/Dockerfile @@ -31,7 +31,7 @@ ENV TARGETS=arm-linux-androideabi ENV RUST_CONFIGURE_ARGS --arm-linux-androideabi-ndk=/android/ndk/arm-14 -ENV SCRIPT python3 ../x.py test --target $TARGETS +ENV SCRIPT python3 ../x.py --stage 2 test --target $TARGETS COPY scripts/sccache.sh /scripts/ RUN sh /scripts/sccache.sh diff --git a/src/ci/docker/host-x86_64/armhf-gnu/Dockerfile b/src/ci/docker/host-x86_64/armhf-gnu/Dockerfile index 71071761f05..1f3092c5513 100644 --- a/src/ci/docker/host-x86_64/armhf-gnu/Dockerfile +++ b/src/ci/docker/host-x86_64/armhf-gnu/Dockerfile @@ -78,6 +78,6 @@ COPY scripts/sccache.sh /scripts/ RUN sh /scripts/sccache.sh ENV RUST_CONFIGURE_ARGS --qemu-armhf-rootfs=/tmp/rootfs -ENV SCRIPT python3 ../x.py test --target arm-unknown-linux-gnueabihf +ENV SCRIPT python3 ../x.py --stage 2 test --target arm-unknown-linux-gnueabihf ENV NO_CHANGE_USER=1 diff --git a/src/ci/docker/host-x86_64/disabled/asmjs/Dockerfile b/src/ci/docker/host-x86_64/disabled/asmjs/Dockerfile index 3fa65511e94..a4d9f53ebab 100644 --- a/src/ci/docker/host-x86_64/disabled/asmjs/Dockerfile +++ b/src/ci/docker/host-x86_64/disabled/asmjs/Dockerfile @@ -33,7 +33,7 @@ ENV EMCC_CFLAGS=-O1 # Emscripten installation is user-specific ENV NO_CHANGE_USER=1 -ENV SCRIPT python3 ../x.py test --target $TARGETS +ENV SCRIPT python3 ../x.py --stage 2 test --target $TARGETS # This is almost identical to the wasm32-unknown-emscripten target, so # running with assertions again is not useful diff --git a/src/ci/docker/host-x86_64/disabled/dist-armv7-android/Dockerfile b/src/ci/docker/host-x86_64/disabled/dist-armv7-android/Dockerfile index 7227c41ccca..f986c38ea02 100644 --- a/src/ci/docker/host-x86_64/disabled/dist-armv7-android/Dockerfile +++ b/src/ci/docker/host-x86_64/disabled/dist-armv7-android/Dockerfile @@ -33,7 +33,7 @@ ENV RUST_CONFIGURE_ARGS \ # build to finish we use --warn-unresolved-symbols. Note that the missing # symbols does not affect std, only the compiler (llvm) and cargo (openssl). ENV SCRIPT \ - python3 ../x.py build src/llvm --host $HOSTS --target $HOSTS && \ + python3 ../x.py --stage 2 build src/llvm --host $HOSTS --target $HOSTS && \ (export RUSTFLAGS="\"-C link-arg=-Wl,--warn-unresolved-symbols\""; \ rm /android/ndk/arm && \ ln -s /android/ndk/arm-14 /android/ndk/arm && \ diff --git a/src/ci/docker/host-x86_64/disabled/dist-i686-android/Dockerfile b/src/ci/docker/host-x86_64/disabled/dist-i686-android/Dockerfile index b74dcefa351..4dfbc725607 100644 --- a/src/ci/docker/host-x86_64/disabled/dist-i686-android/Dockerfile +++ b/src/ci/docker/host-x86_64/disabled/dist-i686-android/Dockerfile @@ -33,7 +33,7 @@ ENV RUST_CONFIGURE_ARGS \ # build to finish we use --warn-unresolved-symbols. Note that the missing # symbols does not affect std, only the compiler (llvm) and cargo (openssl). ENV SCRIPT \ - python3 ../x.py build src/llvm --host $HOSTS --target $HOSTS && \ + python3 ../x.py --stage 2 build src/llvm --host $HOSTS --target $HOSTS && \ (export RUSTFLAGS="\"-C link-arg=-Wl,--warn-unresolved-symbols\""; \ rm /android/ndk/x86 && \ ln -s /android/ndk/x86-14 /android/ndk/x86 && \ diff --git a/src/ci/docker/host-x86_64/disabled/riscv64gc-linux/Dockerfile b/src/ci/docker/host-x86_64/disabled/riscv64gc-linux/Dockerfile index a938899636a..e3c35000eb8 100644 --- a/src/ci/docker/host-x86_64/disabled/riscv64gc-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/disabled/riscv64gc-linux/Dockerfile @@ -97,6 +97,6 @@ COPY scripts/sccache.sh /scripts/ RUN sh /scripts/sccache.sh ENV RUST_CONFIGURE_ARGS --qemu-riscv64-rootfs=/tmp/rootfs -ENV SCRIPT python3 ../x.py test --target riscv64gc-unknown-linux-gnu +ENV SCRIPT python3 ../x.py --stage 2 test --target riscv64gc-unknown-linux-gnu ENV NO_CHANGE_USER=1 diff --git a/src/ci/docker/host-x86_64/dist-i586-gnu-i586-i686-musl/Dockerfile b/src/ci/docker/host-x86_64/dist-i586-gnu-i586-i686-musl/Dockerfile index 996fffeb871..162d7a1345c 100644 --- a/src/ci/docker/host-x86_64/dist-i586-gnu-i586-i686-musl/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-i586-gnu-i586-i686-musl/Dockerfile @@ -46,5 +46,5 @@ ENV CFLAGS_i586_unknown_linux_musl=-Wa,-mrelax-relocations=no ENV TARGETS=i586-unknown-linux-gnu,i686-unknown-linux-musl ENV SCRIPT \ - python3 ../x.py test --target $TARGETS && \ + python3 ../x.py --stage 2 test --target $TARGETS && \ python3 ../x.py dist --target $TARGETS,i586-unknown-linux-musl diff --git a/src/ci/docker/host-x86_64/dist-i686-freebsd/Dockerfile b/src/ci/docker/host-x86_64/dist-i686-freebsd/Dockerfile index 7978bb70869..14af9b9efe8 100644 --- a/src/ci/docker/host-x86_64/dist-i686-freebsd/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-i686-freebsd/Dockerfile @@ -29,5 +29,5 @@ ENV \ ENV HOSTS=i686-unknown-freebsd -ENV RUST_CONFIGURE_ARGS --enable-extended --disable-docs +ENV RUST_CONFIGURE_ARGS --enable-extended --enable-profiler --disable-docs ENV SCRIPT python3 ../x.py dist --host $HOSTS --target $HOSTS diff --git a/src/ci/docker/host-x86_64/dist-various-1/Dockerfile b/src/ci/docker/host-x86_64/dist-various-1/Dockerfile index ac228cfe01d..fdd777e824b 100644 --- a/src/ci/docker/host-x86_64/dist-various-1/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-various-1/Dockerfile @@ -192,7 +192,7 @@ ENV RUST_CONFIGURE_ARGS \ --disable-docs ENV SCRIPT \ - python3 ../x.py test --target $RUN_MAKE_TARGETS src/test/run-make && \ + python3 ../x.py --stage 2 test --target $RUN_MAKE_TARGETS src/test/run-make && \ python3 ../x.py dist --target $TARGETS # sccache diff --git a/src/ci/docker/host-x86_64/dist-various-2/build-wasi-toolchain.sh b/src/ci/docker/host-x86_64/dist-various-2/build-wasi-toolchain.sh index c82031690ab..c6db200f866 100755 --- a/src/ci/docker/host-x86_64/dist-various-2/build-wasi-toolchain.sh +++ b/src/ci/docker/host-x86_64/dist-various-2/build-wasi-toolchain.sh @@ -4,15 +4,15 @@ set -ex -# Originally from https://releases.llvm.org/9.0.0/clang+llvm-9.0.0-x86_64-linux-gnu-ubuntu-14.04.tar.xz -curl https://ci-mirrors.rust-lang.org/rustc/clang%2Bllvm-9.0.0-x86_64-linux-gnu-ubuntu-14.04.tar.xz | \ +# Originally from https://github.com/llvm/llvm-project/releases/download/llvmorg-10.0.0/clang+llvm-10.0.0-x86_64-linux-gnu-ubuntu-18.04.tar.xz +curl https://ci-mirrors.rust-lang.org/rustc/clang%2Bllvm-10.0.0-x86_64-linux-gnu-ubuntu-18.04.tar.xz | \ tar xJf - -export PATH=`pwd`/clang+llvm-9.0.0-x86_64-linux-gnu-ubuntu-14.04/bin:$PATH +export PATH=`pwd`/clang+llvm-10.0.0-x86_64-linux-gnu-ubuntu-18.04/bin:$PATH -git clone https://github.com/CraneStation/wasi-libc +git clone https://github.com/WebAssembly/wasi-libc cd wasi-libc -git reset --hard 9efc2f428358564fe64c374d762d0bfce1d92507 +git reset --hard 215adc8ac9f91eb055311acc72683fd2eb1ae15a make -j$(nproc) INSTALL_DIR=/wasm32-wasi install cd .. diff --git a/src/ci/docker/host-x86_64/dist-x86_64-freebsd/Dockerfile b/src/ci/docker/host-x86_64/dist-x86_64-freebsd/Dockerfile index 12170a36614..2372c0dad0a 100644 --- a/src/ci/docker/host-x86_64/dist-x86_64-freebsd/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-x86_64-freebsd/Dockerfile @@ -29,5 +29,5 @@ ENV \ ENV HOSTS=x86_64-unknown-freebsd -ENV RUST_CONFIGURE_ARGS --enable-extended --disable-docs +ENV RUST_CONFIGURE_ARGS --enable-extended --enable-profiler --disable-docs ENV SCRIPT python3 ../x.py dist --host $HOSTS --target $HOSTS diff --git a/src/ci/docker/host-x86_64/dist-x86_64-musl/Dockerfile b/src/ci/docker/host-x86_64/dist-x86_64-musl/Dockerfile index c026506b106..ab6515cd1fa 100644 --- a/src/ci/docker/host-x86_64/dist-x86_64-musl/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-x86_64-musl/Dockerfile @@ -33,7 +33,6 @@ ENV HOSTS=x86_64-unknown-linux-musl ENV RUST_CONFIGURE_ARGS \ --musl-root-x86_64=/usr/local/x86_64-linux-musl \ --enable-extended \ - --disable-docs \ --enable-lld \ --set target.x86_64-unknown-linux-musl.crt-static=false \ --build $HOSTS diff --git a/src/ci/docker/host-x86_64/i686-gnu-nopt/Dockerfile b/src/ci/docker/host-x86_64/i686-gnu-nopt/Dockerfile index 436215839f7..6a596b3465f 100644 --- a/src/ci/docker/host-x86_64/i686-gnu-nopt/Dockerfile +++ b/src/ci/docker/host-x86_64/i686-gnu-nopt/Dockerfile @@ -20,7 +20,7 @@ COPY scripts/sccache.sh /scripts/ RUN sh /scripts/sccache.sh ENV RUST_CONFIGURE_ARGS --build=i686-unknown-linux-gnu --disable-optimize-tests -ENV SCRIPT python3 ../x.py test +ENV SCRIPT python3 ../x.py --stage 2 test # FIXME(#59637) takes too long on CI right now ENV NO_LLVM_ASSERTIONS=1 NO_DEBUG_ASSERTIONS=1 diff --git a/src/ci/docker/host-x86_64/i686-gnu/Dockerfile b/src/ci/docker/host-x86_64/i686-gnu/Dockerfile index 34a76f39668..9d319017d79 100644 --- a/src/ci/docker/host-x86_64/i686-gnu/Dockerfile +++ b/src/ci/docker/host-x86_64/i686-gnu/Dockerfile @@ -22,7 +22,7 @@ RUN sh /scripts/sccache.sh ENV RUST_CONFIGURE_ARGS --build=i686-unknown-linux-gnu # Exclude some tests that are unlikely to be platform specific, to speed up # this slow job. -ENV SCRIPT python3 ../x.py test \ +ENV SCRIPT python3 ../x.py --stage 2 test \ --exclude src/bootstrap \ --exclude src/test/rustdoc-js \ --exclude src/tools/error_index_generator \ diff --git a/src/ci/docker/host-x86_64/mingw-check/Dockerfile b/src/ci/docker/host-x86_64/mingw-check/Dockerfile index 0c59b95ea21..b902eda87bc 100644 --- a/src/ci/docker/host-x86_64/mingw-check/Dockerfile +++ b/src/ci/docker/host-x86_64/mingw-check/Dockerfile @@ -22,10 +22,10 @@ RUN sh /scripts/sccache.sh COPY host-x86_64/mingw-check/validate-toolstate.sh /scripts/ ENV RUN_CHECK_WITH_PARALLEL_QUERIES 1 -ENV SCRIPT python3 ../x.py test src/tools/expand-yaml-anchors && \ +ENV SCRIPT python3 ../x.py --stage 2 test src/tools/expand-yaml-anchors && \ python3 ../x.py check --target=i686-pc-windows-gnu --host=i686-pc-windows-gnu && \ python3 ../x.py build --stage 0 src/tools/build-manifest && \ python3 ../x.py test --stage 0 src/tools/compiletest && \ - python3 ../x.py test src/tools/tidy && \ + python3 ../x.py test --stage 2 src/tools/tidy && \ python3 ../x.py doc --stage 0 library/std && \ /scripts/validate-toolstate.sh diff --git a/src/ci/docker/host-x86_64/test-various/Dockerfile b/src/ci/docker/host-x86_64/test-various/Dockerfile index b7276f60867..c55a284e137 100644 --- a/src/ci/docker/host-x86_64/test-various/Dockerfile +++ b/src/ci/docker/host-x86_64/test-various/Dockerfile @@ -40,7 +40,7 @@ ENV RUST_CONFIGURE_ARGS \ ENV NO_DEBUG_ASSERTIONS=1 ENV WASM_TARGETS=wasm32-unknown-unknown -ENV WASM_SCRIPT python3 /checkout/x.py test --target $WASM_TARGETS \ +ENV WASM_SCRIPT python3 /checkout/x.py --stage 2 test --target $WASM_TARGETS \ src/test/run-make \ src/test/ui \ src/test/compile-fail \ @@ -49,13 +49,13 @@ ENV WASM_SCRIPT python3 /checkout/x.py test --target $WASM_TARGETS \ library/core ENV NVPTX_TARGETS=nvptx64-nvidia-cuda -ENV NVPTX_SCRIPT python3 /checkout/x.py test --target $NVPTX_TARGETS \ +ENV NVPTX_SCRIPT python3 /checkout/x.py --stage 2 test --target $NVPTX_TARGETS \ src/test/run-make \ src/test/assembly ENV MUSL_TARGETS=x86_64-unknown-linux-musl \ CC_x86_64_unknown_linux_musl=x86_64-linux-musl-gcc \ CXX_x86_64_unknown_linux_musl=x86_64-linux-musl-g++ -ENV MUSL_SCRIPT python3 /checkout/x.py test --target $MUSL_TARGETS +ENV MUSL_SCRIPT python3 /checkout/x.py --stage 2 test --target $MUSL_TARGETS ENV SCRIPT $WASM_SCRIPT && $NVPTX_SCRIPT && $MUSL_SCRIPT diff --git a/src/ci/docker/host-x86_64/wasm32/Dockerfile b/src/ci/docker/host-x86_64/wasm32/Dockerfile index a40ccb6bfd5..e00177b4a67 100644 --- a/src/ci/docker/host-x86_64/wasm32/Dockerfile +++ b/src/ci/docker/host-x86_64/wasm32/Dockerfile @@ -52,7 +52,7 @@ ENV NO_CHANGE_USER=1 # FIXME: Re-enable these tests once https://github.com/rust-lang/cargo/pull/7476 # is picked up by CI -ENV SCRIPT python3 ../x.py test --target $TARGETS \ +ENV SCRIPT python3 ../x.py test --stage 2 --target $TARGETS \ --exclude library/core \ --exclude library/alloc \ --exclude library/proc_macro \ diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-debug/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-debug/Dockerfile index c5e41b8a75a..c1cb20b631d 100644 --- a/src/ci/docker/host-x86_64/x86_64-gnu-debug/Dockerfile +++ b/src/ci/docker/host-x86_64/x86_64-gnu-debug/Dockerfile @@ -40,5 +40,5 @@ ENV RUST_CONFIGURE_ARGS \ --set target.x86_64-unknown-linux-gnu.cxx=clang++ ENV SCRIPT \ - python3 ../x.py build && \ - python3 ../x.py test src/test/run-make-fulldeps --test-args clang + python3 ../x.py --stage 2 build && \ + python3 ../x.py --stage 2 test src/test/run-make-fulldeps --test-args clang diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-distcheck/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-distcheck/Dockerfile index cc07a591cc1..68e89a7bade 100644 --- a/src/ci/docker/host-x86_64/x86_64-gnu-distcheck/Dockerfile +++ b/src/ci/docker/host-x86_64/x86_64-gnu-distcheck/Dockerfile @@ -19,10 +19,10 @@ COPY scripts/sccache.sh /scripts/ RUN sh /scripts/sccache.sh ENV RUST_CONFIGURE_ARGS --build=x86_64-unknown-linux-gnu --set rust.ignore-git=false -ENV SCRIPT python3 ../x.py test distcheck +ENV SCRIPT python3 ../x.py --stage 2 test distcheck ENV DIST_SRC 1 -# The purpose of this builder is to test that we can `./x.py test` successfully +# The purpose of this builder is to test that we can `./x.py --stage 2 test` successfully # from a tarball, not to test LLVM/rustc's own set of assertions. These cause a # significant hit to CI compile time (over a half hour as observed in #61185), # so disable assertions for this builder. diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-full-bootstrap/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-full-bootstrap/Dockerfile index de7ee6950b5..8648e5ed7a4 100644 --- a/src/ci/docker/host-x86_64/x86_64-gnu-full-bootstrap/Dockerfile +++ b/src/ci/docker/host-x86_64/x86_64-gnu-full-bootstrap/Dockerfile @@ -21,7 +21,7 @@ RUN sh /scripts/sccache.sh ENV RUST_CONFIGURE_ARGS \ --build=x86_64-unknown-linux-gnu \ --enable-full-bootstrap -ENV SCRIPT python3 ../x.py build +ENV SCRIPT python3 ../x.py --stage 2 build # In general this just slows down the build and we're just a smoke test that # a full bootstrap works in general, so there's not much need to take this diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-8/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-8/Dockerfile index 1d9cad149d9..5c971c73c97 100644 --- a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-8/Dockerfile +++ b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-8/Dockerfile @@ -30,7 +30,7 @@ ENV RUST_CONFIGURE_ARGS \ --enable-llvm-link-shared \ --set rust.thin-lto-import-instr-limit=10 -ENV SCRIPT python2.7 ../x.py test --exclude src/tools/tidy && \ +ENV SCRIPT python2.7 ../x.py --stage 2 test --exclude src/tools/tidy && \ # Run the `mir-opt` tests again but this time for a 32-bit target. # This enforces that tests using `// EMIT_MIR_FOR_EACH_BIT_WIDTH` have # both 32-bit and 64-bit outputs updated by the PR author, before @@ -43,7 +43,7 @@ ENV SCRIPT python2.7 ../x.py test --exclude src/tools/tidy && \ # This also requires `--pass=build` because we can't execute the tests # on the `x86_64` host when they're built as `armv5te` binaries. # (we're only interested in the MIR output, so this doesn't matter) - python2.7 ../x.py test src/test/mir-opt --pass=build \ + python2.7 ../x.py --stage 2 test src/test/mir-opt --pass=build \ --target=armv5te-unknown-linux-gnueabi && \ # Run the UI test suite again, but in `--pass=check` mode # @@ -53,9 +53,9 @@ ENV SCRIPT python2.7 ../x.py test --exclude src/tools/tidy && \ # FIXME: We ideally want to test this in 32-bit mode, but currently # (due to the LLVM problems mentioned above) that isn't readily # possible. - python2.7 ../x.py test src/test/ui --pass=check && \ + python2.7 ../x.py --stage 2 test src/test/ui --pass=check && \ # Run tidy at the very end, after all the other tests. - python2.7 ../x.py test src/tools/tidy + python2.7 ../x.py --stage 2 test src/tools/tidy # The purpose of this container isn't to test with debug assertions and # this is run on all PRs, so let's get speedier builds by disabling these extra diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-nopt/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-nopt/Dockerfile index 096f67e13d1..fa769cac9c1 100644 --- a/src/ci/docker/host-x86_64/x86_64-gnu-nopt/Dockerfile +++ b/src/ci/docker/host-x86_64/x86_64-gnu-nopt/Dockerfile @@ -21,4 +21,4 @@ RUN sh /scripts/sccache.sh ENV RUST_CONFIGURE_ARGS --build=x86_64-unknown-linux-gnu \ --disable-optimize-tests \ --set rust.test-compare-mode -ENV SCRIPT python3 ../x.py test +ENV SCRIPT python3 ../x.py --stage 2 test diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-tools/checktools.sh b/src/ci/docker/host-x86_64/x86_64-gnu-tools/checktools.sh index b4b23a245e0..49a8e5e88a0 100755 --- a/src/ci/docker/host-x86_64/x86_64-gnu-tools/checktools.sh +++ b/src/ci/docker/host-x86_64/x86_64-gnu-tools/checktools.sh @@ -7,7 +7,7 @@ X_PY="$1" # Try to test all the tools and store the build/test success in the TOOLSTATE_FILE set +e -python3 "$X_PY" test --no-fail-fast \ +python3 "$X_PY" test --stage 2 --no-fail-fast \ src/doc/book \ src/doc/nomicon \ src/doc/reference \ @@ -22,5 +22,5 @@ set -e # debugging: print out the saved toolstates cat /tmp/toolstate/toolstates.json -python3 "$X_PY" test check-tools -python3 "$X_PY" test src/tools/clippy +python3 "$X_PY" test --stage 2 check-tools +python3 "$X_PY" test --stage 2 src/tools/clippy diff --git a/src/ci/docker/host-x86_64/x86_64-gnu/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu/Dockerfile index af6e1318062..f8bacf79ac0 100644 --- a/src/ci/docker/host-x86_64/x86_64-gnu/Dockerfile +++ b/src/ci/docker/host-x86_64/x86_64-gnu/Dockerfile @@ -23,4 +23,4 @@ ENV RUST_CONFIGURE_ARGS \ --enable-sanitizers \ --enable-profiler \ --enable-compiler-docs -ENV SCRIPT python3 ../x.py test +ENV SCRIPT python3 ../x.py --stage 2 test diff --git a/src/ci/github-actions/ci.yml b/src/ci/github-actions/ci.yml index 0aeb6a04e5f..8a6973bcdd6 100644 --- a/src/ci/github-actions/ci.yml +++ b/src/ci/github-actions/ci.yml @@ -84,6 +84,9 @@ x--expand-yaml-anchors--remove: os: windows-latest-xl <<: *base-job + - &job-aarch64-linux + os: [self-hosted, ARM64, linux] + - &step if: success() && !env.SKIP_JOB @@ -471,7 +474,7 @@ jobs: - name: x86_64-msvc-cargo env: - SCRIPT: python x.py test src/tools/cargotest src/tools/cargo + SCRIPT: python x.py --stage 2 test src/tools/cargotest src/tools/cargo RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --enable-lld VCVARS_BAT: vcvars64.bat # FIXME(#59637) @@ -586,6 +589,13 @@ jobs: strategy: matrix: include: + ############################# + # Linux/Docker builders # + ############################# + + - name: aarch64-gnu + <<: *job-aarch64-linux + #################### # macOS Builders # #################### @@ -613,7 +623,7 @@ jobs: - name: x86_64-apple env: - SCRIPT: ./x.py test + SCRIPT: ./x.py --stage 2 test RUST_CONFIGURE_ARGS: --build=x86_64-apple-darwin --enable-sanitizers --enable-profiler --set rust.jemalloc RUSTC_RETRY_LINKER_ON_SEGFAULT: 1 MACOSX_DEPLOYMENT_TARGET: 10.8 diff --git a/src/ci/scripts/symlink-build-dir.sh b/src/ci/scripts/symlink-build-dir.sh index 50178b9c33e..28d8aa3b6e7 100755 --- a/src/ci/scripts/symlink-build-dir.sh +++ b/src/ci/scripts/symlink-build-dir.sh @@ -12,7 +12,7 @@ source "$(cd "$(dirname "$0")" && pwd)/../shared.sh" if isWindows && isAzurePipelines; then cmd //c "mkdir c:\\MORE_SPACE" cmd //c "mklink /J build c:\\MORE_SPACE" -elif isLinux && isGitHubActions; then +elif isLinux && isGitHubActions && ! isSelfHostedGitHubActions; then sudo mkdir -p /mnt/more-space sudo chown -R "$(whoami):" /mnt/more-space diff --git a/src/ci/shared.sh b/src/ci/shared.sh index 206065d7072..8222758ed6d 100644 --- a/src/ci/shared.sh +++ b/src/ci/shared.sh @@ -38,6 +38,11 @@ function isGitHubActions { [[ "${GITHUB_ACTIONS-false}" = "true" ]] } + +function isSelfHostedGitHubActions { + [[ "${RUST_GHA_SELF_HOSTED-false}" = "true" ]] +} + function isMacOS { [[ "${OSTYPE}" = "darwin"* ]] } diff --git a/src/doc/rustdoc/src/lints.md b/src/doc/rustdoc/src/lints.md index beb2556872d..d1d6bc1c1fe 100644 --- a/src/doc/rustdoc/src/lints.md +++ b/src/doc/rustdoc/src/lints.md @@ -11,7 +11,7 @@ can use them like any other lints by doing this: Here is the list of the lints provided by `rustdoc`: -## intra_doc_link_resolution_failure +## broken_intra_doc_links This lint **warns by default** and is **nightly-only**. This lint detects when an intra-doc link fails to get resolved. For example: diff --git a/src/doc/unstable-book/src/language-features/plugin.md b/src/doc/unstable-book/src/language-features/plugin.md index 47ac986c224..38351131527 100644 --- a/src/doc/unstable-book/src/language-features/plugin.md +++ b/src/doc/unstable-book/src/language-features/plugin.md @@ -35,7 +35,7 @@ of a library. Plugins can extend [Rust's lint infrastructure](../../reference/attributes/diagnostics.md#lint-check-attributes) with additional checks for code style, safety, etc. Now let's write a plugin -[`lint_plugin_test.rs`](https://github.com/rust-lang/rust/blob/master/src/test/ui-fulldeps/auxiliary/lint_plugin_test.rs) +[`lint-plugin-test.rs`](https://github.com/rust-lang/rust/blob/master/src/test/ui-fulldeps/auxiliary/lint-plugin-test.rs) that warns about any item named `lintme`. ```rust,ignore @@ -45,42 +45,40 @@ that warns about any item named `lintme`. extern crate rustc_ast; // Load rustc as a plugin to get macros -#[macro_use] -extern crate rustc; extern crate rustc_driver; +#[macro_use] +extern crate rustc_lint; +#[macro_use] +extern crate rustc_session; -use rustc::lint::{EarlyContext, LintContext, LintPass, EarlyLintPass, - EarlyLintPassObject, LintArray}; use rustc_driver::plugin::Registry; +use rustc_lint::{EarlyContext, EarlyLintPass, LintArray, LintContext, LintPass}; use rustc_ast::ast; - declare_lint!(TEST_LINT, Warn, "Warn about items named 'lintme'"); -struct Pass; - -impl LintPass for Pass { - fn get_lints(&self) -> LintArray { - lint_array!(TEST_LINT) - } -} +declare_lint_pass!(Pass => [TEST_LINT]); impl EarlyLintPass for Pass { fn check_item(&mut self, cx: &EarlyContext, it: &ast::Item) { - if it.ident.as_str() == "lintme" { - cx.span_lint(TEST_LINT, it.span, "item is named 'lintme'"); + if it.ident.name.as_str() == "lintme" { + cx.lint(TEST_LINT, |lint| { + lint.build("item is named 'lintme'").set_span(it.span).emit() + }); } } } #[plugin_registrar] pub fn plugin_registrar(reg: &mut Registry) { - reg.register_early_lint_pass(box Pass as EarlyLintPassObject); + reg.lint_store.register_lints(&[&TEST_LINT]); + reg.lint_store.register_early_pass(|| box Pass); } ``` Then code like ```rust,ignore +#![feature(plugin)] #![plugin(lint_plugin_test)] fn lintme() { } @@ -107,7 +105,7 @@ The components of a lint plugin are: Lint passes are syntax traversals, but they run at a late stage of compilation where type information is available. `rustc`'s [built-in -lints](https://github.com/rust-lang/rust/blob/master/src/librustc/lint/builtin.rs) +lints](https://github.com/rust-lang/rust/blob/master/src/librustc_session/lint/builtin.rs) mostly use the same infrastructure as lint plugins, and provide examples of how to access type information. diff --git a/src/etc/test-float-parse/runtests.py b/src/etc/test-float-parse/runtests.py index 7106078f897..218552a4597 100644 --- a/src/etc/test-float-parse/runtests.py +++ b/src/etc/test-float-parse/runtests.py @@ -193,11 +193,12 @@ def interact(proc, queue): def main(): global MAILBOX - tests = [os.path.splitext(f)[0] for f in glob('*.rs') - if not f.startswith('_')] - listed = sys.argv[1:] - if listed: - tests = [test for test in tests if test in listed] + all_tests = [os.path.splitext(f)[0] for f in glob('*.rs') if not f.startswith('_')] + args = sys.argv[1:] + if args: + tests = [test for test in all_tests if test in args] + else + tests = all_tests if not tests: print("Error: No tests to run") sys.exit(1) diff --git a/src/librustc_ast/Cargo.toml b/src/librustc_ast/Cargo.toml index 6bd65fd5f96..a36f49bd414 100644 --- a/src/librustc_ast/Cargo.toml +++ b/src/librustc_ast/Cargo.toml @@ -11,7 +11,7 @@ doctest = false [dependencies] rustc_serialize = { path = "../librustc_serialize" } -log = "0.4" +log = { package = "tracing", version = "0.1" } scoped-tls = "1.0" rustc_span = { path = "../librustc_span" } rustc_data_structures = { path = "../librustc_data_structures" } diff --git a/src/librustc_ast/token.rs b/src/librustc_ast/token.rs index 173ea5e48d6..e1c94ddf782 100644 --- a/src/librustc_ast/token.rs +++ b/src/librustc_ast/token.rs @@ -673,62 +673,6 @@ impl Token { Some(Token::new(kind, self.span.to(joint.span))) } - - // See comments in `Nonterminal::to_tokenstream` for why we care about - // *probably* equal here rather than actual equality - crate fn probably_equal_for_proc_macro(&self, other: &Token) -> bool { - if mem::discriminant(&self.kind) != mem::discriminant(&other.kind) { - return false; - } - match (&self.kind, &other.kind) { - (&Eq, &Eq) - | (&Lt, &Lt) - | (&Le, &Le) - | (&EqEq, &EqEq) - | (&Ne, &Ne) - | (&Ge, &Ge) - | (&Gt, &Gt) - | (&AndAnd, &AndAnd) - | (&OrOr, &OrOr) - | (&Not, &Not) - | (&Tilde, &Tilde) - | (&At, &At) - | (&Dot, &Dot) - | (&DotDot, &DotDot) - | (&DotDotDot, &DotDotDot) - | (&DotDotEq, &DotDotEq) - | (&Comma, &Comma) - | (&Semi, &Semi) - | (&Colon, &Colon) - | (&ModSep, &ModSep) - | (&RArrow, &RArrow) - | (&LArrow, &LArrow) - | (&FatArrow, &FatArrow) - | (&Pound, &Pound) - | (&Dollar, &Dollar) - | (&Question, &Question) - | (&Whitespace, &Whitespace) - | (&Comment, &Comment) - | (&Eof, &Eof) => true, - - (&BinOp(a), &BinOp(b)) | (&BinOpEq(a), &BinOpEq(b)) => a == b, - - (&OpenDelim(a), &OpenDelim(b)) | (&CloseDelim(a), &CloseDelim(b)) => a == b, - - (&DocComment(a), &DocComment(b)) | (&Shebang(a), &Shebang(b)) => a == b, - - (&Literal(a), &Literal(b)) => a == b, - - (&Lifetime(a), &Lifetime(b)) => a == b, - (&Ident(a, b), &Ident(c, d)) => { - b == d && (a == c || a == kw::DollarCrate || c == kw::DollarCrate) - } - - (&Interpolated(..), &Interpolated(..)) => false, - - _ => panic!("forgot to add a token?"), - } - } } impl PartialEq<TokenKind> for Token { @@ -760,6 +704,67 @@ pub enum Nonterminal { #[cfg(target_arch = "x86_64")] rustc_data_structures::static_assert_size!(Nonterminal, 40); +#[derive(Debug, Copy, Clone, PartialEq, RustcEncodable, RustcDecodable)] +pub enum NonterminalKind { + Item, + Block, + Stmt, + Pat, + Expr, + Ty, + Ident, + Lifetime, + Literal, + Meta, + Path, + Vis, + TT, +} + +impl NonterminalKind { + pub fn from_symbol(symbol: Symbol) -> Option<NonterminalKind> { + Some(match symbol { + sym::item => NonterminalKind::Item, + sym::block => NonterminalKind::Block, + sym::stmt => NonterminalKind::Stmt, + sym::pat => NonterminalKind::Pat, + sym::expr => NonterminalKind::Expr, + sym::ty => NonterminalKind::Ty, + sym::ident => NonterminalKind::Ident, + sym::lifetime => NonterminalKind::Lifetime, + sym::literal => NonterminalKind::Literal, + sym::meta => NonterminalKind::Meta, + sym::path => NonterminalKind::Path, + sym::vis => NonterminalKind::Vis, + sym::tt => NonterminalKind::TT, + _ => return None, + }) + } + fn symbol(self) -> Symbol { + match self { + NonterminalKind::Item => sym::item, + NonterminalKind::Block => sym::block, + NonterminalKind::Stmt => sym::stmt, + NonterminalKind::Pat => sym::pat, + NonterminalKind::Expr => sym::expr, + NonterminalKind::Ty => sym::ty, + NonterminalKind::Ident => sym::ident, + NonterminalKind::Lifetime => sym::lifetime, + NonterminalKind::Literal => sym::literal, + NonterminalKind::Meta => sym::meta, + NonterminalKind::Path => sym::path, + NonterminalKind::Vis => sym::vis, + NonterminalKind::TT => sym::tt, + } + } +} + +impl fmt::Display for NonterminalKind { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", self.symbol()) + } +} + impl Nonterminal { fn span(&self) -> Span { match self { diff --git a/src/librustc_ast/tokenstream.rs b/src/librustc_ast/tokenstream.rs index 15ae12ebf10..9d0199078fa 100644 --- a/src/librustc_ast/tokenstream.rs +++ b/src/librustc_ast/tokenstream.rs @@ -21,8 +21,6 @@ use rustc_macros::HashStable_Generic; use rustc_span::{Span, DUMMY_SP}; use smallvec::{smallvec, SmallVec}; -use log::debug; - use std::{iter, mem}; /// When the main rust parser encounters a syntax-extension invocation, it @@ -68,23 +66,6 @@ impl TokenTree { } } - // See comments in `Nonterminal::to_tokenstream` for why we care about - // *probably* equal here rather than actual equality - // - // This is otherwise the same as `eq_unspanned`, only recursing with a - // different method. - pub fn probably_equal_for_proc_macro(&self, other: &TokenTree) -> bool { - match (self, other) { - (TokenTree::Token(token), TokenTree::Token(token2)) => { - token.probably_equal_for_proc_macro(token2) - } - (TokenTree::Delimited(_, delim, tts), TokenTree::Delimited(_, delim2, tts2)) => { - delim == delim2 && tts.probably_equal_for_proc_macro(&tts2) - } - _ => false, - } - } - /// Retrieves the TokenTree's span. pub fn span(&self) -> Span { match self { @@ -307,112 +288,6 @@ impl TokenStream { t1.next().is_none() && t2.next().is_none() } - // See comments in `Nonterminal::to_tokenstream` for why we care about - // *probably* equal here rather than actual equality - // - // This is otherwise the same as `eq_unspanned`, only recursing with a - // different method. - pub fn probably_equal_for_proc_macro(&self, other: &TokenStream) -> bool { - // When checking for `probably_eq`, we ignore certain tokens that aren't - // preserved in the AST. Because they are not preserved, the pretty - // printer arbitrarily adds or removes them when printing as token - // streams, making a comparison between a token stream generated from an - // AST and a token stream which was parsed into an AST more reliable. - fn semantic_tree(tree: &TokenTree) -> bool { - if let TokenTree::Token(token) = tree { - if let - // The pretty printer tends to add trailing commas to - // everything, and in particular, after struct fields. - | token::Comma - // The pretty printer emits `NoDelim` as whitespace. - | token::OpenDelim(DelimToken::NoDelim) - | token::CloseDelim(DelimToken::NoDelim) - // The pretty printer collapses many semicolons into one. - | token::Semi - // The pretty printer collapses whitespace arbitrarily and can - // introduce whitespace from `NoDelim`. - | token::Whitespace - // The pretty printer can turn `$crate` into `::crate_name` - | token::ModSep = token.kind { - return false; - } - } - true - } - - // When comparing two `TokenStream`s, we ignore the `IsJoint` information. - // - // However, `rustc_parse::lexer::tokentrees::TokenStreamBuilder` will - // use `Token.glue` on adjacent tokens with the proper `IsJoint`. - // Since we are ignoreing `IsJoint`, a 'glued' token (e.g. `BinOp(Shr)`) - // and its 'split'/'unglued' compoenents (e.g. `Gt, Gt`) are equivalent - // when determining if two `TokenStream`s are 'probably equal'. - // - // Therefore, we use `break_two_token_op` to convert all tokens - // to the 'unglued' form (if it exists). This ensures that two - // `TokenStream`s which differ only in how their tokens are glued - // will be considered 'probably equal', which allows us to keep spans. - // - // This is important when the original `TokenStream` contained - // extra spaces (e.g. `f :: < Vec < _ > > ( ) ;'). These extra spaces - // will be omitted when we pretty-print, which can cause the original - // and reparsed `TokenStream`s to differ in the assignment of `IsJoint`, - // leading to some tokens being 'glued' together in one stream but not - // the other. See #68489 for more details. - fn break_tokens(tree: TokenTree) -> impl Iterator<Item = TokenTree> { - // In almost all cases, we should have either zero or one levels - // of 'unglueing'. However, in some unusual cases, we may need - // to iterate breaking tokens mutliple times. For example: - // '[BinOpEq(Shr)] => [Gt, Ge] -> [Gt, Gt, Eq]' - let mut token_trees: SmallVec<[_; 2]>; - if let TokenTree::Token(token) = &tree { - let mut out = SmallVec::<[_; 2]>::new(); - out.push(token.clone()); - // Iterate to fixpoint: - // * We start off with 'out' containing our initial token, and `temp` empty - // * If we are able to break any tokens in `out`, then `out` will have - // at least one more element than 'temp', so we will try to break tokens - // again. - // * If we cannot break any tokens in 'out', we are done - loop { - let mut temp = SmallVec::<[_; 2]>::new(); - let mut changed = false; - - for token in out.into_iter() { - if let Some((first, second)) = token.kind.break_two_token_op() { - temp.push(Token::new(first, DUMMY_SP)); - temp.push(Token::new(second, DUMMY_SP)); - changed = true; - } else { - temp.push(token); - } - } - out = temp; - if !changed { - break; - } - } - token_trees = out.into_iter().map(TokenTree::Token).collect(); - if token_trees.len() != 1 { - debug!("break_tokens: broke {:?} to {:?}", tree, token_trees); - } - } else { - token_trees = SmallVec::new(); - token_trees.push(tree); - } - token_trees.into_iter() - } - - let mut t1 = self.trees().filter(semantic_tree).flat_map(break_tokens); - let mut t2 = other.trees().filter(semantic_tree).flat_map(break_tokens); - for (t1, t2) in t1.by_ref().zip(t2.by_ref()) { - if !t1.probably_equal_for_proc_macro(&t2) { - return false; - } - } - t1.next().is_none() && t2.next().is_none() - } - pub fn map_enumerated<F: FnMut(usize, TokenTree) -> TokenTree>(self, mut f: F) -> TokenStream { TokenStream(Lrc::new( self.0 diff --git a/src/librustc_ast_lowering/Cargo.toml b/src/librustc_ast_lowering/Cargo.toml index d71eb4fcd5c..bf7e69a31ab 100644 --- a/src/librustc_ast_lowering/Cargo.toml +++ b/src/librustc_ast_lowering/Cargo.toml @@ -11,7 +11,7 @@ doctest = false [dependencies] rustc_arena = { path = "../librustc_arena" } -log = { version = "0.4", features = ["release_max_level_info", "std"] } +tracing = "0.1" rustc_ast_pretty = { path = "../librustc_ast_pretty" } rustc_hir = { path = "../librustc_hir" } rustc_target = { path = "../librustc_target" } diff --git a/src/librustc_ast_lowering/item.rs b/src/librustc_ast_lowering/item.rs index dd5e658102f..5414e584290 100644 --- a/src/librustc_ast_lowering/item.rs +++ b/src/librustc_ast_lowering/item.rs @@ -17,9 +17,9 @@ use rustc_span::symbol::{kw, sym, Ident}; use rustc_span::Span; use rustc_target::spec::abi; -use log::debug; use smallvec::{smallvec, SmallVec}; use std::collections::BTreeSet; +use tracing::debug; pub(super) struct ItemLowerer<'a, 'lowering, 'hir> { pub(super) lctx: &'a mut LoweringContext<'lowering, 'hir>, diff --git a/src/librustc_ast_lowering/lib.rs b/src/librustc_ast_lowering/lib.rs index 1c70eef3bf5..9df7ad2a9ac 100644 --- a/src/librustc_ast_lowering/lib.rs +++ b/src/librustc_ast_lowering/lib.rs @@ -64,10 +64,10 @@ use rustc_span::source_map::{respan, DesugaringKind, ExpnData, ExpnKind}; use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::Span; -use log::{debug, trace}; use smallvec::{smallvec, SmallVec}; use std::collections::BTreeMap; use std::mem; +use tracing::{debug, trace}; macro_rules! arena_vec { ($this:expr; $($x:expr),*) => ({ diff --git a/src/librustc_ast_lowering/pat.rs b/src/librustc_ast_lowering/pat.rs index 55c1f802663..171856e7e63 100644 --- a/src/librustc_ast_lowering/pat.rs +++ b/src/librustc_ast_lowering/pat.rs @@ -112,7 +112,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // Found a sub-tuple pattern `$binding_mode $ident @ ..`. // This is not allowed as a sub-tuple pattern PatKind::Ident(ref _bm, ident, Some(ref sub)) if sub.is_rest() => { - rest = Some((idx, pat.span)); let sp = pat.span; self.diagnostic() .struct_span_err( @@ -128,7 +127,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { Applicability::MaybeIncorrect, ) .emit(); - break; } _ => {} } diff --git a/src/librustc_ast_lowering/path.rs b/src/librustc_ast_lowering/path.rs index e5ce51f8d2d..2541d6824fe 100644 --- a/src/librustc_ast_lowering/path.rs +++ b/src/librustc_ast_lowering/path.rs @@ -12,8 +12,8 @@ use rustc_session::lint::BuiltinLintDiagnostics; use rustc_span::symbol::Ident; use rustc_span::Span; -use log::debug; use smallvec::smallvec; +use tracing::debug; impl<'a, 'hir> LoweringContext<'a, 'hir> { crate fn lower_qpath( diff --git a/src/librustc_ast_passes/Cargo.toml b/src/librustc_ast_passes/Cargo.toml index e4d1d79abb2..6db9bce3164 100644 --- a/src/librustc_ast_passes/Cargo.toml +++ b/src/librustc_ast_passes/Cargo.toml @@ -10,7 +10,7 @@ path = "lib.rs" [dependencies] itertools = "0.8" -log = "0.4" +tracing = "0.1" rustc_ast_pretty = { path = "../librustc_ast_pretty" } rustc_attr = { path = "../librustc_attr" } rustc_data_structures = { path = "../librustc_data_structures" } diff --git a/src/librustc_ast_passes/feature_gate.rs b/src/librustc_ast_passes/feature_gate.rs index b424c8afb34..2fe208c3ce6 100644 --- a/src/librustc_ast_passes/feature_gate.rs +++ b/src/librustc_ast_passes/feature_gate.rs @@ -10,7 +10,7 @@ use rustc_span::source_map::Spanned; use rustc_span::symbol::{sym, Symbol}; use rustc_span::Span; -use log::debug; +use tracing::debug; macro_rules! gate_feature_fn { ($cx: expr, $has_feature: expr, $span: expr, $name: expr, $explain: expr) => {{ diff --git a/src/librustc_ast_pretty/Cargo.toml b/src/librustc_ast_pretty/Cargo.toml index 6c076d2c5b8..d26205c791d 100644 --- a/src/librustc_ast_pretty/Cargo.toml +++ b/src/librustc_ast_pretty/Cargo.toml @@ -10,7 +10,7 @@ path = "lib.rs" doctest = false [dependencies] -log = "0.4" +tracing = "0.1" rustc_span = { path = "../librustc_span" } rustc_ast = { path = "../librustc_ast" } rustc_target = { path = "../librustc_target" } diff --git a/src/librustc_ast_pretty/pp.rs b/src/librustc_ast_pretty/pp.rs index 4bb806a923e..ca7f127ced6 100644 --- a/src/librustc_ast_pretty/pp.rs +++ b/src/librustc_ast_pretty/pp.rs @@ -132,10 +132,10 @@ //! methods called `Printer::scan_*`, and the 'PRINT' process is the //! method called `Printer::print`. -use log::debug; use std::borrow::Cow; use std::collections::VecDeque; use std::fmt; +use tracing::debug; /// How to break. Described in more detail in the module docs. #[derive(Clone, Copy, PartialEq)] diff --git a/src/librustc_ast_pretty/pprust.rs b/src/librustc_ast_pretty/pprust.rs index b0edb1ca41d..4b228629ad7 100644 --- a/src/librustc_ast_pretty/pprust.rs +++ b/src/librustc_ast_pretty/pprust.rs @@ -450,7 +450,9 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere fn print_comment(&mut self, cmnt: &comments::Comment) { match cmnt.style { comments::Mixed => { - self.zerobreak(); + if !self.is_beginning_of_line() { + self.zerobreak(); + } if let Some((last, lines)) = cmnt.lines.split_last() { self.ibox(0); diff --git a/src/librustc_builtin_macros/Cargo.toml b/src/librustc_builtin_macros/Cargo.toml index fdb6c359052..c612781153e 100644 --- a/src/librustc_builtin_macros/Cargo.toml +++ b/src/librustc_builtin_macros/Cargo.toml @@ -11,7 +11,7 @@ doctest = false [dependencies] rustc_parse_format = { path = "../librustc_parse_format" } -log = "0.4" +log = { package = "tracing", version = "0.1" } rustc_ast_pretty = { path = "../librustc_ast_pretty" } rustc_attr = { path = "../librustc_attr" } rustc_data_structures = { path = "../librustc_data_structures" } diff --git a/src/librustc_codegen_llvm/Cargo.toml b/src/librustc_codegen_llvm/Cargo.toml index bedefcc30ed..ec4dfabdcc2 100644 --- a/src/librustc_codegen_llvm/Cargo.toml +++ b/src/librustc_codegen_llvm/Cargo.toml @@ -15,7 +15,7 @@ bitflags = "1.0" flate2 = "1.0" libc = "0.2" measureme = "0.7.1" -log = "0.4" +log = { package = "tracing", version = "0.1" } rustc_middle = { path = "../librustc_middle" } rustc-demangle = "0.1" rustc_attr = { path = "../librustc_attr" } diff --git a/src/librustc_codegen_llvm/callee.rs b/src/librustc_codegen_llvm/callee.rs index 75b4f2e3ca5..afdc8dc6187 100644 --- a/src/librustc_codegen_llvm/callee.rs +++ b/src/librustc_codegen_llvm/callee.rs @@ -172,7 +172,12 @@ pub fn get_fn(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'tcx>) -> &'ll Value } } - if cx.use_dll_storage_attrs && tcx.is_dllimport_foreign_item(instance_def_id) { + // MinGW: For backward compatibility we rely on the linker to decide whether it + // should use dllimport for functions. + if cx.use_dll_storage_attrs + && tcx.is_dllimport_foreign_item(instance_def_id) + && tcx.sess.target.target.target_env != "gnu" + { unsafe { llvm::LLVMSetDLLStorageClass(llfn, llvm::DLLStorageClass::DllImport); } diff --git a/src/librustc_codegen_llvm/consts.rs b/src/librustc_codegen_llvm/consts.rs index 3e9e5d9c8c1..1288870f55f 100644 --- a/src/librustc_codegen_llvm/consts.rs +++ b/src/librustc_codegen_llvm/consts.rs @@ -287,7 +287,7 @@ impl CodegenCx<'ll, 'tcx> { // argument validation. debug_assert!( !(self.tcx.sess.opts.cg.linker_plugin_lto.enabled() - && self.tcx.sess.target.target.options.is_like_msvc + && self.tcx.sess.target.target.options.is_like_windows && self.tcx.sess.opts.cg.prefer_dynamic) ); diff --git a/src/librustc_codegen_llvm/context.rs b/src/librustc_codegen_llvm/context.rs index 33a3cdbfa9b..26707fdf839 100644 --- a/src/librustc_codegen_llvm/context.rs +++ b/src/librustc_codegen_llvm/context.rs @@ -217,7 +217,16 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> { // attributes in LLVM IR as well as native dependencies (in C these // correspond to `__declspec(dllimport)`). // - // Whenever a dynamic library is built by MSVC it must have its public + // LD (BFD) in MinGW mode can often correctly guess `dllexport` but + // relying on that can result in issues like #50176. + // LLD won't support that and expects symbols with proper attributes. + // Because of that we make MinGW target emit dllexport just like MSVC. + // When it comes to dllimport we use it for constants but for functions + // rely on the linker to do the right thing. Opposed to dllexport this + // task is easy for them (both LD and LLD) and allows us to easily use + // symbols from static libraries in shared libraries. + // + // Whenever a dynamic library is built on Windows it must have its public // interface specified by functions tagged with `dllexport` or otherwise // they're not available to be linked against. This poses a few problems // for the compiler, some of which are somewhat fundamental, but we use @@ -254,8 +263,8 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> { // this effect) by marking very little as `dllimport` and praying the // linker will take care of everything. Fixing this problem will likely // require adding a few attributes to Rust itself (feature gated at the - // start) and then strongly recommending static linkage on MSVC! - let use_dll_storage_attrs = tcx.sess.target.target.options.is_like_msvc; + // start) and then strongly recommending static linkage on Windows! + let use_dll_storage_attrs = tcx.sess.target.target.options.is_like_windows; let check_overflow = tcx.sess.overflow_checks(); diff --git a/src/librustc_codegen_llvm/coverageinfo/mapgen.rs b/src/librustc_codegen_llvm/coverageinfo/mapgen.rs index 7f48b1d864c..4d9747a43f2 100644 --- a/src/librustc_codegen_llvm/coverageinfo/mapgen.rs +++ b/src/librustc_codegen_llvm/coverageinfo/mapgen.rs @@ -1,23 +1,15 @@ -use crate::llvm; - use crate::common::CodegenCx; use crate::coverageinfo; +use crate::llvm; +use llvm::coverageinfo::CounterMappingRegion; use log::debug; -use rustc_codegen_ssa::coverageinfo::map::*; -use rustc_codegen_ssa::traits::{BaseTypeMethods, ConstMethods, MiscMethods}; +use rustc_codegen_ssa::coverageinfo::map::{Counter, CounterExpression, Region}; +use rustc_codegen_ssa::traits::{BaseTypeMethods, ConstMethods}; use rustc_data_structures::fx::FxHashMap; use rustc_llvm::RustString; -use rustc_middle::ty::Instance; -use rustc_middle::{bug, mir}; -use std::collections::BTreeMap; use std::ffi::CString; -use std::path::PathBuf; - -// FIXME(richkadel): Complete all variations of generating and exporting the coverage map to LLVM. -// The current implementation is an initial foundation with basic capabilities (Counters, but not -// CounterExpressions, etc.). /// Generates and exports the Coverage Map. /// @@ -32,174 +24,123 @@ use std::path::PathBuf; /// undocumented details in Clang's implementation (that may or may not be important) were also /// replicated for Rust's Coverage Map. pub fn finalize<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>) { - let mut coverage_writer = CoverageMappingWriter::new(cx); - let function_coverage_map = cx.coverage_context().take_function_coverage_map(); + if function_coverage_map.is_empty() { + // This module has no functions with coverage instrumentation + return; + } + + let mut mapgen = CoverageMapGenerator::new(); // Encode coverage mappings and generate function records let mut function_records = Vec::<&'ll llvm::Value>::new(); let coverage_mappings_buffer = llvm::build_byte_buffer(|coverage_mappings_buffer| { for (instance, function_coverage) in function_coverage_map.into_iter() { - if let Some(function_record) = coverage_writer.write_function_mappings_and_record( - instance, - function_coverage, - coverage_mappings_buffer, - ) { - function_records.push(function_record); - } + debug!("Generate coverage map for: {:?}", instance); + + let mangled_function_name = cx.tcx.symbol_name(instance).to_string(); + let function_source_hash = function_coverage.source_hash(); + let (expressions, counter_regions) = + function_coverage.get_expressions_and_counter_regions(); + + let old_len = coverage_mappings_buffer.len(); + mapgen.write_coverage_mappings(expressions, counter_regions, coverage_mappings_buffer); + let mapping_data_size = coverage_mappings_buffer.len() - old_len; + debug_assert!( + mapping_data_size > 0, + "Every `FunctionCoverage` should have at least one counter" + ); + + let function_record = mapgen.make_function_record( + cx, + mangled_function_name, + function_source_hash, + mapping_data_size, + ); + function_records.push(function_record); } }); - // Encode all filenames covered in this module, ordered by `file_id` + // Encode all filenames referenced by counters/expressions in this module let filenames_buffer = llvm::build_byte_buffer(|filenames_buffer| { - coverageinfo::write_filenames_section_to_buffer( - &coverage_writer.filenames, - filenames_buffer, - ); + coverageinfo::write_filenames_section_to_buffer(&mapgen.filenames, filenames_buffer); }); - if coverage_mappings_buffer.len() > 0 { - // Generate the LLVM IR representation of the coverage map and store it in a well-known - // global constant. - coverage_writer.write_coverage_map( - function_records, - filenames_buffer, - coverage_mappings_buffer, - ); - } + // Generate the LLVM IR representation of the coverage map and store it in a well-known global + mapgen.save_generated_coverage_map( + cx, + function_records, + filenames_buffer, + coverage_mappings_buffer, + ); } -struct CoverageMappingWriter<'a, 'll, 'tcx> { - cx: &'a CodegenCx<'ll, 'tcx>, +struct CoverageMapGenerator { filenames: Vec<CString>, filename_to_index: FxHashMap<CString, u32>, } -impl<'a, 'll, 'tcx> CoverageMappingWriter<'a, 'll, 'tcx> { - fn new(cx: &'a CodegenCx<'ll, 'tcx>) -> Self { - Self { cx, filenames: Vec::new(), filename_to_index: FxHashMap::<CString, u32>::default() } +impl CoverageMapGenerator { + fn new() -> Self { + Self { filenames: Vec::new(), filename_to_index: FxHashMap::default() } } - /// For the given function, get the coverage region data, stream it to the given buffer, and - /// then generate and return a new function record. - fn write_function_mappings_and_record( + /// Using the `expressions` and `counter_regions` collected for the current function, generate + /// the `mapping_regions` and `virtual_file_mapping`, and capture any new filenames. Then use + /// LLVM APIs to encode the `virtual_file_mapping`, `expressions`, and `mapping_regions` into + /// the given `coverage_mappings` byte buffer, compliant with the LLVM Coverage Mapping format. + fn write_coverage_mappings( &mut self, - instance: Instance<'tcx>, - mut function_coverage: FunctionCoverage, + expressions: Vec<CounterExpression>, + counter_regions: impl Iterator<Item = (Counter, &'a Region)>, coverage_mappings_buffer: &RustString, - ) -> Option<&'ll llvm::Value> { - let cx = self.cx; - let coverageinfo: &mir::CoverageInfo = cx.tcx.coverageinfo(instance.def_id()); - debug!( - "Generate coverage map for: {:?}, num_counters: {}, num_expressions: {}", - instance, coverageinfo.num_counters, coverageinfo.num_expressions - ); - debug_assert!(coverageinfo.num_counters > 0); - - let regions_in_file_order = function_coverage.regions_in_file_order(cx.sess().source_map()); - if regions_in_file_order.len() == 0 { - return None; + ) { + let mut counter_regions = counter_regions.collect::<Vec<_>>(); + if counter_regions.is_empty() { + return; } - // Stream the coverage mapping regions for the function (`instance`) to the buffer, and - // compute the data byte size used. - let old_len = coverage_mappings_buffer.len(); - self.regions_to_mappings(regions_in_file_order, coverage_mappings_buffer); - let mapping_data_size = coverage_mappings_buffer.len() - old_len; - debug_assert!(mapping_data_size > 0); - - let mangled_function_name = cx.tcx.symbol_name(instance).to_string(); - let name_ref = coverageinfo::compute_hash(&mangled_function_name); - let function_source_hash = function_coverage.source_hash(); - - // Generate and return the function record - let name_ref_val = cx.const_u64(name_ref); - let mapping_data_size_val = cx.const_u32(mapping_data_size as u32); - let func_hash_val = cx.const_u64(function_source_hash); - Some(cx.const_struct( - &[name_ref_val, mapping_data_size_val, func_hash_val], - /*packed=*/ true, - )) - } - - /// For each coverage region, extract its coverage data from the earlier coverage analysis. - /// Use LLVM APIs to convert the data into buffered bytes compliant with the LLVM Coverage - /// Mapping format. - fn regions_to_mappings( - &mut self, - regions_in_file_order: BTreeMap<PathBuf, BTreeMap<CoverageLoc, (usize, CoverageKind)>>, - coverage_mappings_buffer: &RustString, - ) { let mut virtual_file_mapping = Vec::new(); - let mut mapping_regions = coverageinfo::SmallVectorCounterMappingRegion::new(); - let mut expressions = coverageinfo::SmallVectorCounterExpression::new(); - - for (file_id, (file_path, file_coverage_regions)) in - regions_in_file_order.into_iter().enumerate() - { - let file_id = file_id as u32; - let filename = CString::new(file_path.to_string_lossy().to_string()) - .expect("null error converting filename to C string"); - debug!(" file_id: {} = '{:?}'", file_id, filename); - let filenames_index = match self.filename_to_index.get(&filename) { - Some(index) => *index, - None => { - let index = self.filenames.len() as u32; - self.filenames.push(filename.clone()); - self.filename_to_index.insert(filename, index); - index + let mut mapping_regions = Vec::new(); + let mut current_file_path = None; + let mut current_file_id = 0; + + // Convert the list of (Counter, Region) pairs to an array of `CounterMappingRegion`, sorted + // by filename and position. Capture any new files to compute the `CounterMappingRegion`s + // `file_id` (indexing files referenced by the current function), and construct the + // function-specific `virtual_file_mapping` from `file_id` to its index in the module's + // `filenames` array. + counter_regions.sort_unstable_by_key(|(_counter, region)| *region); + for (counter, region) in counter_regions { + let (file_path, start_line, start_col, end_line, end_col) = region.file_start_and_end(); + let same_file = current_file_path.as_ref().map_or(false, |p| p == file_path); + if !same_file { + if current_file_path.is_some() { + current_file_id += 1; } - }; - virtual_file_mapping.push(filenames_index); - - let mut mapping_indexes = vec![0 as u32; file_coverage_regions.len()]; - for (mapping_index, (region_id, _)) in file_coverage_regions.values().enumerate() { - mapping_indexes[*region_id] = mapping_index as u32; - } - - for (region_loc, (region_id, region_kind)) in file_coverage_regions.into_iter() { - let mapping_index = mapping_indexes[region_id]; - match region_kind { - CoverageKind::Counter => { - debug!( - " Counter {}, file_id: {}, region_loc: {}", - mapping_index, file_id, region_loc - ); - mapping_regions.push_from( - mapping_index, - file_id, - region_loc.start_line, - region_loc.start_col, - region_loc.end_line, - region_loc.end_col, - ); - } - CoverageKind::CounterExpression(lhs, op, rhs) => { - debug!( - " CounterExpression {} = {} {:?} {}, file_id: {}, region_loc: {:?}", - mapping_index, lhs, op, rhs, file_id, region_loc, - ); - mapping_regions.push_from( - mapping_index, - file_id, - region_loc.start_line, - region_loc.start_col, - region_loc.end_line, - region_loc.end_col, - ); - expressions.push_from(op, lhs, rhs); - } - CoverageKind::Unreachable => { - debug!( - " Unreachable region, file_id: {}, region_loc: {:?}", - file_id, region_loc, - ); - bug!("Unreachable region not expected and not yet handled!") - // FIXME(richkadel): implement and call - // mapping_regions.push_from(...) for unreachable regions + current_file_path = Some(file_path.clone()); + let filename = CString::new(file_path.to_string_lossy().to_string()) + .expect("null error converting filename to C string"); + debug!(" file_id: {} = '{:?}'", current_file_id, filename); + let filenames_index = match self.filename_to_index.get(&filename) { + Some(index) => *index, + None => { + let index = self.filenames.len() as u32; + self.filenames.push(filename.clone()); + self.filename_to_index.insert(filename.clone(), index); + index } - } + }; + virtual_file_mapping.push(filenames_index); } + mapping_regions.push(CounterMappingRegion::code_region( + counter, + current_file_id, + start_line, + start_col, + end_line, + end_col, + )); } // Encode and append the current function's coverage mapping data @@ -211,14 +152,35 @@ impl<'a, 'll, 'tcx> CoverageMappingWriter<'a, 'll, 'tcx> { ); } - fn write_coverage_map( + /// Generate and return the function record `Value` + fn make_function_record( + &mut self, + cx: &CodegenCx<'ll, 'tcx>, + mangled_function_name: String, + function_source_hash: u64, + mapping_data_size: usize, + ) -> &'ll llvm::Value { + let name_ref = coverageinfo::compute_hash(&mangled_function_name); + let name_ref_val = cx.const_u64(name_ref); + let mapping_data_size_val = cx.const_u32(mapping_data_size as u32); + let func_hash_val = cx.const_u64(function_source_hash); + cx.const_struct( + &[name_ref_val, mapping_data_size_val, func_hash_val], + /*packed=*/ true, + ) + } + + /// Combine the filenames and coverage mappings buffers, construct coverage map header and the + /// array of function records, and combine everything into the complete coverage map. Save the + /// coverage map data into the LLVM IR as a static global using a specific, well-known section + /// and name. + fn save_generated_coverage_map( self, + cx: &CodegenCx<'ll, 'tcx>, function_records: Vec<&'ll llvm::Value>, filenames_buffer: Vec<u8>, mut coverage_mappings_buffer: Vec<u8>, ) { - let cx = self.cx; - // Concatenate the encoded filenames and encoded coverage mappings, and add additional zero // bytes as-needed to ensure 8-byte alignment. let mut coverage_size = coverage_mappings_buffer.len(); diff --git a/src/librustc_codegen_llvm/coverageinfo/mod.rs b/src/librustc_codegen_llvm/coverageinfo/mod.rs index 76894bcd6c1..9d2090eae8f 100644 --- a/src/librustc_codegen_llvm/coverageinfo/mod.rs +++ b/src/librustc_codegen_llvm/coverageinfo/mod.rs @@ -4,8 +4,9 @@ use crate::builder::Builder; use crate::common::CodegenCx; use libc::c_uint; +use llvm::coverageinfo::CounterMappingRegion; use log::debug; -use rustc_codegen_ssa::coverageinfo::map::*; +use rustc_codegen_ssa::coverageinfo::map::{CounterExpression, ExprKind, FunctionCoverage}; use rustc_codegen_ssa::traits::{ BaseTypeMethods, CoverageInfoBuilderMethods, CoverageInfoMethods, StaticMethods, }; @@ -23,7 +24,7 @@ const COVMAP_VAR_ALIGN_BYTES: usize = 8; /// A context object for maintaining all state needed by the coverageinfo module. pub struct CrateCoverageContext<'tcx> { // Coverage region data for each instrumented function identified by DefId. - pub(crate) function_coverage_map: RefCell<FxHashMap<Instance<'tcx>, FunctionCoverage>>, + pub(crate) function_coverage_map: RefCell<FxHashMap<Instance<'tcx>, FunctionCoverage<'tcx>>>, } impl<'tcx> CrateCoverageContext<'tcx> { @@ -31,7 +32,7 @@ impl<'tcx> CrateCoverageContext<'tcx> { Self { function_coverage_map: Default::default() } } - pub fn take_function_coverage_map(&self) -> FxHashMap<Instance<'tcx>, FunctionCoverage> { + pub fn take_function_coverage_map(&self) -> FxHashMap<Instance<'tcx>, FunctionCoverage<'tcx>> { self.function_coverage_map.replace(FxHashMap::default()) } } @@ -47,44 +48,49 @@ impl CoverageInfoBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> { &mut self, instance: Instance<'tcx>, function_source_hash: u64, - index: u32, + id: u32, start_byte_pos: u32, end_byte_pos: u32, ) { debug!( - "adding counter to coverage_regions: instance={:?}, function_source_hash={}, index={}, byte range {}..{}", - instance, function_source_hash, index, start_byte_pos, end_byte_pos, + "adding counter to coverage_regions: instance={:?}, function_source_hash={}, id={}, \ + byte range {}..{}", + instance, function_source_hash, id, start_byte_pos, end_byte_pos, ); let mut coverage_regions = self.coverage_context().function_coverage_map.borrow_mut(); coverage_regions .entry(instance) - .or_insert_with(|| { - FunctionCoverage::with_coverageinfo(self.tcx.coverageinfo(instance.def_id())) - }) - .add_counter(function_source_hash, index, start_byte_pos, end_byte_pos); + .or_insert_with(|| FunctionCoverage::new(self.tcx, instance)) + .add_counter(function_source_hash, id, start_byte_pos, end_byte_pos); } fn add_counter_expression_region( &mut self, instance: Instance<'tcx>, - index: u32, + id_descending_from_max: u32, lhs: u32, - op: CounterOp, + op: ExprKind, rhs: u32, start_byte_pos: u32, end_byte_pos: u32, ) { debug!( - "adding counter expression to coverage_regions: instance={:?}, index={}, {} {:?} {}, byte range {}..{}", - instance, index, lhs, op, rhs, start_byte_pos, end_byte_pos, + "adding counter expression to coverage_regions: instance={:?}, id={}, {} {:?} {}, \ + byte range {}..{}", + instance, id_descending_from_max, lhs, op, rhs, start_byte_pos, end_byte_pos, ); let mut coverage_regions = self.coverage_context().function_coverage_map.borrow_mut(); coverage_regions .entry(instance) - .or_insert_with(|| { - FunctionCoverage::with_coverageinfo(self.tcx.coverageinfo(instance.def_id())) - }) - .add_counter_expression(index, lhs, op, rhs, start_byte_pos, end_byte_pos); + .or_insert_with(|| FunctionCoverage::new(self.tcx, instance)) + .add_counter_expression( + id_descending_from_max, + lhs, + op, + rhs, + start_byte_pos, + end_byte_pos, + ); } fn add_unreachable_region( @@ -100,108 +106,8 @@ impl CoverageInfoBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> { let mut coverage_regions = self.coverage_context().function_coverage_map.borrow_mut(); coverage_regions .entry(instance) - .or_insert_with(|| { - FunctionCoverage::with_coverageinfo(self.tcx.coverageinfo(instance.def_id())) - }) - .add_unreachable(start_byte_pos, end_byte_pos); - } -} - -/// This struct wraps an opaque reference to the C++ template instantiation of -/// `llvm::SmallVector<coverage::CounterExpression>`. Each `coverage::CounterExpression` object is -/// constructed from primative-typed arguments, and pushed to the `SmallVector`, in the C++ -/// implementation of `LLVMRustCoverageSmallVectorCounterExpressionAdd()` (see -/// `src/rustllvm/CoverageMappingWrapper.cpp`). -pub struct SmallVectorCounterExpression<'a> { - pub raw: &'a mut llvm::coverageinfo::SmallVectorCounterExpression<'a>, -} - -impl SmallVectorCounterExpression<'a> { - pub fn new() -> Self { - SmallVectorCounterExpression { - raw: unsafe { llvm::LLVMRustCoverageSmallVectorCounterExpressionCreate() }, - } - } - - pub fn as_ptr(&self) -> *const llvm::coverageinfo::SmallVectorCounterExpression<'a> { - self.raw - } - - pub fn push_from( - &mut self, - kind: rustc_codegen_ssa::coverageinfo::CounterOp, - left_index: u32, - right_index: u32, - ) { - unsafe { - llvm::LLVMRustCoverageSmallVectorCounterExpressionAdd( - &mut *(self.raw as *mut _), - kind, - left_index, - right_index, - ) - } - } -} - -impl Drop for SmallVectorCounterExpression<'a> { - fn drop(&mut self) { - unsafe { - llvm::LLVMRustCoverageSmallVectorCounterExpressionDispose(&mut *(self.raw as *mut _)); - } - } -} - -/// This struct wraps an opaque reference to the C++ template instantiation of -/// `llvm::SmallVector<coverage::CounterMappingRegion>`. Each `coverage::CounterMappingRegion` -/// object is constructed from primative-typed arguments, and pushed to the `SmallVector`, in the -/// C++ implementation of `LLVMRustCoverageSmallVectorCounterMappingRegionAdd()` (see -/// `src/rustllvm/CoverageMappingWrapper.cpp`). -pub struct SmallVectorCounterMappingRegion<'a> { - pub raw: &'a mut llvm::coverageinfo::SmallVectorCounterMappingRegion<'a>, -} - -impl SmallVectorCounterMappingRegion<'a> { - pub fn new() -> Self { - SmallVectorCounterMappingRegion { - raw: unsafe { llvm::LLVMRustCoverageSmallVectorCounterMappingRegionCreate() }, - } - } - - pub fn as_ptr(&self) -> *const llvm::coverageinfo::SmallVectorCounterMappingRegion<'a> { - self.raw - } - - pub fn push_from( - &mut self, - index: u32, - file_id: u32, - line_start: u32, - column_start: u32, - line_end: u32, - column_end: u32, - ) { - unsafe { - llvm::LLVMRustCoverageSmallVectorCounterMappingRegionAdd( - &mut *(self.raw as *mut _), - index, - file_id, - line_start, - column_start, - line_end, - column_end, - ) - } - } -} - -impl Drop for SmallVectorCounterMappingRegion<'a> { - fn drop(&mut self) { - unsafe { - llvm::LLVMRustCoverageSmallVectorCounterMappingRegionDispose( - &mut *(self.raw as *mut _), - ); - } + .or_insert_with(|| FunctionCoverage::new(self.tcx, instance)) + .add_unreachable_region(start_byte_pos, end_byte_pos); } } @@ -218,8 +124,8 @@ pub(crate) fn write_filenames_section_to_buffer(filenames: &Vec<CString>, buffer pub(crate) fn write_mapping_to_buffer( virtual_file_mapping: Vec<u32>, - expressions: SmallVectorCounterExpression<'_>, - mapping_regions: SmallVectorCounterMappingRegion<'_>, + expressions: Vec<CounterExpression>, + mut mapping_regions: Vec<CounterMappingRegion>, buffer: &RustString, ) { unsafe { @@ -227,7 +133,9 @@ pub(crate) fn write_mapping_to_buffer( virtual_file_mapping.as_ptr(), virtual_file_mapping.len() as c_uint, expressions.as_ptr(), - mapping_regions.as_ptr(), + expressions.len() as c_uint, + mapping_regions.as_mut_ptr(), + mapping_regions.len() as c_uint, buffer, ); } diff --git a/src/librustc_codegen_llvm/intrinsic.rs b/src/librustc_codegen_llvm/intrinsic.rs index 11b1c95c58b..728af7b0a8c 100644 --- a/src/librustc_codegen_llvm/intrinsic.rs +++ b/src/librustc_codegen_llvm/intrinsic.rs @@ -13,7 +13,7 @@ use rustc_ast::ast; use rustc_codegen_ssa::base::{compare_simd_types, to_immediate, wants_msvc_seh}; use rustc_codegen_ssa::common::span_invalid_monomorphization_error; use rustc_codegen_ssa::common::{IntPredicate, TypeKind}; -use rustc_codegen_ssa::coverageinfo::CounterOp; +use rustc_codegen_ssa::coverageinfo::ExprKind; use rustc_codegen_ssa::glue; use rustc_codegen_ssa::mir::operand::{OperandRef, OperandValue}; use rustc_codegen_ssa::mir::place::PlaceRef; @@ -90,64 +90,69 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> { args: &Vec<Operand<'tcx>>, caller_instance: ty::Instance<'tcx>, ) -> bool { + let mut is_codegen_intrinsic = true; + // Set `is_codegen_intrinsic` to `false` to bypass `codegen_intrinsic_call()`. + if self.tcx.sess.opts.debugging_opts.instrument_coverage { - // Add the coverage information from the MIR to the Codegen context. Some coverage - // intrinsics are used only to pass along the coverage information (returns `false` - // for `is_codegen_intrinsic()`), but `count_code_region` is also converted into an - // LLVM intrinsic to increment a coverage counter. - match intrinsic { - sym::count_code_region => { - use coverage::count_code_region_args::*; - self.add_counter_region( - caller_instance, - op_to_u64(&args[FUNCTION_SOURCE_HASH]), - op_to_u32(&args[COUNTER_INDEX]), - op_to_u32(&args[START_BYTE_POS]), - op_to_u32(&args[END_BYTE_POS]), - ); - return true; // Also inject the counter increment in the backend - } - sym::coverage_counter_add | sym::coverage_counter_subtract => { - use coverage::coverage_counter_expression_args::*; - self.add_counter_expression_region( - caller_instance, - op_to_u32(&args[COUNTER_EXPRESSION_INDEX]), - op_to_u32(&args[LEFT_INDEX]), - if intrinsic == sym::coverage_counter_add { - CounterOp::Add - } else { - CounterOp::Subtract - }, - op_to_u32(&args[RIGHT_INDEX]), - op_to_u32(&args[START_BYTE_POS]), - op_to_u32(&args[END_BYTE_POS]), - ); - return false; // Does not inject backend code + // If the intrinsic is from the local MIR, add the coverage information to the Codegen + // context, to be encoded into the local crate's coverage map. + if caller_instance.def_id().is_local() { + // FIXME(richkadel): Make sure to add coverage analysis tests on a crate with + // external crate dependencies, where: + // 1. Both binary and dependent crates are compiled with `-Zinstrument-coverage` + // 2. Only binary is compiled with `-Zinstrument-coverage` + // 3. Only dependent crates are compiled with `-Zinstrument-coverage` + match intrinsic { + sym::count_code_region => { + use coverage::count_code_region_args::*; + self.add_counter_region( + caller_instance, + op_to_u64(&args[FUNCTION_SOURCE_HASH]), + op_to_u32(&args[COUNTER_ID]), + op_to_u32(&args[START_BYTE_POS]), + op_to_u32(&args[END_BYTE_POS]), + ); + } + sym::coverage_counter_add | sym::coverage_counter_subtract => { + use coverage::coverage_counter_expression_args::*; + self.add_counter_expression_region( + caller_instance, + op_to_u32(&args[EXPRESSION_ID]), + op_to_u32(&args[LEFT_ID]), + if intrinsic == sym::coverage_counter_add { + ExprKind::Add + } else { + ExprKind::Subtract + }, + op_to_u32(&args[RIGHT_ID]), + op_to_u32(&args[START_BYTE_POS]), + op_to_u32(&args[END_BYTE_POS]), + ); + } + sym::coverage_unreachable => { + use coverage::coverage_unreachable_args::*; + self.add_unreachable_region( + caller_instance, + op_to_u32(&args[START_BYTE_POS]), + op_to_u32(&args[END_BYTE_POS]), + ); + } + _ => {} } - sym::coverage_unreachable => { - use coverage::coverage_unreachable_args::*; - self.add_unreachable_region( - caller_instance, - op_to_u32(&args[START_BYTE_POS]), - op_to_u32(&args[END_BYTE_POS]), - ); - return false; // Does not inject backend code + } + + // Only the `count_code_region` coverage intrinsic is translated into an actual LLVM + // intrinsic call (local or not); otherwise, set `is_codegen_intrinsic` to `false`. + match intrinsic { + sym::coverage_counter_add + | sym::coverage_counter_subtract + | sym::coverage_unreachable => { + is_codegen_intrinsic = false; } _ => {} } - } else { - // NOT self.tcx.sess.opts.debugging_opts.instrument_coverage - if intrinsic == sym::count_code_region { - // An external crate may have been pre-compiled with coverage instrumentation, and - // some references from the current crate to the external crate might carry along - // the call terminators to coverage intrinsics, like `count_code_region` (for - // example, when instantiating a generic function). If the current crate has - // `instrument_coverage` disabled, the `count_code_region` call terminators should - // be ignored. - return false; // Do not inject coverage counters inlined from external crates - } } - true // Unhandled intrinsics should be passed to `codegen_intrinsic_call()` + is_codegen_intrinsic } fn codegen_intrinsic_call( @@ -219,7 +224,7 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> { let num_counters = self.const_u32(coverageinfo.num_counters); use coverage::count_code_region_args::*; let hash = args[FUNCTION_SOURCE_HASH].immediate(); - let index = args[COUNTER_INDEX].immediate(); + let index = args[COUNTER_ID].immediate(); debug!( "translating Rust intrinsic `count_code_region()` to LLVM intrinsic: \ instrprof.increment(fn_name={}, hash={:?}, num_counters={:?}, index={:?})", diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs index 9784beaa079..eb7dc827f93 100644 --- a/src/librustc_codegen_llvm/llvm/ffi.rs +++ b/src/librustc_codegen_llvm/llvm/ffi.rs @@ -1,7 +1,7 @@ #![allow(non_camel_case_types)] #![allow(non_upper_case_globals)] -use super::coverageinfo::{SmallVectorCounterExpression, SmallVectorCounterMappingRegion}; +use rustc_codegen_ssa::coverageinfo::map as coverage_map; use super::debuginfo::{ DIArray, DIBasicType, DIBuilder, DICompositeType, DIDerivedType, DIDescriptor, DIEnumerator, @@ -653,13 +653,152 @@ pub type DiagnosticHandler = unsafe extern "C" fn(&DiagnosticInfo, *mut c_void); pub type InlineAsmDiagHandler = unsafe extern "C" fn(&SMDiagnostic, *const c_void, c_uint); pub mod coverageinfo { - use super::InvariantOpaque; + use super::coverage_map; + /// Aligns with [llvm::coverage::CounterMappingRegion::RegionKind](https://github.com/rust-lang/llvm-project/blob/rustc/10.0-2020-05-05/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h#L205-L221) + #[derive(Copy, Clone, Debug)] #[repr(C)] - pub struct SmallVectorCounterExpression<'a>(InvariantOpaque<'a>); + pub enum RegionKind { + /// A CodeRegion associates some code with a counter + CodeRegion = 0, + + /// An ExpansionRegion represents a file expansion region that associates + /// a source range with the expansion of a virtual source file, such as + /// for a macro instantiation or #include file. + ExpansionRegion = 1, + + /// A SkippedRegion represents a source range with code that was skipped + /// by a preprocessor or similar means. + SkippedRegion = 2, + + /// A GapRegion is like a CodeRegion, but its count is only set as the + /// line execution count when its the only region in the line. + GapRegion = 3, + } + /// This struct provides LLVM's representation of a "CoverageMappingRegion", encoded into the + /// coverage map, in accordance with the + /// [LLVM Code Coverage Mapping Format](https://github.com/rust-lang/llvm-project/blob/llvmorg-8.0.0/llvm/docs/CoverageMappingFormat.rst#llvm-code-coverage-mapping-format). + /// The struct composes fields representing the `Counter` type and value(s) (injected counter + /// ID, or expression type and operands), the source file (an indirect index into a "filenames + /// array", encoded separately), and source location (start and end positions of the represented + /// code region). + /// + /// Aligns with [llvm::coverage::CounterMappingRegion](https://github.com/rust-lang/llvm-project/blob/rustc/10.0-2020-05-05/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h#L223-L226) + /// Important: The Rust struct layout (order and types of fields) must match its C++ + /// counterpart. + #[derive(Copy, Clone, Debug)] #[repr(C)] - pub struct SmallVectorCounterMappingRegion<'a>(InvariantOpaque<'a>); + pub struct CounterMappingRegion { + /// The counter type and type-dependent counter data, if any. + counter: coverage_map::Counter, + + /// An indirect reference to the source filename. In the LLVM Coverage Mapping Format, the + /// file_id is an index into a function-specific `virtual_file_mapping` array of indexes + /// that, in turn, are used to look up the filename for this region. + file_id: u32, + + /// If the `RegionKind` is an `ExpansionRegion`, the `expanded_file_id` can be used to find + /// the mapping regions created as a result of macro expansion, by checking if their file id + /// matches the expanded file id. + expanded_file_id: u32, + + /// 1-based starting line of the mapping region. + start_line: u32, + + /// 1-based starting column of the mapping region. + start_col: u32, + + /// 1-based ending line of the mapping region. + end_line: u32, + + /// 1-based ending column of the mapping region. If the high bit is set, the current + /// mapping region is a gap area. + end_col: u32, + + kind: RegionKind, + } + + impl CounterMappingRegion { + pub fn code_region( + counter: coverage_map::Counter, + file_id: u32, + start_line: u32, + start_col: u32, + end_line: u32, + end_col: u32, + ) -> Self { + Self { + counter, + file_id, + expanded_file_id: 0, + start_line, + start_col, + end_line, + end_col, + kind: RegionKind::CodeRegion, + } + } + + pub fn expansion_region( + file_id: u32, + expanded_file_id: u32, + start_line: u32, + start_col: u32, + end_line: u32, + end_col: u32, + ) -> Self { + Self { + counter: coverage_map::Counter::zero(), + file_id, + expanded_file_id, + start_line, + start_col, + end_line, + end_col, + kind: RegionKind::ExpansionRegion, + } + } + + pub fn skipped_region( + file_id: u32, + start_line: u32, + start_col: u32, + end_line: u32, + end_col: u32, + ) -> Self { + Self { + counter: coverage_map::Counter::zero(), + file_id, + expanded_file_id: 0, + start_line, + start_col, + end_line, + end_col, + kind: RegionKind::SkippedRegion, + } + } + + pub fn gap_region( + counter: coverage_map::Counter, + file_id: u32, + start_line: u32, + start_col: u32, + end_line: u32, + end_col: u32, + ) -> Self { + Self { + counter, + file_id, + expanded_file_id: 0, + start_line, + start_col, + end_line, + end_col: ((1 as u32) << 31) | end_col, + kind: RegionKind::GapRegion, + } + } + } } pub mod debuginfo { @@ -1645,33 +1784,6 @@ extern "C" { ConstraintsLen: size_t, ) -> bool; - pub fn LLVMRustCoverageSmallVectorCounterExpressionCreate() - -> &'a mut SmallVectorCounterExpression<'a>; - pub fn LLVMRustCoverageSmallVectorCounterExpressionDispose( - Container: &'a mut SmallVectorCounterExpression<'a>, - ); - pub fn LLVMRustCoverageSmallVectorCounterExpressionAdd( - Container: &mut SmallVectorCounterExpression<'a>, - Kind: rustc_codegen_ssa::coverageinfo::CounterOp, - LeftIndex: c_uint, - RightIndex: c_uint, - ); - - pub fn LLVMRustCoverageSmallVectorCounterMappingRegionCreate() - -> &'a mut SmallVectorCounterMappingRegion<'a>; - pub fn LLVMRustCoverageSmallVectorCounterMappingRegionDispose( - Container: &'a mut SmallVectorCounterMappingRegion<'a>, - ); - pub fn LLVMRustCoverageSmallVectorCounterMappingRegionAdd( - Container: &mut SmallVectorCounterMappingRegion<'a>, - Index: c_uint, - FileID: c_uint, - LineStart: c_uint, - ColumnStart: c_uint, - LineEnd: c_uint, - ColumnEnd: c_uint, - ); - #[allow(improper_ctypes)] pub fn LLVMRustCoverageWriteFilenamesSectionToBuffer( Filenames: *const *const c_char, @@ -1683,8 +1795,10 @@ extern "C" { pub fn LLVMRustCoverageWriteMappingToBuffer( VirtualFileMappingIDs: *const c_uint, NumVirtualFileMappingIDs: c_uint, - Expressions: *const SmallVectorCounterExpression<'_>, - MappingRegions: *const SmallVectorCounterMappingRegion<'_>, + Expressions: *const coverage_map::CounterExpression, + NumExpressions: c_uint, + MappingRegions: *mut coverageinfo::CounterMappingRegion, + NumMappingRegions: c_uint, BufferOut: &RustString, ); diff --git a/src/librustc_codegen_ssa/Cargo.toml b/src/librustc_codegen_ssa/Cargo.toml index e100e0095c9..8fa0de37648 100644 --- a/src/librustc_codegen_ssa/Cargo.toml +++ b/src/librustc_codegen_ssa/Cargo.toml @@ -14,7 +14,7 @@ bitflags = "1.2.1" cc = "1.0.1" num_cpus = "1.0" memmap = "0.7" -log = "0.4.5" +log = { package = "tracing", version = "0.1" } libc = "0.2.50" jobserver = "0.1.11" tempfile = "3.1" diff --git a/src/librustc_codegen_ssa/back/linker.rs b/src/librustc_codegen_ssa/back/linker.rs index d1ae9e37269..f9a782af24c 100644 --- a/src/librustc_codegen_ssa/back/linker.rs +++ b/src/librustc_codegen_ssa/back/linker.rs @@ -523,8 +523,9 @@ impl<'a> Linker for GccLinker<'a> { return; } + let is_windows = self.sess.target.target.options.is_like_windows; let mut arg = OsString::new(); - let path = tmpdir.join("list"); + let path = tmpdir.join(if is_windows { "list.def" } else { "list" }); debug!("EXPORTED SYMBOLS:"); @@ -540,6 +541,21 @@ impl<'a> Linker for GccLinker<'a> { if let Err(e) = res { self.sess.fatal(&format!("failed to write lib.def file: {}", e)); } + } else if is_windows { + let res: io::Result<()> = try { + let mut f = BufWriter::new(File::create(&path)?); + + // .def file similar to MSVC one but without LIBRARY section + // because LD doesn't like when it's empty + writeln!(f, "EXPORTS")?; + for symbol in self.info.exports[&crate_type].iter() { + debug!(" _{}", symbol); + writeln!(f, " {}", symbol)?; + } + }; + if let Err(e) = res { + self.sess.fatal(&format!("failed to write list.def file: {}", e)); + } } else { // Write an LD version script let res: io::Result<()> = try { @@ -573,7 +589,10 @@ impl<'a> Linker for GccLinker<'a> { if !self.is_ld { arg.push("-Wl,") } - arg.push("--version-script="); + // Both LD and LLD accept export list in *.def file form, there are no flags required + if !is_windows { + arg.push("--version-script=") + } } arg.push(&path); diff --git a/src/librustc_codegen_ssa/back/write.rs b/src/librustc_codegen_ssa/back/write.rs index 23e0b9344ec..b0fae566a5a 100644 --- a/src/librustc_codegen_ssa/back/write.rs +++ b/src/librustc_codegen_ssa/back/write.rs @@ -1846,11 +1846,11 @@ fn msvc_imps_needed(tcx: TyCtxt<'_>) -> bool { // something is wrong with commandline arg validation. assert!( !(tcx.sess.opts.cg.linker_plugin_lto.enabled() - && tcx.sess.target.target.options.is_like_msvc + && tcx.sess.target.target.options.is_like_windows && tcx.sess.opts.cg.prefer_dynamic) ); - tcx.sess.target.target.options.is_like_msvc && + tcx.sess.target.target.options.is_like_windows && tcx.sess.crate_types().iter().any(|ct| *ct == CrateType::Rlib) && // ThinLTO can't handle this workaround in all cases, so we don't // emit the `__imp_` symbols. Instead we make them unnecessary by disallowing diff --git a/src/librustc_codegen_ssa/coverageinfo/ffi.rs b/src/librustc_codegen_ssa/coverageinfo/ffi.rs new file mode 100644 index 00000000000..5b04f994994 --- /dev/null +++ b/src/librustc_codegen_ssa/coverageinfo/ffi.rs @@ -0,0 +1,67 @@ +use super::map::{CounterValueReference, MappedExpressionIndex}; + +/// Aligns with [llvm::coverage::Counter::CounterKind](https://github.com/rust-lang/llvm-project/blob/rustc/10.0-2020-05-05/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h#L91) +#[derive(Copy, Clone, Debug)] +#[repr(C)] +enum CounterKind { + Zero = 0, + CounterValueReference = 1, + Expression = 2, +} + +/// A reference to an instance of an abstract "counter" that will yield a value in a coverage +/// report. Note that `id` has different interpretations, depending on the `kind`: +/// * For `CounterKind::Zero`, `id` is assumed to be `0` +/// * For `CounterKind::CounterValueReference`, `id` matches the `counter_id` of the injected +/// instrumentation counter (the `index` argument to the LLVM intrinsic +/// `instrprof.increment()`) +/// * For `CounterKind::Expression`, `id` is the index into the coverage map's array of +/// counter expressions. +/// Aligns with [llvm::coverage::Counter](https://github.com/rust-lang/llvm-project/blob/rustc/10.0-2020-05-05/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h#L98-L99) +/// Important: The Rust struct layout (order and types of fields) must match its C++ counterpart. +#[derive(Copy, Clone, Debug)] +#[repr(C)] +pub struct Counter { + // Important: The layout (order and types of fields) must match its C++ counterpart. + kind: CounterKind, + id: u32, +} + +impl Counter { + pub fn zero() -> Self { + Self { kind: CounterKind::Zero, id: 0 } + } + + pub fn counter_value_reference(counter_id: CounterValueReference) -> Self { + Self { kind: CounterKind::CounterValueReference, id: counter_id.into() } + } + + pub fn expression(mapped_expression_index: MappedExpressionIndex) -> Self { + Self { kind: CounterKind::Expression, id: mapped_expression_index.into() } + } +} + +/// Aligns with [llvm::coverage::CounterExpression::ExprKind](https://github.com/rust-lang/llvm-project/blob/rustc/10.0-2020-05-05/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h#L146) +#[derive(Copy, Clone, Debug)] +#[repr(C)] +pub enum ExprKind { + Subtract = 0, + Add = 1, +} + +/// Aligns with [llvm::coverage::CounterExpression](https://github.com/rust-lang/llvm-project/blob/rustc/10.0-2020-05-05/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h#L147-L148) +/// Important: The Rust struct layout (order and types of fields) must match its C++ +/// counterpart. +#[derive(Copy, Clone, Debug)] +#[repr(C)] +pub struct CounterExpression { + kind: ExprKind, + lhs: Counter, + rhs: Counter, +} + +impl CounterExpression { + pub fn new(lhs: Counter, kind: ExprKind, rhs: Counter) -> Self { + Self { kind, lhs, rhs } + } +} diff --git a/src/librustc_codegen_ssa/coverageinfo/map.rs b/src/librustc_codegen_ssa/coverageinfo/map.rs index a8ffef8bc5b..72138065a90 100644 --- a/src/librustc_codegen_ssa/coverageinfo/map.rs +++ b/src/librustc_codegen_ssa/coverageinfo/map.rs @@ -1,289 +1,364 @@ -use rustc_data_structures::sync::Lrc; -use rustc_middle::mir; -use rustc_span::source_map::{Pos, SourceFile, SourceMap}; -use rustc_span::{BytePos, FileName, RealFileName}; +pub use super::ffi::*; + +use rustc_index::vec::IndexVec; +use rustc_middle::ty::Instance; +use rustc_middle::ty::TyCtxt; +use rustc_span::source_map::{Pos, SourceMap}; +use rustc_span::{BytePos, FileName, Loc, RealFileName}; use std::cmp::{Ord, Ordering}; -use std::collections::BTreeMap; use std::fmt; use std::path::PathBuf; -#[derive(Copy, Clone, Debug)] -#[repr(C)] -pub enum CounterOp { - // Note the order (and therefore the default values) is important. With the attribute - // `#[repr(C)]`, this enum matches the layout of the LLVM enum defined for the nested enum, - // `llvm::coverage::CounterExpression::ExprKind`, as shown in the following source snippet: - // https://github.com/rust-lang/llvm-project/blob/f208b70fbc4dee78067b3c5bd6cb92aa3ba58a1e/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h#L146 - Subtract, - Add, -} - -#[derive(Copy, Clone, Debug)] -pub enum CoverageKind { - Counter, - CounterExpression(u32, CounterOp, u32), - Unreachable, +rustc_index::newtype_index! { + pub struct ExpressionOperandId { + DEBUG_FORMAT = "ExpressionOperandId({})", + MAX = 0xFFFF_FFFF, + } } -#[derive(Clone, Debug)] -pub struct CoverageRegion { - pub kind: CoverageKind, - pub start_byte_pos: u32, - pub end_byte_pos: u32, +rustc_index::newtype_index! { + pub struct CounterValueReference { + DEBUG_FORMAT = "CounterValueReference({})", + MAX = 0xFFFF_FFFF, + } } -impl CoverageRegion { - pub fn source_loc(&self, source_map: &SourceMap) -> Option<(Lrc<SourceFile>, CoverageLoc)> { - let (start_file, start_line, start_col) = - lookup_file_line_col(source_map, BytePos::from_u32(self.start_byte_pos)); - let (end_file, end_line, end_col) = - lookup_file_line_col(source_map, BytePos::from_u32(self.end_byte_pos)); - let start_file_path = match &start_file.name { - FileName::Real(RealFileName::Named(path)) => path, - _ => { - bug!("start_file_path should be a RealFileName, but it was: {:?}", start_file.name) - } - }; - let end_file_path = match &end_file.name { - FileName::Real(RealFileName::Named(path)) => path, - _ => bug!("end_file_path should be a RealFileName, but it was: {:?}", end_file.name), - }; - if start_file_path == end_file_path { - Some((start_file, CoverageLoc { start_line, start_col, end_line, end_col })) - } else { - None - // FIXME(richkadel): There seems to be a problem computing the file location in - // some cases. I need to investigate this more. When I generate and show coverage - // for the example binary in the crates.io crate `json5format`, I had a couple of - // notable problems: - // - // 1. I saw a lot of coverage spans in `llvm-cov show` highlighting regions in - // various comments (not corresponding to rustdoc code), indicating a possible - // problem with the byte_pos-to-source-map implementation. - // - // 2. And (perhaps not related) when I build the aforementioned example binary with: - // `RUST_FLAGS="-Zinstrument-coverage" cargo build --example formatjson5` - // and then run that binary with - // `LLVM_PROFILE_FILE="formatjson5.profraw" ./target/debug/examples/formatjson5 \ - // some.json5` for some reason the binary generates *TWO* `.profraw` files. One - // named `default.profraw` and the other named `formatjson5.profraw` (the expected - // name, in this case). - // - // If the byte range conversion is wrong, fix it. But if it - // is right, then it is possible for the start and end to be in different files. - // Can I do something other than ignore coverages that span multiple files? - // - // If I can resolve this, remove the "Option<>" result type wrapper - // `regions_in_file_order()` accordingly. - } +rustc_index::newtype_index! { + pub struct InjectedExpressionIndex { + DEBUG_FORMAT = "InjectedExpressionIndex({})", + MAX = 0xFFFF_FFFF, } } -impl Default for CoverageRegion { - fn default() -> Self { - Self { - // The default kind (Unreachable) is a placeholder that will be overwritten before - // backend codegen. - kind: CoverageKind::Unreachable, - start_byte_pos: 0, - end_byte_pos: 0, - } +rustc_index::newtype_index! { + pub struct MappedExpressionIndex { + DEBUG_FORMAT = "MappedExpressionIndex({})", + MAX = 0xFFFF_FFFF, } } -/// A source code region used with coverage information. -#[derive(Debug, Eq, PartialEq)] -pub struct CoverageLoc { - /// The (1-based) line number of the region start. - pub start_line: u32, - /// The (1-based) column number of the region start. - pub start_col: u32, - /// The (1-based) line number of the region end. - pub end_line: u32, - /// The (1-based) column number of the region end. - pub end_col: u32, +#[derive(Clone, Debug)] +pub struct Region { + start: Loc, + end: Loc, } -impl Ord for CoverageLoc { +impl Ord for Region { fn cmp(&self, other: &Self) -> Ordering { - (self.start_line, &self.start_col, &self.end_line, &self.end_col).cmp(&( - other.start_line, - &other.start_col, - &other.end_line, - &other.end_col, - )) + (&self.start.file.name, &self.start.line, &self.start.col, &self.end.line, &self.end.col) + .cmp(&( + &other.start.file.name, + &other.start.line, + &other.start.col, + &other.end.line, + &other.end.col, + )) } } -impl PartialOrd for CoverageLoc { +impl PartialOrd for Region { fn partial_cmp(&self, other: &Self) -> Option<Ordering> { Some(self.cmp(other)) } } -impl fmt::Display for CoverageLoc { +impl PartialEq for Region { + fn eq(&self, other: &Self) -> bool { + self.start.file.name == other.start.file.name + && self.start.line == other.start.line + && self.start.col == other.start.col + && self.end.line == other.end.line + && self.end.col == other.end.col + } +} + +impl Eq for Region {} + +impl fmt::Display for Region { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - // Customize debug format, and repeat the file name, so generated location strings are - // "clickable" in many IDEs. - write!(f, "{}:{} - {}:{}", self.start_line, self.start_col, self.end_line, self.end_col) + let (file_path, start_line, start_col, end_line, end_col) = self.file_start_and_end(); + write!(f, "{:?}:{}:{} - {}:{}", file_path, start_line, start_col, end_line, end_col) } } -fn lookup_file_line_col(source_map: &SourceMap, byte_pos: BytePos) -> (Lrc<SourceFile>, u32, u32) { - let found = source_map - .lookup_line(byte_pos) - .expect("should find coverage region byte position in source"); - let file = found.sf; - let line_pos = file.line_begin_pos(byte_pos); +impl Region { + pub fn new(source_map: &SourceMap, start_byte_pos: u32, end_byte_pos: u32) -> Self { + let start = source_map.lookup_char_pos(BytePos::from_u32(start_byte_pos)); + let end = source_map.lookup_char_pos(BytePos::from_u32(end_byte_pos)); + assert_eq!( + start.file.name, end.file.name, + "Region start ({} -> {:?}) and end ({} -> {:?}) don't come from the same source file!", + start_byte_pos, start, end_byte_pos, end + ); + Self { start, end } + } - // Use 1-based indexing. - let line = (found.line + 1) as u32; - let col = (byte_pos - line_pos).to_u32() + 1; + pub fn file_start_and_end<'a>(&'a self) -> (&'a PathBuf, u32, u32, u32, u32) { + let start = &self.start; + let end = &self.end; + match &start.file.name { + FileName::Real(RealFileName::Named(path)) => ( + path, + start.line as u32, + start.col.to_u32() + 1, + end.line as u32, + end.col.to_u32() + 1, + ), + _ => { + bug!("start.file.name should be a RealFileName, but it was: {:?}", start.file.name) + } + } + } +} - (file, line, col) +#[derive(Clone, Debug)] +pub struct ExpressionRegion { + lhs: ExpressionOperandId, + op: ExprKind, + rhs: ExpressionOperandId, + region: Region, } +// FIXME(richkadel): There seems to be a problem computing the file location in +// some cases. I need to investigate this more. When I generate and show coverage +// for the example binary in the crates.io crate `json5format`, I had a couple of +// notable problems: +// +// 1. I saw a lot of coverage spans in `llvm-cov show` highlighting regions in +// various comments (not corresponding to rustdoc code), indicating a possible +// problem with the byte_pos-to-source-map implementation. +// +// 2. And (perhaps not related) when I build the aforementioned example binary with: +// `RUST_FLAGS="-Zinstrument-coverage" cargo build --example formatjson5` +// and then run that binary with +// `LLVM_PROFILE_FILE="formatjson5.profraw" ./target/debug/examples/formatjson5 \ +// some.json5` for some reason the binary generates *TWO* `.profraw` files. One +// named `default.profraw` and the other named `formatjson5.profraw` (the expected +// name, in this case). +// +// 3. I think that if I eliminate regions within a function, their region_ids, +// referenced in expressions, will be wrong? I think the ids are implied by their +// array position in the final coverage map output (IIRC). +// +// 4. I suspect a problem (if not the only problem) is the SourceMap is wrong for some +// region start/end byte positions. Just like I couldn't get the function hash at +// intrinsic codegen time for external crate functions, I think the SourceMap I +// have here only applies to the local crate, and I know I have coverages that +// reference external crates. +// +// I still don't know if I fixed the hash problem correctly. If external crates +// implement the function, can't I use the coverage counters already compiled +// into those external crates? (Maybe not for generics and/or maybe not for +// macros... not sure. But I need to understand this better.) +// +// If the byte range conversion is wrong, fix it. But if it +// is right, then it is possible for the start and end to be in different files. +// Can I do something other than ignore coverages that span multiple files? +// +// If I can resolve this, remove the "Option<>" result type wrapper +// `regions_in_file_order()` accordingly. + /// Collects all of the coverage regions associated with (a) injected counters, (b) counter /// expressions (additions or subtraction), and (c) unreachable regions (always counted as zero), -/// for a given Function. Counters and counter expressions are indexed because they can be operands -/// in an expression. This struct also stores the `function_source_hash`, computed during -/// instrumentation and forwarded with counters. +/// for a given Function. Counters and counter expressions have non-overlapping `id`s because they +/// can both be operands in an expression. This struct also stores the `function_source_hash`, +/// computed during instrumentation, and forwarded with counters. /// -/// Note, it's important to distinguish the `unreachable` region type from what LLVM's refers to as -/// a "gap region" (or "gap area"). A gap region is a code region within a counted region (either -/// counter or expression), but the line or lines in the gap region are not executable (such as -/// lines with only whitespace or comments). According to LLVM Code Coverage Mapping documentation, -/// "A count for a gap area is only used as the line execution count if there are no other regions -/// on a line." -pub struct FunctionCoverage { +/// Note, it may be important to understand LLVM's definitions of `unreachable` regions versus "gap +/// regions" (or "gap areas"). A gap region is a code region within a counted region (either counter +/// or expression), but the line or lines in the gap region are not executable (such as lines with +/// only whitespace or comments). According to LLVM Code Coverage Mapping documentation, "A count +/// for a gap area is only used as the line execution count if there are no other regions on a +/// line." +pub struct FunctionCoverage<'a> { + source_map: &'a SourceMap, source_hash: u64, - counters: Vec<CoverageRegion>, - expressions: Vec<CoverageRegion>, - unreachable: Vec<CoverageRegion>, - translated: bool, + counters: IndexVec<CounterValueReference, Option<Region>>, + expressions: IndexVec<InjectedExpressionIndex, Option<ExpressionRegion>>, + unreachable_regions: Vec<Region>, } -impl FunctionCoverage { - pub fn with_coverageinfo<'tcx>(coverageinfo: &'tcx mir::CoverageInfo) -> Self { +impl<'a> FunctionCoverage<'a> { + pub fn new<'tcx: 'a>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> Self { + let coverageinfo = tcx.coverageinfo(instance.def_id()); Self { + source_map: tcx.sess.source_map(), source_hash: 0, // will be set with the first `add_counter()` - counters: vec![CoverageRegion::default(); coverageinfo.num_counters as usize], - expressions: vec![CoverageRegion::default(); coverageinfo.num_expressions as usize], - unreachable: Vec::new(), - translated: false, + counters: IndexVec::from_elem_n(None, coverageinfo.num_counters as usize), + expressions: IndexVec::from_elem_n(None, coverageinfo.num_expressions as usize), + unreachable_regions: Vec::new(), } } - /// Adds a code region to be counted by an injected counter intrinsic. Return a counter ID - /// for the call. + /// Adds a code region to be counted by an injected counter intrinsic. + /// The source_hash (computed during coverage instrumentation) should also be provided, and + /// should be the same for all counters in a given function. pub fn add_counter( &mut self, source_hash: u64, - index: u32, + id: u32, start_byte_pos: u32, end_byte_pos: u32, ) { - self.source_hash = source_hash; - self.counters[index as usize] = - CoverageRegion { kind: CoverageKind::Counter, start_byte_pos, end_byte_pos }; + if self.source_hash == 0 { + self.source_hash = source_hash; + } else { + debug_assert_eq!(source_hash, self.source_hash); + } + self.counters[CounterValueReference::from(id)] + .replace(Region::new(self.source_map, start_byte_pos, end_byte_pos)) + .expect_none("add_counter called with duplicate `id`"); } + /// Both counters and "counter expressions" (or simply, "expressions") can be operands in other + /// expressions. Expression IDs start from `u32::MAX` and go down, so the range of expression + /// IDs will not overlap with the range of counter IDs. Counters and expressions can be added in + /// any order, and expressions can still be assigned contiguous (though descending) IDs, without + /// knowing what the last counter ID will be. + /// + /// When storing the expression data in the `expressions` vector in the `FunctionCoverage` + /// struct, its vector index is computed, from the given expression ID, by subtracting from + /// `u32::MAX`. + /// + /// Since the expression operands (`lhs` and `rhs`) can reference either counters or + /// expressions, an operand that references an expression also uses its original ID, descending + /// from `u32::MAX`. Theses operands are translated only during code generation, after all + /// counters and expressions have been added. pub fn add_counter_expression( &mut self, - translated_index: u32, + id_descending_from_max: u32, lhs: u32, - op: CounterOp, + op: ExprKind, rhs: u32, start_byte_pos: u32, end_byte_pos: u32, ) { - let index = u32::MAX - translated_index; - // Counter expressions start with "translated indexes", descending from `u32::MAX`, so - // the range of expression indexes is disjoint from the range of counter indexes. This way, - // both counters and expressions can be operands in other expressions. - // - // Once all counters have been added, the final "region index" for an expression is - // `counters.len() + expression_index` (where `expression_index` is its index in - // `self.expressions`), and the expression operands (`lhs` and `rhs`) can be converted to - // final "region index" references by the same conversion, after subtracting from - // `u32::MAX`. - self.expressions[index as usize] = CoverageRegion { - kind: CoverageKind::CounterExpression(lhs, op, rhs), - start_byte_pos, - end_byte_pos, - }; + let expression_id = ExpressionOperandId::from(id_descending_from_max); + let lhs = ExpressionOperandId::from(lhs); + let rhs = ExpressionOperandId::from(rhs); + + let expression_index = self.expression_index(expression_id); + self.expressions[expression_index] + .replace(ExpressionRegion { + lhs, + op, + rhs, + region: Region::new(self.source_map, start_byte_pos, end_byte_pos), + }) + .expect_none("add_counter_expression called with duplicate `id_descending_from_max`"); } - pub fn add_unreachable(&mut self, start_byte_pos: u32, end_byte_pos: u32) { - self.unreachable.push(CoverageRegion { - kind: CoverageKind::Unreachable, - start_byte_pos, - end_byte_pos, - }); + /// Add a region that will be marked as "unreachable", with a constant "zero counter". + pub fn add_unreachable_region(&mut self, start_byte_pos: u32, end_byte_pos: u32) { + self.unreachable_regions.push(Region::new(self.source_map, start_byte_pos, end_byte_pos)); } + /// Return the source hash, generated from the HIR node structure, and used to indicate whether + /// or not the source code structure changed between different compilations. pub fn source_hash(&self) -> u64 { self.source_hash } - fn regions(&'a mut self) -> impl Iterator<Item = &'a CoverageRegion> { + /// Generate an array of CounterExpressions, and an iterator over all `Counter`s and their + /// associated `Regions` (from which the LLVM-specific `CoverageMapGenerator` will create + /// `CounterMappingRegion`s. + pub fn get_expressions_and_counter_regions( + &'a self, + ) -> (Vec<CounterExpression>, impl Iterator<Item = (Counter, &'a Region)>) { assert!(self.source_hash != 0); - self.ensure_expressions_translated(); - self.counters.iter().chain(self.expressions.iter().chain(self.unreachable.iter())) + + let counter_regions = self.counter_regions(); + let (counter_expressions, expression_regions) = self.expressions_with_regions(); + let unreachable_regions = self.unreachable_regions(); + + let counter_regions = + counter_regions.chain(expression_regions.into_iter().chain(unreachable_regions)); + (counter_expressions, counter_regions) } - pub fn regions_in_file_order( - &'a mut self, - source_map: &SourceMap, - ) -> BTreeMap<PathBuf, BTreeMap<CoverageLoc, (usize, CoverageKind)>> { - let mut regions_in_file_order = BTreeMap::new(); - for (region_id, region) in self.regions().enumerate() { - if let Some((source_file, region_loc)) = region.source_loc(source_map) { - // FIXME(richkadel): `region.source_loc()` sometimes fails with two different - // filenames for the start and end byte position. This seems wrong, but for - // now, if encountered, the region is skipped. If resolved, convert the result - // to a non-option value so regions are never skipped. - let real_file_path = match &(*source_file).name { - FileName::Real(RealFileName::Named(path)) => path.clone(), - _ => bug!("coverage mapping expected only real, named files"), - }; - let file_coverage_regions = - regions_in_file_order.entry(real_file_path).or_insert_with(|| BTreeMap::new()); - file_coverage_regions.insert(region_loc, (region_id, region.kind)); - } - } - regions_in_file_order + fn counter_regions(&'a self) -> impl Iterator<Item = (Counter, &'a Region)> { + self.counters.iter_enumerated().filter_map(|(index, entry)| { + // Option::map() will return None to filter out missing counters. This may happen + // if, for example, a MIR-instrumented counter is removed during an optimization. + entry.as_ref().map(|region| { + (Counter::counter_value_reference(index as CounterValueReference), region) + }) + }) } - /// A one-time translation of expression operands is needed, for any operands referencing - /// other CounterExpressions. CounterExpression operands get an initial operand ID that is - /// computed by the simple translation: `u32::max - expression_index` because, when created, - /// the total number of Counters is not yet known. This function recomputes region indexes - /// for expressions so they start with the next region index after the last counter index. - fn ensure_expressions_translated(&mut self) { - if !self.translated { - self.translated = true; - let start = self.counters.len() as u32; - assert!( - (start as u64 + self.expressions.len() as u64) < u32::MAX as u64, - "the number of counters and counter expressions in a single function exceeds {}", - u32::MAX - ); - for region in self.expressions.iter_mut() { - match region.kind { - CoverageKind::CounterExpression(lhs, op, rhs) => { - let lhs = to_region_index(start, lhs); - let rhs = to_region_index(start, rhs); - region.kind = CoverageKind::CounterExpression(lhs, op, rhs); - } - _ => bug!("expressions must only contain CounterExpression kinds"), + fn expressions_with_regions( + &'a self, + ) -> (Vec<CounterExpression>, impl Iterator<Item = (Counter, &'a Region)>) { + let mut counter_expressions = Vec::with_capacity(self.expressions.len()); + let mut expression_regions = Vec::with_capacity(self.expressions.len()); + let mut new_indexes = + IndexVec::from_elem_n(MappedExpressionIndex::from(u32::MAX), self.expressions.len()); + // Note, the initial value shouldn't matter since every index in use in `self.expressions` + // will be set, and after that, `new_indexes` will only be accessed using those same + // indexes. + + // Note that an `ExpressionRegion`s at any given index can include other expressions as + // operands, but expression operands can only come from the subset of expressions having + // `expression_index`s lower than the referencing `ExpressionRegion`. Therefore, it is + // reasonable to look up the new index of an expression operand while the `new_indexes` + // vector is only complete up to the current `ExpressionIndex`. + let id_to_counter = + |new_indexes: &IndexVec<InjectedExpressionIndex, MappedExpressionIndex>, + id: ExpressionOperandId| { + if id.index() < self.counters.len() { + let index = CounterValueReference::from(id.index()); + self.counters + .get(index) + .unwrap() // pre-validated + .as_ref() + .map(|_| Counter::counter_value_reference(index)) + } else { + let index = self.expression_index(id); + self.expressions + .get(index) + .expect("expression id is out of range") + .as_ref() + .map(|_| Counter::expression(new_indexes[index])) } + }; + + for (original_index, expression_region) in + self.expressions.iter_enumerated().filter_map(|(original_index, entry)| { + // Option::map() will return None to filter out missing expressions. This may happen + // if, for example, a MIR-instrumented expression is removed during an optimization. + entry.as_ref().map(|region| (original_index, region)) + }) + { + let region = &expression_region.region; + let ExpressionRegion { lhs, op, rhs, .. } = *expression_region; + + if let Some(Some((lhs_counter, rhs_counter))) = + id_to_counter(&new_indexes, lhs).map(|lhs_counter| { + id_to_counter(&new_indexes, rhs).map(|rhs_counter| (lhs_counter, rhs_counter)) + }) + { + // Both operands exist. `Expression` operands exist in `self.expressions` and have + // been assigned a `new_index`. + let mapped_expression_index = + MappedExpressionIndex::from(counter_expressions.len()); + counter_expressions.push(CounterExpression::new(lhs_counter, op, rhs_counter)); + new_indexes[original_index] = mapped_expression_index; + expression_regions.push((Counter::expression(mapped_expression_index), region)); } } + (counter_expressions, expression_regions.into_iter()) + } + + fn unreachable_regions(&'a self) -> impl Iterator<Item = (Counter, &'a Region)> { + self.unreachable_regions.iter().map(|region| (Counter::zero(), region)) } -} -fn to_region_index(start: u32, index: u32) -> u32 { - if index < start { index } else { start + (u32::MAX - index) } + fn expression_index( + &self, + id_descending_from_max: ExpressionOperandId, + ) -> InjectedExpressionIndex { + debug_assert!(id_descending_from_max.index() >= self.counters.len()); + InjectedExpressionIndex::from(u32::MAX - u32::from(id_descending_from_max)) + } } diff --git a/src/librustc_codegen_ssa/coverageinfo/mod.rs b/src/librustc_codegen_ssa/coverageinfo/mod.rs index 304f8e19da4..1f0ffd289b1 100644 --- a/src/librustc_codegen_ssa/coverageinfo/mod.rs +++ b/src/librustc_codegen_ssa/coverageinfo/mod.rs @@ -1,3 +1,4 @@ +pub mod ffi; pub mod map; -pub use map::CounterOp; +pub use map::ExprKind; diff --git a/src/librustc_codegen_ssa/lib.rs b/src/librustc_codegen_ssa/lib.rs index bdd73c08313..85260d30a3d 100644 --- a/src/librustc_codegen_ssa/lib.rs +++ b/src/librustc_codegen_ssa/lib.rs @@ -1,5 +1,6 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] #![feature(bool_to_option)] +#![feature(option_expect_none)] #![feature(box_patterns)] #![feature(try_blocks)] #![feature(in_band_lifetimes)] @@ -7,6 +8,8 @@ #![feature(or_patterns)] #![feature(trusted_len)] #![feature(associated_type_bounds)] +#![feature(const_fn)] // for rustc_index::newtype_index +#![feature(const_panic)] // for rustc_index::newtype_index #![recursion_limit = "256"] //! This crate contains codegen code that is used by all codegen backends (LLVM and others). diff --git a/src/librustc_codegen_ssa/traits/coverageinfo.rs b/src/librustc_codegen_ssa/traits/coverageinfo.rs index 1b9faa42484..db1d86c974e 100644 --- a/src/librustc_codegen_ssa/traits/coverageinfo.rs +++ b/src/librustc_codegen_ssa/traits/coverageinfo.rs @@ -1,5 +1,5 @@ use super::BackendTypes; -use crate::coverageinfo::CounterOp; +use crate::coverageinfo::ExprKind; use rustc_middle::ty::Instance; pub trait CoverageInfoMethods: BackendTypes { @@ -21,7 +21,7 @@ pub trait CoverageInfoBuilderMethods<'tcx>: BackendTypes { instance: Instance<'tcx>, index: u32, lhs: u32, - op: CounterOp, + op: ExprKind, rhs: u32, start_byte_pos: u32, end_byte_pos: u32, diff --git a/src/librustc_data_structures/Cargo.toml b/src/librustc_data_structures/Cargo.toml index 1c2fb90b2d8..811d1e49626 100644 --- a/src/librustc_data_structures/Cargo.toml +++ b/src/librustc_data_structures/Cargo.toml @@ -12,7 +12,7 @@ doctest = false [dependencies] ena = "0.14" indexmap = "1" -log = "0.4" +log = { package = "tracing", version = "0.1" } jobserver_crate = { version = "0.1.13", package = "jobserver" } lazy_static = "1" once_cell = { version = "1", features = ["parking_lot"] } diff --git a/src/librustc_driver/Cargo.toml b/src/librustc_driver/Cargo.toml index 75d65920766..6474a69b216 100644 --- a/src/librustc_driver/Cargo.toml +++ b/src/librustc_driver/Cargo.toml @@ -12,8 +12,8 @@ crate-type = ["dylib"] [dependencies] lazy_static = "1.0" libc = "0.2" -log = "0.4" -env_logger = { version = "0.7", default-features = false } +log = { package = "tracing", version = "0.1.18", features = ["release_max_level_info"] } +tracing-subscriber = { version = "0.2.10", default-features = false, features = ["fmt", "env-filter", "smallvec", "parking_lot", "ansi"] } rustc_middle = { path = "../librustc_middle" } rustc_ast_pretty = { path = "../librustc_ast_pretty" } rustc_target = { path = "../librustc_target" } diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index ab4eac9440b..7af640c109e 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -1224,9 +1224,26 @@ pub fn install_ice_hook() { } /// This allows tools to enable rust logging without having to magically match rustc's -/// log crate version +/// log crate version. pub fn init_rustc_env_logger() { - env_logger::init_from_env("RUSTC_LOG"); + init_env_logger("RUSTC_LOG") +} + +/// This allows tools to enable rust logging without having to magically match rustc's +/// log crate version. In contrast to `init_rustc_env_logger` it allows you to choose an env var +/// other than `RUSTC_LOG`. +pub fn init_env_logger(env: &str) { + // Don't register a dispatcher if there's no filter to print anything + match std::env::var(env) { + Err(_) => return, + Ok(s) if s.is_empty() => return, + Ok(_) => {} + } + let builder = tracing_subscriber::FmtSubscriber::builder(); + + let builder = builder.with_env_filter(tracing_subscriber::EnvFilter::from_env(env)); + + builder.init() } pub fn main() -> ! { diff --git a/src/librustc_error_codes/error_codes/E0720.md b/src/librustc_error_codes/error_codes/E0720.md index 410aa4f4609..40dfa484d3f 100644 --- a/src/librustc_error_codes/error_codes/E0720.md +++ b/src/librustc_error_codes/error_codes/E0720.md @@ -1,11 +1,13 @@ An `impl Trait` type expands to a recursive type. -An `impl Trait` type must be expandable to a concrete type that contains no -`impl Trait` types. For example the following example tries to create an -`impl Trait` type `T` that is equal to `[T, T]`: +Erroneous code example: ```compile_fail,E0720 fn make_recursive_type() -> impl Sized { [make_recursive_type(), make_recursive_type()] } ``` + +An `impl Trait` type must be expandable to a concrete type that contains no +`impl Trait` types. For example the previous example tries to create an +`impl Trait` type `T` that is equal to `[T, T]`. diff --git a/src/librustc_error_codes/error_codes/E0728.md b/src/librustc_error_codes/error_codes/E0728.md index 1afbedab0ca..f4968a4f00e 100644 --- a/src/librustc_error_codes/error_codes/E0728.md +++ b/src/librustc_error_codes/error_codes/E0728.md @@ -1,6 +1,6 @@ -[`await`] has been used outside [`async`] function or block. +[`await`] has been used outside [`async`] function or [`async`] block. -Erroneous code examples: +Erroneous code example: ```edition2018,compile_fail,E0728 # use std::pin::Pin; @@ -33,7 +33,7 @@ fn foo() { [`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. +an [`async`] context, like an `async` function or an `async` block. ```edition2018 # use std::pin::Pin; diff --git a/src/librustc_error_codes/error_codes/E0730.md b/src/librustc_error_codes/error_codes/E0730.md index c2a71ca5669..016b3f38aa3 100644 --- a/src/librustc_error_codes/error_codes/E0730.md +++ b/src/librustc_error_codes/error_codes/E0730.md @@ -1,6 +1,6 @@ An array without a fixed length was pattern-matched. -Example of erroneous code: +Erroneous code example: ```compile_fail,E0730 #![feature(const_generics)] @@ -14,14 +14,28 @@ fn is_123<const N: usize>(x: [u32; N]) -> bool { } ``` -Ensure that the pattern is consistent with the size of the matched -array. Additional elements can be matched with `..`: +To fix this error, you have two solutions: + 1. Use an array with a fixed length. + 2. Use a slice. +Example with an array with a fixed length: + +``` +fn is_123(x: [u32; 3]) -> bool { // We use an array with a fixed size + match x { + [1, 2, ..] => true, // ok! + _ => false + } +} ``` -let r = &[1, 2, 3, 4]; -match r { - &[a, b, ..] => { // ok! - println!("a={}, b={}", a, b); + +Example with a slice: + +``` +fn is_123(x: &[u32]) -> bool { // We use a slice + match x { + [1, 2, ..] => true, // ok! + _ => false } } ``` diff --git a/src/librustc_error_codes/error_codes/E0733.md b/src/librustc_error_codes/error_codes/E0733.md index 0bda7a7d682..051b75148e5 100644 --- a/src/librustc_error_codes/error_codes/E0733.md +++ b/src/librustc_error_codes/error_codes/E0733.md @@ -1,4 +1,6 @@ -Recursion in an `async fn` requires boxing. For example, this will not compile: +An [`async`] function used recursion without boxing. + +Erroneous code example: ```edition2018,compile_fail,E0733 async fn foo(n: usize) { @@ -8,8 +10,8 @@ async fn foo(n: usize) { } ``` -To achieve async recursion, the `async fn` needs to be desugared -such that the `Future` is explicit in the return type: +To perform async recursion, the `async fn` needs to be desugared such that the +`Future` is explicit in the return type: ```edition2018,compile_fail,E0720 use std::future::Future; @@ -36,5 +38,7 @@ fn foo_recursive(n: usize) -> Pin<Box<dyn Future<Output = ()>>> { } ``` -The `Box<...>` ensures that the result is of known size, -and the pin is required to keep it in the same place in memory. +The `Box<...>` ensures that the result is of known size, and the pin is +required to keep it in the same place in memory. + +[`async`]: https://doc.rust-lang.org/std/keyword.async.html diff --git a/src/librustc_error_codes/error_codes/E0734.md b/src/librustc_error_codes/error_codes/E0734.md index 7506c8e693e..4b8e89a7060 100644 --- a/src/librustc_error_codes/error_codes/E0734.md +++ b/src/librustc_error_codes/error_codes/E0734.md @@ -1,6 +1,6 @@ A stability attribute has been used outside of the standard library. -Erroneous code examples: +Erroneous code example: ```compile_fail,E0734 #[rustc_deprecated(since = "b", reason = "text")] // invalid diff --git a/src/librustc_error_codes/error_codes/E0740.md b/src/librustc_error_codes/error_codes/E0740.md index 37776785189..6240099a99f 100644 --- a/src/librustc_error_codes/error_codes/E0740.md +++ b/src/librustc_error_codes/error_codes/E0740.md @@ -1,4 +1,4 @@ -A `union` cannot have fields with destructors. +A `union` was declared with fields with destructors. Erroneous code example: @@ -14,3 +14,5 @@ impl Drop for A { fn drop(&mut self) { println!("A"); } } ``` + +A `union` cannot have fields with destructors. diff --git a/src/librustc_error_codes/error_codes/E0741.md b/src/librustc_error_codes/error_codes/E0741.md index 0a8650282a3..91379bfe05c 100644 --- a/src/librustc_error_codes/error_codes/E0741.md +++ b/src/librustc_error_codes/error_codes/E0741.md @@ -1,5 +1,6 @@ -Only structural-match types (that is, types that derive `PartialEq` and `Eq`) -may be used as the types of const generic parameters. +A non-structural-match type was used as the type of a const generic parameter. + +Erroneous code example: ```compile_fail,E0741 #![feature(const_generics)] @@ -9,12 +10,15 @@ struct A; struct B<const X: A>; // error! ``` -To fix this example, we derive `PartialEq` and `Eq`. +Only structural-match types (that is, types that derive `PartialEq` and `Eq`) +may be used as the types of const generic parameters. + +To fix the previous code example, we derive `PartialEq` and `Eq`: ``` #![feature(const_generics)] -#[derive(PartialEq, Eq)] +#[derive(PartialEq, Eq)] // We derive both traits here. struct A; struct B<const X: A>; // ok! diff --git a/src/librustc_error_codes/error_codes/E0743.md b/src/librustc_error_codes/error_codes/E0743.md index 1780fe59cbd..ddd3136df0c 100644 --- a/src/librustc_error_codes/error_codes/E0743.md +++ b/src/librustc_error_codes/error_codes/E0743.md @@ -8,10 +8,9 @@ Erroneous code example: fn foo2(x: u8, y: &...) {} // error! ``` -Only foreign functions can use the C-variadic type (`...`). -In such functions, `...` may only occur non-nested. -That is, `y: &'a ...` is not allowed. +Only foreign functions can use the C-variadic type (`...`). In such functions, +`...` may only occur non-nested. That is, `y: &'a ...` is not allowed. -A C-variadic type is used to give an undefined number -of parameters to a given function (like `printf` in C). -The equivalent in Rust would be to use macros directly. +A C-variadic type is used to give an undefined number of parameters to a given +function (like `printf` in C). The equivalent in Rust would be to use macros +directly (like `println!` for example). diff --git a/src/librustc_error_codes/error_codes/E0744.md b/src/librustc_error_codes/error_codes/E0744.md index 56b947a8282..14cff3613e0 100644 --- a/src/librustc_error_codes/error_codes/E0744.md +++ b/src/librustc_error_codes/error_codes/E0744.md @@ -1,7 +1,6 @@ -Control-flow expressions are not allowed inside a const context. +A control-flow expression was used inside a const context. -At the moment, `if` and `match`, as well as the looping constructs `for`, -`while`, and `loop`, are forbidden inside a `const`, `static`, or `const fn`. +Erroneous code example: ```compile_fail,E0744 const _: i32 = { @@ -13,6 +12,9 @@ const _: i32 = { }; ``` +At the moment, `if` and `match`, as well as the looping constructs `for`, +`while`, and `loop`, are forbidden inside a `const`, `static`, or `const fn`. + This will be allowed at some point in the future, but the implementation is not yet complete. See the tracking issue for [conditionals] or [loops] in a const context for the current status. diff --git a/src/librustc_errors/Cargo.toml b/src/librustc_errors/Cargo.toml index 7f72161aff8..d0f04c3fe76 100644 --- a/src/librustc_errors/Cargo.toml +++ b/src/librustc_errors/Cargo.toml @@ -10,7 +10,7 @@ path = "lib.rs" doctest = false [dependencies] -log = "0.4" +log = { package = "tracing", version = "0.1" } rustc_serialize = { path = "../librustc_serialize" } rustc_span = { path = "../librustc_span" } rustc_data_structures = { path = "../librustc_data_structures" } diff --git a/src/librustc_expand/Cargo.toml b/src/librustc_expand/Cargo.toml index ef617acfe13..bdf039c36ab 100644 --- a/src/librustc_expand/Cargo.toml +++ b/src/librustc_expand/Cargo.toml @@ -12,7 +12,7 @@ doctest = false [dependencies] rustc_serialize = { path = "../librustc_serialize" } -log = "0.4" +log = { package = "tracing", version = "0.1" } rustc_span = { path = "../librustc_span" } rustc_ast_pretty = { path = "../librustc_ast_pretty" } rustc_ast_passes = { path = "../librustc_ast_passes" } diff --git a/src/librustc_expand/mbe.rs b/src/librustc_expand/mbe.rs index a728261d711..6f2daaa81c0 100644 --- a/src/librustc_expand/mbe.rs +++ b/src/librustc_expand/mbe.rs @@ -9,7 +9,7 @@ crate mod macro_rules; crate mod quoted; crate mod transcribe; -use rustc_ast::token::{self, Token, TokenKind}; +use rustc_ast::token::{self, NonterminalKind, Token, TokenKind}; use rustc_ast::tokenstream::DelimSpan; use rustc_span::symbol::Ident; @@ -84,7 +84,7 @@ enum TokenTree { /// e.g., `$var` MetaVar(Span, Ident), /// e.g., `$var:expr`. This is only used in the left hand side of MBE macros. - MetaVarDecl(Span, Ident /* name to bind */, Ident /* kind of nonterminal */), + MetaVarDecl(Span, Ident /* name to bind */, Option<NonterminalKind>), } impl TokenTree { diff --git a/src/librustc_expand/mbe/macro_parser.rs b/src/librustc_expand/mbe/macro_parser.rs index 3c15a81c67f..d2fe7fe10a8 100644 --- a/src/librustc_expand/mbe/macro_parser.rs +++ b/src/librustc_expand/mbe/macro_parser.rs @@ -76,15 +76,11 @@ use TokenTreeOrTokenTreeSlice::*; use crate::mbe::{self, TokenTree}; -use rustc_ast::ptr::P; use rustc_ast::token::{self, DocComment, Nonterminal, Token}; -use rustc_ast_pretty::pprust; -use rustc_parse::parser::{FollowedByType, Parser, PathStyle}; +use rustc_parse::parser::Parser; use rustc_session::parse::ParseSess; -use rustc_span::symbol::{kw, sym, Ident, MacroRulesNormalizedIdent, Symbol}; +use rustc_span::symbol::MacroRulesNormalizedIdent; -use rustc_errors::PResult; -use rustc_span::Span; use smallvec::{smallvec, SmallVec}; use rustc_data_structures::fx::FxHashMap; @@ -382,7 +378,7 @@ fn nameize<I: Iterator<Item = NamedMatch>>( n_rec(sess, next_m, res.by_ref(), ret_val)?; } } - TokenTree::MetaVarDecl(span, _, id) if id.name == kw::Invalid => { + TokenTree::MetaVarDecl(span, _, None) => { if sess.missing_fragment_specifiers.borrow_mut().remove(&span).is_some() { return Err((span, "missing fragment specifier".to_string())); } @@ -565,7 +561,7 @@ fn inner_parse_loop<'root, 'tt>( } // We need to match a metavar (but the identifier is invalid)... this is an error - TokenTree::MetaVarDecl(span, _, id) if id.name == kw::Invalid => { + TokenTree::MetaVarDecl(span, _, None) => { if sess.missing_fragment_specifiers.borrow_mut().remove(&span).is_some() { return Error(span, "missing fragment specifier".to_string()); } @@ -573,10 +569,10 @@ fn inner_parse_loop<'root, 'tt>( // We need to match a metavar with a valid ident... call out to the black-box // parser by adding an item to `bb_items`. - TokenTree::MetaVarDecl(_, _, id) => { + TokenTree::MetaVarDecl(_, _, Some(kind)) => { // Built-in nonterminals never start with these tokens, // so we can eliminate them from consideration. - if may_begin_with(token, id.name) { + if Parser::nonterminal_may_begin_with(kind, token) { bb_items.push(item); } } @@ -706,7 +702,7 @@ pub(super) fn parse_tt(parser: &mut Cow<'_, Parser<'_>>, ms: &[TokenTree]) -> Na let nts = bb_items .iter() .map(|item| match item.top_elts.get_tt(item.idx) { - TokenTree::MetaVarDecl(_, bind, name) => format!("{} ('{}')", name, bind), + TokenTree::MetaVarDecl(_, bind, Some(kind)) => format!("{} ('{}')", kind, bind), _ => panic!(), }) .collect::<Vec<String>>() @@ -736,10 +732,17 @@ pub(super) fn parse_tt(parser: &mut Cow<'_, Parser<'_>>, ms: &[TokenTree]) -> Na assert_eq!(bb_items.len(), 1); let mut item = bb_items.pop().unwrap(); - if let TokenTree::MetaVarDecl(span, _, ident) = item.top_elts.get_tt(item.idx) { + if let TokenTree::MetaVarDecl(span, _, Some(kind)) = item.top_elts.get_tt(item.idx) { let match_cur = item.match_cur; - let nt = match parse_nt(parser.to_mut(), span, ident.name) { - Err(()) => return ErrorReported, + let nt = match parser.to_mut().parse_nonterminal(kind) { + Err(mut err) => { + err.span_label( + span, + format!("while parsing argument for this `{}` macro fragment", kind), + ) + .emit(); + return ErrorReported; + } Ok(nt) => nt, }; item.push_match(match_cur, MatchedNonterminal(Lrc::new(nt))); @@ -754,178 +757,3 @@ pub(super) fn parse_tt(parser: &mut Cow<'_, Parser<'_>>, ms: &[TokenTree]) -> Na assert!(!cur_items.is_empty()); } } - -/// The token is an identifier, but not `_`. -/// We prohibit passing `_` to macros expecting `ident` for now. -fn get_macro_ident(token: &Token) -> Option<(Ident, bool)> { - token.ident().filter(|(ident, _)| ident.name != kw::Underscore) -} - -/// Checks whether a non-terminal may begin with a particular token. -/// -/// Returning `false` is a *stability guarantee* that such a matcher will *never* begin with that -/// token. Be conservative (return true) if not sure. -fn may_begin_with(token: &Token, name: Symbol) -> bool { - /// Checks whether the non-terminal may contain a single (non-keyword) identifier. - fn may_be_ident(nt: &token::Nonterminal) -> bool { - match *nt { - token::NtItem(_) | token::NtBlock(_) | token::NtVis(_) | token::NtLifetime(_) => false, - _ => true, - } - } - - match name { - sym::expr => { - token.can_begin_expr() - // This exception is here for backwards compatibility. - && !token.is_keyword(kw::Let) - } - sym::ty => token.can_begin_type(), - sym::ident => get_macro_ident(token).is_some(), - sym::literal => token.can_begin_literal_maybe_minus(), - sym::vis => match token.kind { - // The follow-set of :vis + "priv" keyword + interpolated - token::Comma | token::Ident(..) | token::Interpolated(..) => true, - _ => token.can_begin_type(), - }, - sym::block => match token.kind { - token::OpenDelim(token::Brace) => true, - token::Interpolated(ref nt) => match **nt { - token::NtItem(_) - | token::NtPat(_) - | token::NtTy(_) - | token::NtIdent(..) - | token::NtMeta(_) - | token::NtPath(_) - | token::NtVis(_) => false, // none of these may start with '{'. - _ => true, - }, - _ => false, - }, - sym::path | sym::meta => match token.kind { - token::ModSep | token::Ident(..) => true, - token::Interpolated(ref nt) => match **nt { - token::NtPath(_) | token::NtMeta(_) => true, - _ => may_be_ident(&nt), - }, - _ => false, - }, - sym::pat => match token.kind { - token::Ident(..) | // box, ref, mut, and other identifiers (can stricten) - token::OpenDelim(token::Paren) | // tuple pattern - token::OpenDelim(token::Bracket) | // slice pattern - token::BinOp(token::And) | // reference - token::BinOp(token::Minus) | // negative literal - token::AndAnd | // double reference - token::Literal(..) | // literal - token::DotDot | // range pattern (future compat) - token::DotDotDot | // range pattern (future compat) - token::ModSep | // path - token::Lt | // path (UFCS constant) - token::BinOp(token::Shl) => true, // path (double UFCS) - token::Interpolated(ref nt) => may_be_ident(nt), - _ => false, - }, - sym::lifetime => match token.kind { - token::Lifetime(_) => true, - token::Interpolated(ref nt) => match **nt { - token::NtLifetime(_) | token::NtTT(_) => true, - _ => false, - }, - _ => false, - }, - _ => match token.kind { - token::CloseDelim(_) => false, - _ => true, - }, - } -} - -/// A call to the "black-box" parser to parse some Rust non-terminal. -/// -/// # Parameters -/// -/// - `p`: the "black-box" parser to use -/// - `sp`: the `Span` we want to parse -/// - `name`: the name of the metavar _matcher_ we want to match (e.g., `tt`, `ident`, `block`, -/// etc...) -/// -/// # Returns -/// -/// The parsed non-terminal. -fn parse_nt(p: &mut Parser<'_>, sp: Span, name: Symbol) -> Result<Nonterminal, ()> { - // FIXME(Centril): Consider moving this to `parser.rs` to make - // the visibilities of the methods used below `pub(super)` at most. - if name == sym::tt { - return Ok(token::NtTT(p.parse_token_tree())); - } - parse_nt_inner(p, sp, name).map_err(|mut err| { - err.span_label(sp, format!("while parsing argument for this `{}` macro fragment", name)) - .emit() - }) -} - -fn parse_nt_inner<'a>(p: &mut Parser<'a>, sp: Span, name: Symbol) -> PResult<'a, Nonterminal> { - // Any `Nonterminal` which stores its tokens (currently `NtItem` and `NtExpr`) - // needs to have them force-captured here. - // A `macro_rules!` invocation may pass a captured item/expr to a proc-macro, - // which requires having captured tokens available. Since we cannot determine - // in advance whether or not a proc-macro will be (transitively) invoked, - // we always capture tokens for any `Nonterminal` which needs them. - Ok(match name { - sym::item => match p.collect_tokens(|this| this.parse_item())? { - (Some(mut item), tokens) => { - // If we captured tokens during parsing (due to outer attributes), - // use those. - if item.tokens.is_none() { - item.tokens = Some(tokens); - } - token::NtItem(item) - } - (None, _) => return Err(p.struct_span_err(p.token.span, "expected an item keyword")), - }, - sym::block => token::NtBlock(p.parse_block()?), - sym::stmt => match p.parse_stmt()? { - Some(s) => token::NtStmt(s), - None => return Err(p.struct_span_err(p.token.span, "expected a statement")), - }, - sym::pat => token::NtPat(p.parse_pat(None)?), - sym::expr => { - let (mut expr, tokens) = p.collect_tokens(|this| this.parse_expr())?; - // If we captured tokens during parsing (due to outer attributes), - // use those. - if expr.tokens.is_none() { - expr.tokens = Some(tokens); - } - token::NtExpr(expr) - } - sym::literal => token::NtLiteral(p.parse_literal_maybe_minus()?), - sym::ty => token::NtTy(p.parse_ty()?), - // this could be handled like a token, since it is one - sym::ident => { - if let Some((ident, is_raw)) = get_macro_ident(&p.token) { - p.bump(); - token::NtIdent(ident, is_raw) - } else { - let token_str = pprust::token_to_string(&p.token); - let msg = &format!("expected ident, found {}", &token_str); - return Err(p.struct_span_err(p.token.span, msg)); - } - } - sym::path => token::NtPath(p.parse_path(PathStyle::Type)?), - sym::meta => token::NtMeta(P(p.parse_attr_item()?)), - sym::vis => token::NtVis(p.parse_visibility(FollowedByType::Yes)?), - sym::lifetime => { - if p.check_lifetime() { - token::NtLifetime(p.expect_lifetime().ident) - } else { - let token_str = pprust::token_to_string(&p.token); - let msg = &format!("expected a lifetime, found `{}`", &token_str); - return Err(p.struct_span_err(p.token.span, msg)); - } - } - // this is not supposed to happen, since it has been checked - // when compiling the macro. - _ => p.span_bug(sp, "invalid fragment specifier"), - }) -} diff --git a/src/librustc_expand/mbe/macro_rules.rs b/src/librustc_expand/mbe/macro_rules.rs index 36b323df697..74d4023b410 100644 --- a/src/librustc_expand/mbe/macro_rules.rs +++ b/src/librustc_expand/mbe/macro_rules.rs @@ -9,7 +9,7 @@ use crate::mbe::macro_parser::{MatchedNonterminal, MatchedSeq}; use crate::mbe::transcribe::transcribe; use rustc_ast::ast; -use rustc_ast::token::{self, NtTT, Token, TokenKind::*}; +use rustc_ast::token::{self, NonterminalKind, NtTT, Token, TokenKind::*}; use rustc_ast::tokenstream::{DelimSpan, TokenStream}; use rustc_ast_pretty::pprust; use rustc_attr::{self as attr, TransparencyError}; @@ -21,7 +21,7 @@ use rustc_parse::parser::Parser; use rustc_session::parse::ParseSess; use rustc_span::edition::Edition; use rustc_span::hygiene::Transparency; -use rustc_span::symbol::{kw, sym, Ident, MacroRulesNormalizedIdent, Symbol}; +use rustc_span::symbol::{kw, sym, Ident, MacroRulesNormalizedIdent}; use rustc_span::Span; use log::debug; @@ -29,10 +29,6 @@ use std::borrow::Cow; use std::collections::hash_map::Entry; use std::{mem, slice}; -const VALID_FRAGMENT_NAMES_MSG: &str = "valid fragment specifiers are \ - `ident`, `block`, `stmt`, `expr`, `pat`, `ty`, `lifetime`, \ - `literal`, `path`, `meta`, `tt`, `item` and `vis`"; - crate struct ParserAnyMacro<'a> { parser: Parser<'a>, @@ -403,7 +399,7 @@ pub fn compile_declarative_macro( let diag = &sess.span_diagnostic; let lhs_nm = Ident::new(sym::lhs, def.span); let rhs_nm = Ident::new(sym::rhs, def.span); - let tt_spec = Ident::new(sym::tt, def.span); + let tt_spec = Some(NonterminalKind::TT); // Parse the macro_rules! invocation let (macro_rules, body) = match &def.kind { @@ -571,7 +567,7 @@ fn check_lhs_no_empty_seq(sess: &ParseSess, tts: &[mbe::TokenTree]) -> bool { TokenTree::Sequence(span, ref seq) => { if seq.separator.is_none() && seq.tts.iter().all(|seq_tt| match *seq_tt { - TokenTree::MetaVarDecl(_, _, id) => id.name == sym::vis, + TokenTree::MetaVarDecl(_, _, Some(NonterminalKind::Vis)) => true, TokenTree::Sequence(_, ref sub_seq) => { sub_seq.kleene.op == mbe::KleeneOp::ZeroOrMore || sub_seq.kleene.op == mbe::KleeneOp::ZeroOrOne @@ -890,21 +886,7 @@ fn check_matcher_core( // of NT tokens that might end the sequence `... token`. match *token { TokenTree::Token(..) | TokenTree::MetaVar(..) | TokenTree::MetaVarDecl(..) => { - let can_be_followed_by_any; - if let Err(bad_frag) = has_legal_fragment_specifier(sess, features, attrs, token) { - let msg = format!("invalid fragment specifier `{}`", bad_frag); - sess.span_diagnostic - .struct_span_err(token.span(), &msg) - .help(VALID_FRAGMENT_NAMES_MSG) - .emit(); - // (This eliminates false positives and duplicates - // from error messages.) - can_be_followed_by_any = true; - } else { - can_be_followed_by_any = token_can_be_followed_by_any(token); - } - - if can_be_followed_by_any { + if token_can_be_followed_by_any(token) { // don't need to track tokens that work with any, last.replace_with_irrelevant(); // ... and don't need to check tokens that can be @@ -967,19 +949,10 @@ fn check_matcher_core( // Now `last` holds the complete set of NT tokens that could // end the sequence before SUFFIX. Check that every one works with `suffix`. - 'each_last: for token in &last.tokens { - if let TokenTree::MetaVarDecl(_, name, frag_spec) = *token { + for token in &last.tokens { + if let TokenTree::MetaVarDecl(_, name, Some(kind)) = *token { for next_token in &suffix_first.tokens { - match is_in_follow(next_token, frag_spec.name) { - IsInFollow::Invalid(msg, help) => { - sess.span_diagnostic - .struct_span_err(next_token.span(), &msg) - .help(help) - .emit(); - // don't bother reporting every source of - // conflict for a particular element of `last`. - continue 'each_last; - } + match is_in_follow(next_token, kind) { IsInFollow::Yes => {} IsInFollow::No(possible) => { let may_be = if last.tokens.len() == 1 && suffix_first.tokens.len() == 1 @@ -996,22 +969,19 @@ fn check_matcher_core( "`${name}:{frag}` {may_be} followed by `{next}`, which \ is not allowed for `{frag}` fragments", name = name, - frag = frag_spec, + frag = kind, next = quoted_tt_to_string(next_token), may_be = may_be ), ); - err.span_label( - sp, - format!("not allowed after `{}` fragments", frag_spec), - ); + err.span_label(sp, format!("not allowed after `{}` fragments", kind)); let msg = "allowed there are: "; match possible { &[] => {} &[t] => { err.note(&format!( "only {} is allowed after `{}` fragments", - t, frag_spec, + t, kind, )); } ts => { @@ -1038,8 +1008,8 @@ fn check_matcher_core( } fn token_can_be_followed_by_any(tok: &mbe::TokenTree) -> bool { - if let mbe::TokenTree::MetaVarDecl(_, _, frag_spec) = *tok { - frag_can_be_followed_by_any(frag_spec.name) + if let mbe::TokenTree::MetaVarDecl(_, _, Some(kind)) = *tok { + frag_can_be_followed_by_any(kind) } else { // (Non NT's can always be followed by anything in matchers.) true @@ -1054,26 +1024,23 @@ fn token_can_be_followed_by_any(tok: &mbe::TokenTree) -> bool { /// specifier which consumes at most one token tree can be followed by /// a fragment specifier (indeed, these fragments can be followed by /// ANYTHING without fear of future compatibility hazards). -fn frag_can_be_followed_by_any(frag: Symbol) -> bool { - match frag { - sym::item | // always terminated by `}` or `;` - sym::block | // exactly one token tree - sym::ident | // exactly one token tree - sym::literal | // exactly one token tree - sym::meta | // exactly one token tree - sym::lifetime | // exactly one token tree - sym::tt => // exactly one token tree - true, - - _ => - false, +fn frag_can_be_followed_by_any(kind: NonterminalKind) -> bool { + match kind { + NonterminalKind::Item // always terminated by `}` or `;` + | NonterminalKind::Block // exactly one token tree + | NonterminalKind::Ident // exactly one token tree + | NonterminalKind::Literal // exactly one token tree + | NonterminalKind::Meta // exactly one token tree + | NonterminalKind::Lifetime // exactly one token tree + | NonterminalKind::TT => true, // exactly one token tree + + _ => false, } } enum IsInFollow { Yes, No(&'static [&'static str]), - Invalid(String, &'static str), } /// Returns `true` if `frag` can legally be followed by the token `tok`. For @@ -1084,7 +1051,7 @@ enum IsInFollow { /// break macros that were relying on that binary operator as a /// separator. // when changing this do not forget to update doc/book/macros.md! -fn is_in_follow(tok: &mbe::TokenTree, frag: Symbol) -> IsInFollow { +fn is_in_follow(tok: &mbe::TokenTree, kind: NonterminalKind) -> IsInFollow { use mbe::TokenTree; if let TokenTree::Token(Token { kind: token::CloseDelim(_), .. }) = *tok { @@ -1092,18 +1059,18 @@ fn is_in_follow(tok: &mbe::TokenTree, frag: Symbol) -> IsInFollow { // iow, we always require that `(` and `)` match, etc. IsInFollow::Yes } else { - match frag { - sym::item => { + match kind { + NonterminalKind::Item => { // since items *must* be followed by either a `;` or a `}`, we can // accept anything after them IsInFollow::Yes } - sym::block => { + NonterminalKind::Block => { // anything can follow block, the braces provide an easy boundary to // maintain IsInFollow::Yes } - sym::stmt | sym::expr => { + NonterminalKind::Stmt | NonterminalKind::Expr => { const TOKENS: &[&str] = &["`=>`", "`,`", "`;`"]; match tok { TokenTree::Token(token) => match token.kind { @@ -1113,7 +1080,7 @@ fn is_in_follow(tok: &mbe::TokenTree, frag: Symbol) -> IsInFollow { _ => IsInFollow::No(TOKENS), } } - sym::pat => { + NonterminalKind::Pat => { const TOKENS: &[&str] = &["`=>`", "`,`", "`=`", "`|`", "`if`", "`in`"]; match tok { TokenTree::Token(token) => match token.kind { @@ -1124,7 +1091,7 @@ fn is_in_follow(tok: &mbe::TokenTree, frag: Symbol) -> IsInFollow { _ => IsInFollow::No(TOKENS), } } - sym::path | sym::ty => { + NonterminalKind::Path | NonterminalKind::Ty => { const TOKENS: &[&str] = &[ "`{`", "`[`", "`=>`", "`,`", "`>`", "`=`", "`:`", "`;`", "`|`", "`as`", "`where`", @@ -1146,26 +1113,24 @@ fn is_in_follow(tok: &mbe::TokenTree, frag: Symbol) -> IsInFollow { } _ => IsInFollow::No(TOKENS), }, - TokenTree::MetaVarDecl(_, _, frag) if frag.name == sym::block => { - IsInFollow::Yes - } + TokenTree::MetaVarDecl(_, _, Some(NonterminalKind::Block)) => IsInFollow::Yes, _ => IsInFollow::No(TOKENS), } } - sym::ident | sym::lifetime => { + NonterminalKind::Ident | NonterminalKind::Lifetime => { // being a single token, idents and lifetimes are harmless IsInFollow::Yes } - sym::literal => { + NonterminalKind::Literal => { // literals may be of a single token, or two tokens (negative numbers) IsInFollow::Yes } - sym::meta | sym::tt => { + NonterminalKind::Meta | NonterminalKind::TT => { // being either a single token or a delimited sequence, tt is // harmless IsInFollow::Yes } - sym::vis => { + NonterminalKind::Vis => { // Explicitly disallow `priv`, on the off chance it comes back. const TOKENS: &[&str] = &["`,`", "an ident", "a type"]; match tok { @@ -1180,78 +1145,24 @@ fn is_in_follow(tok: &mbe::TokenTree, frag: Symbol) -> IsInFollow { } } }, - TokenTree::MetaVarDecl(_, _, frag) - if frag.name == sym::ident - || frag.name == sym::ty - || frag.name == sym::path => - { - IsInFollow::Yes - } + TokenTree::MetaVarDecl( + _, + _, + Some(NonterminalKind::Ident | NonterminalKind::Ty | NonterminalKind::Path), + ) => IsInFollow::Yes, _ => IsInFollow::No(TOKENS), } } - kw::Invalid => IsInFollow::Yes, - _ => IsInFollow::Invalid( - format!("invalid fragment specifier `{}`", frag), - VALID_FRAGMENT_NAMES_MSG, - ), } } } -fn has_legal_fragment_specifier( - sess: &ParseSess, - features: &Features, - attrs: &[ast::Attribute], - tok: &mbe::TokenTree, -) -> Result<(), String> { - debug!("has_legal_fragment_specifier({:?})", tok); - if let mbe::TokenTree::MetaVarDecl(_, _, ref frag_spec) = *tok { - let frag_span = tok.span(); - if !is_legal_fragment_specifier(sess, features, attrs, frag_spec.name, frag_span) { - return Err(frag_spec.to_string()); - } - } - Ok(()) -} - -fn is_legal_fragment_specifier( - _sess: &ParseSess, - _features: &Features, - _attrs: &[ast::Attribute], - frag_name: Symbol, - _frag_span: Span, -) -> bool { - /* - * If new fragment specifiers are invented in nightly, `_sess`, - * `_features`, `_attrs`, and `_frag_span` will be useful here - * for checking against feature gates. See past versions of - * this function. - */ - match frag_name { - sym::item - | sym::block - | sym::stmt - | sym::expr - | sym::pat - | sym::lifetime - | sym::path - | sym::ty - | sym::ident - | sym::meta - | sym::tt - | sym::vis - | sym::literal - | kw::Invalid => true, - _ => false, - } -} - fn quoted_tt_to_string(tt: &mbe::TokenTree) -> String { match *tt { mbe::TokenTree::Token(ref token) => pprust::token_to_string(&token), mbe::TokenTree::MetaVar(_, name) => format!("${}", name), - mbe::TokenTree::MetaVarDecl(_, name, kind) => format!("${}:{}", name, kind), + mbe::TokenTree::MetaVarDecl(_, name, Some(kind)) => format!("${}:{}", name, kind), + mbe::TokenTree::MetaVarDecl(_, name, None) => format!("${}:", name), _ => panic!( "unexpected mbe::TokenTree::{{Sequence or Delimited}} \ in follow set checker" diff --git a/src/librustc_expand/mbe/quoted.rs b/src/librustc_expand/mbe/quoted.rs index 09306f26ee0..774cc84afde 100644 --- a/src/librustc_expand/mbe/quoted.rs +++ b/src/librustc_expand/mbe/quoted.rs @@ -12,6 +12,10 @@ use rustc_span::Span; use rustc_data_structures::sync::Lrc; +const VALID_FRAGMENT_NAMES_MSG: &str = "valid fragment specifiers are \ + `ident`, `block`, `stmt`, `expr`, `pat`, `ty`, `lifetime`, \ + `literal`, `path`, `meta`, `tt`, `item` and `vis`"; + /// Takes a `tokenstream::TokenStream` and returns a `Vec<self::TokenTree>`. Specifically, this /// takes a generic `TokenStream`, such as is used in the rest of the compiler, and returns a /// collection of `TokenTree` for use in parsing a macro. @@ -55,9 +59,21 @@ pub(super) fn parse( Some(tokenstream::TokenTree::Token(Token { kind: token::Colon, span })) => { match trees.next() { Some(tokenstream::TokenTree::Token(token)) => match token.ident() { - Some((kind, _)) => { + Some((frag, _)) => { let span = token.span.with_lo(start_sp.lo()); - result.push(TokenTree::MetaVarDecl(span, ident, kind)); + let kind = token::NonterminalKind::from_symbol(frag.name) + .unwrap_or_else(|| { + let msg = format!( + "invalid fragment specifier `{}`", + frag.name + ); + sess.span_diagnostic + .struct_span_err(span, &msg) + .help(VALID_FRAGMENT_NAMES_MSG) + .emit(); + token::NonterminalKind::Ident + }); + result.push(TokenTree::MetaVarDecl(span, ident, Some(kind))); continue; } _ => token.span, @@ -71,7 +87,7 @@ pub(super) fn parse( // Macros loaded from other crates have dummy node ids. sess.missing_fragment_specifiers.borrow_mut().insert(span, node_id); } - result.push(TokenTree::MetaVarDecl(span, ident, Ident::invalid())); + result.push(TokenTree::MetaVarDecl(span, ident, None)); } // Not a metavar or no matchers allowed, so just return the tree diff --git a/src/librustc_hir/Cargo.toml b/src/librustc_hir/Cargo.toml index 1b91d769c70..4a404e176e1 100644 --- a/src/librustc_hir/Cargo.toml +++ b/src/librustc_hir/Cargo.toml @@ -18,5 +18,5 @@ rustc_span = { path = "../librustc_span" } rustc_serialize = { path = "../librustc_serialize" } rustc_ast = { path = "../librustc_ast" } lazy_static = "1" -log = { version = "0.4", features = ["release_max_level_info", "std"] } +log = { package = "tracing", version = "0.1" } smallvec = { version = "1.0", features = ["union", "may_dangle"] } diff --git a/src/librustc_incremental/Cargo.toml b/src/librustc_incremental/Cargo.toml index 7b3030fa1d9..60a87078d63 100644 --- a/src/librustc_incremental/Cargo.toml +++ b/src/librustc_incremental/Cargo.toml @@ -11,7 +11,7 @@ doctest = false [dependencies] rustc_graphviz = { path = "../librustc_graphviz" } -log = "0.4" +log = { package = "tracing", version = "0.1" } rand = "0.7" rustc_middle = { path = "../librustc_middle" } rustc_data_structures = { path = "../librustc_data_structures" } diff --git a/src/librustc_infer/Cargo.toml b/src/librustc_infer/Cargo.toml index 06fc7ecf95f..9d56fa223a9 100644 --- a/src/librustc_infer/Cargo.toml +++ b/src/librustc_infer/Cargo.toml @@ -11,7 +11,7 @@ doctest = false [dependencies] rustc_graphviz = { path = "../librustc_graphviz" } -log = { version = "0.4", features = ["release_max_level_info", "std"] } +log = { package = "tracing", version = "0.1" } rustc_middle = { path = "../librustc_middle" } rustc_data_structures = { path = "../librustc_data_structures" } rustc_errors = { path = "../librustc_errors" } diff --git a/src/librustc_infer/infer/combine.rs b/src/librustc_infer/infer/combine.rs index 5b4d91de3ca..133c4bf2db5 100644 --- a/src/librustc_infer/infer/combine.rs +++ b/src/librustc_infer/infer/combine.rs @@ -166,7 +166,7 @@ impl<'infcx, 'tcx> InferCtxt<'infcx, 'tcx> { return self.unify_const_variable(!a_is_expected, vid, a); } (ty::ConstKind::Unevaluated(..), _) if self.tcx.lazy_normalization() => { - // FIXME(#59490): Need to remove the leak check to accomodate + // FIXME(#59490): Need to remove the leak check to accommodate // escaping bound variables here. if !a.has_escaping_bound_vars() && !b.has_escaping_bound_vars() { relation.const_equate_obligation(a, b); @@ -174,7 +174,7 @@ impl<'infcx, 'tcx> InferCtxt<'infcx, 'tcx> { return Ok(b); } (_, ty::ConstKind::Unevaluated(..)) if self.tcx.lazy_normalization() => { - // FIXME(#59490): Need to remove the leak check to accomodate + // FIXME(#59490): Need to remove the leak check to accommodate // escaping bound variables here. if !a.has_escaping_bound_vars() && !b.has_escaping_bound_vars() { relation.const_equate_obligation(a, b); diff --git a/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs b/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs index 4fa6d9d2394..0125e0f48e8 100644 --- a/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs +++ b/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs @@ -195,7 +195,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { } } if let (Some(ident), true) = (override_error_code, fn_returns.is_empty()) { - // Provide a more targetted error code and description. + // Provide a more targeted error code and description. err.code(rustc_errors::error_code!(E0772)); err.set_primary_message(&format!( "{} has {} but calling `{}` introduces an implicit `'static` lifetime \ diff --git a/src/librustc_interface/Cargo.toml b/src/librustc_interface/Cargo.toml index 112dc7037f5..5c7edc10dd5 100644 --- a/src/librustc_interface/Cargo.toml +++ b/src/librustc_interface/Cargo.toml @@ -11,7 +11,7 @@ doctest = false [dependencies] libc = "0.2" -log = "0.4" +log = { package = "tracing", version = "0.1" } rayon = { version = "0.3.0", package = "rustc-rayon" } smallvec = { version = "1.0", features = ["union", "may_dangle"] } rustc_ast = { path = "../librustc_ast" } diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index f1b9fafc781..125a020de37 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -2,7 +2,7 @@ use crate::interface::{Compiler, Result}; use crate::proc_macro_decls; use crate::util; -use log::{info, log_enabled, warn}; +use log::{info, warn}; use once_cell::sync::Lazy; use rustc_ast::mut_visit::MutVisitor; use rustc_ast::{self, ast, visit}; @@ -1015,10 +1015,7 @@ pub fn start_codegen<'tcx>( tcx: TyCtxt<'tcx>, outputs: &OutputFilenames, ) -> Box<dyn Any> { - if log_enabled!(::log::Level::Info) { - println!("Pre-codegen"); - tcx.print_debug_stats(); - } + info!("Pre-codegen\n{:?}", tcx.debug_stats()); let (metadata, need_metadata_module) = encode_and_write_metadata(tcx, outputs); @@ -1026,10 +1023,7 @@ pub fn start_codegen<'tcx>( codegen_backend.codegen_crate(tcx, metadata, need_metadata_module) }); - if log_enabled!(::log::Level::Info) { - println!("Post-codegen"); - tcx.print_debug_stats(); - } + info!("Post-codegen\n{:?}", tcx.debug_stats()); if tcx.sess.opts.output_types.contains_key(&OutputType::Mir) { if let Err(e) = mir::transform::dump_mir::emit_mir(tcx, outputs) { diff --git a/src/librustc_lint/Cargo.toml b/src/librustc_lint/Cargo.toml index 58c15257326..3ba1566023d 100644 --- a/src/librustc_lint/Cargo.toml +++ b/src/librustc_lint/Cargo.toml @@ -9,7 +9,7 @@ name = "rustc_lint" path = "lib.rs" [dependencies] -log = "0.4" +log = { package = "tracing", version = "0.1" } unicode-security = "0.0.5" rustc_middle = { path = "../librustc_middle" } rustc_ast_pretty = { path = "../librustc_ast_pretty" } diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index a45817beea1..e32c8fbee68 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -20,7 +20,9 @@ //! If you define a new `LateLintPass`, you will also need to add it to the //! `late_lint_methods!` invocation in `lib.rs`. -use crate::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext}; +use crate::{ + types::CItemKind, EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext, +}; use rustc_ast::ast::{self, Expr}; use rustc_ast::attr::{self, HasAttrs}; use rustc_ast::tokenstream::{TokenStream, TokenTree}; @@ -36,14 +38,14 @@ use rustc_hir::def_id::DefId; use rustc_hir::{ForeignItemKind, GenericParamKind, PatKind}; use rustc_hir::{HirId, HirIdSet, Node}; use rustc_middle::lint::LintDiagnosticBuilder; -use rustc_middle::ty::subst::GenericArgKind; +use rustc_middle::ty::subst::{GenericArgKind, Subst}; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_session::lint::FutureIncompatibleInfo; use rustc_span::edition::Edition; use rustc_span::source_map::Spanned; use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::{BytePos, Span}; -use rustc_target::abi::VariantIdx; +use rustc_target::abi::{LayoutOf, VariantIdx}; use rustc_trait_selection::traits::misc::can_type_implement_copy; use crate::nonstandard_style::{method_context, MethodLateContext}; @@ -2144,7 +2146,13 @@ impl ClashingExternDeclarations { /// Checks whether two types are structurally the same enough that the declarations shouldn't /// clash. We need this so we don't emit a lint when two modules both declare an extern struct, /// with the same members (as the declarations shouldn't clash). - fn structurally_same_type<'tcx>(cx: &LateContext<'tcx>, a: Ty<'tcx>, b: Ty<'tcx>) -> bool { + fn structurally_same_type<'tcx>( + cx: &LateContext<'tcx>, + a: Ty<'tcx>, + b: Ty<'tcx>, + ckind: CItemKind, + ) -> bool { + debug!("structurally_same_type(cx, a = {:?}, b = {:?})", a, b); let tcx = cx.tcx; if a == b || rustc_middle::ty::TyS::same_type(a, b) { // All nominally-same types are structurally same, too. @@ -2155,47 +2163,77 @@ impl ClashingExternDeclarations { let a_kind = &a.kind; let b_kind = &b.kind; + let compare_layouts = |a, b| -> bool { + let a_layout = &cx.layout_of(a).unwrap().layout.abi; + let b_layout = &cx.layout_of(b).unwrap().layout.abi; + debug!("{:?} == {:?} = {}", a_layout, b_layout, a_layout == b_layout); + a_layout == b_layout + }; + + #[allow(rustc::usage_of_ty_tykind)] + let is_primitive_or_pointer = + |kind: &ty::TyKind<'_>| kind.is_primitive() || matches!(kind, RawPtr(..)); + match (a_kind, b_kind) { - (Adt(..), Adt(..)) => { - // Adts are pretty straightforward: just compare the layouts. - use rustc_target::abi::LayoutOf; - let a_layout = cx.layout_of(a).unwrap().layout; - let b_layout = cx.layout_of(b).unwrap().layout; - a_layout == b_layout + (Adt(_, a_substs), Adt(_, b_substs)) => { + let a = a.subst(cx.tcx, a_substs); + let b = b.subst(cx.tcx, b_substs); + debug!("Comparing {:?} and {:?}", a, b); + + if let (Adt(a_def, ..), Adt(b_def, ..)) = (&a.kind, &b.kind) { + // Grab a flattened representation of all fields. + let a_fields = a_def.variants.iter().flat_map(|v| v.fields.iter()); + let b_fields = b_def.variants.iter().flat_map(|v| v.fields.iter()); + compare_layouts(a, b) + && a_fields.eq_by( + b_fields, + |&ty::FieldDef { did: a_did, .. }, + &ty::FieldDef { did: b_did, .. }| { + Self::structurally_same_type( + cx, + tcx.type_of(a_did), + tcx.type_of(b_did), + ckind, + ) + }, + ) + } else { + unreachable!() + } } (Array(a_ty, a_const), Array(b_ty, b_const)) => { // For arrays, we also check the constness of the type. a_const.val == b_const.val - && Self::structurally_same_type(cx, a_const.ty, b_const.ty) - && Self::structurally_same_type(cx, a_ty, b_ty) + && Self::structurally_same_type(cx, a_const.ty, b_const.ty, ckind) + && Self::structurally_same_type(cx, a_ty, b_ty, ckind) } - (Slice(a_ty), Slice(b_ty)) => Self::structurally_same_type(cx, a_ty, b_ty), + (Slice(a_ty), Slice(b_ty)) => Self::structurally_same_type(cx, a_ty, b_ty, ckind), (RawPtr(a_tymut), RawPtr(b_tymut)) => { - a_tymut.mutbl == a_tymut.mutbl - && Self::structurally_same_type(cx, &a_tymut.ty, &b_tymut.ty) + a_tymut.mutbl == b_tymut.mutbl + && Self::structurally_same_type(cx, &a_tymut.ty, &b_tymut.ty, ckind) } (Ref(_a_region, a_ty, a_mut), Ref(_b_region, b_ty, b_mut)) => { // For structural sameness, we don't need the region to be same. - a_mut == b_mut && Self::structurally_same_type(cx, a_ty, b_ty) + a_mut == b_mut && Self::structurally_same_type(cx, a_ty, b_ty, ckind) } (FnDef(..), FnDef(..)) => { - // As we don't compare regions, skip_binder is fine. let a_poly_sig = a.fn_sig(tcx); let b_poly_sig = b.fn_sig(tcx); + // As we don't compare regions, skip_binder is fine. let a_sig = a_poly_sig.skip_binder(); let b_sig = b_poly_sig.skip_binder(); (a_sig.abi, a_sig.unsafety, a_sig.c_variadic) == (b_sig.abi, b_sig.unsafety, b_sig.c_variadic) && a_sig.inputs().iter().eq_by(b_sig.inputs().iter(), |a, b| { - Self::structurally_same_type(cx, a, b) + Self::structurally_same_type(cx, a, b, ckind) }) - && Self::structurally_same_type(cx, a_sig.output(), b_sig.output()) + && Self::structurally_same_type(cx, a_sig.output(), b_sig.output(), ckind) } (Tuple(a_substs), Tuple(b_substs)) => { a_substs.types().eq_by(b_substs.types(), |a_ty, b_ty| { - Self::structurally_same_type(cx, a_ty, b_ty) + Self::structurally_same_type(cx, a_ty, b_ty, ckind) }) } // For these, it's not quite as easy to define structural-sameness quite so easily. @@ -2208,9 +2246,27 @@ impl ClashingExternDeclarations { | (GeneratorWitness(..), GeneratorWitness(..)) | (Projection(..), Projection(..)) | (Opaque(..), Opaque(..)) => false, + // These definitely should have been caught above. (Bool, Bool) | (Char, Char) | (Never, Never) | (Str, Str) => unreachable!(), - _ => false, + + // An Adt and a primitive type. This can be FFI-safe is the ADT is an enum with a + // non-null field. + (Adt(..), other_kind) | (other_kind, Adt(..)) + if is_primitive_or_pointer(other_kind) => + { + let (primitive, adt) = + if is_primitive_or_pointer(&a.kind) { (a, b) } else { (b, a) }; + if let Some(ty) = crate::types::repr_nullable_ptr(cx, adt, ckind) { + ty == primitive + } else { + compare_layouts(a, b) + } + } + // Otherwise, just compare the layouts. This may fail to lint for some + // incompatible types, but at the very least, will stop reads into + // uninitialised memory. + _ => compare_layouts(a, b), } } } @@ -2231,7 +2287,12 @@ impl<'tcx> LateLintPass<'tcx> for ClashingExternDeclarations { existing_hid, existing_decl_ty, this_fi.hir_id, this_decl_ty ); // Check that the declarations match. - if !Self::structurally_same_type(cx, existing_decl_ty, this_decl_ty) { + if !Self::structurally_same_type( + cx, + existing_decl_ty, + this_decl_ty, + CItemKind::Declaration, + ) { let orig_fi = tcx.hir().expect_foreign_item(existing_hid); let orig = Self::name_of_extern_decl(tcx, orig_fi); diff --git a/src/librustc_lint/context.rs b/src/librustc_lint/context.rs index 84f5ea7bcda..31d30a264a5 100644 --- a/src/librustc_lint/context.rs +++ b/src/librustc_lint/context.rs @@ -573,7 +573,7 @@ pub trait LintContext: Sized { } } BuiltinLintDiagnostics::DeprecatedMacro(suggestion, span) => { - stability::deprecation_suggestion(&mut db, suggestion, span) + stability::deprecation_suggestion(&mut db, "macro", suggestion, span) } BuiltinLintDiagnostics::UnusedDocComment(span) => { db.span_label(span, "rustdoc does not generate documentation for macro invocations"); diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index ab30d545edf..15a9affbff7 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -61,8 +61,8 @@ use rustc_hir::def_id::LocalDefId; use rustc_middle::ty::query::Providers; use rustc_middle::ty::TyCtxt; use rustc_session::lint::builtin::{ - BARE_TRAIT_OBJECTS, ELIDED_LIFETIMES_IN_PATHS, EXPLICIT_OUTLIVES_REQUIREMENTS, - INTRA_DOC_LINK_RESOLUTION_FAILURE, INVALID_CODEBLOCK_ATTRIBUTES, MISSING_DOC_CODE_EXAMPLES, + BARE_TRAIT_OBJECTS, BROKEN_INTRA_DOC_LINKS, ELIDED_LIFETIMES_IN_PATHS, + EXPLICIT_OUTLIVES_REQUIREMENTS, INVALID_CODEBLOCK_ATTRIBUTES, MISSING_DOC_CODE_EXAMPLES, PRIVATE_DOC_TESTS, }; use rustc_span::symbol::{Ident, Symbol}; @@ -303,7 +303,7 @@ fn register_builtins(store: &mut LintStore, no_interleave_lints: bool) { add_lint_group!( "rustdoc", - INTRA_DOC_LINK_RESOLUTION_FAILURE, + BROKEN_INTRA_DOC_LINKS, INVALID_CODEBLOCK_ATTRIBUTES, MISSING_DOC_CODE_EXAMPLES, PRIVATE_DOC_TESTS @@ -318,6 +318,7 @@ fn register_builtins(store: &mut LintStore, no_interleave_lints: bool) { store.register_renamed("async_idents", "keyword_idents"); store.register_renamed("exceeding_bitshifts", "arithmetic_overflow"); store.register_renamed("redundant_semicolon", "redundant_semicolons"); + store.register_renamed("intra_doc_link_resolution_failure", "broken_intra_doc_links"); store.register_removed("unknown_features", "replaced by an error"); store.register_removed("unsigned_negation", "replaced by negate_unsigned feature gate"); store.register_removed("negate_unsigned", "cast a signed value instead"); diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs index 1affc9457b8..de750010ed1 100644 --- a/src/librustc_lint/types.rs +++ b/src/librustc_lint/types.rs @@ -15,8 +15,9 @@ use rustc_middle::ty::{self, AdtKind, Ty, TypeFoldable}; use rustc_span::source_map; use rustc_span::symbol::sym; use rustc_span::{Span, DUMMY_SP}; +use rustc_target::abi::Abi; use rustc_target::abi::{Integer, LayoutOf, TagEncoding, VariantIdx, Variants}; -use rustc_target::spec::abi::Abi; +use rustc_target::spec::abi::Abi as SpecAbi; use log::debug; use std::cmp; @@ -509,14 +510,15 @@ declare_lint! { declare_lint_pass!(ImproperCTypesDefinitions => [IMPROPER_CTYPES_DEFINITIONS]); -enum ImproperCTypesMode { - Declarations, - Definitions, +#[derive(Clone, Copy)] +crate enum CItemKind { + Declaration, + Definition, } struct ImproperCTypesVisitor<'a, 'tcx> { cx: &'a LateContext<'tcx>, - mode: ImproperCTypesMode, + mode: CItemKind, } enum FfiResult<'tcx> { @@ -525,54 +527,94 @@ enum FfiResult<'tcx> { FfiUnsafe { ty: Ty<'tcx>, reason: String, help: Option<String> }, } -impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { - /// Is type known to be non-null? - fn ty_is_known_nonnull(&self, ty: Ty<'tcx>) -> bool { - match ty.kind { - ty::FnPtr(_) => true, - ty::Ref(..) => true, - ty::Adt(def, _) - if def.is_box() && matches!(self.mode, ImproperCTypesMode::Definitions) => - { - true - } - ty::Adt(def, substs) if def.repr.transparent() && !def.is_union() => { - let guaranteed_nonnull_optimization = self - .cx - .tcx - .get_attrs(def.did) - .iter() - .any(|a| a.check_name(sym::rustc_nonnull_optimization_guaranteed)); - - if guaranteed_nonnull_optimization { - return true; - } +/// Is type known to be non-null? +fn ty_is_known_nonnull<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, mode: CItemKind) -> bool { + let tcx = cx.tcx; + match ty.kind { + ty::FnPtr(_) => true, + ty::Ref(..) => true, + ty::Adt(def, _) if def.is_box() && matches!(mode, CItemKind::Definition) => true, + ty::Adt(def, substs) if def.repr.transparent() && !def.is_union() => { + let guaranteed_nonnull_optimization = tcx + .get_attrs(def.did) + .iter() + .any(|a| a.check_name(sym::rustc_nonnull_optimization_guaranteed)); - for variant in &def.variants { - if let Some(field) = variant.transparent_newtype_field(self.cx.tcx) { - if self.ty_is_known_nonnull(field.ty(self.cx.tcx, substs)) { - return true; - } + if guaranteed_nonnull_optimization { + return true; + } + for variant in &def.variants { + if let Some(field) = variant.transparent_newtype_field(tcx) { + if ty_is_known_nonnull(cx, field.ty(tcx, substs), mode) { + return true; } } - - false } - _ => false, + + false } + _ => false, } +} +/// Given a non-null scalar (or transparent) type `ty`, return the nullable version of that type. +/// If the type passed in was not scalar, returns None. +fn get_nullable_type<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<Ty<'tcx>> { + let tcx = cx.tcx; + Some(match ty.kind { + ty::Adt(field_def, field_substs) => { + let inner_field_ty = { + let first_non_zst_ty = + field_def.variants.iter().filter_map(|v| v.transparent_newtype_field(tcx)); + debug_assert_eq!( + first_non_zst_ty.clone().count(), + 1, + "Wrong number of fields for transparent type" + ); + first_non_zst_ty + .last() + .expect("No non-zst fields in transparent type.") + .ty(tcx, field_substs) + }; + return get_nullable_type(cx, inner_field_ty); + } + ty::Int(ty) => tcx.mk_mach_int(ty), + ty::Uint(ty) => tcx.mk_mach_uint(ty), + ty::RawPtr(ty_mut) => tcx.mk_ptr(ty_mut), + // As these types are always non-null, the nullable equivalent of + // Option<T> of these types are their raw pointer counterparts. + ty::Ref(_region, ty, mutbl) => tcx.mk_ptr(ty::TypeAndMut { ty, mutbl }), + ty::FnPtr(..) => { + // There is no nullable equivalent for Rust's function pointers -- you + // must use an Option<fn(..) -> _> to represent it. + ty + } - /// Check if this enum can be safely exported based on the "nullable pointer optimization". - /// Currently restricted to function pointers, boxes, references, `core::num::NonZero*`, - /// `core::ptr::NonNull`, and `#[repr(transparent)]` newtypes. - fn is_repr_nullable_ptr( - &self, - ty: Ty<'tcx>, - ty_def: &'tcx ty::AdtDef, - substs: SubstsRef<'tcx>, - ) -> bool { + // We should only ever reach this case if ty_is_known_nonnull is extended + // to other types. + ref unhandled => { + debug!( + "get_nullable_type: Unhandled scalar kind: {:?} while checking {:?}", + unhandled, ty + ); + return None; + } + }) +} + +/// Check if this enum can be safely exported based on the "nullable pointer optimization". If it +/// can, return the the type that `ty` can be safely converted to, otherwise return `None`. +/// Currently restricted to function pointers, boxes, references, `core::num::NonZero*`, +/// `core::ptr::NonNull`, and `#[repr(transparent)]` newtypes. +/// FIXME: This duplicates code in codegen. +crate fn repr_nullable_ptr<'tcx>( + cx: &LateContext<'tcx>, + ty: Ty<'tcx>, + ckind: CItemKind, +) -> Option<Ty<'tcx>> { + debug!("is_repr_nullable_ptr(cx, ty = {:?})", ty); + if let ty::Adt(ty_def, substs) = ty.kind { if ty_def.variants.len() != 2 { - return false; + return None; } let get_variant_fields = |index| &ty_def.variants[VariantIdx::new(index)].fields; @@ -582,30 +624,42 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { } else if variant_fields[1].is_empty() { &variant_fields[0] } else { - return false; + return None; }; if fields.len() != 1 { - return false; + return None; } - let field_ty = fields[0].ty(self.cx.tcx, substs); - if !self.ty_is_known_nonnull(field_ty) { - return false; + let field_ty = fields[0].ty(cx.tcx, substs); + if !ty_is_known_nonnull(cx, field_ty, ckind) { + return None; } - // At this point, the field's type is known to be nonnull and the parent enum is - // Option-like. If the computed size for the field and the enum are different, the non-null - // optimization isn't being applied (and we've got a problem somewhere). - let compute_size_skeleton = - |t| SizeSkeleton::compute(t, self.cx.tcx, self.cx.param_env).unwrap(); + // At this point, the field's type is known to be nonnull and the parent enum is Option-like. + // If the computed size for the field and the enum are different, the nonnull optimization isn't + // being applied (and we've got a problem somewhere). + let compute_size_skeleton = |t| SizeSkeleton::compute(t, cx.tcx, cx.param_env).unwrap(); if !compute_size_skeleton(ty).same_size(compute_size_skeleton(field_ty)) { bug!("improper_ctypes: Option nonnull optimization not applied?"); } - true + // Return the nullable type this Option-like enum can be safely represented with. + let field_ty_abi = &cx.layout_of(field_ty).unwrap().abi; + if let Abi::Scalar(field_ty_scalar) = field_ty_abi { + match (field_ty_scalar.valid_range.start(), field_ty_scalar.valid_range.end()) { + (0, _) => unreachable!("Non-null optimisation extended to a non-zero value."), + (1, _) => { + return Some(get_nullable_type(cx, field_ty).unwrap()); + } + (start, end) => unreachable!("Unhandled start and end range: ({}, {})", start, end), + }; + } } + None +} +impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { /// Check if the type is array and emit an unsafe type lint. fn check_for_array_ty(&mut self, sp: Span, ty: Ty<'tcx>) -> bool { if let ty::Array(..) = ty.kind { @@ -686,7 +740,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { fn check_type_for_ffi(&self, cache: &mut FxHashSet<Ty<'tcx>>, ty: Ty<'tcx>) -> FfiResult<'tcx> { use FfiResult::*; - let cx = self.cx.tcx; + let tcx = self.cx.tcx; // Protect against infinite recursion, for example // `struct S(*mut S);`. @@ -697,9 +751,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { } match ty.kind { - ty::Adt(def, _) - if def.is_box() && matches!(self.mode, ImproperCTypesMode::Definitions) => - { + ty::Adt(def, _) if def.is_box() && matches!(self.mode, CItemKind::Definition) => { FfiSafe } @@ -753,7 +805,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { // discriminant. if !def.repr.c() && !def.repr.transparent() && def.repr.int.is_none() { // Special-case types like `Option<extern fn()>`. - if !self.is_repr_nullable_ptr(ty, def, substs) { + if repr_nullable_ptr(self.cx, ty, self.mode).is_none() { return FfiUnsafe { ty, reason: "enum has no representation hint".into(), @@ -836,7 +888,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { ty::RawPtr(ty::TypeAndMut { ty, .. }) | ty::Ref(_, ty, _) if { - matches!(self.mode, ImproperCTypesMode::Definitions) + matches!(self.mode, CItemKind::Definition) && ty.is_sized(self.cx.tcx.at(DUMMY_SP), self.cx.param_env) } => { @@ -862,7 +914,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { }; } - let sig = cx.erase_late_bound_regions(&sig); + let sig = tcx.erase_late_bound_regions(&sig); if !sig.output().is_unit() { let r = self.check_type_for_ffi(cache, sig.output()); match r { @@ -894,9 +946,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { // `extern "C" fn` functions can have type parameters, which may or may not be FFI-safe, // so they are currently ignored for the purposes of this lint. - ty::Param(..) | ty::Projection(..) - if matches!(self.mode, ImproperCTypesMode::Definitions) => - { + ty::Param(..) | ty::Projection(..) if matches!(self.mode, CItemKind::Definition) => { FfiSafe } @@ -921,14 +971,14 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { help: Option<&str>, ) { let lint = match self.mode { - ImproperCTypesMode::Declarations => IMPROPER_CTYPES, - ImproperCTypesMode::Definitions => IMPROPER_CTYPES_DEFINITIONS, + CItemKind::Declaration => IMPROPER_CTYPES, + CItemKind::Definition => IMPROPER_CTYPES_DEFINITIONS, }; self.cx.struct_span_lint(lint, sp, |lint| { let item_description = match self.mode { - ImproperCTypesMode::Declarations => "block", - ImproperCTypesMode::Definitions => "fn", + CItemKind::Declaration => "block", + CItemKind::Definition => "fn", }; let mut diag = lint.build(&format!( "`extern` {} uses type `{}`, which is not FFI-safe", @@ -1052,8 +1102,12 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { self.check_type_for_ffi_and_report_errors(span, ty, true, false); } - fn is_internal_abi(&self, abi: Abi) -> bool { - if let Abi::Rust | Abi::RustCall | Abi::RustIntrinsic | Abi::PlatformIntrinsic = abi { + fn is_internal_abi(&self, abi: SpecAbi) -> bool { + if let SpecAbi::Rust + | SpecAbi::RustCall + | SpecAbi::RustIntrinsic + | SpecAbi::PlatformIntrinsic = abi + { true } else { false @@ -1063,7 +1117,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { impl<'tcx> LateLintPass<'tcx> for ImproperCTypesDeclarations { fn check_foreign_item(&mut self, cx: &LateContext<'_>, it: &hir::ForeignItem<'_>) { - let mut vis = ImproperCTypesVisitor { cx, mode: ImproperCTypesMode::Declarations }; + let mut vis = ImproperCTypesVisitor { cx, mode: CItemKind::Declaration }; let abi = cx.tcx.hir().get_foreign_abi(it.hir_id); if !vis.is_internal_abi(abi) { @@ -1098,7 +1152,7 @@ impl<'tcx> LateLintPass<'tcx> for ImproperCTypesDefinitions { _ => return, }; - let mut vis = ImproperCTypesVisitor { cx, mode: ImproperCTypesMode::Definitions }; + let mut vis = ImproperCTypesVisitor { cx, mode: CItemKind::Definition }; if !vis.is_internal_abi(abi) { vis.check_foreign_fn(hir_id, decl); } diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index dcb44ab6444..a33f9206035 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -203,6 +203,28 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults { // Otherwise, we don't lint, to avoid false positives. _ => false, }, + ty::Closure(..) => { + cx.struct_span_lint(UNUSED_MUST_USE, span, |lint| { + let mut err = lint.build(&format!( + "unused {}closure{}{} that must be used", + descr_pre, plural_suffix, descr_post, + )); + err.note("closures are lazy and do nothing unless called"); + err.emit(); + }); + true + } + ty::Generator(..) => { + cx.struct_span_lint(UNUSED_MUST_USE, span, |lint| { + let mut err = lint.build(&format!( + "unused {}generator{}{} that must be used", + descr_pre, plural_suffix, descr_post, + )); + err.note("generators are lazy and do nothing unless resumed"); + err.emit(); + }); + true + } _ => false, } } @@ -400,7 +422,7 @@ trait UnusedDelimLint { lhs_needs_parens || (followed_by_block && match inner.kind { - ExprKind::Ret(_) | ExprKind::Break(..) => true, + ExprKind::Ret(_) | ExprKind::Break(..) | ExprKind::Yield(..) => true, _ => parser::contains_exterior_struct_lit(&inner), }) } diff --git a/src/librustc_metadata/Cargo.toml b/src/librustc_metadata/Cargo.toml index 7bbe7567d29..2c0e2aa39fd 100644 --- a/src/librustc_metadata/Cargo.toml +++ b/src/librustc_metadata/Cargo.toml @@ -12,7 +12,7 @@ doctest = false [dependencies] flate2 = "1.0" libc = "0.2" -log = "0.4" +log = { package = "tracing", version = "0.1" } memmap = "0.7" smallvec = { version = "1.0", features = ["union", "may_dangle"] } rustc_middle = { path = "../librustc_middle" } diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index 724b4123fab..9bc6c054e4d 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -13,7 +13,7 @@ use rustc_expand::base::SyntaxExtension; use rustc_hir::def_id::{CrateNum, LocalDefId, LOCAL_CRATE}; use rustc_hir::definitions::Definitions; use rustc_index::vec::IndexVec; -use rustc_middle::middle::cstore::{CrateSource, DepKind, ExternCrate}; +use rustc_middle::middle::cstore::{CrateDepKind, CrateSource, ExternCrate}; use rustc_middle::middle::cstore::{ExternCrateSource, MetadataLoaderDyn}; use rustc_middle::ty::TyCtxt; use rustc_session::config::{self, CrateType, ExternLocation}; @@ -26,7 +26,7 @@ use rustc_span::symbol::{sym, Symbol}; use rustc_span::{Span, DUMMY_SP}; use rustc_target::spec::{PanicStrategy, TargetTriple}; -use log::{debug, info, log_enabled}; +use log::{debug, info}; use proc_macro::bridge::client::ProcMacro; use std::path::Path; use std::{cmp, env, fs}; @@ -82,24 +82,36 @@ impl std::ops::Deref for CrateMetadataRef<'_> { } } -fn dump_crates(cstore: &CStore) { - info!("resolved crates:"); - cstore.iter_crate_data(|cnum, data| { - info!(" name: {}", data.name()); - info!(" cnum: {}", cnum); - info!(" hash: {}", data.hash()); - info!(" reqd: {:?}", data.dep_kind()); - let CrateSource { dylib, rlib, rmeta } = data.source(); - if let Some(dylib) = dylib { - info!(" dylib: {}", dylib.0.display()); - } - if let Some(rlib) = rlib { - info!(" rlib: {}", rlib.0.display()); - } - if let Some(rmeta) = rmeta { - info!(" rmeta: {}", rmeta.0.display()); - } - }); +struct CrateDump<'a>(&'a CStore); + +impl<'a> std::fmt::Debug for CrateDump<'a> { + fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + writeln!(fmt, "resolved crates:")?; + // `iter_crate_data` does not allow returning values. Thus we use a mutable variable here + // that aggregates the value (and any errors that could happen). + let mut res = Ok(()); + self.0.iter_crate_data(|cnum, data| { + res = res.and( + try { + writeln!(fmt, " name: {}", data.name())?; + writeln!(fmt, " cnum: {}", cnum)?; + writeln!(fmt, " hash: {}", data.hash())?; + writeln!(fmt, " reqd: {:?}", data.dep_kind())?; + let CrateSource { dylib, rlib, rmeta } = data.source(); + if let Some(dylib) = dylib { + writeln!(fmt, " dylib: {}", dylib.0.display())?; + } + if let Some(rlib) = rlib { + writeln!(fmt, " rlib: {}", rlib.0.display())?; + } + if let Some(rmeta) = rmeta { + writeln!(fmt, " rmeta: {}", rmeta.0.display())?; + } + }, + ); + }); + res + } } impl CStore { @@ -236,9 +248,9 @@ impl<'a> CrateLoader<'a> { // Only use `--extern crate_name=path` here, not `--extern crate_name`. if let Some(mut files) = entry.files() { if files.any(|l| { - let l = fs::canonicalize(l).ok(); - source.dylib.as_ref().map(|p| &p.0) == l.as_ref() - || source.rlib.as_ref().map(|p| &p.0) == l.as_ref() + let l = fs::canonicalize(l).unwrap_or(l.clone().into()); + source.dylib.as_ref().map(|p| &p.0) == Some(&l) + || source.rlib.as_ref().map(|p| &p.0) == Some(&l) }) { ret = Some(cnum); } @@ -294,7 +306,7 @@ impl<'a> CrateLoader<'a> { host_lib: Option<Library>, root: Option<&CratePaths>, lib: Library, - dep_kind: DepKind, + dep_kind: CrateDepKind, name: Symbol, ) -> Result<CrateNum, CrateError> { let _prof_timer = self.sess.prof.generic_activity("metadata_register_crate"); @@ -425,7 +437,7 @@ impl<'a> CrateLoader<'a> { &'b mut self, name: Symbol, span: Span, - dep_kind: DepKind, + dep_kind: CrateDepKind, dep: Option<(&'b CratePaths, &'b CrateDep)>, ) -> CrateNum { if dep.is_none() { @@ -438,7 +450,7 @@ impl<'a> CrateLoader<'a> { fn maybe_resolve_crate<'b>( &'b mut self, name: Symbol, - mut dep_kind: DepKind, + mut dep_kind: CrateDepKind, dep: Option<(&'b CratePaths, &'b CrateDep)>, ) -> Result<CrateNum, CrateError> { info!("resolving crate `{}`", name); @@ -475,7 +487,7 @@ impl<'a> CrateLoader<'a> { match self.load(&mut locator)? { Some(res) => (res, None), None => { - dep_kind = DepKind::MacrosOnly; + dep_kind = CrateDepKind::MacrosOnly; match self.load_proc_macro(&mut locator, path_kind)? { Some(res) => res, None => return Err(locator.into_error()), @@ -488,7 +500,7 @@ impl<'a> CrateLoader<'a> { (LoadResult::Previous(cnum), None) => { let data = self.cstore.get_crate_data(cnum); if data.is_proc_macro_crate() { - dep_kind = DepKind::MacrosOnly; + dep_kind = CrateDepKind::MacrosOnly; } data.update_dep_kind(|data_dep_kind| cmp::max(data_dep_kind, dep_kind)); Ok(cnum) @@ -548,7 +560,7 @@ impl<'a> CrateLoader<'a> { crate_root: &CrateRoot<'_>, metadata: &MetadataBlob, krate: CrateNum, - dep_kind: DepKind, + dep_kind: CrateDepKind, ) -> Result<CrateNumMap, CrateError> { debug!("resolving deps of external crate"); if crate_root.is_proc_macro_crate() { @@ -567,7 +579,7 @@ impl<'a> CrateLoader<'a> { dep.name, dep.hash, dep.extra_filename ); let dep_kind = match dep_kind { - DepKind::MacrosOnly => DepKind::MacrosOnly, + CrateDepKind::MacrosOnly => CrateDepKind::MacrosOnly, _ => dep.kind, }; let cnum = self.maybe_resolve_crate(dep.name, dep_kind, Some((root, &dep)))?; @@ -634,7 +646,7 @@ impl<'a> CrateLoader<'a> { self.inject_dependency_if(cnum, "a panic runtime", &|data| { data.needs_panic_runtime() }); - runtime_found = runtime_found || data.dep_kind() == DepKind::Explicit; + runtime_found = runtime_found || data.dep_kind() == CrateDepKind::Explicit; } }); @@ -663,7 +675,7 @@ impl<'a> CrateLoader<'a> { }; info!("panic runtime not found -- loading {}", name); - let cnum = self.resolve_crate(name, DUMMY_SP, DepKind::Implicit, None); + let cnum = self.resolve_crate(name, DUMMY_SP, CrateDepKind::Implicit, None); let data = self.cstore.get_crate_data(cnum); // Sanity check the loaded crate to ensure it is indeed a panic runtime @@ -693,7 +705,7 @@ impl<'a> CrateLoader<'a> { info!("loading profiler"); let name = sym::profiler_builtins; - let cnum = self.resolve_crate(name, DUMMY_SP, DepKind::Implicit, None); + let cnum = self.resolve_crate(name, DUMMY_SP, CrateDepKind::Implicit, None); let data = self.cstore.get_crate_data(cnum); // Sanity check the loaded crate to ensure it is indeed a profiler runtime @@ -864,9 +876,7 @@ impl<'a> CrateLoader<'a> { self.inject_allocator_crate(krate); self.inject_panic_runtime(krate); - if log_enabled!(log::Level::Info) { - dump_crates(&self.cstore); - } + info!("{:?}", CrateDump(&self.cstore)); self.report_unused_deps(krate); } @@ -891,9 +901,9 @@ impl<'a> CrateLoader<'a> { None => item.ident.name, }; let dep_kind = if attr::contains_name(&item.attrs, sym::no_link) { - DepKind::MacrosOnly + CrateDepKind::MacrosOnly } else { - DepKind::Explicit + CrateDepKind::Explicit }; let cnum = self.resolve_crate(name, item.span, dep_kind, None); @@ -915,7 +925,7 @@ impl<'a> CrateLoader<'a> { } pub fn process_path_extern(&mut self, name: Symbol, span: Span) -> CrateNum { - let cnum = self.resolve_crate(name, span, DepKind::Explicit, None); + let cnum = self.resolve_crate(name, span, CrateDepKind::Explicit, None); self.update_extern_crate( cnum, @@ -932,6 +942,6 @@ impl<'a> CrateLoader<'a> { } pub fn maybe_process_path_extern(&mut self, name: Symbol) -> Option<CrateNum> { - self.maybe_resolve_crate(name, DepKind::Explicit, None).ok() + self.maybe_resolve_crate(name, CrateDepKind::Explicit, None).ok() } } diff --git a/src/librustc_metadata/dependency_format.rs b/src/librustc_metadata/dependency_format.rs index aa5fafcc614..bb5ae4d0557 100644 --- a/src/librustc_metadata/dependency_format.rs +++ b/src/librustc_metadata/dependency_format.rs @@ -56,7 +56,7 @@ use crate::creader::CStore; use rustc_data_structures::fx::FxHashMap; use rustc_hir::def_id::CrateNum; use rustc_middle::middle::cstore::LinkagePreference::{self, RequireDynamic, RequireStatic}; -use rustc_middle::middle::cstore::{self, DepKind}; +use rustc_middle::middle::cstore::{self, CrateDepKind}; use rustc_middle::middle::dependency_format::{Dependencies, DependencyList, Linkage}; use rustc_middle::ty::TyCtxt; use rustc_session::config::CrateType; @@ -188,7 +188,7 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: CrateType) -> DependencyList { let src = tcx.used_crate_source(cnum); if src.dylib.is_none() && !formats.contains_key(&cnum) - && tcx.dep_kind(cnum) == DepKind::Explicit + && tcx.dep_kind(cnum) == CrateDepKind::Explicit { assert!(src.rlib.is_some() || src.rmeta.is_some()); log::info!("adding staticlib: {}", tcx.crate_name(cnum)); @@ -284,7 +284,7 @@ fn attempt_static(tcx: TyCtxt<'_>) -> Option<DependencyList> { let last_crate = tcx.crates().len(); let mut ret = (1..last_crate + 1) .map(|cnum| { - if tcx.dep_kind(CrateNum::new(cnum)) == DepKind::Explicit { + if tcx.dep_kind(CrateNum::new(cnum)) == CrateDepKind::Explicit { Linkage::Static } else { Linkage::NotLinked diff --git a/src/librustc_metadata/lib.rs b/src/librustc_metadata/lib.rs index d4add2ab7ad..059ae340bcf 100644 --- a/src/librustc_metadata/lib.rs +++ b/src/librustc_metadata/lib.rs @@ -9,6 +9,7 @@ #![feature(proc_macro_internals)] #![feature(min_specialization)] #![feature(stmt_expr_attributes)] +#![feature(try_blocks)] #![feature(never_type)] #![recursion_limit = "256"] diff --git a/src/librustc_metadata/locator.rs b/src/librustc_metadata/locator.rs index 371ec4cd911..8828b318d1e 100644 --- a/src/librustc_metadata/locator.rs +++ b/src/librustc_metadata/locator.rs @@ -426,20 +426,17 @@ impl<'a> CrateLocator<'a> { info!("lib candidate: {}", spf.path.display()); let (rlibs, rmetas, dylibs) = candidates.entry(hash.to_string()).or_default(); - fs::canonicalize(&spf.path) - .map(|p| { - if seen_paths.contains(&p) { - return FileDoesntMatch; - }; - seen_paths.insert(p.clone()); - match found_kind { - CrateFlavor::Rlib => rlibs.insert(p, kind), - CrateFlavor::Rmeta => rmetas.insert(p, kind), - CrateFlavor::Dylib => dylibs.insert(p, kind), - }; - FileMatches - }) - .unwrap_or(FileDoesntMatch) + let path = fs::canonicalize(&spf.path).unwrap_or_else(|_| spf.path.clone()); + if seen_paths.contains(&path) { + return FileDoesntMatch; + }; + seen_paths.insert(path.clone()); + match found_kind { + CrateFlavor::Rlib => rlibs.insert(path, kind), + CrateFlavor::Rmeta => rmetas.insert(path, kind), + CrateFlavor::Dylib => dylibs.insert(path, kind), + }; + FileMatches }); self.rejected_via_kind.extend(staticlibs); @@ -688,12 +685,13 @@ impl<'a> CrateLocator<'a> { && file.ends_with(&self.target.options.dll_suffix) { // Make sure there's at most one rlib and at most one dylib. + let loc = fs::canonicalize(&loc).unwrap_or_else(|_| loc.clone()); if loc.file_name().unwrap().to_str().unwrap().ends_with(".rlib") { - rlibs.insert(fs::canonicalize(&loc).unwrap(), PathKind::ExternFlag); + rlibs.insert(loc, PathKind::ExternFlag); } else if loc.file_name().unwrap().to_str().unwrap().ends_with(".rmeta") { - rmetas.insert(fs::canonicalize(&loc).unwrap(), PathKind::ExternFlag); + rmetas.insert(loc, PathKind::ExternFlag); } else { - dylibs.insert(fs::canonicalize(&loc).unwrap(), PathKind::ExternFlag); + dylibs.insert(loc, PathKind::ExternFlag); } } else { self.rejected_via_filename diff --git a/src/librustc_metadata/rmeta/decoder.rs b/src/librustc_metadata/rmeta/decoder.rs index b7f5921438f..3c045df45da 100644 --- a/src/librustc_metadata/rmeta/decoder.rs +++ b/src/librustc_metadata/rmeta/decoder.rs @@ -100,7 +100,7 @@ crate struct CrateMetadata { /// Same ID set as `cnum_map` plus maybe some injected crates like panic runtime. dependencies: Lock<Vec<CrateNum>>, /// How to link (or not link) this crate to the currently compiled crate. - dep_kind: Lock<DepKind>, + dep_kind: Lock<CrateDepKind>, /// Filesystem location of this crate. source: CrateSource, /// Whether or not this crate should be consider a private dependency @@ -780,7 +780,6 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { fn get_variant( &self, - tcx: TyCtxt<'tcx>, kind: &EntryKind, index: DefIndex, parent_did: DefId, @@ -805,7 +804,6 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { let ctor_did = data.ctor.map(|index| self.local_def_id(index)); ty::VariantDef::new( - tcx, self.item_ident(index, sess), variant_did, ctor_did, @@ -826,6 +824,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { adt_kind, parent_did, false, + data.is_non_exhaustive, ) } @@ -847,10 +846,10 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { .get(self, item_id) .unwrap_or(Lazy::empty()) .decode(self) - .map(|index| self.get_variant(tcx, &self.kind(index), index, did, tcx.sess)) + .map(|index| self.get_variant(&self.kind(index), index, did, tcx.sess)) .collect() } else { - std::iter::once(self.get_variant(tcx, &kind, item_id, did, tcx.sess)).collect() + std::iter::once(self.get_variant(&kind, item_id, did, tcx.sess)).collect() }; tcx.alloc_adt_def(did, adt_kind, variants, repr) @@ -1670,7 +1669,7 @@ impl CrateMetadata { raw_proc_macros: Option<&'static [ProcMacro]>, cnum: CrateNum, cnum_map: CrateNumMap, - dep_kind: DepKind, + dep_kind: CrateDepKind, source: CrateSource, private_dep: bool, host_hash: Option<Svh>, @@ -1728,11 +1727,11 @@ impl CrateMetadata { &self.source } - crate fn dep_kind(&self) -> DepKind { + crate fn dep_kind(&self) -> CrateDepKind { *self.dep_kind.lock() } - crate fn update_dep_kind(&self, f: impl FnOnce(DepKind) -> DepKind) { + crate fn update_dep_kind(&self, f: impl FnOnce(CrateDepKind) -> CrateDepKind) { self.dep_kind.with_lock(|dep_kind| *dep_kind = f(*dep_kind)) } diff --git a/src/librustc_metadata/rmeta/encoder.rs b/src/librustc_metadata/rmeta/encoder.rs index dc8d14a44f8..352b8bff7e2 100644 --- a/src/librustc_metadata/rmeta/encoder.rs +++ b/src/librustc_metadata/rmeta/encoder.rs @@ -267,7 +267,7 @@ impl<'a, 'tcx> SpecializedEncoder<Span> for EncodeContext<'a, 'tcx> { // real code should never need to care about this. // // 2. Using `Span::def_site` or `Span::mixed_site` will not - // include any hygiene information associated with the defintion + // include any hygiene information associated with the definition // site. This means that a proc-macro cannot emit a `$crate` // identifier which resolves to one of its dependencies, // which also should never come up in practice. @@ -738,6 +738,7 @@ impl EncodeContext<'a, 'tcx> { ctor_kind: variant.ctor_kind, discr: variant.discr, ctor: variant.ctor_def_id.map(|did| did.index), + is_non_exhaustive: variant.is_field_list_non_exhaustive(), }; let enum_id = tcx.hir().as_local_hir_id(def.did.expect_local()); @@ -782,6 +783,7 @@ impl EncodeContext<'a, 'tcx> { ctor_kind: variant.ctor_kind, discr: variant.discr, ctor: Some(def_id.index), + is_non_exhaustive: variant.is_field_list_non_exhaustive(), }; // Variant constructors have the same visibility as the parent enums, unless marked as @@ -886,6 +888,7 @@ impl EncodeContext<'a, 'tcx> { ctor_kind: variant.ctor_kind, discr: variant.discr, ctor: Some(def_id.index), + is_non_exhaustive: variant.is_field_list_non_exhaustive(), }; let struct_id = tcx.hir().as_local_hir_id(adt_def.did.expect_local()); @@ -1235,6 +1238,7 @@ impl EncodeContext<'a, 'tcx> { ctor_kind: variant.ctor_kind, discr: variant.discr, ctor, + is_non_exhaustive: variant.is_field_list_non_exhaustive(), }), adt_def.repr) } hir::ItemKind::Union(..) => { @@ -1245,6 +1249,7 @@ impl EncodeContext<'a, 'tcx> { ctor_kind: variant.ctor_kind, discr: variant.discr, ctor: None, + is_non_exhaustive: variant.is_field_list_non_exhaustive(), }), adt_def.repr) } hir::ItemKind::Impl { defaultness, .. } => { diff --git a/src/librustc_metadata/rmeta/mod.rs b/src/librustc_metadata/rmeta/mod.rs index 55ef66f1939..12d2f50363c 100644 --- a/src/librustc_metadata/rmeta/mod.rs +++ b/src/librustc_metadata/rmeta/mod.rs @@ -11,7 +11,7 @@ use rustc_hir::def_id::{DefId, DefIndex}; use rustc_hir::lang_items; use rustc_index::{bit_set::FiniteBitSet, vec::IndexVec}; use rustc_middle::hir::exports::Export; -use rustc_middle::middle::cstore::{DepKind, ForeignModule, LinkagePreference, NativeLib}; +use rustc_middle::middle::cstore::{CrateDepKind, ForeignModule, LinkagePreference, NativeLib}; use rustc_middle::middle::exported_symbols::{ExportedSymbol, SymbolExportLevel}; use rustc_middle::mir; use rustc_middle::ty::{self, ReprOptions, Ty}; @@ -226,7 +226,7 @@ crate struct CrateDep { pub name: Symbol, pub hash: Svh, pub host_hash: Option<Svh>, - pub kind: DepKind, + pub kind: CrateDepKind, pub extra_filename: String, } @@ -346,6 +346,7 @@ struct VariantData { discr: ty::VariantDiscr, /// If this is unit or tuple-variant/struct, then this is the index of the ctor id. ctor: Option<DefIndex>, + is_non_exhaustive: bool, } #[derive(RustcEncodable, RustcDecodable)] diff --git a/src/librustc_middle/Cargo.toml b/src/librustc_middle/Cargo.toml index 02d82c67933..678fcfe6539 100644 --- a/src/librustc_middle/Cargo.toml +++ b/src/librustc_middle/Cargo.toml @@ -13,7 +13,7 @@ doctest = false rustc_arena = { path = "../librustc_arena" } bitflags = "1.2.1" scoped-tls = "1.0" -log = { version = "0.4", features = ["release_max_level_info", "std"] } +log = { package = "tracing", version = "0.1" } rustc-rayon-core = "0.3.0" polonius-engine = "0.12.0" rustc_apfloat = { path = "../librustc_apfloat" } diff --git a/src/librustc_middle/middle/cstore.rs b/src/librustc_middle/middle/cstore.rs index 97e877df966..0a34c06adf0 100644 --- a/src/librustc_middle/middle/cstore.rs +++ b/src/librustc_middle/middle/cstore.rs @@ -40,7 +40,7 @@ impl CrateSource { #[derive(RustcEncodable, RustcDecodable, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Debug)] #[derive(HashStable)] -pub enum DepKind { +pub enum CrateDepKind { /// A dependency that is only used for its macros. MacrosOnly, /// A dependency that is always injected into the dependency list and so @@ -51,11 +51,11 @@ pub enum DepKind { Explicit, } -impl DepKind { +impl CrateDepKind { pub fn macros_only(self) -> bool { match self { - DepKind::MacrosOnly => true, - DepKind::Implicit | DepKind::Explicit => false, + CrateDepKind::MacrosOnly => true, + CrateDepKind::Implicit | CrateDepKind::Explicit => false, } } } diff --git a/src/librustc_middle/middle/stability.rs b/src/librustc_middle/middle/stability.rs index 5f7ff54fd31..b913d7dd4ad 100644 --- a/src/librustc_middle/middle/stability.rs +++ b/src/librustc_middle/middle/stability.rs @@ -166,29 +166,31 @@ pub fn deprecation_in_effect(is_since_rustc_version: bool, since: Option<&str>) pub fn deprecation_suggestion( diag: &mut DiagnosticBuilder<'_>, + kind: &str, suggestion: Option<Symbol>, span: Span, ) { if let Some(suggestion) = suggestion { diag.span_suggestion( span, - "replace the use of the deprecated item", + &format!("replace the use of the deprecated {}", kind), suggestion.to_string(), Applicability::MachineApplicable, ); } } -pub fn deprecation_message(depr: &Deprecation, path: &str) -> (String, &'static Lint) { +pub fn deprecation_message(depr: &Deprecation, kind: &str, path: &str) -> (String, &'static Lint) { let (message, lint) = if deprecation_in_effect( depr.is_since_rustc_version, depr.since.map(Symbol::as_str).as_deref(), ) { - (format!("use of deprecated item '{}'", path), DEPRECATED) + (format!("use of deprecated {} `{}`", kind, path), DEPRECATED) } else { ( format!( - "use of item '{}' that will be deprecated in future version {}", + "use of {} `{}` that will be deprecated in future version {}", + kind, path, depr.since.unwrap() ), @@ -224,6 +226,7 @@ fn late_report_deprecation( lint: &'static Lint, span: Span, hir_id: HirId, + def_id: DefId, ) { if span.in_derive_expansion() { return; @@ -232,7 +235,8 @@ fn late_report_deprecation( tcx.struct_span_lint_hir(lint, hir_id, span, |lint| { let mut diag = lint.build(message); if let hir::Node::Expr(_) = tcx.hir().get(hir_id) { - deprecation_suggestion(&mut diag, suggestion, span); + let kind = tcx.def_kind(def_id).descr(def_id); + deprecation_suggestion(&mut diag, kind, suggestion, span); } diag.emit() }); @@ -304,8 +308,9 @@ impl<'tcx> TyCtxt<'tcx> { // #[rustc_deprecated] however wants to emit down the whole // hierarchy. if !skip || depr_entry.attr.is_since_rustc_version { - let (message, lint) = - deprecation_message(&depr_entry.attr, &self.def_path_str(def_id)); + let path = &self.def_path_str(def_id); + let kind = self.def_kind(def_id).descr(def_id); + let (message, lint) = deprecation_message(&depr_entry.attr, kind, path); late_report_deprecation( self, &message, @@ -313,6 +318,7 @@ impl<'tcx> TyCtxt<'tcx> { lint, span, id, + def_id, ); } }; diff --git a/src/librustc_middle/mir/coverage/mod.rs b/src/librustc_middle/mir/coverage/mod.rs index 1e06dadfa24..82365ef6a73 100644 --- a/src/librustc_middle/mir/coverage/mod.rs +++ b/src/librustc_middle/mir/coverage/mod.rs @@ -3,7 +3,7 @@ /// Positional arguments to `libcore::count_code_region()` pub mod count_code_region_args { pub const FUNCTION_SOURCE_HASH: usize = 0; - pub const COUNTER_INDEX: usize = 1; + pub const COUNTER_ID: usize = 1; pub const START_BYTE_POS: usize = 2; pub const END_BYTE_POS: usize = 3; } @@ -11,9 +11,9 @@ pub mod count_code_region_args { /// Positional arguments to `libcore::coverage_counter_add()` and /// `libcore::coverage_counter_subtract()` pub mod coverage_counter_expression_args { - pub const COUNTER_EXPRESSION_INDEX: usize = 0; - pub const LEFT_INDEX: usize = 1; - pub const RIGHT_INDEX: usize = 2; + pub const EXPRESSION_ID: usize = 0; + pub const LEFT_ID: usize = 1; + pub const RIGHT_ID: usize = 2; pub const START_BYTE_POS: usize = 3; pub const END_BYTE_POS: usize = 4; } diff --git a/src/librustc_middle/mir/interpret/queries.rs b/src/librustc_middle/mir/interpret/queries.rs index d7c0be05859..442e7f6b0f4 100644 --- a/src/librustc_middle/mir/interpret/queries.rs +++ b/src/librustc_middle/mir/interpret/queries.rs @@ -18,7 +18,7 @@ impl<'tcx> TyCtxt<'tcx> { let substs = InternalSubsts::identity_for_item(self, def_id); let instance = ty::Instance::new(def_id, substs); let cid = GlobalId { instance, promoted: None }; - let param_env = self.param_env(def_id).with_reveal_all(); + let param_env = self.param_env(def_id).with_reveal_all_normalized(self); self.const_eval_global_id(param_env, cid, None) } diff --git a/src/librustc_middle/mir/interpret/value.rs b/src/librustc_middle/mir/interpret/value.rs index 9de2d17457a..2c76f0b5ad0 100644 --- a/src/librustc_middle/mir/interpret/value.rs +++ b/src/librustc_middle/mir/interpret/value.rs @@ -78,7 +78,7 @@ impl<'tcx> ConstValue<'tcx> { param_env: ParamEnv<'tcx>, ty: Ty<'tcx>, ) -> Option<u128> { - let size = tcx.layout_of(param_env.with_reveal_all().and(ty)).ok()?.size; + let size = tcx.layout_of(param_env.with_reveal_all_normalized(tcx).and(ty)).ok()?.size; self.try_to_bits(size) } diff --git a/src/librustc_middle/query/mod.rs b/src/librustc_middle/query/mod.rs index f857af28622..862c046358b 100644 --- a/src/librustc_middle/query/mod.rs +++ b/src/librustc_middle/query/mod.rs @@ -864,11 +864,17 @@ rustc_queries! { /// type-checking etc, and it does not normalize specializable /// associated types. This is almost always what you want, /// unless you are doing MIR optimizations, in which case you - /// might want to use `reveal_all()` method to change modes. query param_env(def_id: DefId) -> ty::ParamEnv<'tcx> { desc { |tcx| "computing normalized predicates of `{}`", tcx.def_path_str(def_id) } } + /// Like `param_env`, but returns the `ParamEnv in `Reveal::All` mode. + /// Prefer this over `tcx.param_env(def_id).with_reveal_all_normalized(tcx)`, + /// as this method is more efficient. + query param_env_reveal_all_normalized(def_id: DefId) -> ty::ParamEnv<'tcx> { + desc { |tcx| "computing revealed normalized predicates of `{}`", tcx.def_path_str(def_id) } + } + /// Trait selection queries. These are best used by invoking `ty.is_copy_modulo_regions()`, /// `ty.is_copy()`, etc, since that will prune the environment where possible. query is_copy_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool { @@ -1180,7 +1186,7 @@ rustc_queries! { } Other { - query dep_kind(_: CrateNum) -> DepKind { + query dep_kind(_: CrateNum) -> CrateDepKind { eval_always desc { "fetching what a dependency looks like" } } @@ -1527,5 +1533,9 @@ rustc_queries! { ty::Instance::new(key.value.0.to_def_id(), key.value.2), } } + + query normalize_opaque_types(key: &'tcx ty::List<ty::Predicate<'tcx>>) -> &'tcx ty::List<ty::Predicate<'tcx>> { + desc { "normalizing opaque types in {:?}", key } + } } } diff --git a/src/librustc_middle/ty/consts.rs b/src/librustc_middle/ty/consts.rs index f3a863c3fce..c0b5693dc59 100644 --- a/src/librustc_middle/ty/consts.rs +++ b/src/librustc_middle/ty/consts.rs @@ -158,7 +158,7 @@ impl<'tcx> Const<'tcx> { ty: Ty<'tcx>, ) -> Option<u128> { assert_eq!(self.ty, ty); - let size = tcx.layout_of(param_env.with_reveal_all().and(ty)).ok()?.size; + let size = tcx.layout_of(param_env.with_reveal_all_normalized(tcx).and(ty)).ok()?.size; // if `ty` does not depend on generic parameters, use an empty param_env self.val.eval(tcx, param_env).try_to_bits(size) } diff --git a/src/librustc_middle/ty/consts/kind.rs b/src/librustc_middle/ty/consts/kind.rs index 75287ff7dac..e8a1e714a8f 100644 --- a/src/librustc_middle/ty/consts/kind.rs +++ b/src/librustc_middle/ty/consts/kind.rs @@ -96,12 +96,16 @@ impl<'tcx> ConstKind<'tcx> { if let ConstKind::Unevaluated(def, substs, promoted) = self { use crate::mir::interpret::ErrorHandled; - let param_env_and_substs = param_env.with_reveal_all().and(substs); - // HACK(eddyb) this erases lifetimes even though `const_eval_resolve` // also does later, but we want to do it before checking for // inference variables. - let param_env_and_substs = tcx.erase_regions(¶m_env_and_substs); + // Note that we erase regions *before* calling `with_reveal_all_normalized`, + // so that we don't try to invoke this query with + // any region variables. + let param_env_and_substs = tcx + .erase_regions(¶m_env) + .with_reveal_all_normalized(tcx) + .and(tcx.erase_regions(&substs)); // HACK(eddyb) when the query key would contain inference variables, // attempt using identity substs and `ParamEnv` instead, that will succeed diff --git a/src/librustc_middle/ty/context.rs b/src/librustc_middle/ty/context.rs index eeb58a0c55a..775d755444d 100644 --- a/src/librustc_middle/ty/context.rs +++ b/src/librustc_middle/ty/context.rs @@ -352,7 +352,7 @@ pub struct TypeckResults<'tcx> { pat_binding_modes: ItemLocalMap<BindingMode>, /// Stores the types which were implicitly dereferenced in pattern binding modes - /// for later usage in HAIR lowering. For example, + /// for later usage in THIR lowering. For example, /// /// ``` /// match &&Some(5i32) { @@ -1831,7 +1831,7 @@ pub mod tls { } macro_rules! sty_debug_print { - ($ctxt: expr, $($variant: ident),*) => {{ + ($fmt: expr, $ctxt: expr, $($variant: ident),*) => {{ // Curious inner module to allow variant names to be used as // variable names. #[allow(non_snake_case)] @@ -1848,7 +1848,7 @@ macro_rules! sty_debug_print { all_infer: usize, } - pub fn go(tcx: TyCtxt<'_>) { + pub fn go(fmt: &mut std::fmt::Formatter<'_>, tcx: TyCtxt<'_>) -> std::fmt::Result { let mut total = DebugStat { total: 0, lt_infer: 0, @@ -1878,8 +1878,8 @@ macro_rules! sty_debug_print { if ct { total.ct_infer += 1; variant.ct_infer += 1 } if lt && ty && ct { total.all_infer += 1; variant.all_infer += 1 } } - println!("Ty interner total ty lt ct all"); - $(println!(" {:18}: {uses:6} {usespc:4.1}%, \ + writeln!(fmt, "Ty interner total ty lt ct all")?; + $(writeln!(fmt, " {:18}: {uses:6} {usespc:4.1}%, \ {ty:4.1}% {lt:5.1}% {ct:4.1}% {all:4.1}%", stringify!($variant), uses = $variant.total, @@ -1887,9 +1887,9 @@ macro_rules! sty_debug_print { ty = $variant.ty_infer as f64 * 100.0 / total.total as f64, lt = $variant.lt_infer as f64 * 100.0 / total.total as f64, ct = $variant.ct_infer as f64 * 100.0 / total.total as f64, - all = $variant.all_infer as f64 * 100.0 / total.total as f64); + all = $variant.all_infer as f64 * 100.0 / total.total as f64)?; )* - println!(" total {uses:6} \ + writeln!(fmt, " total {uses:6} \ {ty:4.1}% {lt:5.1}% {ct:4.1}% {all:4.1}%", uses = total.total, ty = total.ty_infer as f64 * 100.0 / total.total as f64, @@ -1899,41 +1899,56 @@ macro_rules! sty_debug_print { } } - inner::go($ctxt) + inner::go($fmt, $ctxt) }} } impl<'tcx> TyCtxt<'tcx> { - pub fn print_debug_stats(self) { - sty_debug_print!( - self, - Adt, - Array, - Slice, - RawPtr, - Ref, - FnDef, - FnPtr, - Placeholder, - Generator, - GeneratorWitness, - Dynamic, - Closure, - Tuple, - Bound, - Param, - Infer, - Projection, - Opaque, - Foreign - ); - - println!("InternalSubsts interner: #{}", self.interners.substs.len()); - println!("Region interner: #{}", self.interners.region.len()); - println!("Stability interner: #{}", self.stability_interner.len()); - println!("Const Stability interner: #{}", self.const_stability_interner.len()); - println!("Allocation interner: #{}", self.allocation_interner.len()); - println!("Layout interner: #{}", self.layout_interner.len()); + pub fn debug_stats(self) -> impl std::fmt::Debug + 'tcx { + struct DebugStats<'tcx>(TyCtxt<'tcx>); + + impl std::fmt::Debug for DebugStats<'tcx> { + fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + sty_debug_print!( + fmt, + self.0, + Adt, + Array, + Slice, + RawPtr, + Ref, + FnDef, + FnPtr, + Placeholder, + Generator, + GeneratorWitness, + Dynamic, + Closure, + Tuple, + Bound, + Param, + Infer, + Projection, + Opaque, + Foreign + )?; + + writeln!(fmt, "InternalSubsts interner: #{}", self.0.interners.substs.len())?; + writeln!(fmt, "Region interner: #{}", self.0.interners.region.len())?; + writeln!(fmt, "Stability interner: #{}", self.0.stability_interner.len())?; + writeln!( + fmt, + "Const Stability interner: #{}", + self.0.const_stability_interner.len() + )?; + writeln!(fmt, "Allocation interner: #{}", self.0.allocation_interner.len())?; + writeln!(fmt, "Layout interner: #{}", self.0.layout_interner.len())?; + + Ok(()) + } + } + + DebugStats(self) } } diff --git a/src/librustc_middle/ty/layout.rs b/src/librustc_middle/ty/layout.rs index 215f44819b5..143d3c4e1e9 100644 --- a/src/librustc_middle/ty/layout.rs +++ b/src/librustc_middle/ty/layout.rs @@ -1903,7 +1903,7 @@ impl<'tcx> LayoutOf for LayoutCx<'tcx, TyCtxt<'tcx>> { /// Computes the layout of a type. Note that this implicitly /// executes in "reveal all" mode. fn layout_of(&self, ty: Ty<'tcx>) -> Self::TyAndLayout { - let param_env = self.param_env.with_reveal_all(); + let param_env = self.param_env.with_reveal_all_normalized(self.tcx); let ty = self.tcx.normalize_erasing_regions(param_env, ty); let layout = self.tcx.layout_raw(param_env.and(ty))?; let layout = TyAndLayout { ty, layout }; @@ -1927,7 +1927,7 @@ impl LayoutOf for LayoutCx<'tcx, ty::query::TyCtxtAt<'tcx>> { /// Computes the layout of a type. Note that this implicitly /// executes in "reveal all" mode. fn layout_of(&self, ty: Ty<'tcx>) -> Self::TyAndLayout { - let param_env = self.param_env.with_reveal_all(); + let param_env = self.param_env.with_reveal_all_normalized(*self.tcx); let ty = self.tcx.normalize_erasing_regions(param_env, ty); let layout = self.tcx.layout_raw(param_env.and(ty))?; let layout = TyAndLayout { ty, layout }; diff --git a/src/librustc_middle/ty/mod.rs b/src/librustc_middle/ty/mod.rs index d1c6d3be5f4..bd45f866abc 100644 --- a/src/librustc_middle/ty/mod.rs +++ b/src/librustc_middle/ty/mod.rs @@ -1,5 +1,5 @@ // ignore-tidy-filelength -pub use self::fold::{TypeFoldable, TypeVisitor}; +pub use self::fold::{TypeFoldable, TypeFolder, TypeVisitor}; pub use self::AssocItemContainer::*; pub use self::BorrowKind::*; pub use self::IntVarValue::*; @@ -1874,9 +1874,15 @@ impl<'tcx> ParamEnv<'tcx> { /// the desired behavior during codegen and certain other special /// contexts; normally though we want to use `Reveal::UserFacing`, /// which is the default. - pub fn with_reveal_all(mut self) -> Self { - self.packed_data |= 1; - self + /// All opaque types in the caller_bounds of the `ParamEnv` + /// will be normalized to their underlying types. + /// See PR #65989 and issue #65918 for more details + pub fn with_reveal_all_normalized(self, tcx: TyCtxt<'tcx>) -> Self { + if self.packed_data & 1 == 1 { + return self; + } + + ParamEnv::new(tcx.normalize_opaque_types(self.caller_bounds()), Reveal::All, self.def_id) } /// Returns this same environment but with no caller bounds. @@ -2046,7 +2052,6 @@ impl<'tcx> VariantDef { /// If someone speeds up attribute loading to not be a performance concern, they can /// remove this hack and use the constructor `DefId` everywhere. pub fn new( - tcx: TyCtxt<'tcx>, ident: Ident, variant_did: Option<DefId>, ctor_def_id: Option<DefId>, @@ -2056,6 +2061,7 @@ impl<'tcx> VariantDef { adt_kind: AdtKind, parent_did: DefId, recovered: bool, + is_field_list_non_exhaustive: bool, ) -> Self { debug!( "VariantDef::new(ident = {:?}, variant_did = {:?}, ctor_def_id = {:?}, discr = {:?}, @@ -2064,14 +2070,8 @@ impl<'tcx> VariantDef { ); let mut flags = VariantFlags::NO_VARIANT_FLAGS; - if adt_kind == AdtKind::Struct && tcx.has_attr(parent_did, sym::non_exhaustive) { - debug!("found non-exhaustive field list for {:?}", parent_did); - flags = flags | VariantFlags::IS_FIELD_LIST_NON_EXHAUSTIVE; - } else if let Some(variant_did) = variant_did { - if tcx.has_attr(variant_did, sym::non_exhaustive) { - debug!("found non-exhaustive field list for {:?}", variant_did); - flags = flags | VariantFlags::IS_FIELD_LIST_NON_EXHAUSTIVE; - } + if is_field_list_non_exhaustive { + flags |= VariantFlags::IS_FIELD_LIST_NON_EXHAUSTIVE; } VariantDef { @@ -3122,6 +3122,7 @@ pub fn provide(providers: &mut ty::query::Providers) { context::provide(providers); erase_regions::provide(providers); layout::provide(providers); + util::provide(providers); super::util::bug::provide(providers); *providers = ty::query::Providers { trait_impls_of: trait_def::trait_impls_of_provider, diff --git a/src/librustc_middle/ty/query/keys.rs b/src/librustc_middle/ty/query/keys.rs index cb2b7a662cb..3f7a20bba2b 100644 --- a/src/librustc_middle/ty/query/keys.rs +++ b/src/librustc_middle/ty/query/keys.rs @@ -270,6 +270,17 @@ impl<'tcx> Key for Ty<'tcx> { } } +impl<'tcx> Key for &'tcx ty::List<ty::Predicate<'tcx>> { + type CacheSelector = DefaultCacheSelector; + + fn query_crate(&self) -> CrateNum { + LOCAL_CRATE + } + fn default_span(&self, _: TyCtxt<'_>) -> Span { + DUMMY_SP + } +} + impl<'tcx> Key for ty::ParamEnv<'tcx> { type CacheSelector = DefaultCacheSelector; diff --git a/src/librustc_middle/ty/query/mod.rs b/src/librustc_middle/ty/query/mod.rs index 2f7a9aee536..b39c0b5190a 100644 --- a/src/librustc_middle/ty/query/mod.rs +++ b/src/librustc_middle/ty/query/mod.rs @@ -1,10 +1,10 @@ -use crate::dep_graph::{self, DepNode, DepNodeParams}; +use crate::dep_graph::{self, DepKind, DepNode, DepNodeParams}; use crate::hir::exports::Export; use crate::hir::map; use crate::infer::canonical::{self, Canonical}; use crate::lint::LintLevelMap; use crate::middle::codegen_fn_attrs::CodegenFnAttrs; -use crate::middle::cstore::{CrateSource, DepKind}; +use crate::middle::cstore::{CrateDepKind, CrateSource}; use crate::middle::cstore::{ExternCrate, ForeignModule, LinkagePreference, NativeLib}; use crate::middle::exported_symbols::{ExportedSymbol, SymbolExportLevel}; use crate::middle::lib_features::LibFeatures; @@ -161,7 +161,7 @@ pub fn force_from_dep_node<'tcx>(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> bool // hit the cache instead of having to go through `force_from_dep_node`. // This assertion makes sure, we actually keep applying the solution above. debug_assert!( - dep_node.kind != crate::dep_graph::DepKind::codegen_unit, + dep_node.kind != DepKind::codegen_unit, "calling force_from_dep_node() on DepKind::codegen_unit" ); @@ -172,14 +172,14 @@ pub fn force_from_dep_node<'tcx>(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> bool rustc_dep_node_force!([dep_node, tcx] // These are inputs that are expected to be pre-allocated and that // should therefore always be red or green already. - crate::dep_graph::DepKind::CrateMetadata | + DepKind::CrateMetadata | // These are anonymous nodes. - crate::dep_graph::DepKind::TraitSelect | + DepKind::TraitSelect | // We don't have enough information to reconstruct the query key of // these. - crate::dep_graph::DepKind::CompileCodegenUnit => { + DepKind::CompileCodegenUnit => { bug!("force_from_dep_node: encountered {:?}", dep_node) } ); diff --git a/src/librustc_middle/ty/sty.rs b/src/librustc_middle/ty/sty.rs index df8fa4d73dd..310ab4f7235 100644 --- a/src/librustc_middle/ty/sty.rs +++ b/src/librustc_middle/ty/sty.rs @@ -202,6 +202,16 @@ pub enum TyKind<'tcx> { Error(DelaySpanBugEmitted), } +impl TyKind<'tcx> { + #[inline] + pub fn is_primitive(&self) -> bool { + match self { + Bool | Char | Int(_) | Uint(_) | Float(_) => true, + _ => false, + } + } +} + /// A type that is not publicly constructable. This prevents people from making `TyKind::Error` /// except through `tcx.err*()`. #[derive(Copy, Clone, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)] @@ -1766,10 +1776,7 @@ impl<'tcx> TyS<'tcx> { #[inline] pub fn is_primitive(&self) -> bool { - match self.kind { - Bool | Char | Int(_) | Uint(_) | Float(_) => true, - _ => false, - } + self.kind.is_primitive() } #[inline] diff --git a/src/librustc_middle/ty/util.rs b/src/librustc_middle/ty/util.rs index adba45facc9..07221082048 100644 --- a/src/librustc_middle/ty/util.rs +++ b/src/librustc_middle/ty/util.rs @@ -3,11 +3,12 @@ use crate::ich::NodeIdHashingMode; use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags; use crate::mir::interpret::{sign_extend, truncate}; +use crate::ty::fold::TypeFolder; use crate::ty::layout::IntegerExt; use crate::ty::query::TyCtxtAt; use crate::ty::subst::{GenericArgKind, InternalSubsts, Subst, SubstsRef}; use crate::ty::TyKind::*; -use crate::ty::{self, DefIdTree, GenericParamDefKind, Ty, TyCtxt, TypeFoldable}; +use crate::ty::{self, DefIdTree, GenericParamDefKind, List, Ty, TyCtxt, TypeFoldable}; use rustc_apfloat::Float as _; use rustc_ast::ast; use rustc_attr::{self as attr, SignedInt, UnsignedInt}; @@ -557,82 +558,84 @@ impl<'tcx> TyCtxt<'tcx> { def_id: DefId, substs: SubstsRef<'tcx>, ) -> Result<Ty<'tcx>, Ty<'tcx>> { - use crate::ty::fold::TypeFolder; - - struct OpaqueTypeExpander<'tcx> { - // Contains the DefIds of the opaque types that are currently being - // expanded. When we expand an opaque type we insert the DefId of - // that type, and when we finish expanding that type we remove the - // its DefId. - seen_opaque_tys: FxHashSet<DefId>, - // Cache of all expansions we've seen so far. This is a critical - // optimization for some large types produced by async fn trees. - expanded_cache: FxHashMap<(DefId, SubstsRef<'tcx>), Ty<'tcx>>, - primary_def_id: DefId, - found_recursion: bool, - tcx: TyCtxt<'tcx>, - } - - impl<'tcx> OpaqueTypeExpander<'tcx> { - fn expand_opaque_ty( - &mut self, - def_id: DefId, - substs: SubstsRef<'tcx>, - ) -> Option<Ty<'tcx>> { - if self.found_recursion { - return None; - } - let substs = substs.fold_with(self); - if self.seen_opaque_tys.insert(def_id) { - let expanded_ty = match self.expanded_cache.get(&(def_id, substs)) { - Some(expanded_ty) => expanded_ty, - None => { - let generic_ty = self.tcx.type_of(def_id); - let concrete_ty = generic_ty.subst(self.tcx, substs); - let expanded_ty = self.fold_ty(concrete_ty); - self.expanded_cache.insert((def_id, substs), expanded_ty); - expanded_ty - } - }; - self.seen_opaque_tys.remove(&def_id); - Some(expanded_ty) - } else { - // If another opaque type that we contain is recursive, then it - // will report the error, so we don't have to. - self.found_recursion = def_id == self.primary_def_id; - None - } - } - } - - impl<'tcx> TypeFolder<'tcx> for OpaqueTypeExpander<'tcx> { - fn tcx(&self) -> TyCtxt<'tcx> { - self.tcx - } - - fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { - if let ty::Opaque(def_id, substs) = t.kind { - self.expand_opaque_ty(def_id, substs).unwrap_or(t) - } else if t.has_opaque_types() { - t.super_fold_with(self) - } else { - t - } - } - } - let mut visitor = OpaqueTypeExpander { seen_opaque_tys: FxHashSet::default(), expanded_cache: FxHashMap::default(), - primary_def_id: def_id, + primary_def_id: Some(def_id), found_recursion: false, + check_recursion: true, tcx: self, }; + let expanded_type = visitor.expand_opaque_ty(def_id, substs).unwrap(); if visitor.found_recursion { Err(expanded_type) } else { Ok(expanded_type) } } } +struct OpaqueTypeExpander<'tcx> { + // Contains the DefIds of the opaque types that are currently being + // expanded. When we expand an opaque type we insert the DefId of + // that type, and when we finish expanding that type we remove the + // its DefId. + seen_opaque_tys: FxHashSet<DefId>, + // Cache of all expansions we've seen so far. This is a critical + // optimization for some large types produced by async fn trees. + expanded_cache: FxHashMap<(DefId, SubstsRef<'tcx>), Ty<'tcx>>, + primary_def_id: Option<DefId>, + found_recursion: bool, + /// Whether or not to check for recursive opaque types. + /// This is `true` when we're explicitly checking for opaque type + /// recursion, and 'false' otherwise to avoid unnecessary work. + check_recursion: bool, + tcx: TyCtxt<'tcx>, +} + +impl<'tcx> OpaqueTypeExpander<'tcx> { + fn expand_opaque_ty(&mut self, def_id: DefId, substs: SubstsRef<'tcx>) -> Option<Ty<'tcx>> { + if self.found_recursion { + return None; + } + let substs = substs.fold_with(self); + if !self.check_recursion || self.seen_opaque_tys.insert(def_id) { + let expanded_ty = match self.expanded_cache.get(&(def_id, substs)) { + Some(expanded_ty) => expanded_ty, + None => { + let generic_ty = self.tcx.type_of(def_id); + let concrete_ty = generic_ty.subst(self.tcx, substs); + let expanded_ty = self.fold_ty(concrete_ty); + self.expanded_cache.insert((def_id, substs), expanded_ty); + expanded_ty + } + }; + if self.check_recursion { + self.seen_opaque_tys.remove(&def_id); + } + Some(expanded_ty) + } else { + // If another opaque type that we contain is recursive, then it + // will report the error, so we don't have to. + self.found_recursion = def_id == *self.primary_def_id.as_ref().unwrap(); + None + } + } +} + +impl<'tcx> TypeFolder<'tcx> for OpaqueTypeExpander<'tcx> { + fn tcx(&self) -> TyCtxt<'tcx> { + self.tcx + } + + fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { + if let ty::Opaque(def_id, substs) = t.kind { + self.expand_opaque_ty(def_id, substs).unwrap_or(t) + } else if t.has_opaque_types() { + t.super_fold_with(self) + } else { + t + } + } +} + impl<'tcx> ty::TyS<'tcx> { /// Returns the maximum value for the given numeric type (including `char`s) /// or returns `None` if the type is not numeric. @@ -1142,3 +1145,24 @@ pub fn needs_drop_components( #[derive(Copy, Clone, Debug, HashStable, RustcEncodable, RustcDecodable)] pub struct AlwaysRequiresDrop; + +/// Normalizes all opaque types in the given value, replacing them +/// with their underlying types. +pub fn normalize_opaque_types( + tcx: TyCtxt<'tcx>, + val: &'tcx List<ty::Predicate<'tcx>>, +) -> &'tcx List<ty::Predicate<'tcx>> { + let mut visitor = OpaqueTypeExpander { + seen_opaque_tys: FxHashSet::default(), + expanded_cache: FxHashMap::default(), + primary_def_id: None, + found_recursion: false, + check_recursion: false, + tcx, + }; + val.fold_with(&mut visitor) +} + +pub fn provide(providers: &mut ty::query::Providers) { + *providers = ty::query::Providers { normalize_opaque_types, ..*providers } +} diff --git a/src/librustc_mir/Cargo.toml b/src/librustc_mir/Cargo.toml index aebce78e401..f05c47e0ed6 100644 --- a/src/librustc_mir/Cargo.toml +++ b/src/librustc_mir/Cargo.toml @@ -13,7 +13,7 @@ doctest = false either = "1.5.0" rustc_graphviz = { path = "../librustc_graphviz" } itertools = "0.8" -log = "0.4" +log = { package = "tracing", version = "0.1" } log_settings = "0.1.1" polonius-engine = "0.12.0" rustc_middle = { path = "../librustc_middle" } diff --git a/src/librustc_mir/const_eval/machine.rs b/src/librustc_mir/const_eval/machine.rs index 6453630bb92..0dac8b64910 100644 --- a/src/librustc_mir/const_eval/machine.rs +++ b/src/librustc_mir/const_eval/machine.rs @@ -56,7 +56,7 @@ impl<'mir, 'tcx> InterpCx<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>> { self.copy_op(place.into(), dest)?; self.return_to_block(ret.map(|r| r.1))?; - self.dump_place(*dest); + trace!("{:?}", self.dump_place(*dest)); Ok(true) } diff --git a/src/librustc_mir/interpret/cast.rs b/src/librustc_mir/interpret/cast.rs index 60cf21552e9..78f149f6451 100644 --- a/src/librustc_mir/interpret/cast.rs +++ b/src/librustc_mir/interpret/cast.rs @@ -8,11 +8,14 @@ use rustc_middle::mir::interpret::{InterpResult, PointerArithmetic, Scalar}; use rustc_middle::mir::CastKind; use rustc_middle::ty::adjustment::PointerCast; use rustc_middle::ty::layout::{IntegerExt, TyAndLayout}; -use rustc_middle::ty::{self, Ty, TypeAndMut, TypeFoldable}; +use rustc_middle::ty::{self, Ty, TypeAndMut}; use rustc_span::symbol::sym; use rustc_target::abi::{Integer, LayoutOf, Variants}; -use super::{truncate, FnVal, ImmTy, Immediate, InterpCx, Machine, OpTy, PlaceTy}; +use super::{ + truncate, util::ensure_monomorphic_enough, FnVal, ImmTy, Immediate, InterpCx, Machine, OpTy, + PlaceTy, +}; impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { pub fn cast( @@ -47,9 +50,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { match src.layout.ty.kind { ty::FnDef(def_id, substs) => { // All reifications must be monomorphic, bail out otherwise. - if src.layout.ty.needs_subst() { - throw_inval!(TooGeneric); - } + ensure_monomorphic_enough(*self.tcx, src.layout.ty)?; if self.tcx.has_attr(def_id, sym::rustc_args_required_const) { span_bug!( @@ -89,9 +90,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { match src.layout.ty.kind { ty::Closure(def_id, substs) => { // All reifications must be monomorphic, bail out otherwise. - if src.layout.ty.needs_subst() { - throw_inval!(TooGeneric); - } + ensure_monomorphic_enough(*self.tcx, src.layout.ty)?; let instance = ty::Instance::resolve_closure( *self.tcx, diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index 3d3d756cffe..1e9be097815 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -1,5 +1,4 @@ use std::cell::Cell; -use std::fmt::Write; use std::mem; use rustc_data_structures::fx::FxHashMap; @@ -719,6 +718,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } ); + if unwinding && self.frame_idx() == 0 { + throw_ub_format!("unwinding past the topmost frame of the stack"); + } + ::log_settings::settings().indentation -= 1; let frame = self.stack_mut().pop().expect("tried to pop a stack frame, but there were none"); @@ -728,7 +731,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { if let Some(return_place) = frame.return_place { let op = self.access_local(&frame, mir::RETURN_PLACE, None)?; self.copy_op_transmute(op, return_place)?; - self.dump_place(*return_place); + trace!("{:?}", self.dump_place(*return_place)); } else { throw_ub!(Unreachable); } @@ -819,13 +822,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { ) -> InterpResult<'tcx> { // FIXME: should we tell the user that there was a local which was never written to? if let LocalValue::Live(Operand::Indirect(MemPlace { ptr, .. })) = local { - trace!("deallocating local"); // All locals have a backing allocation, even if the allocation is empty // due to the local having ZST type. let ptr = ptr.assert_ptr(); - if log_enabled!(::log::Level::Trace) { - self.memory.dump_alloc(ptr.alloc_id); - } + trace!("deallocating local: {:?}", self.memory.dump_alloc(ptr.alloc_id)); self.memory.deallocate_local(ptr)?; }; Ok(()) @@ -881,47 +881,77 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { self.raw_const_to_mplace(val) } - pub fn dump_place(&self, place: Place<M::PointerTag>) { - // Debug output - if !log_enabled!(::log::Level::Trace) { - return; + #[must_use] + pub fn dump_place(&'a self, place: Place<M::PointerTag>) -> PlacePrinter<'a, 'mir, 'tcx, M> { + PlacePrinter { ecx: self, place } + } + + #[must_use] + pub fn generate_stacktrace(&self) -> Vec<FrameInfo<'tcx>> { + let mut frames = Vec::new(); + for frame in self.stack().iter().rev() { + let source_info = frame.current_source_info(); + let lint_root = source_info.and_then(|source_info| { + match &frame.body.source_scopes[source_info.scope].local_data { + mir::ClearCrossCrate::Set(data) => Some(data.lint_root), + mir::ClearCrossCrate::Clear => None, + } + }); + let span = source_info.map_or(DUMMY_SP, |source_info| source_info.span); + + frames.push(FrameInfo { span, instance: frame.instance, lint_root }); } - match place { + trace!("generate stacktrace: {:#?}", frames); + frames + } +} + +#[doc(hidden)] +/// Helper struct for the `dump_place` function. +pub struct PlacePrinter<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> { + ecx: &'a InterpCx<'mir, 'tcx, M>, + place: Place<M::PointerTag>, +} + +impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> std::fmt::Debug + for PlacePrinter<'a, 'mir, 'tcx, M> +{ + fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self.place { Place::Local { frame, local } => { let mut allocs = Vec::new(); - let mut msg = format!("{:?}", local); - if frame != self.frame_idx() { - write!(msg, " ({} frames up)", self.frame_idx() - frame).unwrap(); + write!(fmt, "{:?}", local)?; + if frame != self.ecx.frame_idx() { + write!(fmt, " ({} frames up)", self.ecx.frame_idx() - frame)?; } - write!(msg, ":").unwrap(); + write!(fmt, ":")?; - match self.stack()[frame].locals[local].value { - LocalValue::Dead => write!(msg, " is dead").unwrap(), - LocalValue::Uninitialized => write!(msg, " is uninitialized").unwrap(), + match self.ecx.stack()[frame].locals[local].value { + LocalValue::Dead => write!(fmt, " is dead")?, + LocalValue::Uninitialized => write!(fmt, " is uninitialized")?, LocalValue::Live(Operand::Indirect(mplace)) => match mplace.ptr { Scalar::Ptr(ptr) => { write!( - msg, + fmt, " by align({}){} ref:", mplace.align.bytes(), match mplace.meta { MemPlaceMeta::Meta(meta) => format!(" meta({:?})", meta), MemPlaceMeta::Poison | MemPlaceMeta::None => String::new(), } - ) - .unwrap(); + )?; allocs.push(ptr.alloc_id); } - ptr => write!(msg, " by integral ref: {:?}", ptr).unwrap(), + ptr => write!(fmt, " by integral ref: {:?}", ptr)?, }, LocalValue::Live(Operand::Immediate(Immediate::Scalar(val))) => { - write!(msg, " {:?}", val).unwrap(); + write!(fmt, " {:?}", val)?; if let ScalarMaybeUninit::Scalar(Scalar::Ptr(ptr)) = val { allocs.push(ptr.alloc_id); } } LocalValue::Live(Operand::Immediate(Immediate::ScalarPair(val1, val2))) => { - write!(msg, " ({:?}, {:?})", val1, val2).unwrap(); + write!(fmt, " ({:?}, {:?})", val1, val2)?; if let ScalarMaybeUninit::Scalar(Scalar::Ptr(ptr)) = val1 { allocs.push(ptr.alloc_id); } @@ -931,36 +961,19 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } } - trace!("{}", msg); - self.memory.dump_allocs(allocs); + write!(fmt, ": {:?}", self.ecx.memory.dump_allocs(allocs)) } Place::Ptr(mplace) => match mplace.ptr { - Scalar::Ptr(ptr) => { - trace!("by align({}) ref:", mplace.align.bytes()); - self.memory.dump_alloc(ptr.alloc_id); - } - ptr => trace!(" integral by ref: {:?}", ptr), + Scalar::Ptr(ptr) => write!( + fmt, + "by align({}) ref: {:?}", + mplace.align.bytes(), + self.ecx.memory.dump_alloc(ptr.alloc_id) + ), + ptr => write!(fmt, " integral by ref: {:?}", ptr), }, } } - - pub fn generate_stacktrace(&self) -> Vec<FrameInfo<'tcx>> { - let mut frames = Vec::new(); - for frame in self.stack().iter().rev() { - let source_info = frame.current_source_info(); - let lint_root = source_info.and_then(|source_info| { - match &frame.body.source_scopes[source_info.scope].local_data { - mir::ClearCrossCrate::Set(data) => Some(data.lint_root), - mir::ClearCrossCrate::Clear => None, - } - }); - let span = source_info.map_or(DUMMY_SP, |source_info| source_info.span); - - frames.push(FrameInfo { span, instance: frame.instance, lint_root }); - } - trace!("generate stacktrace: {:#?}", frames); - frames - } } impl<'ctx, 'mir, 'tcx, Tag, Extra> HashStable<StableHashingContext<'ctx>> diff --git a/src/librustc_mir/interpret/intrinsics.rs b/src/librustc_mir/interpret/intrinsics.rs index 39ed3b60793..b45045716d1 100644 --- a/src/librustc_mir/interpret/intrinsics.rs +++ b/src/librustc_mir/interpret/intrinsics.rs @@ -12,11 +12,13 @@ use rustc_middle::mir::{ }; use rustc_middle::ty; use rustc_middle::ty::subst::SubstsRef; -use rustc_middle::ty::{Ty, TyCtxt, TypeFoldable}; +use rustc_middle::ty::{Ty, TyCtxt}; use rustc_span::symbol::{sym, Symbol}; use rustc_target::abi::{Abi, LayoutOf as _, Primitive, Size}; -use super::{CheckInAllocMsg, ImmTy, InterpCx, Machine, OpTy, PlaceTy}; +use super::{ + util::ensure_monomorphic_enough, CheckInAllocMsg, ImmTy, InterpCx, Machine, OpTy, PlaceTy, +}; mod caller_location; mod type_name; @@ -54,9 +56,7 @@ crate fn eval_nullary_intrinsic<'tcx>( let name = tcx.item_name(def_id); Ok(match name { sym::type_name => { - if tp_ty.needs_subst() { - throw_inval!(TooGeneric); - } + ensure_monomorphic_enough(tcx, tp_ty)?; let alloc = type_name::alloc_type_name(tcx, tp_ty); ConstValue::Slice { data: alloc, start: 0, end: alloc.len() } } @@ -72,9 +72,7 @@ crate fn eval_nullary_intrinsic<'tcx>( ConstValue::from_machine_usize(n, &tcx) } sym::type_id => { - if tp_ty.needs_subst() { - throw_inval!(TooGeneric); - } + ensure_monomorphic_enough(tcx, tp_ty)?; ConstValue::from_u64(tcx.type_id_hash(tp_ty)) } sym::variant_count => { @@ -120,6 +118,21 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { self.write_scalar(location.ptr, dest)?; } + sym::min_align_of_val | sym::size_of_val => { + let place = self.deref_operand(args[0])?; + let (size, align) = self + .size_and_align_of(place.meta, place.layout)? + .ok_or_else(|| err_unsup_format!("`extern type` does not have known layout"))?; + + let result = match intrinsic_name { + sym::min_align_of_val => align.bytes(), + sym::size_of_val => size.bytes(), + _ => bug!(), + }; + + self.write_scalar(Scalar::from_machine_usize(result, self), dest)?; + } + sym::min_align_of | sym::pref_align_of | sym::needs_drop @@ -430,7 +443,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { _ => return Ok(false), } - self.dump_place(*dest); + trace!("{:?}", self.dump_place(*dest)); self.go_to_block(ret); Ok(true) } diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs index ea7a1c6cffa..a9e6e324eb2 100644 --- a/src/librustc_mir/interpret/memory.rs +++ b/src/librustc_mir/interpret/memory.rs @@ -667,69 +667,20 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { Ok(()) } - /// Print an allocation and all allocations it points to, recursively. - /// This prints directly to stderr, ignoring RUSTC_LOG! It is up to the caller to - /// control for this. - pub fn dump_alloc(&self, id: AllocId) { - self.dump_allocs(vec![id]); + /// Create a lazy debug printer that prints the given allocation and all allocations it points + /// to, recursively. + #[must_use] + pub fn dump_alloc<'a>(&'a self, id: AllocId) -> DumpAllocs<'a, 'mir, 'tcx, M> { + self.dump_allocs(vec![id]) } - /// Print a list of allocations and all allocations they point to, recursively. - /// This prints directly to stderr, ignoring RUSTC_LOG! It is up to the caller to - /// control for this. - pub fn dump_allocs(&self, mut allocs: Vec<AllocId>) { - // Cannot be a closure because it is generic in `Tag`, `Extra`. - fn write_allocation_track_relocs<'tcx, Tag: Copy + fmt::Debug, Extra>( - tcx: TyCtxt<'tcx>, - allocs_to_print: &mut VecDeque<AllocId>, - alloc: &Allocation<Tag, Extra>, - ) { - for &(_, target_id) in alloc.relocations().values() { - allocs_to_print.push_back(target_id); - } - pretty::write_allocation(tcx, alloc, &mut std::io::stderr()).unwrap(); - } - + /// Create a lazy debug printer for a list of allocations and all allocations they point to, + /// recursively. + #[must_use] + pub fn dump_allocs<'a>(&'a self, mut allocs: Vec<AllocId>) -> DumpAllocs<'a, 'mir, 'tcx, M> { allocs.sort(); allocs.dedup(); - let mut allocs_to_print = VecDeque::from(allocs); - // `allocs_printed` contains all allocations that we have already printed. - let mut allocs_printed = FxHashSet::default(); - - while let Some(id) = allocs_to_print.pop_front() { - if !allocs_printed.insert(id) { - // Already printed, so skip this. - continue; - } - - eprint!("{}", id); - match self.alloc_map.get(id) { - Some(&(kind, ref alloc)) => { - // normal alloc - eprint!(" ({}, ", kind); - write_allocation_track_relocs(self.tcx, &mut allocs_to_print, alloc); - } - None => { - // global alloc - match self.tcx.get_global_alloc(id) { - Some(GlobalAlloc::Memory(alloc)) => { - eprint!(" (unchanged global, "); - write_allocation_track_relocs(self.tcx, &mut allocs_to_print, alloc); - } - Some(GlobalAlloc::Function(func)) => { - eprint!(" (fn: {})", func); - } - Some(GlobalAlloc::Static(did)) => { - eprint!(" (static: {})", self.tcx.def_path_str(did)); - } - None => { - eprint!(" (deallocated)"); - } - } - } - } - eprintln!(); - } + DumpAllocs { mem: self, allocs } } /// Print leaked memory. Allocations reachable from `static_roots` or a `Global` allocation @@ -760,8 +711,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { }); let n = leaks.len(); if n > 0 { - eprintln!("The following memory was leaked:"); - self.dump_allocs(leaks); + eprintln!("The following memory was leaked: {:?}", self.dump_allocs(leaks)); } n } @@ -772,6 +722,80 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { } } +#[doc(hidden)] +/// There's no way to use this directly, it's just a helper struct for the `dump_alloc(s)` methods. +pub struct DumpAllocs<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> { + mem: &'a Memory<'mir, 'tcx, M>, + allocs: Vec<AllocId>, +} + +impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> std::fmt::Debug for DumpAllocs<'a, 'mir, 'tcx, M> { + fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + // Cannot be a closure because it is generic in `Tag`, `Extra`. + fn write_allocation_track_relocs<'tcx, Tag: Copy + fmt::Debug, Extra>( + fmt: &mut std::fmt::Formatter<'_>, + tcx: TyCtxt<'tcx>, + allocs_to_print: &mut VecDeque<AllocId>, + alloc: &Allocation<Tag, Extra>, + ) -> std::fmt::Result { + for &(_, target_id) in alloc.relocations().values() { + allocs_to_print.push_back(target_id); + } + write!(fmt, "{}", pretty::display_allocation(tcx, alloc)) + } + + let mut allocs_to_print: VecDeque<_> = self.allocs.iter().copied().collect(); + // `allocs_printed` contains all allocations that we have already printed. + let mut allocs_printed = FxHashSet::default(); + + while let Some(id) = allocs_to_print.pop_front() { + if !allocs_printed.insert(id) { + // Already printed, so skip this. + continue; + } + + write!(fmt, "{}", id)?; + match self.mem.alloc_map.get(id) { + Some(&(kind, ref alloc)) => { + // normal alloc + write!(fmt, " ({}, ", kind)?; + write_allocation_track_relocs( + &mut *fmt, + self.mem.tcx, + &mut allocs_to_print, + alloc, + )?; + } + None => { + // global alloc + match self.mem.tcx.get_global_alloc(id) { + Some(GlobalAlloc::Memory(alloc)) => { + write!(fmt, " (unchanged global, ")?; + write_allocation_track_relocs( + &mut *fmt, + self.mem.tcx, + &mut allocs_to_print, + alloc, + )?; + } + Some(GlobalAlloc::Function(func)) => { + write!(fmt, " (fn: {})", func)?; + } + Some(GlobalAlloc::Static(did)) => { + write!(fmt, " (static: {})", self.mem.tcx.def_path_str(did))?; + } + None => { + write!(fmt, " (deallocated)")?; + } + } + } + } + writeln!(fmt)?; + } + Ok(()) + } +} + /// Reading and writing. impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { /// Reads the given number of bytes from memory. Returns them as a slice. diff --git a/src/librustc_mir/interpret/mod.rs b/src/librustc_mir/interpret/mod.rs index 5de9b502a37..ebb061f4851 100644 --- a/src/librustc_mir/interpret/mod.rs +++ b/src/librustc_mir/interpret/mod.rs @@ -12,6 +12,7 @@ mod place; mod step; mod terminator; mod traits; +mod util; mod validity; mod visitor; diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index c5d17273225..15e341d9c4c 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -648,7 +648,7 @@ where place_ty = self.place_projection(place_ty, &elem)? } - self.dump_place(place_ty.place); + trace!("{:?}", self.dump_place(place_ty.place)); // Sanity-check the type we ended up with. debug_assert!(mir_assign_valid_types( *self.tcx, diff --git a/src/librustc_mir/interpret/step.rs b/src/librustc_mir/interpret/step.rs index 3d1e3eccc61..fcd26c86c47 100644 --- a/src/librustc_mir/interpret/step.rs +++ b/src/librustc_mir/interpret/step.rs @@ -271,7 +271,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } } - self.dump_place(*dest); + trace!("{:?}", self.dump_place(*dest)); Ok(()) } diff --git a/src/librustc_mir/interpret/traits.rs b/src/librustc_mir/interpret/traits.rs index 589da04d6a3..77f4593fa16 100644 --- a/src/librustc_mir/interpret/traits.rs +++ b/src/librustc_mir/interpret/traits.rs @@ -1,9 +1,10 @@ use std::convert::TryFrom; use rustc_middle::mir::interpret::{InterpResult, Pointer, PointerArithmetic, Scalar}; -use rustc_middle::ty::{self, Instance, Ty, TypeFoldable}; +use rustc_middle::ty::{self, Instance, Ty}; use rustc_target::abi::{Align, LayoutOf, Size}; +use super::util::ensure_monomorphic_enough; use super::{FnVal, InterpCx, Machine, MemoryKind}; impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { @@ -23,9 +24,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let (ty, poly_trait_ref) = self.tcx.erase_regions(&(ty, poly_trait_ref)); // All vtables must be monomorphic, bail out otherwise. - if ty.needs_subst() || poly_trait_ref.needs_subst() { - throw_inval!(TooGeneric); - } + ensure_monomorphic_enough(*self.tcx, ty)?; + ensure_monomorphic_enough(*self.tcx, poly_trait_ref)?; if let Some(&vtable) = self.vtables.get(&(ty, poly_trait_ref)) { // This means we guarantee that there are no duplicate vtables, we will diff --git a/src/librustc_mir/interpret/util.rs b/src/librustc_mir/interpret/util.rs new file mode 100644 index 00000000000..c0eac8a9305 --- /dev/null +++ b/src/librustc_mir/interpret/util.rs @@ -0,0 +1,73 @@ +use rustc_middle::mir::interpret::InterpResult; +use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, TypeVisitor}; +use std::convert::TryInto; + +/// Returns `true` if a used generic parameter requires substitution. +crate fn ensure_monomorphic_enough<'tcx, T>(tcx: TyCtxt<'tcx>, ty: T) -> InterpResult<'tcx> +where + T: TypeFoldable<'tcx>, +{ + debug!("ensure_monomorphic_enough: ty={:?}", ty); + if !ty.needs_subst() { + return Ok(()); + } + + struct UsedParamsNeedSubstVisitor<'tcx> { + tcx: TyCtxt<'tcx>, + }; + + impl<'tcx> TypeVisitor<'tcx> for UsedParamsNeedSubstVisitor<'tcx> { + fn visit_const(&mut self, c: &'tcx ty::Const<'tcx>) -> bool { + if !c.needs_subst() { + return false; + } + + match c.val { + ty::ConstKind::Param(..) => true, + _ => c.super_visit_with(self), + } + } + + fn visit_ty(&mut self, ty: Ty<'tcx>) -> bool { + if !ty.needs_subst() { + return false; + } + + match ty.kind { + ty::Param(_) => true, + ty::Closure(def_id, substs) + | ty::Generator(def_id, substs, ..) + | ty::FnDef(def_id, substs) => { + let unused_params = self.tcx.unused_generic_params(def_id); + for (index, subst) in substs.into_iter().enumerate() { + let index = index + .try_into() + .expect("more generic parameters than can fit into a `u32`"); + let is_used = + unused_params.contains(index).map(|unused| !unused).unwrap_or(true); + // Only recurse when generic parameters in fns, closures and generators + // are used and require substitution. + if is_used && subst.needs_subst() { + // Just in case there are closures or generators within this subst, + // recurse. + if subst.super_visit_with(self) { + // Only return when we find a parameter so the remaining substs + // are not skipped. + return true; + } + } + } + false + } + _ => ty.super_visit_with(self), + } + } + } + + let mut vis = UsedParamsNeedSubstVisitor { tcx }; + if ty.visit_with(&mut vis) { + throw_inval!(TooGeneric); + } else { + Ok(()) + } +} diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs index bfa9bb9e0f0..6a7653b6075 100644 --- a/src/librustc_mir/shim.rs +++ b/src/librustc_mir/shim.rs @@ -193,7 +193,7 @@ fn build_drop_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, ty: Option<Ty<'tcx>>) ); } let patch = { - let param_env = tcx.param_env(def_id).with_reveal_all(); + let param_env = tcx.param_env_reveal_all_normalized(def_id); let mut elaborator = DropShimElaborator { body: &body, patch: MirPatch::new(&body), tcx, param_env }; let dropee = tcx.mk_place_deref(dropee_ptr); diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index a1db06e6aa3..8e2fd709d66 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -328,7 +328,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { ) -> ConstPropagator<'mir, 'tcx> { let def_id = source.def_id(); let substs = &InternalSubsts::identity_for_item(tcx, def_id); - let param_env = tcx.param_env(def_id).with_reveal_all(); + let param_env = tcx.param_env_reveal_all_normalized(def_id); let span = tcx.def_span(def_id); let can_const_prop = CanConstProp::check(body); diff --git a/src/librustc_mir/transform/elaborate_drops.rs b/src/librustc_mir/transform/elaborate_drops.rs index d3bfd872d16..ad49090bfc5 100644 --- a/src/librustc_mir/transform/elaborate_drops.rs +++ b/src/librustc_mir/transform/elaborate_drops.rs @@ -25,7 +25,7 @@ impl<'tcx> MirPass<'tcx> for ElaborateDrops { debug!("elaborate_drops({:?} @ {:?})", src, body.span); let def_id = src.def_id(); - let param_env = tcx.param_env(src.def_id()).with_reveal_all(); + let param_env = tcx.param_env_reveal_all_normalized(src.def_id()); let move_data = match MoveData::gather_moves(body, tcx, param_env) { Ok(move_data) => move_data, Err((move_data, _)) => { diff --git a/src/librustc_mir/transform/inline.rs b/src/librustc_mir/transform/inline.rs index c03be2a8fcd..92ea162e419 100644 --- a/src/librustc_mir/transform/inline.rs +++ b/src/librustc_mir/transform/inline.rs @@ -72,7 +72,7 @@ impl Inliner<'tcx> { let mut callsites = VecDeque::new(); - let param_env = self.tcx.param_env(self.source.def_id()).with_reveal_all(); + let param_env = self.tcx.param_env_reveal_all_normalized(self.source.def_id()); // Only do inlining into fn bodies. let id = self.tcx.hir().as_local_hir_id(self.source.def_id().expect_local()); diff --git a/src/librustc_mir/transform/instrument_coverage.rs b/src/librustc_mir/transform/instrument_coverage.rs index 9933a975e4d..fe63a67fdbb 100644 --- a/src/librustc_mir/transform/instrument_coverage.rs +++ b/src/librustc_mir/transform/instrument_coverage.rs @@ -7,10 +7,9 @@ use rustc_middle::hir; use rustc_middle::ich::StableHashingContext; use rustc_middle::mir::coverage::*; use rustc_middle::mir::interpret::Scalar; -use rustc_middle::mir::CoverageInfo; use rustc_middle::mir::{ - self, traversal, BasicBlock, BasicBlockData, Operand, Place, SourceInfo, StatementKind, - Terminator, TerminatorKind, START_BLOCK, + self, traversal, BasicBlock, BasicBlockData, CoverageInfo, Operand, Place, SourceInfo, + SourceScope, StatementKind, Terminator, TerminatorKind, }; use rustc_middle::ty; use rustc_middle::ty::query::Providers; @@ -41,14 +40,14 @@ fn coverageinfo_from_mir<'tcx>(tcx: TyCtxt<'tcx>, mir_def_id: DefId) -> Coverage tcx.require_lang_item(lang_items::CoverageCounterSubtractFnLangItem, None); // The `num_counters` argument to `llvm.instrprof.increment` is the number of injected - // counters, with each counter having an index from `0..num_counters-1`. MIR optimization + // counters, with each counter having a counter ID from `0..num_counters-1`. MIR optimization // may split and duplicate some BasicBlock sequences. Simply counting the calls may not - // not work; but computing the num_counters by adding `1` to the highest index (for a given + // work; but computing the num_counters by adding `1` to the highest counter_id (for a given // instrumented function) is valid. // // `num_expressions` is the number of counter expressions added to the MIR body. Both // `num_counters` and `num_expressions` are used to initialize new vectors, during backend - // code generate, to lookup counters and expressions by their simple u32 indexes. + // code generate, to lookup counters and expressions by simple u32 indexes. let mut num_counters: u32 = 0; let mut num_expressions: u32 = 0; for terminator in @@ -57,27 +56,26 @@ fn coverageinfo_from_mir<'tcx>(tcx: TyCtxt<'tcx>, mir_def_id: DefId) -> Coverage if let TerminatorKind::Call { func: Operand::Constant(func), args, .. } = &terminator.kind { match func.literal.ty.kind { FnDef(id, _) if id == count_code_region_fn => { - let index_arg = - args.get(count_code_region_args::COUNTER_INDEX).expect("arg found"); - let counter_index = mir::Operand::scalar_from_const(index_arg) + let counter_id_arg = + args.get(count_code_region_args::COUNTER_ID).expect("arg found"); + let counter_id = mir::Operand::scalar_from_const(counter_id_arg) .to_u32() - .expect("index arg is u32"); - num_counters = std::cmp::max(num_counters, counter_index + 1); + .expect("counter_id arg is u32"); + num_counters = std::cmp::max(num_counters, counter_id + 1); } FnDef(id, _) if id == coverage_counter_add_fn || id == coverage_counter_subtract_fn => { - let index_arg = args - .get(coverage_counter_expression_args::COUNTER_EXPRESSION_INDEX) + let expression_id_arg = args + .get(coverage_counter_expression_args::EXPRESSION_ID) .expect("arg found"); - let translated_index = mir::Operand::scalar_from_const(index_arg) + let id_descending_from_max = mir::Operand::scalar_from_const(expression_id_arg) .to_u32() - .expect("index arg is u32"); - // Counter expressions start with "translated indexes", descending from - // `u32::MAX`, so the range of expression indexes is disjoint from the range of - // counter indexes. This way, both counters and expressions can be operands in - // other expressions. - let expression_index = u32::MAX - translated_index; + .expect("expression_id arg is u32"); + // Counter expressions are initially assigned IDs descending from `u32::MAX`, so + // the range of expression IDs is disjoint from the range of counter IDs. This + // way, both counters and expressions can be operands in other expressions. + let expression_index = u32::MAX - id_descending_from_max; num_expressions = std::cmp::max(num_expressions, expression_index + 1); } _ => {} @@ -97,12 +95,10 @@ fn call_terminators(data: &'tcx BasicBlockData<'tcx>) -> Option<&'tcx Terminator impl<'tcx> MirPass<'tcx> for InstrumentCoverage { fn run_pass(&self, tcx: TyCtxt<'tcx>, src: MirSource<'tcx>, mir_body: &mut mir::Body<'tcx>) { - if tcx.sess.opts.debugging_opts.instrument_coverage { - // If the InstrumentCoverage pass is called on promoted MIRs, skip them. - // See: https://github.com/rust-lang/rust/pull/73011#discussion_r438317601 - if src.promoted.is_none() { - Instrumentor::new(tcx, src, mir_body).inject_counters(); - } + // If the InstrumentCoverage pass is called on promoted MIRs, skip them. + // See: https://github.com/rust-lang/rust/pull/73011#discussion_r438317601 + if src.promoted.is_none() { + Instrumentor::new(tcx, src, mir_body).inject_counters(); } } } @@ -113,6 +109,12 @@ enum Op { Subtract, } +struct InjectedCall<'tcx> { + func: Operand<'tcx>, + args: Vec<Operand<'tcx>>, + inject_at: Span, +} + struct Instrumentor<'a, 'tcx> { tcx: TyCtxt<'tcx>, mir_def_id: DefId, @@ -147,11 +149,8 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> { } /// Expression IDs start from u32::MAX and go down because a CounterExpression can reference - /// (add or subtract counts) of both Counter regions and CounterExpression regions. The indexes - /// of each type of region must be contiguous, but also must be unique across both sets. - /// The expression IDs are eventually translated into region indexes (starting after the last - /// counter index, for the given function), during backend code generation, by the helper method - /// `rustc_codegen_ssa::coverageinfo::map::FunctionCoverage::translate_expressions()`. + /// (add or subtract counts) of both Counter regions and CounterExpression regions. The counter + /// expression operand IDs must be unique across both types. fn next_expression(&mut self) -> u32 { assert!(self.num_counters < u32::MAX - self.num_expressions); let next = u32::MAX - self.num_expressions; @@ -171,17 +170,25 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> { } fn inject_counters(&mut self) { + let mir_body = &self.mir_body; let body_span = self.hir_body.value.span; - debug!( - "instrumenting {:?}, span: {}", - self.mir_def_id, - self.tcx.sess.source_map().span_to_string(body_span) - ); + debug!("instrumenting {:?}, span: {:?}", self.mir_def_id, body_span); // FIXME(richkadel): As a first step, counters are only injected at the top of each // function. The complete solution will inject counters at each conditional code branch. - let next_block = START_BLOCK; - self.inject_counter(body_span, next_block); + let _ignore = mir_body; + let id = self.next_counter(); + let function_source_hash = self.function_source_hash(); + let code_region = body_span; + let scope = rustc_middle::mir::OUTERMOST_SOURCE_SCOPE; + let is_cleanup = false; + let next_block = rustc_middle::mir::START_BLOCK; + self.inject_call( + self.make_counter(id, function_source_hash, code_region), + scope, + is_cleanup, + next_block, + ); // FIXME(richkadel): The next step to implement source based coverage analysis will be // instrumenting branches within functions, and some regions will be counted by "counter @@ -190,57 +197,68 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> { let fake_use = false; if fake_use { let add = false; - if add { - self.inject_counter_expression(body_span, next_block, 1, Op::Add, 2); - } else { - self.inject_counter_expression(body_span, next_block, 1, Op::Subtract, 2); - } + let lhs = 1; + let op = if add { Op::Add } else { Op::Subtract }; + let rhs = 2; + + let code_region = body_span; + let scope = rustc_middle::mir::OUTERMOST_SOURCE_SCOPE; + let is_cleanup = false; + let next_block = rustc_middle::mir::START_BLOCK; + + let id = self.next_expression(); + self.inject_call( + self.make_expression(id, code_region, lhs, op, rhs), + scope, + is_cleanup, + next_block, + ); } } - fn inject_counter(&mut self, code_region: Span, next_block: BasicBlock) -> u32 { - let counter_id = self.next_counter(); - let function_source_hash = self.function_source_hash(); - let injection_point = code_region.shrink_to_lo(); + fn make_counter( + &self, + id: u32, + function_source_hash: u64, + code_region: Span, + ) -> InjectedCall<'tcx> { + let inject_at = code_region.shrink_to_lo(); - let count_code_region_fn = function_handle( + let func = function_handle( self.tcx, self.tcx.require_lang_item(lang_items::CountCodeRegionFnLangItem, None), - injection_point, + inject_at, ); let mut args = Vec::new(); use count_code_region_args::*; debug_assert_eq!(FUNCTION_SOURCE_HASH, args.len()); - args.push(self.const_u64(function_source_hash, injection_point)); + args.push(self.const_u64(function_source_hash, inject_at)); - debug_assert_eq!(COUNTER_INDEX, args.len()); - args.push(self.const_u32(counter_id, injection_point)); + debug_assert_eq!(COUNTER_ID, args.len()); + args.push(self.const_u32(id, inject_at)); debug_assert_eq!(START_BYTE_POS, args.len()); - args.push(self.const_u32(code_region.lo().to_u32(), injection_point)); + args.push(self.const_u32(code_region.lo().to_u32(), inject_at)); debug_assert_eq!(END_BYTE_POS, args.len()); - args.push(self.const_u32(code_region.hi().to_u32(), injection_point)); - - self.inject_call(count_code_region_fn, args, injection_point, next_block); + args.push(self.const_u32(code_region.hi().to_u32(), inject_at)); - counter_id + InjectedCall { func, args, inject_at } } - fn inject_counter_expression( - &mut self, + fn make_expression( + &self, + id: u32, code_region: Span, - next_block: BasicBlock, lhs: u32, op: Op, rhs: u32, - ) -> u32 { - let expression_id = self.next_expression(); - let injection_point = code_region.shrink_to_lo(); + ) -> InjectedCall<'tcx> { + let inject_at = code_region.shrink_to_lo(); - let count_code_region_fn = function_handle( + let func = function_handle( self.tcx, self.tcx.require_lang_item( match op { @@ -249,43 +267,51 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> { }, None, ), - injection_point, + inject_at, ); let mut args = Vec::new(); use coverage_counter_expression_args::*; - debug_assert_eq!(COUNTER_EXPRESSION_INDEX, args.len()); - args.push(self.const_u32(expression_id, injection_point)); + debug_assert_eq!(EXPRESSION_ID, args.len()); + args.push(self.const_u32(id, inject_at)); - debug_assert_eq!(LEFT_INDEX, args.len()); - args.push(self.const_u32(lhs, injection_point)); + debug_assert_eq!(LEFT_ID, args.len()); + args.push(self.const_u32(lhs, inject_at)); - debug_assert_eq!(RIGHT_INDEX, args.len()); - args.push(self.const_u32(rhs, injection_point)); + debug_assert_eq!(RIGHT_ID, args.len()); + args.push(self.const_u32(rhs, inject_at)); debug_assert_eq!(START_BYTE_POS, args.len()); - args.push(self.const_u32(code_region.lo().to_u32(), injection_point)); + args.push(self.const_u32(code_region.lo().to_u32(), inject_at)); debug_assert_eq!(END_BYTE_POS, args.len()); - args.push(self.const_u32(code_region.hi().to_u32(), injection_point)); + args.push(self.const_u32(code_region.hi().to_u32(), inject_at)); - self.inject_call(count_code_region_fn, args, injection_point, next_block); - - expression_id + InjectedCall { func, args, inject_at } } fn inject_call( &mut self, - func: Operand<'tcx>, - args: Vec<Operand<'tcx>>, - fn_span: Span, + call: InjectedCall<'tcx>, + scope: SourceScope, + is_cleanup: bool, next_block: BasicBlock, ) { + let InjectedCall { func, args, inject_at } = call; + debug!( + " injecting {}call to {:?}({:?}) at: {:?}, scope: {:?}", + if is_cleanup { "cleanup " } else { "" }, + func, + args, + inject_at, + scope, + ); + let mut patch = MirPatch::new(self.mir_body); - let temp = patch.new_temp(self.tcx.mk_unit(), fn_span); - let new_block = patch.new_block(placeholder_block(fn_span)); + let temp = patch.new_temp(self.tcx.mk_unit(), inject_at); + let new_block = patch.new_block(placeholder_block(inject_at, scope, is_cleanup)); patch.patch_terminator( new_block, TerminatorKind::Call { @@ -295,7 +321,7 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> { destination: Some((Place::from(temp), new_block)), cleanup: None, from_hir_call: false, - fn_span, + fn_span: inject_at, }, ); @@ -325,15 +351,15 @@ fn function_handle<'tcx>(tcx: TyCtxt<'tcx>, fn_def_id: DefId, span: Span) -> Ope Operand::function_handle(tcx, fn_def_id, substs, span) } -fn placeholder_block(span: Span) -> BasicBlockData<'tcx> { +fn placeholder_block(span: Span, scope: SourceScope, is_cleanup: bool) -> BasicBlockData<'tcx> { BasicBlockData { statements: vec![], terminator: Some(Terminator { - source_info: SourceInfo::outermost(span), + source_info: SourceInfo { span, scope }, // this gets overwritten by the counter Call kind: TerminatorKind::Unreachable, }), - is_cleanup: false, + is_cleanup, } } diff --git a/src/librustc_mir/transform/mod.rs b/src/librustc_mir/transform/mod.rs index 283e4b289f2..26b4a696897 100644 --- a/src/librustc_mir/transform/mod.rs +++ b/src/librustc_mir/transform/mod.rs @@ -332,21 +332,25 @@ fn mir_validated( body.required_consts = required_consts; let promote_pass = promote_consts::PromoteTemps::default(); + let promote: &[&dyn MirPass<'tcx>] = &[ + // What we need to run borrowck etc. + &promote_pass, + &simplify::SimplifyCfg::new("qualify-consts"), + ]; + + let opt_coverage: &[&dyn MirPass<'tcx>] = if tcx.sess.opts.debugging_opts.instrument_coverage { + &[&instrument_coverage::InstrumentCoverage] + } else { + &[] + }; + run_passes( tcx, &mut body, InstanceDef::Item(def.to_global()), None, MirPhase::Validated, - &[&[ - // What we need to run borrowck etc. - &promote_pass, - &simplify::SimplifyCfg::new("qualify-consts"), - // If the `instrument-coverage` option is enabled, analyze the CFG, identify each - // conditional branch, construct a coverage map to be passed to LLVM, and inject counters - // where needed. - &instrument_coverage::InstrumentCoverage, - ]], + &[promote, opt_coverage], ); let promoted = promote_pass.promoted_fragments.into_inner(); diff --git a/src/librustc_mir/transform/promote_consts.rs b/src/librustc_mir/transform/promote_consts.rs index 59a8415ef96..f1a7338d11f 100644 --- a/src/librustc_mir/transform/promote_consts.rs +++ b/src/librustc_mir/transform/promote_consts.rs @@ -502,9 +502,47 @@ impl<'tcx> Validator<'_, 'tcx> { fn validate_place(&self, place: PlaceRef<'tcx>) -> Result<(), Unpromotable> { match place { PlaceRef { local, projection: [] } => self.validate_local(local), - PlaceRef { local: _, projection: [proj_base @ .., elem] } => { + PlaceRef { local, projection: [proj_base @ .., elem] } => { match *elem { - ProjectionElem::Deref | ProjectionElem::Downcast(..) => { + ProjectionElem::Deref => { + let mut not_promotable = true; + // This is a special treatment for cases like *&STATIC where STATIC is a + // global static variable. + // This pattern is generated only when global static variables are directly + // accessed and is qualified for promotion safely. + if let TempState::Defined { location, .. } = self.temps[local] { + let def_stmt = + self.body[location.block].statements.get(location.statement_index); + if let Some(Statement { + kind: + StatementKind::Assign(box (_, Rvalue::Use(Operand::Constant(c)))), + .. + }) = def_stmt + { + if let Some(did) = c.check_static_ptr(self.tcx) { + if let Some(hir::ConstContext::Static(..)) = self.const_kind { + // The `is_empty` predicate is introduced to exclude the case + // where the projection operations are [ .field, * ]. + // The reason is because promotion will be illegal if field + // accesses precede the dereferencing. + // Discussion can be found at + // https://github.com/rust-lang/rust/pull/74945#discussion_r463063247 + // There may be opportunity for generalization, but this needs to be + // accounted for. + if proj_base.is_empty() + && !self.tcx.is_thread_local_static(did) + { + not_promotable = false; + } + } + } + } + } + if not_promotable { + return Err(Unpromotable); + } + } + ProjectionElem::Downcast(..) => { return Err(Unpromotable); } diff --git a/src/librustc_mir/transform/simplify.rs b/src/librustc_mir/transform/simplify.rs index 491c37cbe06..9288d6e16f5 100644 --- a/src/librustc_mir/transform/simplify.rs +++ b/src/librustc_mir/transform/simplify.rs @@ -33,6 +33,7 @@ use rustc_index::vec::{Idx, IndexVec}; use rustc_middle::mir::visit::{MutVisitor, MutatingUseContext, PlaceContext, Visitor}; use rustc_middle::mir::*; use rustc_middle::ty::TyCtxt; +use smallvec::SmallVec; use std::borrow::Cow; pub struct SimplifyCfg { @@ -172,9 +173,12 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> { } } - // Collapse a goto chain starting from `start` - fn collapse_goto_chain(&mut self, start: &mut BasicBlock, changed: &mut bool) { - let mut terminator = match self.basic_blocks[*start] { + /// This function will return `None` if + /// * the block has statements + /// * the block has a terminator other than `goto` + /// * the block has no terminator (meaning some other part of the current optimization stole it) + fn take_terminator_if_simple_goto(&mut self, bb: BasicBlock) -> Option<Terminator<'tcx>> { + match self.basic_blocks[bb] { BasicBlockData { ref statements, terminator: @@ -183,32 +187,45 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> { } if statements.is_empty() => terminator.take(), // if `terminator` is None, this means we are in a loop. In that // case, let all the loop collapse to its entry. - _ => return, - }; - - let target = match terminator { - Some(Terminator { kind: TerminatorKind::Goto { ref mut target }, .. }) => { - self.collapse_goto_chain(target, changed); - *target - } - _ => unreachable!(), - }; - self.basic_blocks[*start].terminator = terminator; - - debug!("collapsing goto chain from {:?} to {:?}", *start, target); - - *changed |= *start != target; + _ => None, + } + } - if self.pred_count[*start] == 1 { - // This is the last reference to *start, so the pred-count to - // to target is moved into the current block. - self.pred_count[*start] = 0; - } else { - self.pred_count[target] += 1; - self.pred_count[*start] -= 1; + /// Collapse a goto chain starting from `start` + fn collapse_goto_chain(&mut self, start: &mut BasicBlock, changed: &mut bool) { + // Using `SmallVec` here, because in some logs on libcore oli-obk saw many single-element + // goto chains. We should probably benchmark different sizes. + let mut terminators: SmallVec<[_; 1]> = Default::default(); + let mut current = *start; + while let Some(terminator) = self.take_terminator_if_simple_goto(current) { + let target = match terminator { + Terminator { kind: TerminatorKind::Goto { target }, .. } => target, + _ => unreachable!(), + }; + terminators.push((current, terminator)); + current = target; } + let last = current; + *start = last; + while let Some((current, mut terminator)) = terminators.pop() { + let target = match terminator { + Terminator { kind: TerminatorKind::Goto { ref mut target }, .. } => target, + _ => unreachable!(), + }; + *target = last; + debug!("collapsing goto chain from {:?} to {:?}", current, target); - *start = target; + if self.pred_count[current] == 1 { + // This is the last reference to current, so the pred-count to + // to target is moved into the current block. + self.pred_count[current] = 0; + } else { + self.pred_count[*target] += 1; + self.pred_count[current] -= 1; + } + *changed = true; + self.basic_blocks[current].terminator = Some(terminator); + } } // merge a block with 1 `goto` predecessor to its parent diff --git a/src/librustc_mir/transform/validate.rs b/src/librustc_mir/transform/validate.rs index e794a6949d2..b8a74f09409 100644 --- a/src/librustc_mir/transform/validate.rs +++ b/src/librustc_mir/transform/validate.rs @@ -189,7 +189,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { // Normalize projections and things like that. // FIXME: We need to reveal_all, as some optimizations change types in ways // that require unfolding opaque types. - let param_env = self.param_env.with_reveal_all(); + let param_env = self.param_env.with_reveal_all_normalized(self.tcx); let src = self.tcx.normalize_erasing_regions(param_env, src); let dest = self.tcx.normalize_erasing_regions(param_env, dest); diff --git a/src/librustc_mir/util/pretty.rs b/src/librustc_mir/util/pretty.rs index 990bfc064c2..25657ba98b8 100644 --- a/src/librustc_mir/util/pretty.rs +++ b/src/librustc_mir/util/pretty.rs @@ -177,6 +177,7 @@ fn dump_path( let mut file_path = PathBuf::new(); file_path.push(Path::new(&tcx.sess.opts.debugging_opts.dump_mir_dir)); + let crate_name = tcx.crate_name(source.def_id().krate); let item_name = tcx.def_path(source.def_id()).to_filename_friendly_no_crate(); // All drop shims have the same DefId, so we have to add the type // to get unique file names. @@ -196,8 +197,15 @@ fn dump_path( }; let file_name = format!( - "rustc.{}{}{}{}.{}.{}.{}", - item_name, shim_disambiguator, promotion_id, pass_num, pass_name, disambiguator, extension, + "{}.{}{}{}{}.{}.{}.{}", + crate_name, + item_name, + shim_disambiguator, + promotion_id, + pass_num, + pass_name, + disambiguator, + extension, ); file_path.push(&file_name); @@ -588,7 +596,7 @@ pub fn write_allocations<'tcx>( todo.push(id); } } - write_allocation(tcx, alloc, w) + write!(w, "{}", display_allocation(tcx, alloc)) }; write!(w, "\n{}", id)?; match tcx.get_global_alloc(id) { @@ -640,24 +648,36 @@ pub fn write_allocations<'tcx>( /// After the hex dump, an ascii dump follows, replacing all unprintable characters (control /// characters or characters whose value is larger than 127) with a `.` /// This also prints relocations adequately. -pub fn write_allocation<Tag: Copy + Debug, Extra>( +pub fn display_allocation<Tag: Copy + Debug, Extra>( tcx: TyCtxt<'tcx>, - alloc: &Allocation<Tag, Extra>, - w: &mut dyn Write, -) -> io::Result<()> { - write!(w, "size: {}, align: {})", alloc.size.bytes(), alloc.align.bytes())?; - if alloc.size == Size::ZERO { - // We are done. - return write!(w, " {{}}"); + alloc: &'a Allocation<Tag, Extra>, +) -> RenderAllocation<'a, 'tcx, Tag, Extra> { + RenderAllocation { tcx, alloc } +} + +#[doc(hidden)] +pub struct RenderAllocation<'a, 'tcx, Tag, Extra> { + tcx: TyCtxt<'tcx>, + alloc: &'a Allocation<Tag, Extra>, +} + +impl<Tag: Copy + Debug, Extra> std::fmt::Display for RenderAllocation<'a, 'tcx, Tag, Extra> { + fn fmt(&self, w: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let RenderAllocation { tcx, alloc } = *self; + write!(w, "size: {}, align: {})", alloc.size.bytes(), alloc.align.bytes())?; + if alloc.size == Size::ZERO { + // We are done. + return write!(w, " {{}}"); + } + // Write allocation bytes. + writeln!(w, " {{")?; + write_allocation_bytes(tcx, alloc, w, " ")?; + write!(w, "}}")?; + Ok(()) } - // Write allocation bytes. - writeln!(w, " {{")?; - write_allocation_bytes(tcx, alloc, w, " ")?; - write!(w, "}}")?; - Ok(()) } -fn write_allocation_endline(w: &mut dyn Write, ascii: &str) -> io::Result<()> { +fn write_allocation_endline(w: &mut dyn std::fmt::Write, ascii: &str) -> std::fmt::Result { for _ in 0..(BYTES_PER_LINE - ascii.chars().count()) { write!(w, " ")?; } @@ -669,12 +689,12 @@ const BYTES_PER_LINE: usize = 16; /// Prints the line start address and returns the new line start address. fn write_allocation_newline( - w: &mut dyn Write, + w: &mut dyn std::fmt::Write, mut line_start: Size, ascii: &str, pos_width: usize, prefix: &str, -) -> io::Result<Size> { +) -> Result<Size, std::fmt::Error> { write_allocation_endline(w, ascii)?; line_start += Size::from_bytes(BYTES_PER_LINE); write!(w, "{}0x{:02$x} │ ", prefix, line_start.bytes(), pos_width)?; @@ -687,9 +707,9 @@ fn write_allocation_newline( fn write_allocation_bytes<Tag: Copy + Debug, Extra>( tcx: TyCtxt<'tcx>, alloc: &Allocation<Tag, Extra>, - w: &mut dyn Write, + w: &mut dyn std::fmt::Write, prefix: &str, -) -> io::Result<()> { +) -> std::fmt::Result { let num_lines = alloc.size.bytes_usize().saturating_sub(BYTES_PER_LINE); // Number of chars needed to represent all line numbers. let pos_width = format!("{:x}", alloc.size.bytes()).len(); diff --git a/src/librustc_mir_build/Cargo.toml b/src/librustc_mir_build/Cargo.toml index 401a5009e3c..96059fa43e5 100644 --- a/src/librustc_mir_build/Cargo.toml +++ b/src/librustc_mir_build/Cargo.toml @@ -11,7 +11,7 @@ doctest = false [dependencies] rustc_arena = { path = "../librustc_arena" } -log = "0.4" +log = { package = "tracing", version = "0.1" } rustc_middle = { path = "../librustc_middle" } rustc_apfloat = { path = "../librustc_apfloat" } rustc_attr = { path = "../librustc_attr" } diff --git a/src/librustc_mir_build/build/block.rs b/src/librustc_mir_build/build/block.rs index 2be4136ad42..d1cbf209b06 100644 --- a/src/librustc_mir_build/build/block.rs +++ b/src/librustc_mir_build/build/block.rs @@ -1,7 +1,7 @@ use crate::build::matches::ArmHasGuard; use crate::build::ForGuard::OutsideGuard; use crate::build::{BlockAnd, BlockAndExtension, BlockFrame, Builder}; -use crate::hair::*; +use crate::thir::*; use rustc_hir as hir; use rustc_middle::mir::*; use rustc_session::lint::builtin::UNSAFE_OP_IN_UNSAFE_FN; @@ -176,7 +176,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let tail_result_is_ignored = destination_ty.is_unit() || this.block_context.currently_ignores_tail_results(); let span = match expr { - ExprRef::Hair(expr) => expr.span, + ExprRef::Thir(expr) => expr.span, ExprRef::Mirror(ref expr) => expr.span, }; this.block_context.push(BlockFrame::TailExpr { tail_result_is_ignored, span }); @@ -235,11 +235,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { .push_unsafe_count .checked_sub(1) .unwrap_or_else(|| span_bug!(span, "unsafe count underflow")); - if self.push_unsafe_count == 0 { - Some(self.unpushed_unsafe) - } else { - None - } + if self.push_unsafe_count == 0 { Some(self.unpushed_unsafe) } else { None } } }; diff --git a/src/librustc_mir_build/build/expr/as_constant.rs b/src/librustc_mir_build/build/expr/as_constant.rs index 03ec0b48f8b..982aefcf604 100644 --- a/src/librustc_mir_build/build/expr/as_constant.rs +++ b/src/librustc_mir_build/build/expr/as_constant.rs @@ -1,7 +1,7 @@ //! See docs in build/expr/mod.rs use crate::build::Builder; -use crate::hair::*; +use crate::thir::*; use rustc_middle::mir::*; use rustc_middle::ty::CanonicalUserTypeAnnotation; diff --git a/src/librustc_mir_build/build/expr/as_operand.rs b/src/librustc_mir_build/build/expr/as_operand.rs index 5949fd1e22c..aac93f313f4 100644 --- a/src/librustc_mir_build/build/expr/as_operand.rs +++ b/src/librustc_mir_build/build/expr/as_operand.rs @@ -2,7 +2,7 @@ use crate::build::expr::category::Category; use crate::build::{BlockAnd, BlockAndExtension, Builder}; -use crate::hair::*; +use crate::thir::*; use rustc_middle::middle::region; use rustc_middle::mir::*; diff --git a/src/librustc_mir_build/build/expr/as_place.rs b/src/librustc_mir_build/build/expr/as_place.rs index e811d68d5a5..1e3e104c2ba 100644 --- a/src/librustc_mir_build/build/expr/as_place.rs +++ b/src/librustc_mir_build/build/expr/as_place.rs @@ -3,7 +3,7 @@ use crate::build::expr::category::Category; use crate::build::ForGuard::{OutsideGuard, RefWithinGuard}; use crate::build::{BlockAnd, BlockAndExtension, Builder}; -use crate::hair::*; +use crate::thir::*; use rustc_middle::middle::region; use rustc_middle::mir::AssertKind::BoundsCheck; use rustc_middle::mir::*; diff --git a/src/librustc_mir_build/build/expr/as_rvalue.rs b/src/librustc_mir_build/build/expr/as_rvalue.rs index e2217fdfac0..9c5fddc6b77 100644 --- a/src/librustc_mir_build/build/expr/as_rvalue.rs +++ b/src/librustc_mir_build/build/expr/as_rvalue.rs @@ -4,7 +4,7 @@ use rustc_index::vec::Idx; use crate::build::expr::category::{Category, RvalueFunc}; use crate::build::{BlockAnd, BlockAndExtension, Builder}; -use crate::hair::*; +use crate::thir::*; use rustc_middle::middle::region; use rustc_middle::mir::AssertKind; use rustc_middle::mir::*; diff --git a/src/librustc_mir_build/build/expr/as_temp.rs b/src/librustc_mir_build/build/expr/as_temp.rs index 901dadd6612..a9cc0cc2f24 100644 --- a/src/librustc_mir_build/build/expr/as_temp.rs +++ b/src/librustc_mir_build/build/expr/as_temp.rs @@ -2,7 +2,7 @@ use crate::build::scope::DropKind; use crate::build::{BlockAnd, BlockAndExtension, Builder}; -use crate::hair::*; +use crate::thir::*; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_hir as hir; use rustc_middle::middle::region; @@ -67,12 +67,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { ExprKind::StaticRef { def_id, .. } => { assert!(!this.hir.tcx().is_thread_local_static(def_id)); local_decl.internal = true; - local_decl.local_info = Some(box LocalInfo::StaticRef { def_id, is_thread_local: false }); + local_decl.local_info = + Some(box LocalInfo::StaticRef { def_id, is_thread_local: false }); } ExprKind::ThreadLocalRef(def_id) => { assert!(this.hir.tcx().is_thread_local_static(def_id)); local_decl.internal = true; - local_decl.local_info = Some(box LocalInfo::StaticRef { def_id, is_thread_local: true }); + local_decl.local_info = + Some(box LocalInfo::StaticRef { def_id, is_thread_local: true }); } _ => {} } diff --git a/src/librustc_mir_build/build/expr/category.rs b/src/librustc_mir_build/build/expr/category.rs index fb4b7997b6a..9cabd186d84 100644 --- a/src/librustc_mir_build/build/expr/category.rs +++ b/src/librustc_mir_build/build/expr/category.rs @@ -1,4 +1,4 @@ -use crate::hair::*; +use crate::thir::*; #[derive(Debug, PartialEq)] crate enum Category { diff --git a/src/librustc_mir_build/build/expr/into.rs b/src/librustc_mir_build/build/expr/into.rs index 36f8034336b..c3f54b39a3f 100644 --- a/src/librustc_mir_build/build/expr/into.rs +++ b/src/librustc_mir_build/build/expr/into.rs @@ -2,7 +2,7 @@ use crate::build::expr::category::{Category, RvalueFunc}; use crate::build::{BlockAnd, BlockAndExtension, BlockFrame, Builder}; -use crate::hair::*; +use crate::thir::*; use rustc_ast::ast::InlineAsmOptions; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::stack::ensure_sufficient_stack; @@ -320,23 +320,23 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { block.unit() } ExprKind::InlineAsm { template, operands, options, line_spans } => { - use crate::hair; + use crate::thir; use rustc_middle::mir; let operands = operands .into_iter() .map(|op| match op { - hair::InlineAsmOperand::In { reg, expr } => mir::InlineAsmOperand::In { + thir::InlineAsmOperand::In { reg, expr } => mir::InlineAsmOperand::In { reg, value: unpack!(block = this.as_local_operand(block, expr)), }, - hair::InlineAsmOperand::Out { reg, late, expr } => { + thir::InlineAsmOperand::Out { reg, late, expr } => { mir::InlineAsmOperand::Out { reg, late, place: expr.map(|expr| unpack!(block = this.as_place(block, expr))), } } - hair::InlineAsmOperand::InOut { reg, late, expr } => { + thir::InlineAsmOperand::InOut { reg, late, expr } => { let place = unpack!(block = this.as_place(block, expr)); mir::InlineAsmOperand::InOut { reg, @@ -346,7 +346,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { out_place: Some(place), } } - hair::InlineAsmOperand::SplitInOut { reg, late, in_expr, out_expr } => { + thir::InlineAsmOperand::SplitInOut { reg, late, in_expr, out_expr } => { mir::InlineAsmOperand::InOut { reg, late, @@ -356,13 +356,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { }), } } - hair::InlineAsmOperand::Const { expr } => mir::InlineAsmOperand::Const { + thir::InlineAsmOperand::Const { expr } => mir::InlineAsmOperand::Const { value: unpack!(block = this.as_local_operand(block, expr)), }, - hair::InlineAsmOperand::SymFn { expr } => { + thir::InlineAsmOperand::SymFn { expr } => { mir::InlineAsmOperand::SymFn { value: box this.as_constant(expr) } } - hair::InlineAsmOperand::SymStatic { def_id } => { + thir::InlineAsmOperand::SymStatic { def_id } => { mir::InlineAsmOperand::SymStatic { def_id } } }) diff --git a/src/librustc_mir_build/build/expr/stmt.rs b/src/librustc_mir_build/build/expr/stmt.rs index 49d6ce39ddf..f117689d940 100644 --- a/src/librustc_mir_build/build/expr/stmt.rs +++ b/src/librustc_mir_build/build/expr/stmt.rs @@ -1,11 +1,11 @@ use crate::build::scope::BreakableTarget; use crate::build::{BlockAnd, BlockAndExtension, BlockFrame, Builder}; -use crate::hair::*; +use crate::thir::*; use rustc_middle::middle::region; use rustc_middle::mir::*; impl<'a, 'tcx> Builder<'a, 'tcx> { - /// Builds a block of MIR statements to evaluate the HAIR `expr`. + /// Builds a block of MIR statements to evaluate the THIR `expr`. /// If the original expression was an AST statement, /// (e.g., `some().code(&here());`) then `opt_stmt_span` is the /// span of that statement (including its semicolon, if any). @@ -150,8 +150,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { break; } } - this.block_context - .push(BlockFrame::TailExpr { tail_result_is_ignored: true, span: expr.span }); + this.block_context.push(BlockFrame::TailExpr { + tail_result_is_ignored: true, + span: expr.span, + }); return Some(expr.span); } } diff --git a/src/librustc_mir_build/build/into.rs b/src/librustc_mir_build/build/into.rs index 0baa0c833a5..7264e495b84 100644 --- a/src/librustc_mir_build/build/into.rs +++ b/src/librustc_mir_build/build/into.rs @@ -5,7 +5,7 @@ //! latter `EvalInto` trait. use crate::build::{BlockAnd, Builder}; -use crate::hair::*; +use crate::thir::*; use rustc_middle::mir::*; pub(in crate::build) trait EvalInto<'tcx> { diff --git a/src/librustc_mir_build/build/matches/mod.rs b/src/librustc_mir_build/build/matches/mod.rs index 19948196f25..77c0fe8dda5 100644 --- a/src/librustc_mir_build/build/matches/mod.rs +++ b/src/librustc_mir_build/build/matches/mod.rs @@ -9,15 +9,18 @@ use crate::build::scope::DropKind; use crate::build::ForGuard::{self, OutsideGuard, RefWithinGuard}; use crate::build::{BlockAnd, BlockAndExtension, Builder}; use crate::build::{GuardFrame, GuardFrameLocal, LocalsForNode}; -use crate::hair::{self, *}; -use rustc_data_structures::{fx::{FxHashMap, FxHashSet}, stack::ensure_sufficient_stack}; +use crate::thir::{self, *}; +use rustc_data_structures::{ + fx::{FxHashMap, FxHashSet}, + stack::ensure_sufficient_stack, +}; use rustc_hir::HirId; use rustc_index::bit_set::BitSet; use rustc_middle::middle::region; use rustc_middle::mir::*; use rustc_middle::ty::{self, CanonicalUserTypeAnnotation, Ty}; -use rustc_span::Span; use rustc_span::symbol::Symbol; +use rustc_span::Span; use rustc_target::abi::VariantIdx; use smallvec::{smallvec, SmallVec}; @@ -395,7 +398,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { .. }, ascription: - hair::pattern::Ascription { user_ty: pat_ascription_ty, variance: _, user_ty_span }, + thir::pattern::Ascription { user_ty: pat_ascription_ty, variance: _, user_ty_span }, } => { let place = self.storage_live_binding(block, var, irrefutable_pat.span, OutsideGuard, true); @@ -631,7 +634,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { PatKind::AscribeUserType { ref subpattern, - ascription: hair::pattern::Ascription { ref user_ty, user_ty_span, variance: _ }, + ascription: thir::pattern::Ascription { ref user_ty, user_ty_span, variance: _ }, } => { // This corresponds to something like // @@ -1982,16 +1985,18 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { source_info, internal: false, is_block_tail: None, - local_info: Some(box LocalInfo::User(ClearCrossCrate::Set(BindingForm::Var(VarBindingForm { - binding_mode, - // hypothetically, `visit_primary_bindings` could try to unzip - // an outermost hir::Ty as we descend, matching up - // idents in pat; but complex w/ unclear UI payoff. - // Instead, just abandon providing diagnostic info. - opt_ty_info: None, - opt_match_place, - pat_span, - })))), + local_info: Some(box LocalInfo::User(ClearCrossCrate::Set(BindingForm::Var( + VarBindingForm { + binding_mode, + // hypothetically, `visit_primary_bindings` could try to unzip + // an outermost hir::Ty as we descend, matching up + // idents in pat; but complex w/ unclear UI payoff. + // Instead, just abandon providing diagnostic info. + opt_ty_info: None, + opt_match_place, + pat_span, + }, + )))), }; let for_arm_body = self.local_decls.push(local); self.var_debug_info.push(VarDebugInfo { @@ -2009,7 +2014,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { source_info, internal: false, is_block_tail: None, - local_info: Some(box LocalInfo::User(ClearCrossCrate::Set(BindingForm::RefForGuard))), + local_info: Some(box LocalInfo::User(ClearCrossCrate::Set( + BindingForm::RefForGuard, + ))), }); self.var_debug_info.push(VarDebugInfo { name, diff --git a/src/librustc_mir_build/build/matches/simplify.rs b/src/librustc_mir_build/build/matches/simplify.rs index 2917a771a2c..e584aeb9226 100644 --- a/src/librustc_mir_build/build/matches/simplify.rs +++ b/src/librustc_mir_build/build/matches/simplify.rs @@ -14,7 +14,7 @@ use crate::build::matches::{Ascription, Binding, Candidate, MatchPair}; use crate::build::Builder; -use crate::hair::{self, *}; +use crate::thir::{self, *}; use rustc_attr::{SignedInt, UnsignedInt}; use rustc_hir::RangeEnd; use rustc_middle::mir::interpret::truncate; @@ -108,7 +108,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { match *match_pair.pattern.kind { PatKind::AscribeUserType { ref subpattern, - ascription: hair::pattern::Ascription { variance, user_ty, user_ty_span }, + ascription: thir::pattern::Ascription { variance, user_ty, user_ty_span }, } => { // Apply the type ascription to the value at `match_pair.place`, which is the // value being matched, taking the variance field into account. diff --git a/src/librustc_mir_build/build/matches/test.rs b/src/librustc_mir_build/build/matches/test.rs index 3e7bfc7d59b..158ad78a1bf 100644 --- a/src/librustc_mir_build/build/matches/test.rs +++ b/src/librustc_mir_build/build/matches/test.rs @@ -7,8 +7,8 @@ use crate::build::matches::{Candidate, MatchPair, Test, TestKind}; use crate::build::Builder; -use crate::hair::pattern::compare_const_vals; -use crate::hair::*; +use crate::thir::pattern::compare_const_vals; +use crate::thir::*; use rustc_data_structures::fx::FxHashMap; use rustc_hir::RangeEnd; use rustc_index::bit_set::BitSet; @@ -443,7 +443,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { destination: Some((eq_result, eq_block)), cleanup: Some(cleanup), from_hir_call: false, - fn_span: source_info.span + fn_span: source_info.span, }, ); diff --git a/src/librustc_mir_build/build/matches/util.rs b/src/librustc_mir_build/build/matches/util.rs index 7d89a93129b..605396c5eb6 100644 --- a/src/librustc_mir_build/build/matches/util.rs +++ b/src/librustc_mir_build/build/matches/util.rs @@ -1,6 +1,6 @@ use crate::build::matches::MatchPair; use crate::build::Builder; -use crate::hair::*; +use crate::thir::*; use rustc_middle::mir::*; use rustc_middle::ty; use smallvec::SmallVec; diff --git a/src/librustc_mir_build/build/mod.rs b/src/librustc_mir_build/build/mod.rs index 1e677f3d2ab..3c4587119cd 100644 --- a/src/librustc_mir_build/build/mod.rs +++ b/src/librustc_mir_build/build/mod.rs @@ -1,7 +1,7 @@ use crate::build; use crate::build::scope::DropKind; -use crate::hair::cx::Cx; -use crate::hair::{BindingMode, LintLevel, PatKind}; +use crate::thir::cx::Cx; +use crate::thir::{BindingMode, LintLevel, PatKind}; use rustc_attr::{self as attr, UnwindAttr}; use rustc_errors::ErrorReported; use rustc_hir as hir; @@ -10,6 +10,7 @@ use rustc_hir::lang_items; use rustc_hir::{GeneratorKind, HirIdMap, Node}; use rustc_index::vec::{Idx, IndexVec}; use rustc_infer::infer::TyCtxtInferExt; +use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::middle::region; use rustc_middle::mir::*; use rustc_middle::ty::subst::Subst; @@ -293,7 +294,7 @@ struct Builder<'a, 'tcx> { /// see the `scope` module for more details. scopes: scope::Scopes<'tcx>, - /// The block-context: each time we build the code within an hair::Block, + /// The block-context: each time we build the code within an thir::Block, /// we push a frame here tracking whether we are building a statement or /// if we are pushing the tail expression of the block. This is used to /// embed information in generated temps about whether they were created @@ -797,12 +798,22 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { argument_scope: region::Scope, ast_body: &'tcx hir::Expr<'tcx>, ) -> BlockAnd<()> { + let tcx = self.hir.tcx(); + let attrs = tcx.codegen_fn_attrs(fn_def_id); + let naked = attrs.flags.contains(CodegenFnAttrFlags::NAKED); + // Allocate locals for the function arguments for &ArgInfo(ty, _, arg_opt, _) in arguments.iter() { let source_info = SourceInfo::outermost(arg_opt.map_or(self.fn_span, |arg| arg.pat.span)); let arg_local = self.local_decls.push(LocalDecl::with_source_info(ty, source_info)); + // Emit function argument debuginfo only for non-naked functions. + // See: https://github.com/rust-lang/rust/issues/42779 + if naked { + continue; + } + // If this is a simple binding pattern, give debuginfo a nice name. if let Some(arg) = arg_opt { if let Some(ident) = arg.pat.simple_ident() { @@ -815,7 +826,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } } - let tcx = self.hir.tcx(); let tcx_hir = tcx.hir(); let hir_typeck_results = self.hir.typeck_results(); diff --git a/src/librustc_mir_build/build/scope.rs b/src/librustc_mir_build/build/scope.rs index b8df2709447..2a03bb78c6b 100644 --- a/src/librustc_mir_build/build/scope.rs +++ b/src/librustc_mir_build/build/scope.rs @@ -1,6 +1,6 @@ /*! Managing the scope stack. The scopes are tied to lexical scopes, so as -we descend the HAIR, we push a scope on the stack, build its +we descend the THIR, we push a scope on the stack, build its contents, and then pop it off. Every scope is named by a `region::Scope`. @@ -83,12 +83,12 @@ should go to. */ use crate::build::{BlockAnd, BlockAndExtension, BlockFrame, Builder, CFG}; -use crate::hair::{Expr, ExprRef, LintLevel}; -use rustc_middle::middle::region; -use rustc_middle::mir::*; +use crate::thir::{Expr, ExprRef, LintLevel}; use rustc_data_structures::fx::FxHashMap; use rustc_hir as hir; use rustc_hir::GeneratorKind; +use rustc_middle::middle::region; +use rustc_middle::mir::*; use rustc_span::{Span, DUMMY_SP}; use std::collections::hash_map::Entry; use std::mem; diff --git a/src/librustc_mir_build/lib.rs b/src/librustc_mir_build/lib.rs index ed154b9dc6f..30545558933 100644 --- a/src/librustc_mir_build/lib.rs +++ b/src/librustc_mir_build/lib.rs @@ -17,13 +17,13 @@ extern crate log; extern crate rustc_middle; mod build; -mod hair; mod lints; +mod thir; use rustc_middle::ty::query::Providers; pub fn provide(providers: &mut Providers) { - providers.check_match = hair::pattern::check_match; - providers.lit_to_const = hair::constant::lit_to_const; + providers.check_match = thir::pattern::check_match; + providers.lit_to_const = thir::constant::lit_to_const; providers.mir_built = build::mir_built; } diff --git a/src/librustc_mir_build/hair/constant.rs b/src/librustc_mir_build/thir/constant.rs index e5af0b5bd6b..e5af0b5bd6b 100644 --- a/src/librustc_mir_build/hair/constant.rs +++ b/src/librustc_mir_build/thir/constant.rs diff --git a/src/librustc_mir_build/hair/cx/block.rs b/src/librustc_mir_build/thir/cx/block.rs index a5381781d1d..980888df7fe 100644 --- a/src/librustc_mir_build/hair/cx/block.rs +++ b/src/librustc_mir_build/thir/cx/block.rs @@ -1,6 +1,6 @@ -use crate::hair::cx::to_ref::ToRef; -use crate::hair::cx::Cx; -use crate::hair::{self, *}; +use crate::thir::cx::to_ref::ToRef; +use crate::thir::cx::Cx; +use crate::thir::{self, *}; use rustc_hir as hir; use rustc_middle::middle::region; @@ -71,7 +71,7 @@ fn mirror_stmts<'a, 'tcx>( ty: pattern.ty, span: pattern.span, kind: Box::new(PatKind::AscribeUserType { - ascription: hair::pattern::Ascription { + ascription: thir::pattern::Ascription { user_ty: PatTyProj::from_user_type(user_ty), user_ty_span: ty.span, variance: ty::Variance::Covariant, diff --git a/src/librustc_mir_build/hair/cx/expr.rs b/src/librustc_mir_build/thir/cx/expr.rs index 6e1d8a8fc40..ea41a66b3e4 100644 --- a/src/librustc_mir_build/hair/cx/expr.rs +++ b/src/librustc_mir_build/thir/cx/expr.rs @@ -1,8 +1,8 @@ -use crate::hair::cx::block; -use crate::hair::cx::to_ref::ToRef; -use crate::hair::cx::Cx; -use crate::hair::util::UserAnnotatedTyHelpers; -use crate::hair::*; +use crate::thir::cx::block; +use crate::thir::cx::to_ref::ToRef; +use crate::thir::cx::Cx; +use crate::thir::util::UserAnnotatedTyHelpers; +use crate::thir::*; use rustc_hir as hir; use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res}; use rustc_index::vec::Idx; @@ -1020,7 +1020,7 @@ fn overloaded_place<'a, 'tcx>( // line up (this is because `*x` and `x[y]` represent places): let recv_ty = match args[0] { - ExprRef::Hair(e) => cx.typeck_results().expr_ty_adjusted(e), + ExprRef::Thir(e) => cx.typeck_results().expr_ty_adjusted(e), ExprRef::Mirror(ref e) => e.ty, }; diff --git a/src/librustc_mir_build/hair/cx/mod.rs b/src/librustc_mir_build/thir/cx/mod.rs index 2694cde14fd..21736df7b07 100644 --- a/src/librustc_mir_build/hair/cx/mod.rs +++ b/src/librustc_mir_build/thir/cx/mod.rs @@ -1,9 +1,9 @@ //! This module contains the functionality to convert from the wacky tcx data -//! structures into the HAIR. The `builder` is generally ignorant of the tcx, +//! structures into the THIR. The `builder` is generally ignorant of the tcx, //! etc., and instead goes through the `Cx` for most of its work. -use crate::hair::util::UserAnnotatedTyHelpers; -use crate::hair::*; +use crate::thir::util::UserAnnotatedTyHelpers; +use crate::thir::*; use rustc_ast::ast; use rustc_ast::attr; diff --git a/src/librustc_mir_build/hair/cx/to_ref.rs b/src/librustc_mir_build/thir/cx/to_ref.rs index 6cf8122e200..53a988ebb79 100644 --- a/src/librustc_mir_build/hair/cx/to_ref.rs +++ b/src/librustc_mir_build/thir/cx/to_ref.rs @@ -1,4 +1,4 @@ -use crate::hair::*; +use crate::thir::*; use rustc_hir as hir; @@ -11,7 +11,7 @@ impl<'tcx> ToRef for &'tcx hir::Expr<'tcx> { type Output = ExprRef<'tcx>; fn to_ref(self) -> ExprRef<'tcx> { - ExprRef::Hair(self) + ExprRef::Thir(self) } } @@ -19,7 +19,7 @@ impl<'tcx> ToRef for &'tcx &'tcx hir::Expr<'tcx> { type Output = ExprRef<'tcx>; fn to_ref(self) -> ExprRef<'tcx> { - ExprRef::Hair(&**self) + ExprRef::Thir(&**self) } } diff --git a/src/librustc_mir_build/hair/mod.rs b/src/librustc_mir_build/thir/mod.rs index ccff510f2d4..b6ce7e0b41e 100644 --- a/src/librustc_mir_build/hair/mod.rs +++ b/src/librustc_mir_build/thir/mod.rs @@ -1,5 +1,5 @@ -//! The MIR is built from some high-level abstract IR -//! (HAIR). This section defines the HAIR along with a trait for +//! The MIR is built from some typed high-level IR +//! (THIR). This section defines the THIR along with a trait for //! accessing it. The intention is to allow MIR construction to be //! unit-tested and separated from the Rust source and compiler data //! structures. @@ -99,18 +99,18 @@ crate enum StmtKind<'tcx> { #[cfg(target_arch = "x86_64")] rustc_data_structures::static_assert_size!(Expr<'_>, 168); -/// The Hair trait implementor lowers their expressions (`&'tcx H::Expr`) +/// The Thir trait implementor lowers their expressions (`&'tcx H::Expr`) /// into instances of this `Expr` enum. This lowering can be done /// basically as lazily or as eagerly as desired: every recursive /// reference to an expression in this enum is an `ExprRef<'tcx>`, which /// may in turn be another instance of this enum (boxed), or else an /// unlowered `&'tcx H::Expr`. Note that instances of `Expr` are very -/// short-lived. They are created by `Hair::to_expr`, analyzed and +/// short-lived. They are created by `Thir::to_expr`, analyzed and /// converted into MIR, and then discarded. /// /// If you compare `Expr` to the full compiler AST, you will see it is /// a good bit simpler. In fact, a number of the more straight-forward -/// MIR simplifications are already done in the impl of `Hair`. For +/// MIR simplifications are already done in the impl of `Thir`. For /// example, method calls and overloaded operators are absent: they are /// expected to be converted into `Expr::Call` instances. #[derive(Clone, Debug)] @@ -302,7 +302,7 @@ crate enum ExprKind<'tcx> { #[derive(Clone, Debug)] crate enum ExprRef<'tcx> { - Hair(&'tcx hir::Expr<'tcx>), + Thir(&'tcx hir::Expr<'tcx>), Mirror(Box<Expr<'tcx>>), } @@ -342,7 +342,7 @@ crate enum LogicalOp { impl<'tcx> ExprRef<'tcx> { crate fn span(&self) -> Span { match self { - ExprRef::Hair(expr) => expr.span, + ExprRef::Thir(expr) => expr.span, ExprRef::Mirror(expr) => expr.span, } } @@ -385,7 +385,7 @@ crate enum InlineAsmOperand<'tcx> { // The Mirror trait /// "Mirroring" is the process of converting from a HIR type into one -/// of the HAIR types defined in this file. This is basically a "on +/// of the THIR types defined in this file. This is basically a "on /// the fly" desugaring step that hides a lot of the messiness in the /// tcx. For example, the mirror of a `&'tcx hir::Expr` is an /// `Expr<'tcx>`. @@ -394,7 +394,7 @@ crate enum InlineAsmOperand<'tcx> { /// + e2`, the references to the inner expressions `e1` and `e2` are /// `ExprRef<'tcx>` instances, and they may or may not be eagerly /// mirrored. This allows a single AST node from the compiler to -/// expand into one or more Hair nodes, which lets the Hair nodes be +/// expand into one or more Thir nodes, which lets the Thir nodes be /// simpler. crate trait Mirror<'tcx> { type Output; @@ -415,7 +415,7 @@ impl<'tcx> Mirror<'tcx> for ExprRef<'tcx> { fn make_mirror(self, hir: &mut Cx<'_, 'tcx>) -> Expr<'tcx> { match self { - ExprRef::Hair(h) => h.make_mirror(hir), + ExprRef::Thir(h) => h.make_mirror(hir), ExprRef::Mirror(m) => *m, } } diff --git a/src/librustc_mir_build/hair/pattern/_match.rs b/src/librustc_mir_build/thir/pattern/_match.rs index 3202f7d1b1b..3202f7d1b1b 100644 --- a/src/librustc_mir_build/hair/pattern/_match.rs +++ b/src/librustc_mir_build/thir/pattern/_match.rs diff --git a/src/librustc_mir_build/hair/pattern/check_match.rs b/src/librustc_mir_build/thir/pattern/check_match.rs index 744f319205f..744f319205f 100644 --- a/src/librustc_mir_build/hair/pattern/check_match.rs +++ b/src/librustc_mir_build/thir/pattern/check_match.rs diff --git a/src/librustc_mir_build/hair/pattern/const_to_pat.rs b/src/librustc_mir_build/thir/pattern/const_to_pat.rs index 6dd7e0871b4..6dd7e0871b4 100644 --- a/src/librustc_mir_build/hair/pattern/const_to_pat.rs +++ b/src/librustc_mir_build/thir/pattern/const_to_pat.rs diff --git a/src/librustc_mir_build/hair/pattern/mod.rs b/src/librustc_mir_build/thir/pattern/mod.rs index a5c87bc963f..daff10eb194 100644 --- a/src/librustc_mir_build/hair/pattern/mod.rs +++ b/src/librustc_mir_build/thir/pattern/mod.rs @@ -6,7 +6,7 @@ mod const_to_pat; pub(crate) use self::check_match::check_match; -use crate::hair::util::UserAnnotatedTyHelpers; +use crate::thir::util::UserAnnotatedTyHelpers; use rustc_ast::ast; use rustc_errors::struct_span_err; @@ -16,7 +16,7 @@ use rustc_hir::pat_util::EnumerateAndAdjustIterator; use rustc_hir::RangeEnd; use rustc_index::vec::Idx; use rustc_middle::mir::interpret::{get_slice_bytes, sign_extend, ConstValue}; -use rustc_middle::mir::interpret::{LitToConstError, LitToConstInput}; +use rustc_middle::mir::interpret::{ErrorHandled, LitToConstError, LitToConstInput}; use rustc_middle::mir::UserTypeProjection; use rustc_middle::mir::{BorrowKind, Field, Mutability}; use rustc_middle::ty::subst::{GenericArg, SubstsRef}; @@ -133,7 +133,7 @@ crate enum PatKind<'tcx> { var: hir::HirId, ty: Ty<'tcx>, subpattern: Option<Pat<'tcx>>, - /// Is this the leftmost occurance of the binding, i.e., is `var` the + /// Is this the leftmost occurrence of the binding, i.e., is `var` the /// `HirId` of this pattern? is_primary: bool, }, @@ -402,7 +402,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { // // `vec![&&Option<i32>, &Option<i32>]`. // - // Applying the adjustments, we want to instead output `&&Some(n)` (as a HAIR pattern). So + // Applying the adjustments, we want to instead output `&&Some(n)` (as a THIR pattern). So // we wrap the unadjusted pattern in `PatKind::Deref` repeatedly, consuming the // adjustments in *reverse order* (last-in-first-out, so that the last `Deref` inserted // gets the least-dereferenced type). @@ -776,7 +776,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { // Use `Reveal::All` here because patterns are always monomorphic even if their function // isn't. - let param_env_reveal_all = self.param_env.with_reveal_all(); + let param_env_reveal_all = self.param_env.with_reveal_all_normalized(self.tcx); let substs = self.typeck_results.node_substs(id); let instance = match ty::Instance::resolve(self.tcx, param_env_reveal_all, def_id, substs) { Ok(Some(i)) => i, @@ -834,6 +834,12 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { pattern } } + Err(ErrorHandled::TooGeneric) => { + // While `Reported | Linted` cases will have diagnostics emitted already + // it is not true for TooGeneric case, so we need to give user more information. + self.tcx.sess.span_err(span, "constant pattern depends on a generic parameter"); + pat_from_kind(PatKind::Wild) + } Err(_) => { self.tcx.sess.span_err(span, "could not evaluate constant pattern"); pat_from_kind(PatKind::Wild) diff --git a/src/librustc_mir_build/hair/util.rs b/src/librustc_mir_build/thir/util.rs index 7de60ddda41..7de60ddda41 100644 --- a/src/librustc_mir_build/hair/util.rs +++ b/src/librustc_mir_build/thir/util.rs diff --git a/src/librustc_parse/Cargo.toml b/src/librustc_parse/Cargo.toml index 7164c678808..25144bd610d 100644 --- a/src/librustc_parse/Cargo.toml +++ b/src/librustc_parse/Cargo.toml @@ -11,7 +11,7 @@ doctest = false [dependencies] bitflags = "1.0" -log = "0.4" +log = { package = "tracing", version = "0.1" } rustc_ast_pretty = { path = "../librustc_ast_pretty" } rustc_data_structures = { path = "../librustc_data_structures" } rustc_feature = { path = "../librustc_feature" } @@ -21,3 +21,4 @@ rustc_session = { path = "../librustc_session" } rustc_span = { path = "../librustc_span" } rustc_ast = { path = "../librustc_ast" } unicode-normalization = "0.1.11" +smallvec = { version = "1.0", features = ["union", "may_dangle"] } diff --git a/src/librustc_parse/lib.rs b/src/librustc_parse/lib.rs index be86b4b7c77..3319ca44da4 100644 --- a/src/librustc_parse/lib.rs +++ b/src/librustc_parse/lib.rs @@ -7,14 +7,16 @@ #![feature(or_patterns)] use rustc_ast::ast; -use rustc_ast::token::{self, Nonterminal}; +use rustc_ast::token::{self, DelimToken, Nonterminal, Token}; use rustc_ast::tokenstream::{self, TokenStream, TokenTree}; use rustc_ast_pretty::pprust; use rustc_data_structures::sync::Lrc; use rustc_errors::{Diagnostic, FatalError, Level, PResult}; use rustc_session::parse::ParseSess; -use rustc_span::{FileName, SourceFile, Span}; +use rustc_span::{symbol::kw, FileName, SourceFile, Span, DUMMY_SP}; +use smallvec::SmallVec; +use std::mem; use std::path::Path; use std::str; @@ -306,7 +308,7 @@ pub fn nt_to_tokenstream(nt: &Nonterminal, sess: &ParseSess, span: Span) -> Toke // modifications, including adding/removing typically non-semantic // tokens such as extra braces and commas, don't happen. if let Some(tokens) = tokens { - if tokens.probably_equal_for_proc_macro(&tokens_for_real) { + if tokenstream_probably_equal_for_proc_macro(&tokens, &tokens_for_real) { return tokens; } info!( @@ -319,6 +321,186 @@ pub fn nt_to_tokenstream(nt: &Nonterminal, sess: &ParseSess, span: Span) -> Toke tokens_for_real } +// See comments in `Nonterminal::to_tokenstream` for why we care about +// *probably* equal here rather than actual equality +// +// This is otherwise the same as `eq_unspanned`, only recursing with a +// different method. +pub fn tokenstream_probably_equal_for_proc_macro(first: &TokenStream, other: &TokenStream) -> bool { + // When checking for `probably_eq`, we ignore certain tokens that aren't + // preserved in the AST. Because they are not preserved, the pretty + // printer arbitrarily adds or removes them when printing as token + // streams, making a comparison between a token stream generated from an + // AST and a token stream which was parsed into an AST more reliable. + fn semantic_tree(tree: &TokenTree) -> bool { + if let TokenTree::Token(token) = tree { + if let + // The pretty printer tends to add trailing commas to + // everything, and in particular, after struct fields. + | token::Comma + // The pretty printer emits `NoDelim` as whitespace. + | token::OpenDelim(DelimToken::NoDelim) + | token::CloseDelim(DelimToken::NoDelim) + // The pretty printer collapses many semicolons into one. + | token::Semi + // The pretty printer collapses whitespace arbitrarily and can + // introduce whitespace from `NoDelim`. + | token::Whitespace + // The pretty printer can turn `$crate` into `::crate_name` + | token::ModSep = token.kind { + return false; + } + } + true + } + + // When comparing two `TokenStream`s, we ignore the `IsJoint` information. + // + // However, `rustc_parse::lexer::tokentrees::TokenStreamBuilder` will + // use `Token.glue` on adjacent tokens with the proper `IsJoint`. + // Since we are ignoreing `IsJoint`, a 'glued' token (e.g. `BinOp(Shr)`) + // and its 'split'/'unglued' compoenents (e.g. `Gt, Gt`) are equivalent + // when determining if two `TokenStream`s are 'probably equal'. + // + // Therefore, we use `break_two_token_op` to convert all tokens + // to the 'unglued' form (if it exists). This ensures that two + // `TokenStream`s which differ only in how their tokens are glued + // will be considered 'probably equal', which allows us to keep spans. + // + // This is important when the original `TokenStream` contained + // extra spaces (e.g. `f :: < Vec < _ > > ( ) ;'). These extra spaces + // will be omitted when we pretty-print, which can cause the original + // and reparsed `TokenStream`s to differ in the assignment of `IsJoint`, + // leading to some tokens being 'glued' together in one stream but not + // the other. See #68489 for more details. + fn break_tokens(tree: TokenTree) -> impl Iterator<Item = TokenTree> { + // In almost all cases, we should have either zero or one levels + // of 'unglueing'. However, in some unusual cases, we may need + // to iterate breaking tokens mutliple times. For example: + // '[BinOpEq(Shr)] => [Gt, Ge] -> [Gt, Gt, Eq]' + let mut token_trees: SmallVec<[_; 2]>; + if let TokenTree::Token(token) = &tree { + let mut out = SmallVec::<[_; 2]>::new(); + out.push(token.clone()); + // Iterate to fixpoint: + // * We start off with 'out' containing our initial token, and `temp` empty + // * If we are able to break any tokens in `out`, then `out` will have + // at least one more element than 'temp', so we will try to break tokens + // again. + // * If we cannot break any tokens in 'out', we are done + loop { + let mut temp = SmallVec::<[_; 2]>::new(); + let mut changed = false; + + for token in out.into_iter() { + if let Some((first, second)) = token.kind.break_two_token_op() { + temp.push(Token::new(first, DUMMY_SP)); + temp.push(Token::new(second, DUMMY_SP)); + changed = true; + } else { + temp.push(token); + } + } + out = temp; + if !changed { + break; + } + } + token_trees = out.into_iter().map(TokenTree::Token).collect(); + if token_trees.len() != 1 { + debug!("break_tokens: broke {:?} to {:?}", tree, token_trees); + } + } else { + token_trees = SmallVec::new(); + token_trees.push(tree); + } + token_trees.into_iter() + } + + let mut t1 = first.trees().filter(semantic_tree).flat_map(break_tokens); + let mut t2 = other.trees().filter(semantic_tree).flat_map(break_tokens); + for (t1, t2) in t1.by_ref().zip(t2.by_ref()) { + if !tokentree_probably_equal_for_proc_macro(&t1, &t2) { + return false; + } + } + t1.next().is_none() && t2.next().is_none() +} + +// See comments in `Nonterminal::to_tokenstream` for why we care about +// *probably* equal here rather than actual equality +// +// This is otherwise the same as `eq_unspanned`, only recursing with a +// different method. +fn tokentree_probably_equal_for_proc_macro(first: &TokenTree, other: &TokenTree) -> bool { + match (first, other) { + (TokenTree::Token(token), TokenTree::Token(token2)) => { + token_probably_equal_for_proc_macro(token, token2) + } + (TokenTree::Delimited(_, delim, tts), TokenTree::Delimited(_, delim2, tts2)) => { + delim == delim2 && tokenstream_probably_equal_for_proc_macro(&tts, &tts2) + } + _ => false, + } +} + +// See comments in `Nonterminal::to_tokenstream` for why we care about +// *probably* equal here rather than actual equality +fn token_probably_equal_for_proc_macro(first: &Token, other: &Token) -> bool { + if mem::discriminant(&first.kind) != mem::discriminant(&other.kind) { + return false; + } + use rustc_ast::token::TokenKind::*; + match (&first.kind, &other.kind) { + (&Eq, &Eq) + | (&Lt, &Lt) + | (&Le, &Le) + | (&EqEq, &EqEq) + | (&Ne, &Ne) + | (&Ge, &Ge) + | (&Gt, &Gt) + | (&AndAnd, &AndAnd) + | (&OrOr, &OrOr) + | (&Not, &Not) + | (&Tilde, &Tilde) + | (&At, &At) + | (&Dot, &Dot) + | (&DotDot, &DotDot) + | (&DotDotDot, &DotDotDot) + | (&DotDotEq, &DotDotEq) + | (&Comma, &Comma) + | (&Semi, &Semi) + | (&Colon, &Colon) + | (&ModSep, &ModSep) + | (&RArrow, &RArrow) + | (&LArrow, &LArrow) + | (&FatArrow, &FatArrow) + | (&Pound, &Pound) + | (&Dollar, &Dollar) + | (&Question, &Question) + | (&Whitespace, &Whitespace) + | (&Comment, &Comment) + | (&Eof, &Eof) => true, + + (&BinOp(a), &BinOp(b)) | (&BinOpEq(a), &BinOpEq(b)) => a == b, + + (&OpenDelim(a), &OpenDelim(b)) | (&CloseDelim(a), &CloseDelim(b)) => a == b, + + (&DocComment(a), &DocComment(b)) | (&Shebang(a), &Shebang(b)) => a == b, + + (&Literal(a), &Literal(b)) => a == b, + + (&Lifetime(a), &Lifetime(b)) => a == b, + (&Ident(a, b), &Ident(c, d)) => { + b == d && (a == c || a == kw::DollarCrate || c == kw::DollarCrate) + } + + (&Interpolated(..), &Interpolated(..)) => false, + + _ => panic!("forgot to add a token?"), + } +} + fn prepend_attrs( sess: &ParseSess, attrs: &[ast::Attribute], diff --git a/src/librustc_parse/parser/diagnostics.rs b/src/librustc_parse/parser/diagnostics.rs index 609a0c961e9..5e9411327ca 100644 --- a/src/librustc_parse/parser/diagnostics.rs +++ b/src/librustc_parse/parser/diagnostics.rs @@ -333,6 +333,7 @@ impl<'a> Parser<'a> { Applicability::MachineApplicable }, ); + self.sess.type_ascription_path_suggestions.borrow_mut().insert(sp); } else if op_pos.line != next_pos.line && maybe_expected_semicolon { err.span_suggestion( sp, diff --git a/src/librustc_parse/parser/expr.rs b/src/librustc_parse/parser/expr.rs index d06b172bc14..3aec300d86d 100644 --- a/src/librustc_parse/parser/expr.rs +++ b/src/librustc_parse/parser/expr.rs @@ -1450,7 +1450,7 @@ impl<'a> Parser<'a> { /// Matches `'-' lit | lit` (cf. `ast_validation::AstValidator::check_expr_within_pat`). /// Keep this in sync with `Token::can_begin_literal_maybe_minus`. - pub fn parse_literal_maybe_minus(&mut self) -> PResult<'a, P<Expr>> { + pub(super) fn parse_literal_maybe_minus(&mut self) -> PResult<'a, P<Expr>> { maybe_whole_expr!(self); let lo = self.token.span; diff --git a/src/librustc_parse/parser/mod.rs b/src/librustc_parse/parser/mod.rs index 72866468b65..2509a979221 100644 --- a/src/librustc_parse/parser/mod.rs +++ b/src/librustc_parse/parser/mod.rs @@ -1,16 +1,17 @@ pub mod attr; +mod diagnostics; mod expr; +mod generics; mod item; +mod nonterminal; mod pat; mod path; -mod ty; -pub use path::PathStyle; -mod diagnostics; -mod generics; mod stmt; -use diagnostics::Error; +mod ty; use crate::lexer::UnmatchedBrace; +use diagnostics::Error; +pub use path::PathStyle; use log::debug; use rustc_ast::ast::DUMMY_NODE_ID; @@ -958,7 +959,7 @@ impl<'a> Parser<'a> { } /// Parses a single token tree from the input. - pub fn parse_token_tree(&mut self) -> TokenTree { + pub(crate) fn parse_token_tree(&mut self) -> TokenTree { match self.token.kind { token::OpenDelim(..) => { let frame = mem::replace( @@ -1017,7 +1018,7 @@ impl<'a> Parser<'a> { /// If the following element can't be a tuple (i.e., it's a function definition), then /// it's not a tuple struct field), and the contents within the parentheses isn't valid, /// so emit a proper diagnostic. - pub fn parse_visibility(&mut self, fbt: FollowedByType) -> PResult<'a, Visibility> { + pub(crate) fn parse_visibility(&mut self, fbt: FollowedByType) -> PResult<'a, Visibility> { maybe_whole!(self, NtVis, |x| x); self.expected_tokens.push(TokenType::Keyword(kw::Crate)); diff --git a/src/librustc_parse/parser/nonterminal.rs b/src/librustc_parse/parser/nonterminal.rs new file mode 100644 index 00000000000..12139771bbf --- /dev/null +++ b/src/librustc_parse/parser/nonterminal.rs @@ -0,0 +1,163 @@ +use rustc_ast::ptr::P; +use rustc_ast::token::{self, Nonterminal, NonterminalKind, Token}; +use rustc_ast_pretty::pprust; +use rustc_errors::PResult; +use rustc_span::symbol::{kw, Ident}; + +use crate::parser::{FollowedByType, Parser, PathStyle}; + +impl<'a> Parser<'a> { + /// Checks whether a non-terminal may begin with a particular token. + /// + /// Returning `false` is a *stability guarantee* that such a matcher will *never* begin with that + /// token. Be conservative (return true) if not sure. + pub fn nonterminal_may_begin_with(kind: NonterminalKind, token: &Token) -> bool { + /// Checks whether the non-terminal may contain a single (non-keyword) identifier. + fn may_be_ident(nt: &token::Nonterminal) -> bool { + match *nt { + token::NtItem(_) | token::NtBlock(_) | token::NtVis(_) | token::NtLifetime(_) => { + false + } + _ => true, + } + } + + match kind { + NonterminalKind::Expr => { + token.can_begin_expr() + // This exception is here for backwards compatibility. + && !token.is_keyword(kw::Let) + } + NonterminalKind::Ty => token.can_begin_type(), + NonterminalKind::Ident => get_macro_ident(token).is_some(), + NonterminalKind::Literal => token.can_begin_literal_maybe_minus(), + NonterminalKind::Vis => match token.kind { + // The follow-set of :vis + "priv" keyword + interpolated + token::Comma | token::Ident(..) | token::Interpolated(..) => true, + _ => token.can_begin_type(), + }, + NonterminalKind::Block => match token.kind { + token::OpenDelim(token::Brace) => true, + token::Interpolated(ref nt) => match **nt { + token::NtItem(_) + | token::NtPat(_) + | token::NtTy(_) + | token::NtIdent(..) + | token::NtMeta(_) + | token::NtPath(_) + | token::NtVis(_) => false, // none of these may start with '{'. + _ => true, + }, + _ => false, + }, + NonterminalKind::Path | NonterminalKind::Meta => match token.kind { + token::ModSep | token::Ident(..) => true, + token::Interpolated(ref nt) => match **nt { + token::NtPath(_) | token::NtMeta(_) => true, + _ => may_be_ident(&nt), + }, + _ => false, + }, + NonterminalKind::Pat => match token.kind { + token::Ident(..) | // box, ref, mut, and other identifiers (can stricten) + token::OpenDelim(token::Paren) | // tuple pattern + token::OpenDelim(token::Bracket) | // slice pattern + token::BinOp(token::And) | // reference + token::BinOp(token::Minus) | // negative literal + token::AndAnd | // double reference + token::Literal(..) | // literal + token::DotDot | // range pattern (future compat) + token::DotDotDot | // range pattern (future compat) + token::ModSep | // path + token::Lt | // path (UFCS constant) + token::BinOp(token::Shl) => true, // path (double UFCS) + token::Interpolated(ref nt) => may_be_ident(nt), + _ => false, + }, + NonterminalKind::Lifetime => match token.kind { + token::Lifetime(_) => true, + token::Interpolated(ref nt) => match **nt { + token::NtLifetime(_) | token::NtTT(_) => true, + _ => false, + }, + _ => false, + }, + NonterminalKind::TT | NonterminalKind::Item | NonterminalKind::Stmt => match token.kind + { + token::CloseDelim(_) => false, + _ => true, + }, + } + } + + pub fn parse_nonterminal(&mut self, kind: NonterminalKind) -> PResult<'a, Nonterminal> { + // Any `Nonterminal` which stores its tokens (currently `NtItem` and `NtExpr`) + // needs to have them force-captured here. + // A `macro_rules!` invocation may pass a captured item/expr to a proc-macro, + // which requires having captured tokens available. Since we cannot determine + // in advance whether or not a proc-macro will be (transitively) invoked, + // we always capture tokens for any `Nonterminal` which needs them. + Ok(match kind { + NonterminalKind::Item => match self.collect_tokens(|this| this.parse_item())? { + (Some(mut item), tokens) => { + // If we captured tokens during parsing (due to outer attributes), + // use those. + if item.tokens.is_none() { + item.tokens = Some(tokens); + } + token::NtItem(item) + } + (None, _) => { + return Err(self.struct_span_err(self.token.span, "expected an item keyword")); + } + }, + NonterminalKind::Block => token::NtBlock(self.parse_block()?), + NonterminalKind::Stmt => match self.parse_stmt()? { + Some(s) => token::NtStmt(s), + None => return Err(self.struct_span_err(self.token.span, "expected a statement")), + }, + NonterminalKind::Pat => token::NtPat(self.parse_pat(None)?), + NonterminalKind::Expr => { + let (mut expr, tokens) = self.collect_tokens(|this| this.parse_expr())?; + // If we captured tokens during parsing (due to outer attributes), + // use those. + if expr.tokens.is_none() { + expr.tokens = Some(tokens); + } + token::NtExpr(expr) + } + NonterminalKind::Literal => token::NtLiteral(self.parse_literal_maybe_minus()?), + NonterminalKind::Ty => token::NtTy(self.parse_ty()?), + // this could be handled like a token, since it is one + NonterminalKind::Ident => { + if let Some((ident, is_raw)) = get_macro_ident(&self.token) { + self.bump(); + token::NtIdent(ident, is_raw) + } else { + let token_str = pprust::token_to_string(&self.token); + let msg = &format!("expected ident, found {}", &token_str); + return Err(self.struct_span_err(self.token.span, msg)); + } + } + NonterminalKind::Path => token::NtPath(self.parse_path(PathStyle::Type)?), + NonterminalKind::Meta => token::NtMeta(P(self.parse_attr_item()?)), + NonterminalKind::TT => token::NtTT(self.parse_token_tree()), + NonterminalKind::Vis => token::NtVis(self.parse_visibility(FollowedByType::Yes)?), + NonterminalKind::Lifetime => { + if self.check_lifetime() { + token::NtLifetime(self.expect_lifetime().ident) + } else { + let token_str = pprust::token_to_string(&self.token); + let msg = &format!("expected a lifetime, found `{}`", &token_str); + return Err(self.struct_span_err(self.token.span, msg)); + } + } + }) + } +} + +/// The token is an identifier, but not `_`. +/// We prohibit passing `_` to macros expecting `ident` for now. +fn get_macro_ident(token: &Token) -> Option<(Ident, bool)> { + token.ident().filter(|(ident, _)| ident.name != kw::Underscore) +} diff --git a/src/librustc_parse/parser/path.rs b/src/librustc_parse/parser/path.rs index 3dcefd36257..d4e44c54b12 100644 --- a/src/librustc_parse/parser/path.rs +++ b/src/librustc_parse/parser/path.rs @@ -125,7 +125,7 @@ impl<'a> Parser<'a> { /// `a::b::C::<D>` (with disambiguator) /// `Fn(Args)` (without disambiguator) /// `Fn::(Args)` (with disambiguator) - pub fn parse_path(&mut self, style: PathStyle) -> PResult<'a, Path> { + pub(super) fn parse_path(&mut self, style: PathStyle) -> PResult<'a, Path> { maybe_whole!(self, NtPath, |path| { if style == PathStyle::Mod && path.segments.iter().any(|segment| segment.args.is_some()) { diff --git a/src/librustc_parse/parser/stmt.rs b/src/librustc_parse/parser/stmt.rs index d04920de47f..5c3a5e99873 100644 --- a/src/librustc_parse/parser/stmt.rs +++ b/src/librustc_parse/parser/stmt.rs @@ -21,7 +21,7 @@ use std::mem; impl<'a> Parser<'a> { /// Parses a statement. This stops just before trailing semicolons on everything but items. /// e.g., a `StmtKind::Semi` parses to a `StmtKind::Expr`, leaving the trailing `;` unconsumed. - pub fn parse_stmt(&mut self) -> PResult<'a, Option<Stmt>> { + pub(super) fn parse_stmt(&mut self) -> PResult<'a, Option<Stmt>> { Ok(self.parse_stmt_without_recovery().unwrap_or_else(|mut e| { e.emit(); self.recover_stmt_(SemiColonMode::Break, BlockMode::Ignore); @@ -247,7 +247,7 @@ impl<'a> Parser<'a> { } /// Parses a block. No inner attributes are allowed. - pub fn parse_block(&mut self) -> PResult<'a, P<Block>> { + pub(super) fn parse_block(&mut self) -> PResult<'a, P<Block>> { let (attrs, block) = self.parse_inner_attrs_and_block()?; if let [.., last] = &*attrs { self.error_on_forbidden_inner_attr(last.span, DEFAULT_INNER_ATTR_FORBIDDEN); diff --git a/src/librustc_parse/parser/ty.rs b/src/librustc_parse/parser/ty.rs index a6015504a32..cd66b917f23 100644 --- a/src/librustc_parse/parser/ty.rs +++ b/src/librustc_parse/parser/ty.rs @@ -610,13 +610,13 @@ impl<'a> Parser<'a> { } } - pub fn check_lifetime(&mut self) -> bool { + pub(super) fn check_lifetime(&mut self) -> bool { self.expected_tokens.push(TokenType::Lifetime); self.token.is_lifetime() } /// Parses a single lifetime `'a` or panics. - pub fn expect_lifetime(&mut self) -> Lifetime { + pub(super) fn expect_lifetime(&mut self) -> Lifetime { if let Some(ident) = self.token.lifetime() { self.bump(); Lifetime { ident, id: ast::DUMMY_NODE_ID } diff --git a/src/librustc_passes/Cargo.toml b/src/librustc_passes/Cargo.toml index 69048cbf24a..d9fa435e3ad 100644 --- a/src/librustc_passes/Cargo.toml +++ b/src/librustc_passes/Cargo.toml @@ -9,7 +9,7 @@ name = "rustc_passes" path = "lib.rs" [dependencies] -log = "0.4" +log = { package = "tracing", version = "0.1" } rustc_middle = { path = "../librustc_middle" } rustc_attr = { path = "../librustc_attr" } rustc_data_structures = { path = "../librustc_data_structures" } diff --git a/src/librustc_passes/layout_test.rs b/src/librustc_passes/layout_test.rs index 2419e696596..55a6d3f7645 100644 --- a/src/librustc_passes/layout_test.rs +++ b/src/librustc_passes/layout_test.rs @@ -82,8 +82,10 @@ impl LayoutTest<'tcx> { } sym::debug => { - let normalized_ty = - self.tcx.normalize_erasing_regions(param_env.with_reveal_all(), ty); + let normalized_ty = self.tcx.normalize_erasing_regions( + param_env.with_reveal_all_normalized(self.tcx), + ty, + ); self.tcx.sess.span_err( item.span, &format!("layout_of({:?}) = {:#?}", normalized_ty, *ty_layout), diff --git a/src/librustc_privacy/Cargo.toml b/src/librustc_privacy/Cargo.toml index 6110d2ef7fc..6f543e71b42 100644 --- a/src/librustc_privacy/Cargo.toml +++ b/src/librustc_privacy/Cargo.toml @@ -17,4 +17,4 @@ rustc_typeck = { path = "../librustc_typeck" } rustc_session = { path = "../librustc_session" } rustc_span = { path = "../librustc_span" } rustc_data_structures = { path = "../librustc_data_structures" } -log = "0.4" +log = { package = "tracing", version = "0.1" } diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 9c5fb4ce734..fc00050f405 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -637,7 +637,7 @@ impl EmbargoVisitor<'tcx> { &mut self, segments: &[hir::PathSegment<'_>], ) { - if let Some([module, segment]) = segments.rchunks_exact(2).next() { + if let [.., module, segment] = segments { if let Some(item) = module .res .and_then(|res| res.mod_def_id()) diff --git a/src/librustc_query_system/Cargo.toml b/src/librustc_query_system/Cargo.toml index 73d50f84fe8..64af9c5f1a1 100644 --- a/src/librustc_query_system/Cargo.toml +++ b/src/librustc_query_system/Cargo.toml @@ -11,7 +11,7 @@ doctest = false [dependencies] rustc_arena = { path = "../librustc_arena" } -log = { version = "0.4", features = ["release_max_level_info", "std"] } +log = { package = "tracing", version = "0.1" } rustc-rayon-core = "0.3.0" rustc_data_structures = { path = "../librustc_data_structures" } rustc_errors = { path = "../librustc_errors" } diff --git a/src/librustc_resolve/Cargo.toml b/src/librustc_resolve/Cargo.toml index 6f6104c3d69..1cb49132ead 100644 --- a/src/librustc_resolve/Cargo.toml +++ b/src/librustc_resolve/Cargo.toml @@ -12,7 +12,7 @@ doctest = false [dependencies] bitflags = "1.2.1" -log = "0.4" +log = { package = "tracing", version = "0.1" } rustc_ast = { path = "../librustc_ast" } rustc_arena = { path = "../librustc_arena" } rustc_middle = { path = "../librustc_middle" } diff --git a/src/librustc_resolve/late.rs b/src/librustc_resolve/late.rs index bcd2c6c1f1c..44ff4209095 100644 --- a/src/librustc_resolve/late.rs +++ b/src/librustc_resolve/late.rs @@ -1510,30 +1510,18 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { pat_src: PatternSource, bindings: &mut SmallVec<[(PatBoundCtx, FxHashSet<Ident>); 1]>, ) { - let is_tuple_struct_pat = matches!(pat.kind, PatKind::TupleStruct(_, _)); - // Visit all direct subpatterns of this pattern. pat.walk(&mut |pat| { debug!("resolve_pattern pat={:?} node={:?}", pat, pat.kind); match pat.kind { PatKind::Ident(bmode, ident, ref sub) => { - if is_tuple_struct_pat && sub.as_ref().filter(|p| p.is_rest()).is_some() { - // In tuple struct patterns ignore the invalid `ident @ ...`. - // It will be handled as an error by the AST lowering. - self.r - .session - .delay_span_bug(ident.span, "ident in tuple pattern is invalid"); - } else { - // First try to resolve the identifier as some existing entity, - // then fall back to a fresh binding. - let has_sub = sub.is_some(); - let res = self - .try_resolve_as_non_binding(pat_src, pat, bmode, ident, has_sub) - .unwrap_or_else(|| { - self.fresh_binding(ident, pat.id, pat_src, bindings) - }); - self.r.record_partial_res(pat.id, PartialRes::new(res)); - } + // First try to resolve the identifier as some existing entity, + // then fall back to a fresh binding. + let has_sub = sub.is_some(); + let res = self + .try_resolve_as_non_binding(pat_src, pat, bmode, ident, has_sub) + .unwrap_or_else(|| self.fresh_binding(ident, pat.id, pat_src, bindings)); + self.r.record_partial_res(pat.id, PartialRes::new(res)); } PatKind::TupleStruct(ref path, ..) => { self.smart_resolve_path(pat.id, None, path, PathSource::TupleStruct(pat.span)); @@ -2241,8 +2229,15 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { self.resolve_expr(argument, None); } } - ExprKind::Type(ref type_expr, _) => { - self.diagnostic_metadata.current_type_ascription.push(type_expr.span); + ExprKind::Type(ref type_expr, ref ty) => { + // `ParseSess::type_ascription_path_suggestions` keeps spans of colon tokens in + // type ascription. Here we are trying to retrieve the span of the colon token as + // well, but only if it's written without spaces `expr:Ty` and therefore confusable + // with `expr::Ty`, only in this case it will match the span from + // `type_ascription_path_suggestions`. + self.diagnostic_metadata + .current_type_ascription + .push(type_expr.span.between(ty.span)); visit::walk_expr(self, expr); self.diagnostic_metadata.current_type_ascription.pop(); } diff --git a/src/librustc_resolve/late/diagnostics.rs b/src/librustc_resolve/late/diagnostics.rs index c86b4141847..ec6dbb070df 100644 --- a/src/librustc_resolve/late/diagnostics.rs +++ b/src/librustc_resolve/late/diagnostics.rs @@ -17,7 +17,7 @@ use rustc_hir::PrimTy; use rustc_session::config::nightly_options; use rustc_span::hygiene::MacroKind; use rustc_span::symbol::{kw, sym, Ident}; -use rustc_span::Span; +use rustc_span::{BytePos, Span}; use log::debug; @@ -223,13 +223,31 @@ impl<'a> LateResolutionVisitor<'a, '_, '_> { if candidates.is_empty() && is_expected(Res::Def(DefKind::Enum, crate_def_id)) { let enum_candidates = self.r.lookup_import_candidates(ident, ns, &self.parent_scope, is_enum_variant); - let mut enum_candidates = enum_candidates - .iter() - .map(|suggestion| import_candidate_to_enum_paths(&suggestion)) - .collect::<Vec<_>>(); - enum_candidates.sort(); if !enum_candidates.is_empty() { + if let (PathSource::Type, Some(span)) = + (source, self.diagnostic_metadata.current_type_ascription.last()) + { + if self + .r + .session + .parse_sess + .type_ascription_path_suggestions + .borrow() + .contains(span) + { + // Already reported this issue on the lhs of the type ascription. + err.delay_as_bug(); + return (err, candidates); + } + } + + let mut enum_candidates = enum_candidates + .iter() + .map(|suggestion| import_candidate_to_enum_paths(&suggestion)) + .collect::<Vec<_>>(); + enum_candidates.sort(); + // Contextualize for E0412 "cannot find type", but don't belabor the point // (that it's a variant) for E0573 "expected type, found variant". let preamble = if res.is_none() { @@ -484,10 +502,21 @@ impl<'a> LateResolutionVisitor<'a, '_, '_> { match source { PathSource::Expr(Some( parent @ Expr { kind: ExprKind::Field(..) | ExprKind::MethodCall(..), .. }, - )) => { - path_sep(err, &parent); - } - PathSource::Expr(None) if followed_by_brace => { + )) if path_sep(err, &parent) => {} + PathSource::Expr( + None + | Some(Expr { + kind: + ExprKind::Path(..) + | ExprKind::Binary(..) + | ExprKind::Unary(..) + | ExprKind::If(..) + | ExprKind::While(..) + | ExprKind::ForLoop(..) + | ExprKind::Match(..), + .. + }), + ) if followed_by_brace => { if let Some(sp) = closing_brace { err.multipart_suggestion( "surround the struct literal with parentheses", @@ -508,11 +537,7 @@ impl<'a> LateResolutionVisitor<'a, '_, '_> { ); } } - PathSource::Expr( - None | Some(Expr { kind: ExprKind::Call(..) | ExprKind::Path(..), .. }), - ) - | PathSource::TupleStruct(_) - | PathSource::Pat => { + PathSource::Expr(_) | PathSource::TupleStruct(_) | PathSource::Pat => { let span = match &source { PathSource::Expr(Some(Expr { span, kind: ExprKind::Call(_, _), .. @@ -593,6 +618,24 @@ impl<'a> LateResolutionVisitor<'a, '_, '_> { Res::Def(DefKind::Enum, def_id), PathSource::TupleStruct(_) | PathSource::Expr(..), ) => { + if self + .diagnostic_metadata + .current_type_ascription + .last() + .map(|sp| { + self.r + .session + .parse_sess + .type_ascription_path_suggestions + .borrow() + .contains(&sp) + }) + .unwrap_or(false) + { + err.delay_as_bug(); + // We already suggested changing `:` into `::` during parsing. + return false; + } if let Some(variants) = self.collect_enum_variants(def_id) { if !variants.is_empty() { let msg = if variants.len() == 1 { @@ -609,7 +652,7 @@ impl<'a> LateResolutionVisitor<'a, '_, '_> { ); } } else { - err.note("did you mean to use one of the enum's variants?"); + err.note("you might have meant to use one of the enum's variants"); } } (Res::Def(DefKind::Struct, def_id), _) if ns == ValueNS => { @@ -829,77 +872,73 @@ impl<'a> LateResolutionVisitor<'a, '_, '_> { fn type_ascription_suggestion(&self, err: &mut DiagnosticBuilder<'_>, base_span: Span) { let sm = self.r.session.source_map(); let base_snippet = sm.span_to_snippet(base_span); - if let Some(sp) = self.diagnostic_metadata.current_type_ascription.last() { - let mut sp = *sp; - loop { - // Try to find the `:`; bail on first non-':' / non-whitespace. - sp = sm.next_point(sp); - if let Ok(snippet) = sm.span_to_snippet(sp.to(sm.next_point(sp))) { - let line_sp = sm.lookup_char_pos(sp.hi()).line; - let line_base_sp = sm.lookup_char_pos(base_span.lo()).line; - if snippet == ":" { - let mut show_label = true; - if line_sp != line_base_sp { - err.span_suggestion_short( - sp, - "did you mean to use `;` here instead?", - ";".to_string(), + if let Some(&sp) = self.diagnostic_metadata.current_type_ascription.last() { + if let Ok(snippet) = sm.span_to_snippet(sp) { + let len = snippet.trim_end().len() as u32; + if snippet.trim() == ":" { + let colon_sp = + sp.with_lo(sp.lo() + BytePos(len - 1)).with_hi(sp.lo() + BytePos(len)); + let mut show_label = true; + if sm.is_multiline(sp) { + err.span_suggestion_short( + colon_sp, + "maybe you meant to write `;` here", + ";".to_string(), + Applicability::MaybeIncorrect, + ); + } else { + let after_colon_sp = + self.get_colon_suggestion_span(colon_sp.shrink_to_hi()); + if snippet.len() == 1 { + // `foo:bar` + err.span_suggestion( + colon_sp, + "maybe you meant to write a path separator here", + "::".to_string(), Applicability::MaybeIncorrect, ); - } else { - let colon_sp = self.get_colon_suggestion_span(sp); - let after_colon_sp = - self.get_colon_suggestion_span(colon_sp.shrink_to_hi()); - if !sm - .span_to_snippet(after_colon_sp) - .map(|s| s == " ") - .unwrap_or(false) + show_label = false; + if !self + .r + .session + .parse_sess + .type_ascription_path_suggestions + .borrow_mut() + .insert(colon_sp) { - err.span_suggestion( - colon_sp, - "maybe you meant to write a path separator here", - "::".to_string(), - Applicability::MaybeIncorrect, - ); - show_label = false; + err.delay_as_bug(); } - if let Ok(base_snippet) = base_snippet { - let mut sp = after_colon_sp; - for _ in 0..100 { - // Try to find an assignment - sp = sm.next_point(sp); - let snippet = sm.span_to_snippet(sp.to(sm.next_point(sp))); - match snippet { - Ok(ref x) if x.as_str() == "=" => { - err.span_suggestion( - base_span, - "maybe you meant to write an assignment here", - format!("let {}", base_snippet), - Applicability::MaybeIncorrect, - ); - show_label = false; - break; - } - Ok(ref x) if x.as_str() == "\n" => break, - Err(_) => break, - Ok(_) => {} + } + if let Ok(base_snippet) = base_snippet { + let mut sp = after_colon_sp; + for _ in 0..100 { + // Try to find an assignment + sp = sm.next_point(sp); + let snippet = sm.span_to_snippet(sp.to(sm.next_point(sp))); + match snippet { + Ok(ref x) if x.as_str() == "=" => { + err.span_suggestion( + base_span, + "maybe you meant to write an assignment here", + format!("let {}", base_snippet), + Applicability::MaybeIncorrect, + ); + show_label = false; + break; } + Ok(ref x) if x.as_str() == "\n" => break, + Err(_) => break, + Ok(_) => {} } } } - if show_label { - err.span_label( - base_span, - "expecting a type here because of type ascription", - ); - } - break; - } else if !snippet.trim().is_empty() { - debug!("tried to find type ascription `:` token, couldn't find it"); - break; } - } else { - break; + if show_label { + err.span_label( + base_span, + "expecting a type here because of type ascription", + ); + } } } } diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index fee7cb4836e..ccc7e16ae4c 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -1020,7 +1020,7 @@ impl<'a> Resolver<'a> { } if let Some(depr) = &ext.deprecation { let path = pprust::path_to_string(&path); - let (message, lint) = stability::deprecation_message(depr, &path); + let (message, lint) = stability::deprecation_message(depr, "macro", &path); stability::early_report_deprecation( &mut self.lint_buffer, &message, diff --git a/src/librustc_save_analysis/Cargo.toml b/src/librustc_save_analysis/Cargo.toml index 5948c88054d..7a5ae0ace3a 100644 --- a/src/librustc_save_analysis/Cargo.toml +++ b/src/librustc_save_analysis/Cargo.toml @@ -9,7 +9,7 @@ name = "rustc_save_analysis" path = "lib.rs" [dependencies] -log = "0.4" +log = { package = "tracing", version = "0.1" } rustc_middle = { path = "../librustc_middle" } rustc_ast = { path = "../librustc_ast" } rustc_ast_pretty = { path = "../librustc_ast_pretty" } diff --git a/src/librustc_session/Cargo.toml b/src/librustc_session/Cargo.toml index abce7359c0e..35c227df850 100644 --- a/src/librustc_session/Cargo.toml +++ b/src/librustc_session/Cargo.toml @@ -11,7 +11,7 @@ path = "lib.rs" [dependencies] bitflags = "1.2.1" getopts = "0.2" -log = "0.4" +log = { package = "tracing", version = "0.1" } rustc_errors = { path = "../librustc_errors" } rustc_feature = { path = "../librustc_feature" } rustc_target = { path = "../librustc_target" } diff --git a/src/librustc_session/config.rs b/src/librustc_session/config.rs index 620a04b45b0..9fcdd46539c 100644 --- a/src/librustc_session/config.rs +++ b/src/librustc_session/config.rs @@ -1717,7 +1717,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options { } // `-Z instrument-coverage` implies: - // * `-Z symbol-mangling-version=v0` - to ensure consistent and reversable name mangling. + // * `-Z symbol-mangling-version=v0` - to ensure consistent and reversible name mangling. // Note, LLVM coverage tools can analyze coverage over multiple runs, including some // changes to source code; so mangled names must be consistent across compilations. // * `-C link-dead-code` - so unexecuted code is still counted as zero, rather than be diff --git a/src/librustc_session/filesearch.rs b/src/librustc_session/filesearch.rs index 27396c524f4..504490d938c 100644 --- a/src/librustc_session/filesearch.rs +++ b/src/librustc_session/filesearch.rs @@ -117,28 +117,22 @@ pub fn make_target_lib_path(sysroot: &Path, target_triple: &str) -> PathBuf { pub fn get_or_default_sysroot() -> PathBuf { // Follow symlinks. If the resolved path is relative, make it absolute. - fn canonicalize(path: Option<PathBuf>) -> Option<PathBuf> { - path.and_then(|path| { - match fs::canonicalize(&path) { - // See comments on this target function, but the gist is that - // gcc chokes on verbatim paths which fs::canonicalize generates - // so we try to avoid those kinds of paths. - Ok(canon) => Some(fix_windows_verbatim_for_gcc(&canon)), - Err(e) => panic!("failed to get realpath: {}", e), - } - }) + fn canonicalize(path: PathBuf) -> PathBuf { + let path = fs::canonicalize(&path).unwrap_or(path); + // See comments on this target function, but the gist is that + // gcc chokes on verbatim paths which fs::canonicalize generates + // so we try to avoid those kinds of paths. + fix_windows_verbatim_for_gcc(&path) } match env::current_exe() { - Ok(exe) => match canonicalize(Some(exe)) { - Some(mut p) => { - p.pop(); - p.pop(); - p - } - None => panic!("can't determine value for sysroot"), - }, - Err(ref e) => panic!(format!("failed to get current_exe: {}", e)), + Ok(exe) => { + let mut p = canonicalize(exe); + p.pop(); + p.pop(); + p + } + Err(e) => panic!("failed to get current_exe: {}", e), } } diff --git a/src/librustc_session/lint/builtin.rs b/src/librustc_session/lint/builtin.rs index aa2a133952f..144a06a4916 100644 --- a/src/librustc_session/lint/builtin.rs +++ b/src/librustc_session/lint/builtin.rs @@ -398,7 +398,7 @@ declare_lint! { } declare_lint! { - pub INTRA_DOC_LINK_RESOLUTION_FAILURE, + pub BROKEN_INTRA_DOC_LINKS, Warn, "failures in resolving intra-doc link targets" } @@ -601,7 +601,7 @@ declare_lint_pass! { ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE, UNSTABLE_NAME_COLLISIONS, IRREFUTABLE_LET_PATTERNS, - INTRA_DOC_LINK_RESOLUTION_FAILURE, + BROKEN_INTRA_DOC_LINKS, INVALID_CODEBLOCK_ATTRIBUTES, MISSING_CRATE_LEVEL_DOCS, MISSING_DOC_CODE_EXAMPLES, diff --git a/src/librustc_session/options.rs b/src/librustc_session/options.rs index 502102fa178..80164840334 100644 --- a/src/librustc_session/options.rs +++ b/src/librustc_session/options.rs @@ -883,7 +883,7 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, "instrument the generated code to support LLVM source-based code coverage \ reports (note, the compiler build config must include `profiler = true`, \ and is mutually exclusive with `-C profile-generate`/`-C profile-use`); \ - implies `-C link-dead-code` (unless explicitly disabled)` and + implies `-C link-dead-code` (unless explicitly disabled)` and \ `-Z symbol-mangling-version=v0`; and disables/overrides some optimization \ options (default: no)"), instrument_mcount: bool = (false, parse_bool, [TRACKED], diff --git a/src/librustc_session/parse.rs b/src/librustc_session/parse.rs index b428315b3cd..9cdb7e966fe 100644 --- a/src/librustc_session/parse.rs +++ b/src/librustc_session/parse.rs @@ -63,7 +63,7 @@ impl GatedSpans { #[derive(Default)] pub struct SymbolGallery { - /// All symbols occurred and their first occurrance span. + /// All symbols occurred and their first occurrence span. pub symbols: Lock<BTreeMap<Symbol, Span>>, } @@ -138,6 +138,8 @@ pub struct ParseSess { pub reached_eof: Lock<bool>, /// Environment variables accessed during the build and their values when they exist. pub env_depinfo: Lock<FxHashSet<(Symbol, Option<Symbol>)>>, + /// All the type ascriptions expressions that have had a suggestion for likely path typo. + pub type_ascription_path_suggestions: Lock<FxHashSet<Span>>, } impl ParseSess { @@ -164,6 +166,7 @@ impl ParseSess { symbol_gallery: SymbolGallery::default(), reached_eof: Lock::new(false), env_depinfo: Default::default(), + type_ascription_path_suggestions: Default::default(), } } diff --git a/src/librustc_session/session.rs b/src/librustc_session/session.rs index 0d4298fa6f5..e9077f40859 100644 --- a/src/librustc_session/session.rs +++ b/src/librustc_session/session.rs @@ -1294,19 +1294,19 @@ pub fn build_session( // commandline argument, you can do so here. fn validate_commandline_args_with_session_available(sess: &Session) { // Since we don't know if code in an rlib will be linked to statically or - // dynamically downstream, rustc generates `__imp_` symbols that help the - // MSVC linker deal with this lack of knowledge (#27438). Unfortunately, + // dynamically downstream, rustc generates `__imp_` symbols that help linkers + // on Windows deal with this lack of knowledge (#27438). Unfortunately, // these manually generated symbols confuse LLD when it tries to merge - // bitcode during ThinLTO. Therefore we disallow dynamic linking on MSVC + // bitcode during ThinLTO. Therefore we disallow dynamic linking on Windows // when compiling for LLD ThinLTO. This way we can validly just not generate // the `dllimport` attributes and `__imp_` symbols in that case. if sess.opts.cg.linker_plugin_lto.enabled() && sess.opts.cg.prefer_dynamic - && sess.target.target.options.is_like_msvc + && sess.target.target.options.is_like_windows { sess.err( "Linker plugin based LTO is not supported together with \ - `-C prefer-dynamic` when targeting MSVC", + `-C prefer-dynamic` when targeting Windows-like targets", ); } diff --git a/src/librustc_span/Cargo.toml b/src/librustc_span/Cargo.toml index 2a7a7748725..2db417ce0e1 100644 --- a/src/librustc_span/Cargo.toml +++ b/src/librustc_span/Cargo.toml @@ -18,6 +18,6 @@ rustc_arena = { path = "../librustc_arena" } scoped-tls = "1.0" unicode-width = "0.1.4" cfg-if = "0.1.2" -log = "0.4" +log = { package = "tracing", version = "0.1" } sha-1 = "0.8" md-5 = "0.8" diff --git a/src/librustc_span/hygiene.rs b/src/librustc_span/hygiene.rs index 13bc1751831..a03ac4e1fdb 100644 --- a/src/librustc_span/hygiene.rs +++ b/src/librustc_span/hygiene.rs @@ -891,7 +891,7 @@ impl UseSpecializedDecodable for ExpnId {} #[derive(Default)] pub struct HygieneEncodeContext { - /// All `SyntaxContexts` for which we have writen `SyntaxContextData` into crate metadata. + /// All `SyntaxContexts` for which we have written `SyntaxContextData` into crate metadata. /// This is `None` after we finish encoding `SyntaxContexts`, to ensure /// that we don't accidentally try to encode any more `SyntaxContexts` serialized_ctxts: Lock<FxHashSet<SyntaxContext>>, @@ -961,7 +961,7 @@ pub struct HygieneDecodeContext { // Maps serialized `SyntaxContext` ids to a `SyntaxContext` in the current // global `HygieneData`. When we deserialize a `SyntaxContext`, we need to create // a new id in the global `HygieneData`. This map tracks the ID we end up picking, - // so that multiple occurences of the same serialized id are decoded to the same + // so that multiple occurrences of the same serialized id are decoded to the same // `SyntaxContext` remapped_ctxts: Lock<Vec<Option<SyntaxContext>>>, // The same as `remapepd_ctxts`, but for `ExpnId`s diff --git a/src/librustc_span/symbol.rs b/src/librustc_span/symbol.rs index dadf040304d..98776a04782 100644 --- a/src/librustc_span/symbol.rs +++ b/src/librustc_span/symbol.rs @@ -1043,6 +1043,7 @@ symbols! { stop_after_dataflow, str, str_alloc, + string_type, stringify, struct_field_attributes, struct_inherit, diff --git a/src/librustc_symbol_mangling/Cargo.toml b/src/librustc_symbol_mangling/Cargo.toml index d670ababe9f..757d86bd95a 100644 --- a/src/librustc_symbol_mangling/Cargo.toml +++ b/src/librustc_symbol_mangling/Cargo.toml @@ -10,7 +10,7 @@ path = "lib.rs" doctest = false [dependencies] -log = "0.4" +log = { package = "tracing", version = "0.1" } punycode = "0.4.0" rustc-demangle = "0.1.16" diff --git a/src/librustc_symbol_mangling/v0.rs b/src/librustc_symbol_mangling/v0.rs index ecf27fbf542..56ee492de87 100644 --- a/src/librustc_symbol_mangling/v0.rs +++ b/src/librustc_symbol_mangling/v0.rs @@ -271,7 +271,7 @@ impl Printer<'tcx> for SymbolMangler<'tcx> { let key = self.tcx.def_key(impl_def_id); let parent_def_id = DefId { index: key.parent.unwrap(), ..impl_def_id }; - let mut param_env = self.tcx.param_env(impl_def_id).with_reveal_all(); + let mut param_env = self.tcx.param_env_reveal_all_normalized(impl_def_id); if !substs.is_empty() { param_env = param_env.subst(self.tcx, substs); } @@ -636,9 +636,7 @@ impl Printer<'tcx> for SymbolMangler<'tcx> { } GenericArgKind::Const(c) => { self.push("K"); - // FIXME(const_generics) implement `ty::print::Print` on `ty::Const`. - // self = c.print(self)?; - self = self.print_const(c)?; + self = c.print(self)?; } } } diff --git a/src/librustc_target/Cargo.toml b/src/librustc_target/Cargo.toml index c73490e4513..21796e84985 100644 --- a/src/librustc_target/Cargo.toml +++ b/src/librustc_target/Cargo.toml @@ -10,7 +10,7 @@ path = "lib.rs" [dependencies] bitflags = "1.2.1" -log = "0.4" +log = { package = "tracing", version = "0.1" } rustc_data_structures = { path = "../librustc_data_structures" } rustc_macros = { path = "../librustc_macros" } rustc_serialize = { path = "../librustc_serialize" } diff --git a/src/librustc_target/spec/thumbv4t_none_eabi.rs b/src/librustc_target/spec/thumbv4t_none_eabi.rs index 31417b01547..a8c78f057fc 100644 --- a/src/librustc_target/spec/thumbv4t_none_eabi.rs +++ b/src/librustc_target/spec/thumbv4t_none_eabi.rs @@ -29,7 +29,7 @@ pub fn target() -> TargetResult { * native integers are 32-bit * All other elements are default */ - data_layout: "e-S64-p:32:32-i64:64-m:e-n32".to_string(), + data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), linker_flavor: LinkerFlavor::Ld, options: TargetOptions { linker: Some("arm-none-eabi-ld".to_string()), diff --git a/src/librustc_trait_selection/Cargo.toml b/src/librustc_trait_selection/Cargo.toml index fd11a85a9c4..c43fe3f2c0c 100644 --- a/src/librustc_trait_selection/Cargo.toml +++ b/src/librustc_trait_selection/Cargo.toml @@ -11,7 +11,7 @@ doctest = false [dependencies] rustc_parse_format = { path = "../librustc_parse_format" } -log = { version = "0.4", features = ["release_max_level_info", "std"] } +log = { package = "tracing", version = "0.1" } rustc_attr = { path = "../librustc_attr" } rustc_middle = { path = "../librustc_middle" } rustc_ast = { path = "../librustc_ast" } diff --git a/src/librustc_trait_selection/traits/auto_trait.rs b/src/librustc_trait_selection/traits/auto_trait.rs index 6fe67509660..05a0c52badb 100644 --- a/src/librustc_trait_selection/traits/auto_trait.rs +++ b/src/librustc_trait_selection/traits/auto_trait.rs @@ -802,6 +802,38 @@ impl AutoTraitFinder<'tcx> { _ => {} }; } + ty::PredicateAtom::ConstEquate(c1, c2) => { + let evaluate = |c: &'tcx ty::Const<'tcx>| { + if let ty::ConstKind::Unevaluated(def, substs, promoted) = c.val { + match select.infcx().const_eval_resolve( + obligation.param_env, + def, + substs, + promoted, + Some(obligation.cause.span), + ) { + Ok(val) => Ok(ty::Const::from_value(select.tcx(), val, c.ty)), + Err(err) => Err(err), + } + } else { + Ok(c) + } + }; + + match (evaluate(c1), evaluate(c2)) { + (Ok(c1), Ok(c2)) => { + match select + .infcx() + .at(&obligation.cause, obligation.param_env) + .eq(c1, c2) + { + Ok(_) => (), + Err(_) => return false, + } + } + _ => return false, + } + } _ => panic!("Unexpected predicate {:?} {:?}", ty, predicate), }; } diff --git a/src/librustc_traits/Cargo.toml b/src/librustc_traits/Cargo.toml index 079b9b10fd0..f8487982e3d 100644 --- a/src/librustc_traits/Cargo.toml +++ b/src/librustc_traits/Cargo.toml @@ -9,7 +9,7 @@ name = "rustc_traits" path = "lib.rs" [dependencies] -log = { version = "0.4" } +log = { package = "tracing", version = "0.1" } rustc_middle = { path = "../librustc_middle" } rustc_data_structures = { path = "../librustc_data_structures" } rustc_hir = { path = "../librustc_hir" } diff --git a/src/librustc_ty/Cargo.toml b/src/librustc_ty/Cargo.toml index b6db75e44f9..6cdb3530002 100644 --- a/src/librustc_ty/Cargo.toml +++ b/src/librustc_ty/Cargo.toml @@ -9,7 +9,7 @@ name = "rustc_ty" path = "lib.rs" [dependencies] -log = "0.4" +log = { package = "tracing", version = "0.1" } rustc_middle = { path = "../librustc_middle" } rustc_data_structures = { path = "../librustc_data_structures" } rustc_errors = { path = "../librustc_errors" } diff --git a/src/librustc_ty/instance.rs b/src/librustc_ty/instance.rs index 324ae4ec29e..1e0c4055af3 100644 --- a/src/librustc_ty/instance.rs +++ b/src/librustc_ty/instance.rs @@ -137,7 +137,7 @@ fn resolve_associated_item<'tcx>( }); let substs = tcx.infer_ctxt().enter(|infcx| { - let param_env = param_env.with_reveal_all(); + let param_env = param_env.with_reveal_all_normalized(tcx); let substs = rcvr_substs.rebase_onto(tcx, trait_def_id, impl_data.substs); let substs = translate_substs( &infcx, diff --git a/src/librustc_ty/ty.rs b/src/librustc_ty/ty.rs index 7f954dacf3e..dfb28b473ff 100644 --- a/src/librustc_ty/ty.rs +++ b/src/librustc_ty/ty.rs @@ -276,6 +276,10 @@ fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> { traits::normalize_param_env_or_error(tcx, def_id, unnormalized_env, cause) } +fn param_env_reveal_all_normalized(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> { + tcx.param_env(def_id).with_reveal_all_normalized(tcx) +} + fn crate_disambiguator(tcx: TyCtxt<'_>, crate_num: CrateNum) -> CrateDisambiguator { assert_eq!(crate_num, LOCAL_CRATE); tcx.sess.local_crate_disambiguator() @@ -502,6 +506,7 @@ pub fn provide(providers: &mut ty::query::Providers) { adt_sized_constraint, def_span, param_env, + param_env_reveal_all_normalized, trait_of_item, crate_disambiguator, original_crate_name, diff --git a/src/librustc_typeck/Cargo.toml b/src/librustc_typeck/Cargo.toml index 93b503c976b..963deda162d 100644 --- a/src/librustc_typeck/Cargo.toml +++ b/src/librustc_typeck/Cargo.toml @@ -12,7 +12,7 @@ doctest = false [dependencies] rustc_arena = { path = "../librustc_arena" } -log = "0.4" +log = { package = "tracing", version = "0.1" } rustc_middle = { path = "../librustc_middle" } rustc_attr = { path = "../librustc_attr" } rustc_data_structures = { path = "../librustc_data_structures" } diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index c7e9b97e2db..db8cdfc5b20 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -456,7 +456,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { // // Both of these trigger a special `CoerceUnsized`-related error (E0376) // - // We can take advantage of this fact to avoid performing unecessary work. + // We can take advantage of this fact to avoid performing unnecessary work. // If either `source` or `target` is a type variable, then any applicable impl // would need to be generic over the self-type (`impl<T> CoerceUnsized<SomeType> for T`) // or generic over the `CoerceUnsized` type parameter (`impl<T> CoerceUnsized<T> for diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index ae2cf6daf53..e69102d1995 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -678,6 +678,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .collect::<Vec<(usize, String)>>(); for ((span, empty_where), obligations) in type_params.into_iter() { restrict_type_params = true; + // #74886: Sort here so that the output is always the same. + let mut obligations = obligations.into_iter().collect::<Vec<_>>(); + obligations.sort(); err.span_suggestion_verbose( span, &format!( @@ -688,7 +691,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { format!( "{} {}", if empty_where { " where" } else { "," }, - obligations.into_iter().collect::<Vec<_>>().join(", ") + obligations.join(", ") ), Applicability::MaybeIncorrect, ); diff --git a/src/librustc_typeck/check/op.rs b/src/librustc_typeck/check/op.rs index 41aac3569d1..fd516c88ec6 100644 --- a/src/librustc_typeck/check/op.rs +++ b/src/librustc_typeck/check/op.rs @@ -562,7 +562,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { on the left and may require reallocation. This \ requires ownership of the string on the left"; - let is_std_string = |ty| &format!("{:?}", ty) == "std::string::String"; + let string_type = self.tcx.get_diagnostic_item(sym::string_type); + let is_std_string = |ty: Ty<'tcx>| match ty.ty_adt_def() { + Some(ty_def) => Some(ty_def.did) == string_type, + None => false, + }; match (&lhs_ty.kind, &rhs_ty.kind) { (&Ref(_, l_ty, _), &Ref(_, r_ty, _)) // &str or &String + &str, &String or &&str diff --git a/src/librustc_typeck/check/pat.rs b/src/librustc_typeck/check/pat.rs index 42170bc199c..9c7ea34bf51 100644 --- a/src/librustc_typeck/check/pat.rs +++ b/src/librustc_typeck/check/pat.rs @@ -345,7 +345,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { debug!("inspecting {:?}", expected); debug!("current discriminant is Ref, inserting implicit deref"); - // Preserve the reference type. We'll need it later during HAIR lowering. + // Preserve the reference type. We'll need it later during THIR lowering. pat_adjustments.push(expected); expected = inner_ty; diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 76439af79f3..8715dacb324 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -858,7 +858,6 @@ fn convert_variant( _ => false, }; ty::VariantDef::new( - tcx, ident, variant_did.map(LocalDefId::to_def_id), ctor_did.map(LocalDefId::to_def_id), @@ -868,6 +867,10 @@ fn convert_variant( adt_kind, parent_did.to_def_id(), recovered, + adt_kind == AdtKind::Struct && tcx.has_attr(parent_did.to_def_id(), sym::non_exhaustive) + || variant_did.map_or(false, |variant_did| { + tcx.has_attr(variant_did.to_def_id(), sym::non_exhaustive) + }), ) } diff --git a/src/librustc_typeck/variance/constraints.rs b/src/librustc_typeck/variance/constraints.rs index cae09267994..b810c9824ce 100644 --- a/src/librustc_typeck/variance/constraints.rs +++ b/src/librustc_typeck/variance/constraints.rs @@ -161,6 +161,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { self.add_constraints_from_sig(current_item, tcx.fn_sig(def_id), self.covariant); } + ty::Error(_) => {} _ => { span_bug!( tcx.def_span(def_id), diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index 98d8f100b27..9c44d27447d 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -430,14 +430,14 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> { } // Converts the calculated ParamEnv and lifetime information to a clean::Generics, suitable for - // display on the docs page. Cleaning the Predicates produces sub-optimal WherePredicate's, + // display on the docs page. Cleaning the Predicates produces sub-optimal `WherePredicate`s, // so we fix them up: // // * Multiple bounds for the same type are coalesced into one: e.g., 'T: Copy', 'T: Debug' // becomes 'T: Copy + Debug' // * Fn bounds are handled specially - instead of leaving it as 'T: Fn(), <T as Fn::Output> = // K', we use the dedicated syntax 'T: Fn() -> K' - // * We explcitly add a '?Sized' bound if we didn't find any 'Sized' predicates for a type + // * We explicitly add a '?Sized' bound if we didn't find any 'Sized' predicates for a type fn param_env_to_generics( &self, tcx: TyCtxt<'tcx>, @@ -480,6 +480,11 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> { .clean(self.cx) .params; + debug!( + "param_env_to_generics({:?}): generic_params={:?}", + param_env_def_id, generic_params + ); + let mut has_sized = FxHashSet::default(); let mut ty_to_bounds: FxHashMap<_, FxHashSet<_>> = Default::default(); let mut lifetime_to_bounds: FxHashMap<_, FxHashSet<_>> = Default::default(); @@ -588,7 +593,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> { .args; match args { - // Convert somethiung like '<T as Iterator::Item> = u8' + // Convert something like '<T as Iterator::Item> = u8' // to 'T: Iterator<Item=u8>' GenericArgs::AngleBracketed { ref mut bindings, .. @@ -712,7 +717,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> { // since FxHasher has different behavior for 32-bit and 64-bit platforms. // // Obviously, it's extremely undesirable for documentation rendering - // to be depndent on the platform it's run on. Apart from being confusing + // to be dependent on the platform it's run on. Apart from being confusing // to end users, it makes writing tests much more difficult, as predicates // can appear in any order in the final result. // diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index cc3a60c596a..5b048372624 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -716,11 +716,11 @@ impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics, ty::GenericPredicates<'tcx // Bounds in the type_params and lifetimes fields are repeated in the // predicates field (see rustc_typeck::collect::ty_generics), so remove // them. - let stripped_typarams = gens + let stripped_params = gens .params .iter() .filter_map(|param| match param.kind { - ty::GenericParamDefKind::Lifetime => None, + ty::GenericParamDefKind::Lifetime => Some(param.clean(cx)), ty::GenericParamDefKind::Type { synthetic, .. } => { if param.name == kw::SelfUpper { assert_eq!(param.index, 0); @@ -732,7 +732,7 @@ impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics, ty::GenericPredicates<'tcx } Some(param.clean(cx)) } - ty::GenericParamDefKind::Const { .. } => None, + ty::GenericParamDefKind::Const { .. } => Some(param.clean(cx)), }) .collect::<Vec<GenericParamDef>>(); @@ -844,8 +844,10 @@ impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics, ty::GenericPredicates<'tcx // Run through the type parameters again and insert a ?Sized // unbound for any we didn't find to be Sized. - for tp in &stripped_typarams { - if !sized_params.contains(&tp.name) { + for tp in &stripped_params { + if matches!(tp.kind, types::GenericParamDefKind::Type { .. }) + && !sized_params.contains(&tp.name) + { where_predicates.push(WP::BoundPredicate { ty: Type::Generic(tp.name.clone()), bounds: vec![GenericBound::maybe_sized(cx)], @@ -858,16 +860,7 @@ impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics, ty::GenericPredicates<'tcx // and instead see `where T: Foo + Bar + Sized + 'a` Generics { - params: gens - .params - .iter() - .flat_map(|param| match param.kind { - ty::GenericParamDefKind::Lifetime => Some(param.clean(cx)), - ty::GenericParamDefKind::Type { .. } => None, - ty::GenericParamDefKind::Const { .. } => Some(param.clean(cx)), - }) - .chain(simplify::ty_params(stripped_typarams).into_iter()) - .collect(), + params: stripped_params, where_predicates: simplify::where_clauses(cx, where_predicates), } } diff --git a/src/librustdoc/clean/simplify.rs b/src/librustdoc/clean/simplify.rs index 0f995a60c22..990189f6ea0 100644 --- a/src/librustdoc/clean/simplify.rs +++ b/src/librustdoc/clean/simplify.rs @@ -12,7 +12,6 @@ //! bounds by special casing scenarios such as these. Fun! use std::collections::BTreeMap; -use std::mem; use rustc_hir::def_id::DefId; use rustc_middle::ty; @@ -118,18 +117,6 @@ pub fn merge_bounds( }) } -pub fn ty_params(mut params: Vec<clean::GenericParamDef>) -> Vec<clean::GenericParamDef> { - for param in &mut params { - match param.kind { - clean::GenericParamDefKind::Type { ref mut bounds, .. } => { - *bounds = mem::take(bounds); - } - _ => panic!("expected only type parameters"), - } - } - params -} - fn trait_is_same_or_supertrait(cx: &DocContext<'_>, child: DefId, trait_: DefId) -> bool { if child == trait_ { return true; diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 071834c59d6..89549eae2cb 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -32,8 +32,9 @@ use crate::clean::inline; use crate::clean::types::Type::{QPath, ResolvedPath}; use crate::core::DocContext; use crate::doctree; -use crate::html::item_type::ItemType; -use crate::html::render::{cache, ExternalLocation}; +use crate::formats::cache::cache; +use crate::formats::item_type::ItemType; +use crate::html::render::cache::ExternalLocation; use self::FnRetTy::*; use self::ItemEnum::*; @@ -1172,7 +1173,7 @@ impl GetDefId for Type { fn def_id(&self) -> Option<DefId> { match *self { ResolvedPath { did, .. } => Some(did), - Primitive(p) => crate::html::render::cache().primitive_locations.get(&p).cloned(), + Primitive(p) => cache().primitive_locations.get(&p).cloned(), BorrowedRef { type_: box Generic(..), .. } => { Primitive(PrimitiveType::Reference).def_id() } diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index 39e33da4496..4f751decc80 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -4,6 +4,9 @@ use std::ffi::OsStr; use std::fmt; use std::path::PathBuf; +use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_hir::def_id::DefId; +use rustc_middle::middle::privacy::AccessLevels; use rustc_session::config::{self, parse_crate_types_from_list, parse_externs, CrateType}; use rustc_session::config::{ build_codegen_options, build_debugging_options, get_cmd_lint_options, host_triple, @@ -249,6 +252,20 @@ pub struct RenderOptions { pub document_hidden: bool, } +/// Temporary storage for data obtained during `RustdocVisitor::clean()`. +/// Later on moved into `CACHE_KEY`. +#[derive(Default, Clone)] +pub struct RenderInfo { + pub inlined: FxHashSet<DefId>, + pub external_paths: crate::core::ExternalPaths, + pub exact_paths: FxHashMap<DefId, Vec<String>>, + pub access_levels: AccessLevels<DefId>, + pub deref_trait_did: Option<DefId>, + pub deref_mut_trait_did: Option<DefId>, + pub owned_box_did: Option<DefId>, + pub output_format: Option<OutputFormat>, +} + impl Options { /// Parses the given command-line for options. If an error message or other early-return has /// been printed, returns `Err` with the exit code. @@ -491,7 +508,7 @@ impl Options { let output_format = match matches.opt_str("output-format") { Some(s) => match OutputFormat::try_from(s.as_str()) { Ok(o) => { - if o.is_json() && !show_coverage { + if o.is_json() && !(show_coverage || nightly_options::is_nightly_build()) { diag.struct_err("json output format isn't supported for doc generation") .emit(); return Err(1); @@ -609,7 +626,9 @@ fn check_deprecated_options(matches: &getopts::Matches, diag: &rustc_errors::Han for flag in deprecated_flags.iter() { if matches.opt_present(flag) { - if *flag == "output-format" && matches.opt_present("show-coverage") { + if *flag == "output-format" + && (matches.opt_present("show-coverage") || nightly_options::is_nightly_build()) + { continue; } let mut err = diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 263909d5559..cbd0ca0de64 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -32,8 +32,8 @@ use std::rc::Rc; use crate::clean; use crate::clean::{AttributesExt, MAX_DEF_ID}; +use crate::config::RenderInfo; use crate::config::{Options as RustdocOptions, RenderOptions}; -use crate::html::render::RenderInfo; use crate::passes::{self, Condition::*, ConditionalPass}; pub use rustc_session::config::{CodegenOptions, DebuggingOptions, Input, Options}; @@ -44,9 +44,9 @@ pub type ExternalPaths = FxHashMap<DefId, (Vec<String>, clean::TypeKind)>; pub struct DocContext<'tcx> { pub tcx: TyCtxt<'tcx>, pub resolver: Rc<RefCell<interface::BoxedResolver>>, - /// Later on moved into `html::render::CACHE_KEY` + /// Later on moved into `CACHE_KEY` pub renderinfo: RefCell<RenderInfo>, - /// Later on moved through `clean::Crate` into `html::render::CACHE_KEY` + /// Later on moved through `clean::Crate` into `CACHE_KEY` pub external_traits: Rc<RefCell<FxHashMap<DefId, clean::Trait>>>, /// Used while populating `external_traits` to ensure we don't process the same trait twice at /// the same time. @@ -315,7 +315,7 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt let cpath = Some(input.clone()); let input = Input::File(input); - let intra_link_resolution_failure_name = lint::builtin::INTRA_DOC_LINK_RESOLUTION_FAILURE.name; + let intra_link_resolution_failure_name = lint::builtin::BROKEN_INTRA_DOC_LINKS.name; let missing_docs = rustc_lint::builtin::MISSING_DOCS.name; let missing_doc_example = rustc_lint::builtin::MISSING_DOC_CODE_EXAMPLES.name; let private_doc_tests = rustc_lint::builtin::PRIVATE_DOC_TESTS.name; diff --git a/src/librustdoc/docfs.rs b/src/librustdoc/docfs.rs index 9a11e8fce28..4ce6bcbe274 100644 --- a/src/librustdoc/docfs.rs +++ b/src/librustdoc/docfs.rs @@ -13,8 +13,7 @@ use std::fs; use std::io; use std::path::Path; use std::string::ToString; -use std::sync::mpsc::{channel, Receiver, Sender}; -use std::sync::Arc; +use std::sync::mpsc::Sender; macro_rules! try_err { ($e:expr, $file:expr) => { @@ -31,47 +30,24 @@ pub trait PathError { S: ToString + Sized; } -pub struct ErrorStorage { - sender: Option<Sender<Option<String>>>, - receiver: Receiver<Option<String>>, -} - -impl ErrorStorage { - pub fn new() -> ErrorStorage { - let (sender, receiver) = channel(); - ErrorStorage { sender: Some(sender), receiver } - } - - /// Prints all stored errors. Returns the number of printed errors. - pub fn write_errors(&mut self, diag: &rustc_errors::Handler) -> usize { - let mut printed = 0; - // In order to drop the sender part of the channel. - self.sender = None; - - for msg in self.receiver.iter() { - if let Some(ref error) = msg { - diag.struct_err(&error).emit(); - printed += 1; - } - } - printed - } -} - pub struct DocFS { sync_only: bool, - errors: Arc<ErrorStorage>, + errors: Option<Sender<String>>, } impl DocFS { - pub fn new(errors: &Arc<ErrorStorage>) -> DocFS { - DocFS { sync_only: false, errors: Arc::clone(errors) } + pub fn new(errors: Sender<String>) -> DocFS { + DocFS { sync_only: false, errors: Some(errors) } } pub fn set_sync_only(&mut self, sync_only: bool) { self.sync_only = sync_only; } + pub fn close(&mut self) { + self.errors = None; + } + pub fn create_dir_all<P: AsRef<Path>>(&self, path: P) -> io::Result<()> { // For now, dir creation isn't a huge time consideration, do it // synchronously, which avoids needing ordering between write() actions @@ -88,20 +64,15 @@ impl DocFS { if !self.sync_only && cfg!(windows) { // A possible future enhancement after more detailed profiling would // be to create the file sync so errors are reported eagerly. - let contents = contents.as_ref().to_vec(); let path = path.as_ref().to_path_buf(); - let sender = self.errors.sender.clone().unwrap(); - rayon::spawn(move || match fs::write(&path, &contents) { - Ok(_) => { - sender.send(None).unwrap_or_else(|_| { - panic!("failed to send error on \"{}\"", path.display()) - }); - } - Err(e) => { - sender.send(Some(format!("\"{}\": {}", path.display(), e))).unwrap_or_else( - |_| panic!("failed to send non-error on \"{}\"", path.display()), - ); - } + let contents = contents.as_ref().to_vec(); + let sender = self.errors.clone().expect("can't write after closing"); + rayon::spawn(move || { + fs::write(&path, contents).unwrap_or_else(|e| { + sender + .send(format!("\"{}\": {}", path.display(), e)) + .expect(&format!("failed to send error on \"{}\"", path.display())); + }); }); Ok(()) } else { diff --git a/src/librustdoc/error.rs b/src/librustdoc/error.rs new file mode 100644 index 00000000000..77063ab4639 --- /dev/null +++ b/src/librustdoc/error.rs @@ -0,0 +1,56 @@ +use std::error; +use std::fmt::{self, Formatter}; +use std::path::{Path, PathBuf}; + +use crate::docfs::PathError; + +#[derive(Debug)] +pub struct Error { + pub file: PathBuf, + pub error: String, +} + +impl error::Error for Error {} + +impl std::fmt::Display for Error { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + let file = self.file.display().to_string(); + if file.is_empty() { + write!(f, "{}", self.error) + } else { + write!(f, "\"{}\": {}", self.file.display(), self.error) + } + } +} + +impl PathError for Error { + fn new<S, P: AsRef<Path>>(e: S, path: P) -> Error + where + S: ToString + Sized, + { + Error { file: path.as_ref().to_path_buf(), error: e.to_string() } + } +} + +#[macro_export] +macro_rules! try_none { + ($e:expr, $file:expr) => {{ + use std::io; + match $e { + Some(e) => e, + None => { + return Err(Error::new(io::Error::new(io::ErrorKind::Other, "not found"), $file)); + } + } + }}; +} + +#[macro_export] +macro_rules! try_err { + ($e:expr, $file:expr) => {{ + match $e { + Ok(e) => e, + Err(e) => return Err(Error::new(e, $file)), + } + }}; +} diff --git a/src/librustdoc/formats/cache.rs b/src/librustdoc/formats/cache.rs new file mode 100644 index 00000000000..99b31473f87 --- /dev/null +++ b/src/librustdoc/formats/cache.rs @@ -0,0 +1,488 @@ +use std::cell::RefCell; +use std::collections::BTreeMap; +use std::mem; +use std::path::{Path, PathBuf}; +use std::sync::Arc; + +use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX}; +use rustc_middle::middle::privacy::AccessLevels; +use rustc_span::source_map::FileName; + +use crate::clean::{self, GetDefId}; +use crate::config::RenderInfo; +use crate::fold::DocFolder; +use crate::formats::item_type::ItemType; +use crate::formats::Impl; +use crate::html::render::cache::{extern_location, get_index_search_type, ExternalLocation}; +use crate::html::render::IndexItem; +use crate::html::render::{plain_summary_line, shorten}; + +thread_local!(crate static CACHE_KEY: RefCell<Arc<Cache>> = Default::default()); + +/// This cache is used to store information about the `clean::Crate` being +/// rendered in order to provide more useful documentation. This contains +/// information like all implementors of a trait, all traits a type implements, +/// documentation for all known traits, etc. +/// +/// This structure purposefully does not implement `Clone` because it's intended +/// to be a fairly large and expensive structure to clone. Instead this adheres +/// to `Send` so it may be stored in a `Arc` instance and shared among the various +/// rendering threads. +#[derive(Default)] +pub struct Cache { + /// Maps a type ID to all known implementations for that type. This is only + /// recognized for intra-crate `ResolvedPath` types, and is used to print + /// out extra documentation on the page of an enum/struct. + /// + /// The values of the map are a list of implementations and documentation + /// found on that implementation. + pub impls: FxHashMap<DefId, Vec<Impl>>, + + /// Maintains a mapping of local crate `DefId`s to the fully qualified name + /// and "short type description" of that node. This is used when generating + /// URLs when a type is being linked to. External paths are not located in + /// this map because the `External` type itself has all the information + /// necessary. + pub paths: FxHashMap<DefId, (Vec<String>, ItemType)>, + + /// Similar to `paths`, but only holds external paths. This is only used for + /// generating explicit hyperlinks to other crates. + pub external_paths: FxHashMap<DefId, (Vec<String>, ItemType)>, + + /// Maps local `DefId`s of exported types to fully qualified paths. + /// Unlike 'paths', this mapping ignores any renames that occur + /// due to 'use' statements. + /// + /// This map is used when writing out the special 'implementors' + /// javascript file. By using the exact path that the type + /// is declared with, we ensure that each path will be identical + /// to the path used if the corresponding type is inlined. By + /// doing this, we can detect duplicate impls on a trait page, and only display + /// the impl for the inlined type. + pub exact_paths: FxHashMap<DefId, Vec<String>>, + + /// This map contains information about all known traits of this crate. + /// Implementations of a crate should inherit the documentation of the + /// parent trait if no extra documentation is specified, and default methods + /// should show up in documentation about trait implementations. + pub traits: FxHashMap<DefId, clean::Trait>, + + /// When rendering traits, it's often useful to be able to list all + /// implementors of the trait, and this mapping is exactly, that: a mapping + /// of trait ids to the list of known implementors of the trait + pub implementors: FxHashMap<DefId, Vec<Impl>>, + + /// Cache of where external crate documentation can be found. + pub extern_locations: FxHashMap<CrateNum, (String, PathBuf, ExternalLocation)>, + + /// Cache of where documentation for primitives can be found. + pub primitive_locations: FxHashMap<clean::PrimitiveType, DefId>, + + // Note that external items for which `doc(hidden)` applies to are shown as + // non-reachable while local items aren't. This is because we're reusing + // the access levels from the privacy check pass. + pub access_levels: AccessLevels<DefId>, + + /// The version of the crate being documented, if given from the `--crate-version` flag. + pub crate_version: Option<String>, + + /// Whether to document private items. + /// This is stored in `Cache` so it doesn't need to be passed through all rustdoc functions. + pub document_private: bool, + + // Private fields only used when initially crawling a crate to build a cache + stack: Vec<String>, + parent_stack: Vec<DefId>, + parent_is_trait_impl: bool, + stripped_mod: bool, + masked_crates: FxHashSet<CrateNum>, + + pub search_index: Vec<IndexItem>, + pub deref_trait_did: Option<DefId>, + pub deref_mut_trait_did: Option<DefId>, + pub owned_box_did: Option<DefId>, + + // In rare case where a structure is defined in one module but implemented + // in another, if the implementing module is parsed before defining module, + // then the fully qualified name of the structure isn't presented in `paths` + // yet when its implementation methods are being indexed. Caches such methods + // and their parent id here and indexes them at the end of crate parsing. + pub orphan_impl_items: Vec<(DefId, clean::Item)>, + + // Similarly to `orphan_impl_items`, sometimes trait impls are picked up + // even though the trait itself is not exported. This can happen if a trait + // was defined in function/expression scope, since the impl will be picked + // up by `collect-trait-impls` but the trait won't be scraped out in the HIR + // crawl. In order to prevent crashes when looking for spotlight traits or + // when gathering trait documentation on a type, hold impls here while + // folding and add them to the cache later on if we find the trait. + orphan_trait_impls: Vec<(DefId, FxHashSet<DefId>, Impl)>, + + /// Aliases added through `#[doc(alias = "...")]`. Since a few items can have the same alias, + /// we need the alias element to have an array of items. + pub aliases: BTreeMap<String, Vec<usize>>, +} + +impl Cache { + pub fn from_krate( + render_info: RenderInfo, + document_private: bool, + extern_html_root_urls: &BTreeMap<String, String>, + dst: &Path, + mut krate: clean::Crate, + ) -> (clean::Crate, Cache) { + // Crawl the crate to build various caches used for the output + let RenderInfo { + inlined: _, + external_paths, + exact_paths, + access_levels, + deref_trait_did, + deref_mut_trait_did, + owned_box_did, + .. + } = render_info; + + let external_paths = + external_paths.into_iter().map(|(k, (v, t))| (k, (v, ItemType::from(t)))).collect(); + + let mut cache = Cache { + external_paths, + exact_paths, + parent_is_trait_impl: false, + stripped_mod: false, + access_levels, + crate_version: krate.version.take(), + document_private, + traits: krate.external_traits.replace(Default::default()), + deref_trait_did, + deref_mut_trait_did, + owned_box_did, + masked_crates: mem::take(&mut krate.masked_crates), + ..Cache::default() + }; + + // Cache where all our extern crates are located + // FIXME: this part is specific to HTML so it'd be nice to remove it from the common code + for &(n, ref e) in &krate.externs { + let src_root = match e.src { + FileName::Real(ref p) => match p.local_path().parent() { + Some(p) => p.to_path_buf(), + None => PathBuf::new(), + }, + _ => PathBuf::new(), + }; + let extern_url = extern_html_root_urls.get(&e.name).map(|u| &**u); + cache + .extern_locations + .insert(n, (e.name.clone(), src_root, extern_location(e, extern_url, &dst))); + + let did = DefId { krate: n, index: CRATE_DEF_INDEX }; + cache.external_paths.insert(did, (vec![e.name.to_string()], ItemType::Module)); + } + + // Cache where all known primitives have their documentation located. + // + // Favor linking to as local extern as possible, so iterate all crates in + // reverse topological order. + for &(_, ref e) in krate.externs.iter().rev() { + for &(def_id, prim, _) in &e.primitives { + cache.primitive_locations.insert(prim, def_id); + } + } + for &(def_id, prim, _) in &krate.primitives { + cache.primitive_locations.insert(prim, def_id); + } + + cache.stack.push(krate.name.clone()); + krate = cache.fold_crate(krate); + + for (trait_did, dids, impl_) in cache.orphan_trait_impls.drain(..) { + if cache.traits.contains_key(&trait_did) { + for did in dids { + cache.impls.entry(did).or_default().push(impl_.clone()); + } + } + } + + (krate, cache) + } +} + +impl DocFolder for Cache { + fn fold_item(&mut self, item: clean::Item) -> Option<clean::Item> { + if item.def_id.is_local() { + debug!("folding {} \"{:?}\", id {:?}", item.type_(), item.name, item.def_id); + } + + // If this is a stripped module, + // we don't want it or its children in the search index. + let orig_stripped_mod = match item.inner { + clean::StrippedItem(box clean::ModuleItem(..)) => { + mem::replace(&mut self.stripped_mod, true) + } + _ => self.stripped_mod, + }; + + // If the impl is from a masked crate or references something from a + // masked crate then remove it completely. + if let clean::ImplItem(ref i) = item.inner { + if self.masked_crates.contains(&item.def_id.krate) + || i.trait_.def_id().map_or(false, |d| self.masked_crates.contains(&d.krate)) + || i.for_.def_id().map_or(false, |d| self.masked_crates.contains(&d.krate)) + { + return None; + } + } + + // Propagate a trait method's documentation to all implementors of the + // trait. + if let clean::TraitItem(ref t) = item.inner { + self.traits.entry(item.def_id).or_insert_with(|| t.clone()); + } + + // Collect all the implementors of traits. + if let clean::ImplItem(ref i) = item.inner { + if let Some(did) = i.trait_.def_id() { + if i.blanket_impl.is_none() { + self.implementors + .entry(did) + .or_default() + .push(Impl { impl_item: item.clone() }); + } + } + } + + // Index this method for searching later on. + if let Some(ref s) = item.name { + let (parent, is_inherent_impl_item) = match item.inner { + clean::StrippedItem(..) => ((None, None), false), + clean::AssocConstItem(..) | clean::TypedefItem(_, true) + if self.parent_is_trait_impl => + { + // skip associated items in trait impls + ((None, None), false) + } + clean::AssocTypeItem(..) + | clean::TyMethodItem(..) + | clean::StructFieldItem(..) + | clean::VariantItem(..) => ( + ( + Some(*self.parent_stack.last().expect("parent_stack is empty")), + Some(&self.stack[..self.stack.len() - 1]), + ), + false, + ), + clean::MethodItem(..) | clean::AssocConstItem(..) => { + if self.parent_stack.is_empty() { + ((None, None), false) + } else { + let last = self.parent_stack.last().expect("parent_stack is empty 2"); + let did = *last; + let path = match self.paths.get(&did) { + // The current stack not necessarily has correlation + // for where the type was defined. On the other + // hand, `paths` always has the right + // information if present. + Some(&( + ref fqp, + ItemType::Trait + | ItemType::Struct + | ItemType::Union + | ItemType::Enum, + )) => Some(&fqp[..fqp.len() - 1]), + Some(..) => Some(&*self.stack), + None => None, + }; + ((Some(*last), path), true) + } + } + _ => ((None, Some(&*self.stack)), false), + }; + + match parent { + (parent, Some(path)) if is_inherent_impl_item || !self.stripped_mod => { + debug_assert!(!item.is_stripped()); + + // A crate has a module at its root, containing all items, + // which should not be indexed. The crate-item itself is + // inserted later on when serializing the search-index. + if item.def_id.index != CRATE_DEF_INDEX { + self.search_index.push(IndexItem { + ty: item.type_(), + name: s.to_string(), + path: path.join("::"), + desc: shorten(plain_summary_line(item.doc_value())), + parent, + parent_idx: None, + search_type: get_index_search_type(&item), + }); + + for alias in item.attrs.get_doc_aliases() { + self.aliases + .entry(alias.to_lowercase()) + .or_insert(Vec::new()) + .push(self.search_index.len() - 1); + } + } + } + (Some(parent), None) if is_inherent_impl_item => { + // We have a parent, but we don't know where they're + // defined yet. Wait for later to index this item. + self.orphan_impl_items.push((parent, item.clone())); + } + _ => {} + } + } + + // Keep track of the fully qualified path for this item. + let pushed = match item.name { + Some(ref n) if !n.is_empty() => { + self.stack.push(n.to_string()); + true + } + _ => false, + }; + + match item.inner { + clean::StructItem(..) + | clean::EnumItem(..) + | clean::TypedefItem(..) + | clean::TraitItem(..) + | clean::FunctionItem(..) + | clean::ModuleItem(..) + | clean::ForeignFunctionItem(..) + | clean::ForeignStaticItem(..) + | clean::ConstantItem(..) + | clean::StaticItem(..) + | clean::UnionItem(..) + | clean::ForeignTypeItem + | clean::MacroItem(..) + | clean::ProcMacroItem(..) + | clean::VariantItem(..) + if !self.stripped_mod => + { + // Re-exported items mean that the same id can show up twice + // in the rustdoc ast that we're looking at. We know, + // however, that a re-exported item doesn't show up in the + // `public_items` map, so we can skip inserting into the + // paths map if there was already an entry present and we're + // not a public item. + if !self.paths.contains_key(&item.def_id) + || self.access_levels.is_public(item.def_id) + { + self.paths.insert(item.def_id, (self.stack.clone(), item.type_())); + } + } + clean::PrimitiveItem(..) => { + self.paths.insert(item.def_id, (self.stack.clone(), item.type_())); + } + + _ => {} + } + + // Maintain the parent stack + let orig_parent_is_trait_impl = self.parent_is_trait_impl; + let parent_pushed = match item.inner { + clean::TraitItem(..) + | clean::EnumItem(..) + | clean::ForeignTypeItem + | clean::StructItem(..) + | clean::UnionItem(..) + | clean::VariantItem(..) => { + self.parent_stack.push(item.def_id); + self.parent_is_trait_impl = false; + true + } + clean::ImplItem(ref i) => { + self.parent_is_trait_impl = i.trait_.is_some(); + match i.for_ { + clean::ResolvedPath { did, .. } => { + self.parent_stack.push(did); + true + } + ref t => { + let prim_did = t + .primitive_type() + .and_then(|t| self.primitive_locations.get(&t).cloned()); + match prim_did { + Some(did) => { + self.parent_stack.push(did); + true + } + None => false, + } + } + } + } + _ => false, + }; + + // Once we've recursively found all the generics, hoard off all the + // implementations elsewhere. + let ret = self.fold_item_recur(item).and_then(|item| { + if let clean::Item { inner: clean::ImplItem(_), .. } = item { + // Figure out the id of this impl. This may map to a + // primitive rather than always to a struct/enum. + // Note: matching twice to restrict the lifetime of the `i` borrow. + let mut dids = FxHashSet::default(); + if let clean::Item { inner: clean::ImplItem(ref i), .. } = item { + match i.for_ { + clean::ResolvedPath { did, .. } + | clean::BorrowedRef { + type_: box clean::ResolvedPath { did, .. }, .. + } => { + dids.insert(did); + } + ref t => { + let did = t + .primitive_type() + .and_then(|t| self.primitive_locations.get(&t).cloned()); + + if let Some(did) = did { + dids.insert(did); + } + } + } + + if let Some(generics) = i.trait_.as_ref().and_then(|t| t.generics()) { + for bound in generics { + if let Some(did) = bound.def_id() { + dids.insert(did); + } + } + } + } else { + unreachable!() + }; + let impl_item = Impl { impl_item: item }; + if impl_item.trait_did().map_or(true, |d| self.traits.contains_key(&d)) { + for did in dids { + self.impls.entry(did).or_insert(vec![]).push(impl_item.clone()); + } + } else { + let trait_did = impl_item.trait_did().expect("no trait did"); + self.orphan_trait_impls.push((trait_did, dids, impl_item)); + } + None + } else { + Some(item) + } + }); + + if pushed { + self.stack.pop().expect("stack already empty"); + } + if parent_pushed { + self.parent_stack.pop().expect("parent stack already empty"); + } + self.stripped_mod = orig_stripped_mod; + self.parent_is_trait_impl = orig_parent_is_trait_impl; + ret + } +} + +crate fn cache() -> Arc<Cache> { + CACHE_KEY.with(|c| c.borrow().clone()) +} diff --git a/src/librustdoc/html/item_type.rs b/src/librustdoc/formats/item_type.rs index cc78b4682d2..696bdae94fc 100644 --- a/src/librustdoc/html/item_type.rs +++ b/src/librustdoc/formats/item_type.rs @@ -13,7 +13,7 @@ use crate::clean; /// The search index uses item types encoded as smaller numbers which equal to /// discriminants. JavaScript then is used to decode them into the original value. /// Consequently, every change to this type should be synchronized to -/// the `itemTypes` mapping table in `static/main.js`. +/// the `itemTypes` mapping table in `html/static/main.js`. /// /// In addition, code in `html::render` uses this enum to generate CSS classes, page prefixes, and /// module headings. If you are adding to this enum and want to ensure that the sidebar also prints diff --git a/src/librustdoc/formats/mod.rs b/src/librustdoc/formats/mod.rs new file mode 100644 index 00000000000..dcb0184c58c --- /dev/null +++ b/src/librustdoc/formats/mod.rs @@ -0,0 +1,44 @@ +pub mod cache; +pub mod item_type; +pub mod renderer; + +pub use renderer::{run_format, FormatRenderer}; + +use rustc_span::def_id::DefId; + +use crate::clean; +use crate::clean::types::GetDefId; + +/// Specifies whether rendering directly implemented trait items or ones from a certain Deref +/// impl. +pub enum AssocItemRender<'a> { + All, + DerefFor { trait_: &'a clean::Type, type_: &'a clean::Type, deref_mut_: bool }, +} + +/// For different handling of associated items from the Deref target of a type rather than the type +/// itself. +#[derive(Copy, Clone, PartialEq)] +pub enum RenderMode { + Normal, + ForDeref { mut_: bool }, +} + +/// Metadata about implementations for a type or trait. +#[derive(Clone, Debug)] +pub struct Impl { + pub impl_item: clean::Item, +} + +impl Impl { + pub fn inner_impl(&self) -> &clean::Impl { + match self.impl_item.inner { + clean::ImplItem(ref impl_) => impl_, + _ => panic!("non-impl item found in impl"), + } + } + + pub fn trait_did(&self) -> Option<DefId> { + self.inner_impl().trait_.def_id() + } +} diff --git a/src/librustdoc/formats/renderer.rs b/src/librustdoc/formats/renderer.rs new file mode 100644 index 00000000000..90ace4d44c4 --- /dev/null +++ b/src/librustdoc/formats/renderer.rs @@ -0,0 +1,106 @@ +use std::sync::Arc; + +use rustc_span::edition::Edition; + +use crate::clean; +use crate::config::{RenderInfo, RenderOptions}; +use crate::error::Error; +use crate::formats::cache::{Cache, CACHE_KEY}; + +/// Allows for different backends to rustdoc to be used with the `run_format()` function. Each +/// backend renderer has hooks for initialization, documenting an item, entering and exiting a +/// module, and cleanup/finalizing output. +pub trait FormatRenderer: Clone { + /// Sets up any state required for the renderer. When this is called the cache has already been + /// populated. + fn init( + krate: clean::Crate, + options: RenderOptions, + render_info: RenderInfo, + edition: Edition, + cache: &mut Cache, + ) -> Result<(Self, clean::Crate), Error>; + + /// Renders a single non-module item. This means no recursive sub-item rendering is required. + fn item(&mut self, item: clean::Item, cache: &Cache) -> Result<(), Error>; + + /// Renders a module (should not handle recursing into children). + fn mod_item_in( + &mut self, + item: &clean::Item, + item_name: &str, + cache: &Cache, + ) -> Result<(), Error>; + + /// Runs after recursively rendering all sub-items of a module. + fn mod_item_out(&mut self, item_name: &str) -> Result<(), Error>; + + /// Post processing hook for cleanup and dumping output to files. + fn after_krate(&mut self, krate: &clean::Crate, cache: &Cache) -> Result<(), Error>; + + /// Called after everything else to write out errors. + fn after_run(&mut self, diag: &rustc_errors::Handler) -> Result<(), Error>; +} + +/// Main method for rendering a crate. +pub fn run_format<T: FormatRenderer>( + krate: clean::Crate, + options: RenderOptions, + render_info: RenderInfo, + diag: &rustc_errors::Handler, + edition: Edition, +) -> Result<(), Error> { + let (krate, mut cache) = Cache::from_krate( + render_info.clone(), + options.document_private, + &options.extern_html_root_urls, + &options.output, + krate, + ); + + let (mut format_renderer, mut krate) = + T::init(krate, options, render_info, edition, &mut cache)?; + + let cache = Arc::new(cache); + // Freeze the cache now that the index has been built. Put an Arc into TLS for future + // parallelization opportunities + CACHE_KEY.with(|v| *v.borrow_mut() = cache.clone()); + + let mut item = match krate.module.take() { + Some(i) => i, + None => return Ok(()), + }; + + item.name = Some(krate.name.clone()); + + // Render the crate documentation + let mut work = vec![(format_renderer.clone(), item)]; + + while let Some((mut cx, item)) = work.pop() { + if item.is_mod() { + // modules are special because they add a namespace. We also need to + // recurse into the items of the module as well. + let name = item.name.as_ref().unwrap().to_string(); + if name.is_empty() { + panic!("Unexpected module with empty name"); + } + + cx.mod_item_in(&item, &name, &cache)?; + let module = match item.inner { + clean::StrippedItem(box clean::ModuleItem(m)) | clean::ModuleItem(m) => m, + _ => unreachable!(), + }; + for it in module.items { + debug!("Adding {:?} to worklist", it.name); + work.push((cx.clone(), it)); + } + + cx.mod_item_out(&name)?; + } else if item.name.is_some() { + cx.item(item, &cache)?; + } + } + + format_renderer.after_krate(&krate, &cache)?; + format_renderer.after_run(diag) +} diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 0d8284029af..699f8c36cba 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -11,13 +11,15 @@ use std::fmt; use rustc_data_structures::fx::FxHashSet; use rustc_hir as hir; -use rustc_hir::def_id::DefId; +use rustc_span::def_id::DefId; use rustc_target::spec::abi::Abi; use crate::clean::{self, PrimitiveType}; +use crate::formats::cache::cache; +use crate::formats::item_type::ItemType; use crate::html::escape::Escape; -use crate::html::item_type::ItemType; -use crate::html::render::{self, cache, CURRENT_DEPTH}; +use crate::html::render::cache::ExternalLocation; +use crate::html::render::CURRENT_DEPTH; pub trait Print { fn print(self, buffer: &mut Buffer); @@ -493,9 +495,9 @@ pub fn href(did: DefId) -> Option<(String, ItemType, Vec<String>)> { fqp, shortty, match cache.extern_locations[&did.krate] { - (.., render::Remote(ref s)) => s.to_string(), - (.., render::Local) => "../".repeat(depth), - (.., render::Unknown) => return None, + (.., ExternalLocation::Remote(ref s)) => s.to_string(), + (.., ExternalLocation::Local) => "../".repeat(depth), + (.., ExternalLocation::Unknown) => return None, }, ) } @@ -574,12 +576,12 @@ fn primitive_link( } Some(&def_id) => { let loc = match m.extern_locations[&def_id.krate] { - (ref cname, _, render::Remote(ref s)) => Some((cname, s.to_string())), - (ref cname, _, render::Local) => { + (ref cname, _, ExternalLocation::Remote(ref s)) => Some((cname, s.to_string())), + (ref cname, _, ExternalLocation::Local) => { let len = CURRENT_DEPTH.with(|s| s.get()); Some((cname, "../".repeat(len))) } - (.., render::Unknown) => None, + (.., ExternalLocation::Unknown) => None, }; if let Some((cname, root)) = loc { write!( diff --git a/src/librustdoc/html/mod.rs b/src/librustdoc/html/mod.rs new file mode 100644 index 00000000000..367538d440e --- /dev/null +++ b/src/librustdoc/html/mod.rs @@ -0,0 +1,9 @@ +crate mod escape; +crate mod format; +crate mod highlight; +crate mod layout; +pub mod markdown; +pub mod render; +crate mod sources; +crate mod static_files; +crate mod toc; diff --git a/src/librustdoc/html/render/cache.rs b/src/librustdoc/html/render/cache.rs index 1b5c8a9378e..378efa1a1be 100644 --- a/src/librustdoc/html/render/cache.rs +++ b/src/librustdoc/html/render/cache.rs @@ -1,18 +1,16 @@ -use crate::clean::{self, AttributesExt, GetDefId}; -use crate::fold::DocFolder; -use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX}; -use rustc_middle::middle::privacy::AccessLevels; -use rustc_span::source_map::FileName; -use rustc_span::symbol::sym; use std::collections::BTreeMap; -use std::mem; -use std::path::{Path, PathBuf}; +use std::path::Path; +use rustc_data_structures::fx::FxHashMap; +use rustc_span::symbol::sym; use serde::Serialize; -use super::{plain_summary_line, shorten, Impl, IndexItem, IndexItemFunctionType, ItemType}; -use super::{Generic, RenderInfo, RenderType, TypeWithKind}; +use crate::clean::types::GetDefId; +use crate::clean::{self, AttributesExt}; +use crate::formats::cache::Cache; +use crate::formats::item_type::ItemType; +use crate::html::render::{plain_summary_line, shorten}; +use crate::html::render::{Generic, IndexItem, IndexItemFunctionType, RenderType, TypeWithKind}; /// Indicates where an external crate can be found. pub enum ExternalLocation { @@ -24,483 +22,9 @@ pub enum ExternalLocation { Unknown, } -/// This cache is used to store information about the `clean::Crate` being -/// rendered in order to provide more useful documentation. This contains -/// information like all implementors of a trait, all traits a type implements, -/// documentation for all known traits, etc. -/// -/// This structure purposefully does not implement `Clone` because it's intended -/// to be a fairly large and expensive structure to clone. Instead this adheres -/// to `Send` so it may be stored in a `Arc` instance and shared among the various -/// rendering threads. -#[derive(Default)] -crate struct Cache { - /// Maps a type ID to all known implementations for that type. This is only - /// recognized for intra-crate `ResolvedPath` types, and is used to print - /// out extra documentation on the page of an enum/struct. - /// - /// The values of the map are a list of implementations and documentation - /// found on that implementation. - pub impls: FxHashMap<DefId, Vec<Impl>>, - - /// Maintains a mapping of local crate `DefId`s to the fully qualified name - /// and "short type description" of that node. This is used when generating - /// URLs when a type is being linked to. External paths are not located in - /// this map because the `External` type itself has all the information - /// necessary. - pub paths: FxHashMap<DefId, (Vec<String>, ItemType)>, - - /// Similar to `paths`, but only holds external paths. This is only used for - /// generating explicit hyperlinks to other crates. - pub external_paths: FxHashMap<DefId, (Vec<String>, ItemType)>, - - /// Maps local `DefId`s of exported types to fully qualified paths. - /// Unlike 'paths', this mapping ignores any renames that occur - /// due to 'use' statements. - /// - /// This map is used when writing out the special 'implementors' - /// javascript file. By using the exact path that the type - /// is declared with, we ensure that each path will be identical - /// to the path used if the corresponding type is inlined. By - /// doing this, we can detect duplicate impls on a trait page, and only display - /// the impl for the inlined type. - pub exact_paths: FxHashMap<DefId, Vec<String>>, - - /// This map contains information about all known traits of this crate. - /// Implementations of a crate should inherit the documentation of the - /// parent trait if no extra documentation is specified, and default methods - /// should show up in documentation about trait implementations. - pub traits: FxHashMap<DefId, clean::Trait>, - - /// When rendering traits, it's often useful to be able to list all - /// implementors of the trait, and this mapping is exactly, that: a mapping - /// of trait ids to the list of known implementors of the trait - pub implementors: FxHashMap<DefId, Vec<Impl>>, - - /// Cache of where external crate documentation can be found. - pub extern_locations: FxHashMap<CrateNum, (String, PathBuf, ExternalLocation)>, - - /// Cache of where documentation for primitives can be found. - pub primitive_locations: FxHashMap<clean::PrimitiveType, DefId>, - - // Note that external items for which `doc(hidden)` applies to are shown as - // non-reachable while local items aren't. This is because we're reusing - // the access levels from the privacy check pass. - pub access_levels: AccessLevels<DefId>, - - /// The version of the crate being documented, if given from the `--crate-version` flag. - pub crate_version: Option<String>, - - /// Whether to document private items. - /// This is stored in `Cache` so it doesn't need to be passed through all rustdoc functions. - pub document_private: bool, - - // Private fields only used when initially crawling a crate to build a cache - stack: Vec<String>, - parent_stack: Vec<DefId>, - parent_is_trait_impl: bool, - search_index: Vec<IndexItem>, - stripped_mod: bool, - pub deref_trait_did: Option<DefId>, - pub deref_mut_trait_did: Option<DefId>, - pub owned_box_did: Option<DefId>, - masked_crates: FxHashSet<CrateNum>, - - // In rare case where a structure is defined in one module but implemented - // in another, if the implementing module is parsed before defining module, - // then the fully qualified name of the structure isn't presented in `paths` - // yet when its implementation methods are being indexed. Caches such methods - // and their parent id here and indexes them at the end of crate parsing. - orphan_impl_items: Vec<(DefId, clean::Item)>, - - // Similarly to `orphan_impl_items`, sometimes trait impls are picked up - // even though the trait itself is not exported. This can happen if a trait - // was defined in function/expression scope, since the impl will be picked - // up by `collect-trait-impls` but the trait won't be scraped out in the HIR - // crawl. In order to prevent crashes when looking for spotlight traits or - // when gathering trait documentation on a type, hold impls here while - // folding and add them to the cache later on if we find the trait. - orphan_trait_impls: Vec<(DefId, FxHashSet<DefId>, Impl)>, - - /// Aliases added through `#[doc(alias = "...")]`. Since a few items can have the same alias, - /// we need the alias element to have an array of items. - pub(super) aliases: BTreeMap<String, Vec<usize>>, -} - -impl Cache { - pub fn from_krate( - renderinfo: RenderInfo, - document_private: bool, - extern_html_root_urls: &BTreeMap<String, String>, - dst: &Path, - mut krate: clean::Crate, - ) -> (clean::Crate, String, Cache) { - // Crawl the crate to build various caches used for the output - let RenderInfo { - inlined: _, - external_paths, - exact_paths, - access_levels, - deref_trait_did, - deref_mut_trait_did, - owned_box_did, - .. - } = renderinfo; - - let external_paths = - external_paths.into_iter().map(|(k, (v, t))| (k, (v, ItemType::from(t)))).collect(); - - let mut cache = Cache { - impls: Default::default(), - external_paths, - exact_paths, - paths: Default::default(), - implementors: Default::default(), - stack: Vec::new(), - parent_stack: Vec::new(), - search_index: Vec::new(), - parent_is_trait_impl: false, - extern_locations: Default::default(), - primitive_locations: Default::default(), - stripped_mod: false, - access_levels, - crate_version: krate.version.take(), - document_private, - orphan_impl_items: Vec::new(), - orphan_trait_impls: Vec::new(), - traits: krate.external_traits.replace(Default::default()), - deref_trait_did, - deref_mut_trait_did, - owned_box_did, - masked_crates: mem::take(&mut krate.masked_crates), - aliases: Default::default(), - }; - - // Cache where all our extern crates are located - for &(n, ref e) in &krate.externs { - let src_root = match e.src { - FileName::Real(ref p) => match p.local_path().parent() { - Some(p) => p.to_path_buf(), - None => PathBuf::new(), - }, - _ => PathBuf::new(), - }; - let extern_url = extern_html_root_urls.get(&e.name).map(|u| &**u); - cache - .extern_locations - .insert(n, (e.name.clone(), src_root, extern_location(e, extern_url, &dst))); - - let did = DefId { krate: n, index: CRATE_DEF_INDEX }; - cache.external_paths.insert(did, (vec![e.name.to_string()], ItemType::Module)); - } - - // Cache where all known primitives have their documentation located. - // - // Favor linking to as local extern as possible, so iterate all crates in - // reverse topological order. - for &(_, ref e) in krate.externs.iter().rev() { - for &(def_id, prim, _) in &e.primitives { - cache.primitive_locations.insert(prim, def_id); - } - } - for &(def_id, prim, _) in &krate.primitives { - cache.primitive_locations.insert(prim, def_id); - } - - cache.stack.push(krate.name.clone()); - krate = cache.fold_crate(krate); - - for (trait_did, dids, impl_) in cache.orphan_trait_impls.drain(..) { - if cache.traits.contains_key(&trait_did) { - for did in dids { - cache.impls.entry(did).or_insert(vec![]).push(impl_.clone()); - } - } - } - - // Build our search index - let index = build_index(&krate, &mut cache); - - (krate, index, cache) - } -} - -impl DocFolder for Cache { - fn fold_item(&mut self, item: clean::Item) -> Option<clean::Item> { - if item.def_id.is_local() { - debug!("folding {} \"{:?}\", id {:?}", item.type_(), item.name, item.def_id); - } - - // If this is a stripped module, - // we don't want it or its children in the search index. - let orig_stripped_mod = match item.inner { - clean::StrippedItem(box clean::ModuleItem(..)) => { - mem::replace(&mut self.stripped_mod, true) - } - _ => self.stripped_mod, - }; - - // If the impl is from a masked crate or references something from a - // masked crate then remove it completely. - if let clean::ImplItem(ref i) = item.inner { - if self.masked_crates.contains(&item.def_id.krate) - || i.trait_.def_id().map_or(false, |d| self.masked_crates.contains(&d.krate)) - || i.for_.def_id().map_or(false, |d| self.masked_crates.contains(&d.krate)) - { - return None; - } - } - - // Propagate a trait method's documentation to all implementors of the - // trait. - if let clean::TraitItem(ref t) = item.inner { - self.traits.entry(item.def_id).or_insert_with(|| t.clone()); - } - - // Collect all the implementors of traits. - if let clean::ImplItem(ref i) = item.inner { - if let Some(did) = i.trait_.def_id() { - if i.blanket_impl.is_none() { - self.implementors - .entry(did) - .or_default() - .push(Impl { impl_item: item.clone() }); - } - } - } - - // Index this method for searching later on. - if let Some(ref s) = item.name { - let (parent, is_inherent_impl_item) = match item.inner { - clean::StrippedItem(..) => ((None, None), false), - clean::AssocConstItem(..) | clean::TypedefItem(_, true) - if self.parent_is_trait_impl => - { - // skip associated items in trait impls - ((None, None), false) - } - clean::AssocTypeItem(..) - | clean::TyMethodItem(..) - | clean::StructFieldItem(..) - | clean::VariantItem(..) => ( - ( - Some(*self.parent_stack.last().expect("parent_stack is empty")), - Some(&self.stack[..self.stack.len() - 1]), - ), - false, - ), - clean::MethodItem(..) | clean::AssocConstItem(..) => { - if self.parent_stack.is_empty() { - ((None, None), false) - } else { - let last = self.parent_stack.last().expect("parent_stack is empty 2"); - let did = *last; - let path = match self.paths.get(&did) { - // The current stack not necessarily has correlation - // for where the type was defined. On the other - // hand, `paths` always has the right - // information if present. - Some(&( - ref fqp, - ItemType::Trait - | ItemType::Struct - | ItemType::Union - | ItemType::Enum, - )) => Some(&fqp[..fqp.len() - 1]), - Some(..) => Some(&*self.stack), - None => None, - }; - ((Some(*last), path), true) - } - } - _ => ((None, Some(&*self.stack)), false), - }; - - match parent { - (parent, Some(path)) if is_inherent_impl_item || !self.stripped_mod => { - debug_assert!(!item.is_stripped()); - - // A crate has a module at its root, containing all items, - // which should not be indexed. The crate-item itself is - // inserted later on when serializing the search-index. - if item.def_id.index != CRATE_DEF_INDEX { - self.search_index.push(IndexItem { - ty: item.type_(), - name: s.to_string(), - path: path.join("::"), - desc: shorten(plain_summary_line(item.doc_value())), - parent, - parent_idx: None, - search_type: get_index_search_type(&item), - }); - - for alias in item.attrs.get_doc_aliases() { - self.aliases - .entry(alias.to_lowercase()) - .or_insert(Vec::new()) - .push(self.search_index.len() - 1); - } - } - } - (Some(parent), None) if is_inherent_impl_item => { - // We have a parent, but we don't know where they're - // defined yet. Wait for later to index this item. - self.orphan_impl_items.push((parent, item.clone())); - } - _ => {} - } - } - - // Keep track of the fully qualified path for this item. - let pushed = match item.name { - Some(ref n) if !n.is_empty() => { - self.stack.push(n.to_string()); - true - } - _ => false, - }; - - match item.inner { - clean::StructItem(..) - | clean::EnumItem(..) - | clean::TypedefItem(..) - | clean::TraitItem(..) - | clean::FunctionItem(..) - | clean::ModuleItem(..) - | clean::ForeignFunctionItem(..) - | clean::ForeignStaticItem(..) - | clean::ConstantItem(..) - | clean::StaticItem(..) - | clean::UnionItem(..) - | clean::ForeignTypeItem - | clean::MacroItem(..) - | clean::ProcMacroItem(..) - | clean::VariantItem(..) - if !self.stripped_mod => - { - // Re-exported items mean that the same id can show up twice - // in the rustdoc ast that we're looking at. We know, - // however, that a re-exported item doesn't show up in the - // `public_items` map, so we can skip inserting into the - // paths map if there was already an entry present and we're - // not a public item. - if !self.paths.contains_key(&item.def_id) - || self.access_levels.is_public(item.def_id) - { - self.paths.insert(item.def_id, (self.stack.clone(), item.type_())); - } - } - clean::PrimitiveItem(..) => { - self.paths.insert(item.def_id, (self.stack.clone(), item.type_())); - } - - _ => {} - } - - // Maintain the parent stack - let orig_parent_is_trait_impl = self.parent_is_trait_impl; - let parent_pushed = match item.inner { - clean::TraitItem(..) - | clean::EnumItem(..) - | clean::ForeignTypeItem - | clean::StructItem(..) - | clean::UnionItem(..) - | clean::VariantItem(..) => { - self.parent_stack.push(item.def_id); - self.parent_is_trait_impl = false; - true - } - clean::ImplItem(ref i) => { - self.parent_is_trait_impl = i.trait_.is_some(); - match i.for_ { - clean::ResolvedPath { did, .. } => { - self.parent_stack.push(did); - true - } - ref t => { - let prim_did = t - .primitive_type() - .and_then(|t| self.primitive_locations.get(&t).cloned()); - match prim_did { - Some(did) => { - self.parent_stack.push(did); - true - } - None => false, - } - } - } - } - _ => false, - }; - - // Once we've recursively found all the generics, hoard off all the - // implementations elsewhere. - let ret = self.fold_item_recur(item).and_then(|item| { - if let clean::Item { inner: clean::ImplItem(_), .. } = item { - // Figure out the id of this impl. This may map to a - // primitive rather than always to a struct/enum. - // Note: matching twice to restrict the lifetime of the `i` borrow. - let mut dids = FxHashSet::default(); - if let clean::Item { inner: clean::ImplItem(ref i), .. } = item { - match i.for_ { - clean::ResolvedPath { did, .. } - | clean::BorrowedRef { - type_: box clean::ResolvedPath { did, .. }, .. - } => { - dids.insert(did); - } - ref t => { - let did = t - .primitive_type() - .and_then(|t| self.primitive_locations.get(&t).cloned()); - - if let Some(did) = did { - dids.insert(did); - } - } - } - - if let Some(generics) = i.trait_.as_ref().and_then(|t| t.generics()) { - for bound in generics { - if let Some(did) = bound.def_id() { - dids.insert(did); - } - } - } - } else { - unreachable!() - }; - let impl_item = Impl { impl_item: item }; - if impl_item.trait_did().map_or(true, |d| self.traits.contains_key(&d)) { - for did in dids { - self.impls.entry(did).or_insert(vec![]).push(impl_item.clone()); - } - } else { - let trait_did = impl_item.trait_did().expect("no trait did"); - self.orphan_trait_impls.push((trait_did, dids, impl_item)); - } - None - } else { - Some(item) - } - }); - - if pushed { - self.stack.pop().expect("stack already empty"); - } - if parent_pushed { - self.parent_stack.pop().expect("parent stack already empty"); - } - self.stripped_mod = orig_stripped_mod; - self.parent_is_trait_impl = orig_parent_is_trait_impl; - ret - } -} - /// Attempts to find where an external crate is located, given that we're /// rendering in to the specified source destination. -fn extern_location( +pub fn extern_location( e: &clean::ExternalCrate, extern_url: Option<&str>, dst: &Path, @@ -538,7 +62,7 @@ fn extern_location( } /// Builds the search index from the collected metadata -fn build_index(krate: &clean::Crate, cache: &mut Cache) -> String { +pub fn build_index(krate: &clean::Crate, cache: &mut Cache) -> String { let mut defid_to_pathid = FxHashMap::default(); let mut crate_items = Vec::with_capacity(cache.search_index.len()); let mut crate_paths = vec![]; @@ -640,7 +164,7 @@ fn build_index(krate: &clean::Crate, cache: &mut Cache) -> String { ) } -fn get_index_search_type(item: &clean::Item) -> Option<IndexItemFunctionType> { +crate fn get_index_search_type(item: &clean::Item) -> Option<IndexItemFunctionType> { let (all_types, ret_types) = match item.inner { clean::FunctionItem(ref f) => (&f.all_types, &f.ret_types), clean::MethodItem(ref m) => (&m.all_types, &m.ret_types), diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render/mod.rs index f7050cf3777..5fb2d9f6f91 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render/mod.rs @@ -25,14 +25,18 @@ //! These threads are not parallelized (they haven't been a bottleneck yet), and //! both occur before the crate is rendered. +pub mod cache; + +#[cfg(test)] +mod tests; + use std::borrow::Cow; use std::cell::{Cell, RefCell}; use std::cmp::Ordering; use std::collections::{BTreeMap, VecDeque}; use std::default::Default; -use std::error; use std::ffi::OsStr; -use std::fmt::{self, Formatter, Write}; +use std::fmt::{self, Write}; use std::fs::{self, File}; use std::io::prelude::*; use std::io::{self, BufReader}; @@ -40,6 +44,7 @@ use std::path::{Component, Path, PathBuf}; use std::rc::Rc; use std::str; use std::string::ToString; +use std::sync::mpsc::{channel, Receiver}; use std::sync::Arc; use itertools::Itertools; @@ -50,7 +55,6 @@ use rustc_feature::UnstableFeatures; use rustc_hir as hir; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; use rustc_hir::Mutability; -use rustc_middle::middle::privacy::AccessLevels; use rustc_middle::middle::stability; use rustc_span::edition::Edition; use rustc_span::hygiene::MacroKind; @@ -60,26 +64,23 @@ use serde::ser::SerializeSeq; use serde::{Serialize, Serializer}; use crate::clean::{self, AttributesExt, Deprecation, GetDefId, SelfTy, TypeKind}; -use crate::config::{OutputFormat, RenderOptions}; -use crate::docfs::{DocFS, ErrorStorage, PathError}; +use crate::config::RenderInfo; +use crate::config::RenderOptions; +use crate::docfs::{DocFS, PathError}; use crate::doctree; +use crate::error::Error; +use crate::formats::cache::{cache, Cache}; +use crate::formats::item_type::ItemType; +use crate::formats::{AssocItemRender, FormatRenderer, Impl, RenderMode}; use crate::html::escape::Escape; use crate::html::format::fmt_impl_for_trait_page; use crate::html::format::Function; use crate::html::format::{href, print_default_space, print_generic_bounds, WhereClause}; use crate::html::format::{print_abi_with_space, Buffer, PrintWithSpace}; -use crate::html::item_type::ItemType; use crate::html::markdown::{self, ErrorCodes, IdMap, Markdown, MarkdownHtml, MarkdownSummaryLine}; use crate::html::sources; use crate::html::{highlight, layout, static_files}; - -#[cfg(test)] -mod tests; - -mod cache; - -use cache::Cache; -crate use cache::ExternalLocation::{self, *}; +use cache::{build_index, ExternalLocation}; /// A pair of name and its optional document. pub type NameDoc = (String, Option<String>); @@ -90,55 +91,6 @@ crate fn ensure_trailing_slash(v: &str) -> impl fmt::Display + '_ { }) } -#[derive(Debug)] -pub struct Error { - pub file: PathBuf, - pub error: String, -} - -impl error::Error for Error {} - -impl std::fmt::Display for Error { - fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - let file = self.file.display().to_string(); - if file.is_empty() { - write!(f, "{}", self.error) - } else { - write!(f, "\"{}\": {}", self.file.display(), self.error) - } - } -} - -impl PathError for Error { - fn new<S, P: AsRef<Path>>(e: S, path: P) -> Error - where - S: ToString + Sized, - { - Error { file: path.as_ref().to_path_buf(), error: e.to_string() } - } -} - -macro_rules! try_none { - ($e:expr, $file:expr) => {{ - use std::io; - match $e { - Some(e) => e, - None => { - return Err(Error::new(io::Error::new(io::ErrorKind::Other, "not found"), $file)); - } - } - }}; -} - -macro_rules! try_err { - ($e:expr, $file:expr) => {{ - match $e { - Ok(e) => e, - Err(e) => return Err(Error::new(e, $file)), - } - }}; -} - /// Major driving force in all rustdoc rendering. This contains information /// about where in the tree-like hierarchy rendering is occurring and controls /// how the current page is being rendered. @@ -147,7 +99,7 @@ macro_rules! try_err { /// easily cloned because it is cloned per work-job (about once per item in the /// rustdoc tree). #[derive(Clone)] -struct Context { +crate struct Context { /// Current hierarchy of components leading down to what's currently being /// rendered pub current: Vec<String>, @@ -161,7 +113,10 @@ struct Context { /// The map used to ensure all generated 'id=' attributes are unique. id_map: Rc<RefCell<IdMap>>, pub shared: Arc<SharedContext>, - pub cache: Arc<Cache>, + all: Rc<RefCell<AllTypes>>, + /// Storage for the errors produced while generating documentation so they + /// can be printed together at the end. + pub errors: Rc<Receiver<String>>, } crate struct SharedContext { @@ -241,53 +196,20 @@ impl SharedContext { } } -/// Metadata about implementations for a type or trait. -#[derive(Clone, Debug)] -pub struct Impl { - pub impl_item: clean::Item, -} - -impl Impl { - fn inner_impl(&self) -> &clean::Impl { - match self.impl_item.inner { - clean::ImplItem(ref impl_) => impl_, - _ => panic!("non-impl item found in impl"), - } - } - - fn trait_did(&self) -> Option<DefId> { - self.inner_impl().trait_.def_id() - } -} - -/// Temporary storage for data obtained during `RustdocVisitor::clean()`. -/// Later on moved into `CACHE_KEY`. -#[derive(Default)] -pub struct RenderInfo { - pub inlined: FxHashSet<DefId>, - pub external_paths: crate::core::ExternalPaths, - pub exact_paths: FxHashMap<DefId, Vec<String>>, - pub access_levels: AccessLevels<DefId>, - pub deref_trait_did: Option<DefId>, - pub deref_mut_trait_did: Option<DefId>, - pub owned_box_did: Option<DefId>, - pub output_format: Option<OutputFormat>, -} - // Helper structs for rendering items/sidebars and carrying along contextual // information /// Struct representing one entry in the JS search index. These are all emitted /// by hand to a large JS file at the end of cache-creation. #[derive(Debug)] -struct IndexItem { - ty: ItemType, - name: String, - path: String, - desc: String, - parent: Option<DefId>, - parent_idx: Option<usize>, - search_type: Option<IndexItemFunctionType>, +pub struct IndexItem { + pub ty: ItemType, + pub name: String, + pub path: String, + pub desc: String, + pub parent: Option<DefId>, + pub parent_idx: Option<usize>, + pub search_type: Option<IndexItemFunctionType>, } impl Serialize for IndexItem { @@ -309,7 +231,7 @@ impl Serialize for IndexItem { /// A type used for the search index. #[derive(Debug)] -struct RenderType { +crate struct RenderType { ty: Option<DefId>, idx: Option<usize>, name: Option<String>, @@ -340,7 +262,7 @@ impl Serialize for RenderType { /// A type used for the search index. #[derive(Debug)] -struct Generic { +crate struct Generic { name: String, defid: Option<DefId>, idx: Option<usize>, @@ -361,7 +283,7 @@ impl Serialize for Generic { /// Full type of functions/methods in the search index. #[derive(Debug)] -struct IndexItemFunctionType { +pub struct IndexItemFunctionType { inputs: Vec<TypeWithKind>, output: Option<Vec<TypeWithKind>>, } @@ -394,7 +316,7 @@ impl Serialize for IndexItemFunctionType { } #[derive(Debug)] -pub struct TypeWithKind { +crate struct TypeWithKind { ty: RenderType, kind: TypeKind, } @@ -426,7 +348,6 @@ pub struct StylePath { pub disabled: bool, } -thread_local!(static CACHE_KEY: RefCell<Arc<Cache>> = Default::default()); thread_local!(pub static CURRENT_DEPTH: Cell<usize> = Cell::new(0)); pub fn initial_ids() -> Vec<String> { @@ -454,147 +375,301 @@ pub fn initial_ids() -> Vec<String> { } /// Generates the documentation for `crate` into the directory `dst` -pub fn run( - mut krate: clean::Crate, - options: RenderOptions, - renderinfo: RenderInfo, - diag: &rustc_errors::Handler, - edition: Edition, -) -> Result<(), Error> { - // need to save a copy of the options for rendering the index page - let md_opts = options.clone(); - let RenderOptions { - output, - external_html, - id_map, - playground_url, - sort_modules_alphabetically, - themes: style_files, - extension_css, - extern_html_root_urls, - resource_suffix, - static_root_path, - generate_search_filter, - document_private, - .. - } = options; - - let src_root = match krate.src { - FileName::Real(ref p) => match p.local_path().parent() { - Some(p) => p.to_path_buf(), - None => PathBuf::new(), - }, - _ => PathBuf::new(), - }; - let mut errors = Arc::new(ErrorStorage::new()); - // If user passed in `--playground-url` arg, we fill in crate name here - let mut playground = None; - if let Some(url) = playground_url { - playground = Some(markdown::Playground { crate_name: Some(krate.name.clone()), url }); - } - let mut layout = layout::Layout { - logo: String::new(), - favicon: String::new(), - external_html, - krate: krate.name.clone(), - css_file_extension: extension_css, - generate_search_filter, - }; - let mut issue_tracker_base_url = None; - let mut include_sources = true; - - // Crawl the crate attributes looking for attributes which control how we're - // going to emit HTML - if let Some(attrs) = krate.module.as_ref().map(|m| &m.attrs) { - for attr in attrs.lists(sym::doc) { - match (attr.name_or_empty(), attr.value_str()) { - (sym::html_favicon_url, Some(s)) => { - layout.favicon = s.to_string(); - } - (sym::html_logo_url, Some(s)) => { - layout.logo = s.to_string(); - } - (sym::html_playground_url, Some(s)) => { - playground = Some(markdown::Playground { - crate_name: Some(krate.name.clone()), - url: s.to_string(), - }); - } - (sym::issue_tracker_base_url, Some(s)) => { - issue_tracker_base_url = Some(s.to_string()); - } - (sym::html_no_source, None) if attr.is_word() => { - include_sources = false; +impl FormatRenderer for Context { + fn init( + mut krate: clean::Crate, + options: RenderOptions, + _render_info: RenderInfo, + edition: Edition, + cache: &mut Cache, + ) -> Result<(Context, clean::Crate), Error> { + // need to save a copy of the options for rendering the index page + let md_opts = options.clone(); + let RenderOptions { + output, + external_html, + id_map, + playground_url, + sort_modules_alphabetically, + themes: style_files, + extension_css, + resource_suffix, + static_root_path, + generate_search_filter, + .. + } = options; + + let src_root = match krate.src { + FileName::Real(ref p) => match p.local_path().parent() { + Some(p) => p.to_path_buf(), + None => PathBuf::new(), + }, + _ => PathBuf::new(), + }; + // If user passed in `--playground-url` arg, we fill in crate name here + let mut playground = None; + if let Some(url) = playground_url { + playground = Some(markdown::Playground { crate_name: Some(krate.name.clone()), url }); + } + let mut layout = layout::Layout { + logo: String::new(), + favicon: String::new(), + external_html, + krate: krate.name.clone(), + css_file_extension: extension_css, + generate_search_filter, + }; + let mut issue_tracker_base_url = None; + let mut include_sources = true; + + // Crawl the crate attributes looking for attributes which control how we're + // going to emit HTML + if let Some(attrs) = krate.module.as_ref().map(|m| &m.attrs) { + for attr in attrs.lists(sym::doc) { + match (attr.name_or_empty(), attr.value_str()) { + (sym::html_favicon_url, Some(s)) => { + layout.favicon = s.to_string(); + } + (sym::html_logo_url, Some(s)) => { + layout.logo = s.to_string(); + } + (sym::html_playground_url, Some(s)) => { + playground = Some(markdown::Playground { + crate_name: Some(krate.name.clone()), + url: s.to_string(), + }); + } + (sym::issue_tracker_base_url, Some(s)) => { + issue_tracker_base_url = Some(s.to_string()); + } + (sym::html_no_source, None) if attr.is_word() => { + include_sources = false; + } + _ => {} } - _ => {} } } + let (sender, receiver) = channel(); + let mut scx = SharedContext { + collapsed: krate.collapsed, + src_root, + include_sources, + local_sources: Default::default(), + issue_tracker_base_url, + layout, + created_dirs: Default::default(), + sort_modules_alphabetically, + style_files, + resource_suffix, + static_root_path, + fs: DocFS::new(sender), + edition, + codes: ErrorCodes::from(UnstableFeatures::from_environment().is_nightly_build()), + playground, + }; + + // Add the default themes to the `Vec` of stylepaths + // + // Note that these must be added before `sources::render` is called + // so that the resulting source pages are styled + // + // `light.css` is not disabled because it is the stylesheet that stays loaded + // by the browser as the theme stylesheet. The theme system (hackily) works by + // changing the href to this stylesheet. All other themes are disabled to + // prevent rule conflicts + scx.style_files.push(StylePath { path: PathBuf::from("light.css"), disabled: false }); + scx.style_files.push(StylePath { path: PathBuf::from("dark.css"), disabled: true }); + scx.style_files.push(StylePath { path: PathBuf::from("ayu.css"), disabled: true }); + + let dst = output; + scx.ensure_dir(&dst)?; + krate = sources::render(&dst, &mut scx, krate)?; + + // Build our search index + let index = build_index(&krate, cache); + + let cache = Arc::new(cache); + let mut cx = Context { + current: Vec::new(), + dst, + render_redirect_pages: false, + id_map: Rc::new(RefCell::new(id_map)), + shared: Arc::new(scx), + all: Rc::new(RefCell::new(AllTypes::new())), + errors: Rc::new(receiver), + }; + + CURRENT_DEPTH.with(|s| s.set(0)); + + // Write shared runs within a flock; disable thread dispatching of IO temporarily. + Arc::get_mut(&mut cx.shared).unwrap().fs.set_sync_only(true); + write_shared(&cx, &krate, index, &md_opts, &cache)?; + Arc::get_mut(&mut cx.shared).unwrap().fs.set_sync_only(false); + Ok((cx, krate)) } - let mut scx = SharedContext { - collapsed: krate.collapsed, - src_root, - include_sources, - local_sources: Default::default(), - issue_tracker_base_url, - layout, - created_dirs: Default::default(), - sort_modules_alphabetically, - style_files, - resource_suffix, - static_root_path, - fs: DocFS::new(&errors), - edition, - codes: ErrorCodes::from(UnstableFeatures::from_environment().is_nightly_build()), - playground, - }; - // Add the default themes to the `Vec` of stylepaths - // - // Note that these must be added before `sources::render` is called - // so that the resulting source pages are styled - // - // `light.css` is not disabled because it is the stylesheet that stays loaded - // by the browser as the theme stylesheet. The theme system (hackily) works by - // changing the href to this stylesheet. All other themes are disabled to - // prevent rule conflicts - scx.style_files.push(StylePath { path: PathBuf::from("light.css"), disabled: false }); - scx.style_files.push(StylePath { path: PathBuf::from("dark.css"), disabled: true }); - scx.style_files.push(StylePath { path: PathBuf::from("ayu.css"), disabled: true }); - - let dst = output; - scx.ensure_dir(&dst)?; - krate = sources::render(&dst, &mut scx, krate)?; - let (new_crate, index, cache) = - Cache::from_krate(renderinfo, document_private, &extern_html_root_urls, &dst, krate); - krate = new_crate; - let cache = Arc::new(cache); - let mut cx = Context { - current: Vec::new(), - dst, - render_redirect_pages: false, - id_map: Rc::new(RefCell::new(id_map)), - shared: Arc::new(scx), - cache: cache.clone(), - }; + fn after_run(&mut self, diag: &rustc_errors::Handler) -> Result<(), Error> { + Arc::get_mut(&mut self.shared).unwrap().fs.close(); + let nb_errors = self.errors.iter().map(|err| diag.struct_err(&err).emit()).count(); + if nb_errors > 0 { + Err(Error::new(io::Error::new(io::ErrorKind::Other, "I/O error"), "")) + } else { + Ok(()) + } + } + + fn after_krate(&mut self, krate: &clean::Crate, cache: &Cache) -> Result<(), Error> { + let final_file = self.dst.join(&krate.name).join("all.html"); + let settings_file = self.dst.join("settings.html"); + let crate_name = krate.name.clone(); - // Freeze the cache now that the index has been built. Put an Arc into TLS - // for future parallelization opportunities - CACHE_KEY.with(|v| *v.borrow_mut() = cache.clone()); - CURRENT_DEPTH.with(|s| s.set(0)); + let mut root_path = self.dst.to_str().expect("invalid path").to_owned(); + if !root_path.ends_with('/') { + root_path.push('/'); + } + let mut page = layout::Page { + title: "List of all items in this crate", + css_class: "mod", + root_path: "../", + static_root_path: self.shared.static_root_path.as_deref(), + description: "List of all items in this crate", + keywords: BASIC_KEYWORDS, + resource_suffix: &self.shared.resource_suffix, + extra_scripts: &[], + static_extra_scripts: &[], + }; + let sidebar = if let Some(ref version) = cache.crate_version { + format!( + "<p class='location'>Crate {}</p>\ + <div class='block version'>\ + <p>Version {}</p>\ + </div>\ + <a id='all-types' href='index.html'><p>Back to index</p></a>", + crate_name, + Escape(version), + ) + } else { + String::new() + }; + let all = self.all.replace(AllTypes::new()); + let v = layout::render( + &self.shared.layout, + &page, + sidebar, + |buf: &mut Buffer| all.print(buf), + &self.shared.style_files, + ); + self.shared.fs.write(&final_file, v.as_bytes())?; - // Write shared runs within a flock; disable thread dispatching of IO temporarily. - Arc::get_mut(&mut cx.shared).unwrap().fs.set_sync_only(true); - write_shared(&cx, &krate, index, &md_opts)?; - Arc::get_mut(&mut cx.shared).unwrap().fs.set_sync_only(false); + // Generating settings page. + page.title = "Rustdoc settings"; + page.description = "Settings of Rustdoc"; + page.root_path = "./"; - // And finally render the whole crate's documentation - let ret = cx.krate(krate); - let nb_errors = Arc::get_mut(&mut errors).map_or_else(|| 0, |errors| errors.write_errors(diag)); - if ret.is_err() { - ret - } else if nb_errors > 0 { - Err(Error::new(io::Error::new(io::ErrorKind::Other, "I/O error"), "")) - } else { + let mut style_files = self.shared.style_files.clone(); + let sidebar = "<p class='location'>Settings</p><div class='sidebar-elems'></div>"; + style_files.push(StylePath { path: PathBuf::from("settings.css"), disabled: false }); + let v = layout::render( + &self.shared.layout, + &page, + sidebar, + settings( + self.shared.static_root_path.as_deref().unwrap_or("./"), + &self.shared.resource_suffix, + ), + &style_files, + ); + self.shared.fs.write(&settings_file, v.as_bytes())?; + Ok(()) + } + + fn mod_item_in( + &mut self, + item: &clean::Item, + item_name: &str, + cache: &Cache, + ) -> Result<(), Error> { + // Stripped modules survive the rustdoc passes (i.e., `strip-private`) + // if they contain impls for public types. These modules can also + // contain items such as publicly re-exported structures. + // + // External crates will provide links to these structures, so + // these modules are recursed into, but not rendered normally + // (a flag on the context). + if !self.render_redirect_pages { + self.render_redirect_pages = item.is_stripped(); + } + let scx = &self.shared; + self.dst.push(item_name); + self.current.push(item_name.to_owned()); + + info!("Recursing into {}", self.dst.display()); + + let buf = self.render_item(item, false, cache); + // buf will be empty if the module is stripped and there is no redirect for it + if !buf.is_empty() { + self.shared.ensure_dir(&self.dst)?; + let joint_dst = self.dst.join("index.html"); + scx.fs.write(&joint_dst, buf.as_bytes())?; + } + + // Render sidebar-items.js used throughout this module. + if !self.render_redirect_pages { + let module = match item.inner { + clean::StrippedItem(box clean::ModuleItem(ref m)) | clean::ModuleItem(ref m) => m, + _ => unreachable!(), + }; + let items = self.build_sidebar_items(module); + let js_dst = self.dst.join("sidebar-items.js"); + let v = format!("initSidebarItems({});", serde_json::to_string(&items).unwrap()); + scx.fs.write(&js_dst, &v)?; + } + Ok(()) + } + + fn mod_item_out(&mut self, _item_name: &str) -> Result<(), Error> { + info!("Recursed; leaving {}", self.dst.display()); + + // Go back to where we were at + self.dst.pop(); + self.current.pop(); + Ok(()) + } + + fn item(&mut self, item: clean::Item, cache: &Cache) -> Result<(), Error> { + // Stripped modules survive the rustdoc passes (i.e., `strip-private`) + // if they contain impls for public types. These modules can also + // contain items such as publicly re-exported structures. + // + // External crates will provide links to these structures, so + // these modules are recursed into, but not rendered normally + // (a flag on the context). + if !self.render_redirect_pages { + self.render_redirect_pages = item.is_stripped(); + } + + let buf = self.render_item(&item, true, cache); + // buf will be empty if the item is stripped and there is no redirect for it + if !buf.is_empty() { + let name = item.name.as_ref().unwrap(); + let item_type = item.type_(); + let file_name = &item_path(item_type, name); + self.shared.ensure_dir(&self.dst)?; + let joint_dst = self.dst.join(file_name); + self.shared.fs.write(&joint_dst, buf.as_bytes())?; + + if !self.render_redirect_pages { + self.all.borrow_mut().append(full_path(self, &item), &item_type); + } + // If the item is a macro, redirect from the old macro URL (with !) + // to the new one (without). + if item_type == ItemType::Macro { + let redir_name = format!("{}.{}!.html", item_type, name); + let redir_dst = self.dst.join(redir_name); + let v = layout::redirect(file_name); + self.shared.fs.write(&redir_dst, v.as_bytes())?; + } + } Ok(()) } } @@ -604,6 +679,7 @@ fn write_shared( krate: &clean::Crate, search_index: String, options: &RenderOptions, + cache: &Cache, ) -> Result<(), Error> { // Write out the shared files. Note that these are shared among all rustdoc // docs placed in the output directory, so this needs to be a synchronized @@ -1001,7 +1077,7 @@ themePicker.onblur = handleThemeButtonsBlur; // Update the list of all implementors for traits let dst = cx.dst.join("implementors"); - for (&did, imps) in &cx.cache.implementors { + for (&did, imps) in &cache.implementors { // Private modules can leak through to this phase of rustdoc, which // could contain implementations for otherwise private types. In some // rare cases we could find an implementation for an item which wasn't @@ -1009,9 +1085,9 @@ themePicker.onblur = handleThemeButtonsBlur; // // FIXME: this is a vague explanation for why this can't be a `get`, in // theory it should be... - let &(ref remote_path, remote_item_type) = match cx.cache.paths.get(&did) { + let &(ref remote_path, remote_item_type) = match cache.paths.get(&did) { Some(p) => p, - None => match cx.cache.external_paths.get(&did) { + None => match cache.external_paths.get(&did) { Some(p) => p, None => continue, }, @@ -1049,7 +1125,7 @@ themePicker.onblur = handleThemeButtonsBlur; // Only create a js file if we have impls to add to it. If the trait is // documented locally though we always create the file to avoid dead // links. - if implementors.is_empty() && !cx.cache.paths.contains_key(&did) { + if implementors.is_empty() && !cache.paths.contains_key(&did) { continue; } @@ -1354,93 +1430,7 @@ impl Context { "../".repeat(self.current.len()) } - /// Main method for rendering a crate. - /// - /// This currently isn't parallelized, but it'd be pretty easy to add - /// parallelization to this function. - fn krate(self, mut krate: clean::Crate) -> Result<(), Error> { - let mut item = match krate.module.take() { - Some(i) => i, - None => return Ok(()), - }; - let final_file = self.dst.join(&krate.name).join("all.html"); - let settings_file = self.dst.join("settings.html"); - - let crate_name = krate.name.clone(); - item.name = Some(krate.name); - - let mut all = AllTypes::new(); - - { - // Render the crate documentation - let mut work = vec![(self.clone(), item)]; - - while let Some((mut cx, item)) = work.pop() { - cx.item(item, &mut all, |cx, item| work.push((cx.clone(), item)))? - } - } - - let mut root_path = self.dst.to_str().expect("invalid path").to_owned(); - if !root_path.ends_with('/') { - root_path.push('/'); - } - let mut page = layout::Page { - title: "List of all items in this crate", - css_class: "mod", - root_path: "../", - static_root_path: self.shared.static_root_path.as_deref(), - description: "List of all items in this crate", - keywords: BASIC_KEYWORDS, - resource_suffix: &self.shared.resource_suffix, - extra_scripts: &[], - static_extra_scripts: &[], - }; - let sidebar = if let Some(ref version) = self.cache.crate_version { - format!( - "<p class='location'>Crate {}</p>\ - <div class='block version'>\ - <p>Version {}</p>\ - </div>\ - <a id='all-types' href='index.html'><p>Back to index</p></a>", - crate_name, - Escape(version), - ) - } else { - String::new() - }; - let v = layout::render( - &self.shared.layout, - &page, - sidebar, - |buf: &mut Buffer| all.print(buf), - &self.shared.style_files, - ); - self.shared.fs.write(&final_file, v.as_bytes())?; - - // Generating settings page. - page.title = "Rustdoc settings"; - page.description = "Settings of Rustdoc"; - page.root_path = "./"; - - let mut style_files = self.shared.style_files.clone(); - let sidebar = "<p class='location'>Settings</p><div class='sidebar-elems'></div>"; - style_files.push(StylePath { path: PathBuf::from("settings.css"), disabled: false }); - let v = layout::render( - &self.shared.layout, - &page, - sidebar, - settings( - self.shared.static_root_path.as_deref().unwrap_or("./"), - &self.shared.resource_suffix, - ), - &style_files, - ); - self.shared.fs.write(&settings_file, v.as_bytes())?; - - Ok(()) - } - - fn render_item(&self, it: &clean::Item, pushname: bool) -> String { + fn render_item(&self, it: &clean::Item, pushname: bool, cache: &Cache) -> String { // A little unfortunate that this is done like this, but it sure // does make formatting *a lot* nicer. CURRENT_DEPTH.with(|slot| { @@ -1493,13 +1483,13 @@ impl Context { layout::render( &self.shared.layout, &page, - |buf: &mut _| print_sidebar(self, it, buf), - |buf: &mut _| print_item(self, it, buf), + |buf: &mut _| print_sidebar(self, it, buf, cache), + |buf: &mut _| print_item(self, it, buf, cache), &self.shared.style_files, ) } else { let mut url = self.root_path(); - if let Some(&(ref names, ty)) = self.cache.paths.get(&it.def_id) { + if let Some(&(ref names, ty)) = cache.paths.get(&it.def_id) { for name in &names[..names.len() - 1] { url.push_str(name); url.push_str("/"); @@ -1512,97 +1502,6 @@ impl Context { } } - /// Non-parallelized version of rendering an item. This will take the input - /// item, render its contents, and then invoke the specified closure with - /// all sub-items which need to be rendered. - /// - /// The rendering driver uses this closure to queue up more work. - fn item<F>(&mut self, item: clean::Item, all: &mut AllTypes, mut f: F) -> Result<(), Error> - where - F: FnMut(&mut Context, clean::Item), - { - // Stripped modules survive the rustdoc passes (i.e., `strip-private`) - // if they contain impls for public types. These modules can also - // contain items such as publicly re-exported structures. - // - // External crates will provide links to these structures, so - // these modules are recursed into, but not rendered normally - // (a flag on the context). - if !self.render_redirect_pages { - self.render_redirect_pages = item.is_stripped(); - } - - if item.is_mod() { - // modules are special because they add a namespace. We also need to - // recurse into the items of the module as well. - let name = item.name.as_ref().unwrap().to_string(); - let scx = &self.shared; - if name.is_empty() { - panic!("Unexpected empty destination: {:?}", self.current); - } - let prev = self.dst.clone(); - self.dst.push(&name); - self.current.push(name); - - info!("Recursing into {}", self.dst.display()); - - let buf = self.render_item(&item, false); - // buf will be empty if the module is stripped and there is no redirect for it - if !buf.is_empty() { - self.shared.ensure_dir(&self.dst)?; - let joint_dst = self.dst.join("index.html"); - scx.fs.write(&joint_dst, buf.as_bytes())?; - } - - let m = match item.inner { - clean::StrippedItem(box clean::ModuleItem(m)) | clean::ModuleItem(m) => m, - _ => unreachable!(), - }; - - // Render sidebar-items.js used throughout this module. - if !self.render_redirect_pages { - let items = self.build_sidebar_items(&m); - let js_dst = self.dst.join("sidebar-items.js"); - let v = format!("initSidebarItems({});", serde_json::to_string(&items).unwrap()); - scx.fs.write(&js_dst, &v)?; - } - - for item in m.items { - f(self, item); - } - - info!("Recursed; leaving {}", self.dst.display()); - - // Go back to where we were at - self.dst = prev; - self.current.pop().unwrap(); - } else if item.name.is_some() { - let buf = self.render_item(&item, true); - // buf will be empty if the item is stripped and there is no redirect for it - if !buf.is_empty() { - let name = item.name.as_ref().unwrap(); - let item_type = item.type_(); - let file_name = &item_path(item_type, name); - self.shared.ensure_dir(&self.dst)?; - let joint_dst = self.dst.join(file_name); - self.shared.fs.write(&joint_dst, buf.as_bytes())?; - - if !self.render_redirect_pages { - all.append(full_path(self, &item), &item_type); - } - // If the item is a macro, redirect from the old macro URL (with !) - // to the new one (without). - if item_type == ItemType::Macro { - let redir_name = format!("{}.{}!.html", item_type, name); - let redir_dst = self.dst.join(redir_name); - let v = layout::redirect(file_name); - self.shared.fs.write(&redir_dst, v.as_bytes())?; - } - } - } - Ok(()) - } - fn build_sidebar_items(&self, m: &clean::Module) -> BTreeMap<String, Vec<NameDoc>> { // BTreeMap instead of HashMap to get a sorted output let mut map: BTreeMap<_, Vec<_>> = BTreeMap::new(); @@ -1629,9 +1528,7 @@ impl Context { } map } -} -impl Context { /// Generates a url appropriate for an `href` attribute back to the source of /// this item. /// @@ -1641,7 +1538,7 @@ impl Context { /// If `None` is returned, then a source link couldn't be generated. This /// may happen, for example, with externally inlined items where the source /// of their crate documentation isn't known. - fn src_href(&self, item: &clean::Item) -> Option<String> { + fn src_href(&self, item: &clean::Item, cache: &Cache) -> Option<String> { let mut root = self.root_path(); let mut path = String::new(); @@ -1660,13 +1557,13 @@ impl Context { return None; } } else { - let (krate, src_root) = match *self.cache.extern_locations.get(&item.source.cnum)? { - (ref name, ref src, Local) => (name, src), - (ref name, ref src, Remote(ref s)) => { + let (krate, src_root) = match *cache.extern_locations.get(&item.source.cnum)? { + (ref name, ref src, ExternalLocation::Local) => (name, src), + (ref name, ref src, ExternalLocation::Remote(ref s)) => { root = s.to_string(); (name, src) } - (_, _, Unknown) => return None, + (_, _, ExternalLocation::Unknown) => return None, }; sources::clean_path(&src_root, file, false, |component| { @@ -1703,7 +1600,7 @@ where write!(w, "</div>") } -fn print_item(cx: &Context, item: &clean::Item, buf: &mut Buffer) { +fn print_item(cx: &Context, item: &clean::Item, buf: &mut Buffer, cache: &Cache) { debug_assert!(!item.is_stripped()); // Write the breadcrumb trail header for the top write!(buf, "<h1 class='fqn'><span class='out-of-band'>"); @@ -1731,7 +1628,7 @@ fn print_item(cx: &Context, item: &clean::Item, buf: &mut Buffer) { // this page, and this link will be auto-clicked. The `id` attribute is // used to find the link to auto-click. if cx.shared.include_sources && !item.is_primitive() { - if let Some(l) = cx.src_href(item) { + if let Some(l) = cx.src_href(item, cache) { write!(buf, "<a class='srclink' href='{}' title='{}'>[src]</a>", l, "goto source code"); } } @@ -1792,20 +1689,20 @@ fn print_item(cx: &Context, item: &clean::Item, buf: &mut Buffer) { clean::FunctionItem(ref f) | clean::ForeignFunctionItem(ref f) => { item_function(buf, cx, item, f) } - clean::TraitItem(ref t) => item_trait(buf, cx, item, t), - clean::StructItem(ref s) => item_struct(buf, cx, item, s), - clean::UnionItem(ref s) => item_union(buf, cx, item, s), - clean::EnumItem(ref e) => item_enum(buf, cx, item, e), - clean::TypedefItem(ref t, _) => item_typedef(buf, cx, item, t), + clean::TraitItem(ref t) => item_trait(buf, cx, item, t, cache), + clean::StructItem(ref s) => item_struct(buf, cx, item, s, cache), + clean::UnionItem(ref s) => item_union(buf, cx, item, s, cache), + clean::EnumItem(ref e) => item_enum(buf, cx, item, e, cache), + clean::TypedefItem(ref t, _) => item_typedef(buf, cx, item, t, cache), clean::MacroItem(ref m) => item_macro(buf, cx, item, m), clean::ProcMacroItem(ref m) => item_proc_macro(buf, cx, item, m), - clean::PrimitiveItem(_) => item_primitive(buf, cx, item), + clean::PrimitiveItem(_) => item_primitive(buf, cx, item, cache), clean::StaticItem(ref i) | clean::ForeignStaticItem(ref i) => item_static(buf, cx, item, i), clean::ConstantItem(ref c) => item_constant(buf, cx, item, c), - clean::ForeignTypeItem => item_foreign_type(buf, cx, item), + clean::ForeignTypeItem => item_foreign_type(buf, cx, item, cache), clean::KeywordItem(_) => item_keyword(buf, cx, item), - clean::OpaqueTyItem(ref e, _) => item_opaque_ty(buf, cx, item, e), - clean::TraitAliasItem(ref ta) => item_trait_alias(buf, cx, item, ta), + clean::OpaqueTyItem(ref e, _) => item_opaque_ty(buf, cx, item, e, cache), + clean::TraitAliasItem(ref ta) => item_trait_alias(buf, cx, item, ta, cache), _ => { // We don't generate pages for any other type. unreachable!(); @@ -1828,7 +1725,7 @@ fn full_path(cx: &Context, item: &clean::Item) -> String { } #[inline] -fn plain_summary_line(s: Option<&str>) -> String { +crate fn plain_summary_line(s: Option<&str>) -> String { let s = s.unwrap_or(""); // This essentially gets the first paragraph of text in one line. let mut line = s @@ -1845,7 +1742,7 @@ fn plain_summary_line(s: Option<&str>) -> String { markdown::plain_summary_line(&line[..]) } -fn shorten(s: String) -> String { +crate fn shorten(s: String) -> String { if s.chars().count() > 60 { let mut len = 0; let mut ret = s @@ -2415,6 +2312,7 @@ fn render_implementor( w: &mut Buffer, implementor_dups: &FxHashMap<&str, (DefId, bool)>, aliases: &[String], + cache: &Cache, ) { // If there's already another implementor that has the same abbridged name, use the // full path, for example in `std::iter::ExactSizeIterator` @@ -2438,10 +2336,17 @@ fn render_implementor( false, false, aliases, + cache, ); } -fn render_impls(cx: &Context, w: &mut Buffer, traits: &[&&Impl], containing_item: &clean::Item) { +fn render_impls( + cx: &Context, + w: &mut Buffer, + traits: &[&&Impl], + containing_item: &clean::Item, + cache: &Cache, +) { let mut impls = traits .iter() .map(|i| { @@ -2460,6 +2365,7 @@ fn render_impls(cx: &Context, w: &mut Buffer, traits: &[&&Impl], containing_item false, true, &[], + cache, ); buffer.into_inner() }) @@ -2492,7 +2398,7 @@ fn compare_impl<'a, 'b>(lhs: &'a &&Impl, rhs: &'b &&Impl) -> Ordering { name_key(&lhs).cmp(&name_key(&rhs)) } -fn item_trait(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Trait) { +fn item_trait(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Trait, cache: &Cache) { let bounds = bounds(&t.bounds, false); let types = t.items.iter().filter(|m| m.is_associated_type()).collect::<Vec<_>>(); let consts = t.items.iter().filter(|m| m.is_associated_const()).collect::<Vec<_>>(); @@ -2652,9 +2558,9 @@ fn item_trait(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Trait) } // If there are methods directly on this trait object, render them here. - render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All); + render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All, cache); - if let Some(implementors) = cx.cache.implementors.get(&it.def_id) { + if let Some(implementors) = cache.implementors.get(&it.def_id) { // The DefId is for the first Type found with that name. The bool is // if any Types with the same name but different DefId have been found. let mut implementor_dups: FxHashMap<&str, (DefId, bool)> = FxHashMap::default(); @@ -2676,7 +2582,7 @@ fn item_trait(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Trait) } let (local, foreign) = implementors.iter().partition::<Vec<_>, _>(|i| { - i.inner_impl().for_.def_id().map_or(true, |d| cx.cache.paths.contains_key(&d)) + i.inner_impl().for_.def_id().map_or(true, |d| cache.paths.contains_key(&d)) }); let (mut synthetic, mut concrete): (Vec<&&Impl>, Vec<&&Impl>) = @@ -2705,6 +2611,7 @@ fn item_trait(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Trait) true, false, &[], + cache, ); } write_loading_content(w, ""); @@ -2717,7 +2624,7 @@ fn item_trait(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Trait) "<div class='item-list' id='implementors-list'>", ); for implementor in concrete { - render_implementor(cx, implementor, w, &implementor_dups, &[]); + render_implementor(cx, implementor, w, &implementor_dups, &[], cache); } write_loading_content(w, "</div>"); @@ -2735,6 +2642,7 @@ fn item_trait(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Trait) w, &implementor_dups, &collect_paths_for_type(implementor.inner_impl().for_.clone()), + cache, ); } write_loading_content(w, "</div>"); @@ -2770,7 +2678,7 @@ fn item_trait(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Trait) path = if it.def_id.is_local() { cx.current.join("/") } else { - let (ref path, _) = cx.cache.external_paths[&it.def_id]; + let (ref path, _) = cache.external_paths[&it.def_id]; path[..path.len() - 1].join("/") }, ty = it.type_(), @@ -2779,7 +2687,7 @@ fn item_trait(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Trait) } fn naive_assoc_href(it: &clean::Item, link: AssocItemLink<'_>) -> String { - use crate::html::item_type::ItemType::*; + use crate::formats::item_type::ItemType::*; let name = it.name.as_ref().unwrap(); let ty = match it.type_() { @@ -2945,7 +2853,7 @@ fn render_assoc_item( } } -fn item_struct(w: &mut Buffer, cx: &Context, it: &clean::Item, s: &clean::Struct) { +fn item_struct(w: &mut Buffer, cx: &Context, it: &clean::Item, s: &clean::Struct, cache: &Cache) { wrap_into_docblock(w, |w| { write!(w, "<pre class='rust struct'>"); render_attributes(w, it, true); @@ -2992,10 +2900,10 @@ fn item_struct(w: &mut Buffer, cx: &Context, it: &clean::Item, s: &clean::Struct } } } - render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All) + render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All, cache) } -fn item_union(w: &mut Buffer, cx: &Context, it: &clean::Item, s: &clean::Union) { +fn item_union(w: &mut Buffer, cx: &Context, it: &clean::Item, s: &clean::Union, cache: &Cache) { wrap_into_docblock(w, |w| { write!(w, "<pre class='rust union'>"); render_attributes(w, it, true); @@ -3038,10 +2946,10 @@ fn item_union(w: &mut Buffer, cx: &Context, it: &clean::Item, s: &clean::Union) document(w, cx, field); } } - render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All) + render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All, cache) } -fn item_enum(w: &mut Buffer, cx: &Context, it: &clean::Item, e: &clean::Enum) { +fn item_enum(w: &mut Buffer, cx: &Context, it: &clean::Item, e: &clean::Enum, cache: &Cache) { wrap_into_docblock(w, |w| { write!(w, "<pre class='rust enum'>"); render_attributes(w, it, true); @@ -3166,7 +3074,7 @@ fn item_enum(w: &mut Buffer, cx: &Context, it: &clean::Item, e: &clean::Enum) { render_stability_since(w, variant, it); } } - render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All) + render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All, cache) } const ALLOWED_ATTRIBUTES: &[Symbol] = &[ @@ -3348,26 +3256,15 @@ impl<'a> AssocItemLink<'a> { } } -enum AssocItemRender<'a> { - All, - DerefFor { trait_: &'a clean::Type, type_: &'a clean::Type, deref_mut_: bool }, -} - -#[derive(Copy, Clone, PartialEq)] -enum RenderMode { - Normal, - ForDeref { mut_: bool }, -} - fn render_assoc_items( w: &mut Buffer, cx: &Context, containing_item: &clean::Item, it: DefId, what: AssocItemRender<'_>, + cache: &Cache, ) { - let c = &cx.cache; - let v = match c.impls.get(&it) { + let v = match cache.impls.get(&it) { Some(v) => v, None => return, }; @@ -3413,6 +3310,7 @@ fn render_assoc_items( false, true, &[], + cache, ); } } @@ -3421,11 +3319,11 @@ fn render_assoc_items( } if !traits.is_empty() { let deref_impl = - traits.iter().find(|t| t.inner_impl().trait_.def_id() == c.deref_trait_did); + traits.iter().find(|t| t.inner_impl().trait_.def_id() == cache.deref_trait_did); if let Some(impl_) = deref_impl { let has_deref_mut = - traits.iter().any(|t| t.inner_impl().trait_.def_id() == c.deref_mut_trait_did); - render_deref_methods(w, cx, impl_, containing_item, has_deref_mut); + traits.iter().any(|t| t.inner_impl().trait_.def_id() == cache.deref_mut_trait_did); + render_deref_methods(w, cx, impl_, containing_item, has_deref_mut, cache); } let (synthetic, concrete): (Vec<&&Impl>, Vec<&&Impl>) = @@ -3434,7 +3332,7 @@ fn render_assoc_items( concrete.into_iter().partition(|t| t.inner_impl().blanket_impl.is_some()); let mut impls = Buffer::empty_from(&w); - render_impls(cx, &mut impls, &concrete, containing_item); + render_impls(cx, &mut impls, &concrete, containing_item, cache); let impls = impls.into_inner(); if !impls.is_empty() { write!( @@ -3459,7 +3357,7 @@ fn render_assoc_items( <div id='synthetic-implementations-list'>\ " ); - render_impls(cx, w, &synthetic, containing_item); + render_impls(cx, w, &synthetic, containing_item, cache); write!(w, "</div>"); } @@ -3474,7 +3372,7 @@ fn render_assoc_items( <div id='blanket-implementations-list'>\ " ); - render_impls(cx, w, &blanket_impl, containing_item); + render_impls(cx, w, &blanket_impl, containing_item, cache); write!(w, "</div>"); } } @@ -3486,6 +3384,7 @@ fn render_deref_methods( impl_: &Impl, container_item: &clean::Item, deref_mut: bool, + cache: &Cache, ) { let deref_type = impl_.inner_impl().trait_.as_ref().unwrap(); let (target, real_target) = impl_ @@ -3503,11 +3402,11 @@ fn render_deref_methods( let what = AssocItemRender::DerefFor { trait_: deref_type, type_: real_target, deref_mut_: deref_mut }; if let Some(did) = target.def_id() { - render_assoc_items(w, cx, container_item, did, what); + render_assoc_items(w, cx, container_item, did, what, cache); } else { if let Some(prim) = target.primitive_type() { - if let Some(&did) = cx.cache.primitive_locations.get(&prim) { - render_assoc_items(w, cx, container_item, did, what); + if let Some(&did) = cache.primitive_locations.get(&prim) { + render_assoc_items(w, cx, container_item, did, what, cache); } } } @@ -3609,6 +3508,7 @@ fn render_impl( // This argument is used to reference same type with different paths to avoid duplication // in documentation pages for trait with automatic implementations like "Send" and "Sync". aliases: &[String], + cache: &Cache, ) { if render_mode == RenderMode::Normal { let id = cx.derive_id(match i.inner_impl().trait_ { @@ -3651,7 +3551,7 @@ fn render_impl( write!(w, "<a href='#{}' class='anchor'></a>", id); let since = i.impl_item.stability.as_ref().map(|s| &s.since[..]); render_stability_since_raw(w, since, outer_version); - if let Some(l) = cx.src_href(&i.impl_item) { + if let Some(l) = cx.src_href(&i.impl_item, cache) { write!(w, "<a class='srclink' href='{}' title='{}'>[src]</a>", l, "goto source code"); } write!(w, "</h3>"); @@ -3683,6 +3583,7 @@ fn render_impl( outer_version: Option<&str>, trait_: Option<&clean::Trait>, show_def_docs: bool, + cache: &Cache, ) { let item_type = item.type_(); let name = item.name.as_ref().unwrap(); @@ -3711,7 +3612,7 @@ fn render_impl( render_assoc_item(w, item, link.anchor(&id), ItemType::Impl); write!(w, "</code>"); render_stability_since_raw(w, item.stable_since(), outer_version); - if let Some(l) = cx.src_href(item) { + if let Some(l) = cx.src_href(item, cache) { write!( w, "<a class='srclink' href='{}' title='{}'>[src]</a>", @@ -3733,7 +3634,7 @@ fn render_impl( assoc_const(w, item, ty, default.as_ref(), link.anchor(&id), ""); write!(w, "</code>"); render_stability_since_raw(w, item.stable_since(), outer_version); - if let Some(l) = cx.src_href(item) { + if let Some(l) = cx.src_href(item, cache) { write!( w, "<a class='srclink' href='{}' title='{}'>[src]</a>", @@ -3784,7 +3685,7 @@ fn render_impl( } } - let traits = &cx.cache.traits; + let traits = &cache.traits; let trait_ = i.trait_did().map(|did| &traits[&did]); write!(w, "<div class='impl-items'>"); @@ -3799,6 +3700,7 @@ fn render_impl( outer_version, trait_, show_def_docs, + cache, ); } @@ -3810,6 +3712,7 @@ fn render_impl( render_mode: RenderMode, outer_version: Option<&str>, show_def_docs: bool, + cache: &Cache, ) { for trait_item in &t.items { let n = trait_item.name.clone(); @@ -3829,6 +3732,7 @@ fn render_impl( outer_version, None, show_def_docs, + cache, ); } } @@ -3847,13 +3751,20 @@ fn render_impl( render_mode, outer_version, show_def_docs, + cache, ); } } write!(w, "</div>"); } -fn item_opaque_ty(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::OpaqueTy) { +fn item_opaque_ty( + w: &mut Buffer, + cx: &Context, + it: &clean::Item, + t: &clean::OpaqueTy, + cache: &Cache, +) { write!(w, "<pre class='rust opaque'>"); render_attributes(w, it, false); write!( @@ -3871,10 +3782,16 @@ fn item_opaque_ty(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Opa // won't be visible anywhere in the docs. It would be nice to also show // associated items from the aliased type (see discussion in #32077), but // we need #14072 to make sense of the generics. - render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All) + render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All, cache) } -fn item_trait_alias(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::TraitAlias) { +fn item_trait_alias( + w: &mut Buffer, + cx: &Context, + it: &clean::Item, + t: &clean::TraitAlias, + cache: &Cache, +) { write!(w, "<pre class='rust trait-alias'>"); render_attributes(w, it, false); write!( @@ -3892,10 +3809,10 @@ fn item_trait_alias(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::T // won't be visible anywhere in the docs. It would be nice to also show // associated items from the aliased type (see discussion in #32077), but // we need #14072 to make sense of the generics. - render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All) + render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All, cache) } -fn item_typedef(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Typedef) { +fn item_typedef(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Typedef, cache: &Cache) { write!(w, "<pre class='rust typedef'>"); render_attributes(w, it, false); write!( @@ -3913,10 +3830,10 @@ fn item_typedef(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Typed // won't be visible anywhere in the docs. It would be nice to also show // associated items from the aliased type (see discussion in #32077), but // we need #14072 to make sense of the generics. - render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All) + render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All, cache) } -fn item_foreign_type(w: &mut Buffer, cx: &Context, it: &clean::Item) { +fn item_foreign_type(w: &mut Buffer, cx: &Context, it: &clean::Item, cache: &Cache) { writeln!(w, "<pre class='rust foreigntype'>extern {{"); render_attributes(w, it, false); write!( @@ -3928,10 +3845,10 @@ fn item_foreign_type(w: &mut Buffer, cx: &Context, it: &clean::Item) { document(w, cx, it); - render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All) + render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All, cache) } -fn print_sidebar(cx: &Context, it: &clean::Item, buffer: &mut Buffer) { +fn print_sidebar(cx: &Context, it: &clean::Item, buffer: &mut Buffer, cache: &Cache) { let parentlen = cx.current.len() - if it.is_mod() { 1 } else { 0 }; if it.is_struct() @@ -3966,7 +3883,7 @@ fn print_sidebar(cx: &Context, it: &clean::Item, buffer: &mut Buffer) { } if it.is_crate() { - if let Some(ref version) = cx.cache.crate_version { + if let Some(ref version) = cache.crate_version { write!( buffer, "<div class='block version'>\ @@ -4603,9 +4520,9 @@ fn item_proc_macro(w: &mut Buffer, cx: &Context, it: &clean::Item, m: &clean::Pr document(w, cx, it) } -fn item_primitive(w: &mut Buffer, cx: &Context, it: &clean::Item) { +fn item_primitive(w: &mut Buffer, cx: &Context, it: &clean::Item, cache: &Cache) { document(w, cx, it); - render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All) + render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All, cache) } fn item_keyword(w: &mut Buffer, cx: &Context, it: &clean::Item) { @@ -4670,7 +4587,3 @@ fn collect_paths_for_type(first_ty: clean::Type) -> Vec<String> { } out } - -crate fn cache() -> Arc<Cache> { - CACHE_KEY.with(|c| c.borrow().clone()) -} diff --git a/src/librustdoc/html/sources.rs b/src/librustdoc/html/sources.rs index e3215921f12..aaa73b100c2 100644 --- a/src/librustdoc/html/sources.rs +++ b/src/librustdoc/html/sources.rs @@ -1,10 +1,11 @@ use crate::clean; use crate::docfs::PathError; +use crate::error::Error; use crate::fold::DocFolder; use crate::html::format::Buffer; use crate::html::highlight; use crate::html::layout; -use crate::html::render::{Error, SharedContext, BASIC_KEYWORDS}; +use crate::html::render::{SharedContext, BASIC_KEYWORDS}; use rustc_hir::def_id::LOCAL_CRATE; use rustc_span::source_map::FileName; use std::ffi::OsStr; diff --git a/src/librustdoc/html/static/themes/ayu.css b/src/librustdoc/html/static/themes/ayu.css index 01b7ae87786..f4710f6ae87 100644 --- a/src/librustdoc/html/static/themes/ayu.css +++ b/src/librustdoc/html/static/themes/ayu.css @@ -197,9 +197,8 @@ pre { color: #a37acc; } -pre.rust .comment, pre.rust .doccomment { - color: #788797; -} +pre.rust .comment { color: #788797; } +pre.rust .doccomment { color: #a1ac88; } nav:not(.sidebar) { border-bottom-color: #424c57; diff --git a/src/librustdoc/json/mod.rs b/src/librustdoc/json/mod.rs new file mode 100644 index 00000000000..14f87ec2aa9 --- /dev/null +++ b/src/librustdoc/json/mod.rs @@ -0,0 +1,47 @@ +use crate::clean; +use crate::config::{RenderInfo, RenderOptions}; +use crate::error::Error; +use crate::formats::cache::Cache; +use crate::formats::FormatRenderer; + +use rustc_span::edition::Edition; + +#[derive(Clone)] +pub struct JsonRenderer {} + +impl FormatRenderer for JsonRenderer { + fn init( + _krate: clean::Crate, + _options: RenderOptions, + _render_info: RenderInfo, + _edition: Edition, + _cache: &mut Cache, + ) -> Result<(Self, clean::Crate), Error> { + unimplemented!() + } + + fn item(&mut self, _item: clean::Item, _cache: &Cache) -> Result<(), Error> { + unimplemented!() + } + + fn mod_item_in( + &mut self, + _item: &clean::Item, + _item_name: &str, + _cache: &Cache, + ) -> Result<(), Error> { + unimplemented!() + } + + fn mod_item_out(&mut self, _item_name: &str) -> Result<(), Error> { + unimplemented!() + } + + fn after_krate(&mut self, _krate: &clean::Crate, _cache: &Cache) -> Result<(), Error> { + unimplemented!() + } + + fn after_run(&mut self, _diag: &rustc_errors::Handler) -> Result<(), Error> { + unimplemented!() + } +} diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index cbf53d52ef0..002c5f96710 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -14,7 +14,6 @@ #![feature(never_type)] #![recursion_limit = "256"] -extern crate env_logger; #[macro_use] extern crate lazy_static; extern crate rustc_ast; @@ -63,19 +62,12 @@ mod config; mod core; mod docfs; mod doctree; +#[macro_use] +mod error; mod fold; -pub mod html { - crate mod escape; - crate mod format; - crate mod highlight; - crate mod item_type; - crate mod layout; - pub mod markdown; - crate mod render; - crate mod sources; - crate mod static_files; - crate mod toc; -} +crate mod formats; +pub mod html; +mod json; mod markdown; mod passes; mod test; @@ -85,7 +77,7 @@ mod visit_lib; struct Output { krate: clean::Crate, - renderinfo: html::render::RenderInfo, + renderinfo: config::RenderInfo, renderopts: config::RenderOptions, } @@ -97,7 +89,8 @@ pub fn main() { }; rustc_driver::set_sigpipe_handler(); rustc_driver::install_ice_hook(); - env_logger::init_from_env("RUSTDOC_LOG"); + rustc_driver::init_env_logger("RUSTDOC_LOG"); + let res = std::thread::Builder::new() .stack_size(thread_stack_size) .spawn(move || get_args().map(|args| main_args(&args)).unwrap_or(1)) @@ -458,6 +451,28 @@ fn wrap_return(diag: &rustc_errors::Handler, res: Result<(), String>) -> i32 { } } +fn run_renderer<T: formats::FormatRenderer>( + krate: clean::Crate, + renderopts: config::RenderOptions, + render_info: config::RenderInfo, + diag: &rustc_errors::Handler, + edition: rustc_span::edition::Edition, +) -> i32 { + match formats::run_format::<T>(krate, renderopts, render_info, &diag, edition) { + Ok(_) => rustc_driver::EXIT_SUCCESS, + Err(e) => { + let mut msg = diag.struct_err(&format!("couldn't generate documentation: {}", e.error)); + let file = e.file.display().to_string(); + if file.is_empty() { + msg.emit() + } else { + msg.note(&format!("failed to create or modify \"{}\"", file)).emit() + } + rustc_driver::EXIT_FAILURE + } + } +} + fn main_options(options: config::Options) -> i32 { let diag = core::new_handler(options.error_format, None, &options.debugging_options); @@ -488,6 +503,7 @@ fn main_options(options: config::Options) -> i32 { let result = rustc_driver::catch_fatal_errors(move || { let crate_name = options.crate_name.clone(); let crate_version = options.crate_version.clone(); + let output_format = options.output_format; let (mut krate, renderinfo, renderopts) = core::run_core(options); info!("finished with rustc"); @@ -510,13 +526,12 @@ fn main_options(options: config::Options) -> i32 { info!("going to format"); let (error_format, edition, debugging_options) = diag_opts; let diag = core::new_handler(error_format, None, &debugging_options); - match html::render::run(krate, renderopts, renderinfo, &diag, edition) { - Ok(_) => rustc_driver::EXIT_SUCCESS, - Err(e) => { - diag.struct_err(&format!("couldn't generate documentation: {}", e.error)) - .note(&format!("failed to create or modify \"{}\"", e.file.display())) - .emit(); - rustc_driver::EXIT_FAILURE + match output_format { + None | Some(config::OutputFormat::Html) => { + run_renderer::<html::render::Context>(krate, renderopts, renderinfo, &diag, edition) + } + Some(config::OutputFormat::Json) => { + run_renderer::<json::JsonRenderer>(krate, renderopts, renderinfo, &diag, edition) } } }); diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 418238181e9..bf7a43236e0 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -867,46 +867,40 @@ fn report_diagnostic( let attrs = &item.attrs; let sp = span_of_attrs(attrs).unwrap_or(item.source.span()); - cx.tcx.struct_span_lint_hir( - lint::builtin::INTRA_DOC_LINK_RESOLUTION_FAILURE, - hir_id, - sp, - |lint| { - let mut diag = lint.build(msg); - - let span = link_range - .as_ref() - .and_then(|range| super::source_span_for_markdown_range(cx, dox, range, attrs)); - - if let Some(link_range) = link_range { - if let Some(sp) = span { - diag.set_span(sp); - } else { - // blah blah blah\nblah\nblah [blah] blah blah\nblah blah - // ^ ~~~~ - // | link_range - // last_new_line_offset - let last_new_line_offset = - dox[..link_range.start].rfind('\n').map_or(0, |n| n + 1); - let line = dox[last_new_line_offset..].lines().next().unwrap_or(""); - - // Print the line containing the `link_range` and manually mark it with '^'s. - diag.note(&format!( - "the link appears in this line:\n\n{line}\n\ + cx.tcx.struct_span_lint_hir(lint::builtin::BROKEN_INTRA_DOC_LINKS, hir_id, sp, |lint| { + let mut diag = lint.build(msg); + + let span = link_range + .as_ref() + .and_then(|range| super::source_span_for_markdown_range(cx, dox, range, attrs)); + + if let Some(link_range) = link_range { + if let Some(sp) = span { + diag.set_span(sp); + } else { + // blah blah blah\nblah\nblah [blah] blah blah\nblah blah + // ^ ~~~~ + // | link_range + // last_new_line_offset + let last_new_line_offset = dox[..link_range.start].rfind('\n').map_or(0, |n| n + 1); + let line = dox[last_new_line_offset..].lines().next().unwrap_or(""); + + // Print the line containing the `link_range` and manually mark it with '^'s. + diag.note(&format!( + "the link appears in this line:\n\n{line}\n\ {indicator: <before$}{indicator:^<found$}", - line = line, - indicator = "", - before = link_range.start - last_new_line_offset, - found = link_range.len(), - )); - } + line = line, + indicator = "", + before = link_range.start - last_new_line_offset, + found = link_range.len(), + )); } + } - decorate(&mut diag, span); + decorate(&mut diag, span); - diag.emit(); - }, - ); + diag.emit(); + }); } fn resolution_failure( diff --git a/src/rustllvm/CoverageMappingWrapper.cpp b/src/rustllvm/CoverageMappingWrapper.cpp index c6c4cdb5562..7c8481540aa 100644 --- a/src/rustllvm/CoverageMappingWrapper.cpp +++ b/src/rustllvm/CoverageMappingWrapper.cpp @@ -8,60 +8,6 @@ using namespace llvm; -extern "C" SmallVectorTemplateBase<coverage::CounterExpression> - *LLVMRustCoverageSmallVectorCounterExpressionCreate() { - return new SmallVector<coverage::CounterExpression, 32>(); -} - -extern "C" void LLVMRustCoverageSmallVectorCounterExpressionDispose( - SmallVectorTemplateBase<coverage::CounterExpression> *Vector) { - delete Vector; -} - -extern "C" void LLVMRustCoverageSmallVectorCounterExpressionAdd( - SmallVectorTemplateBase<coverage::CounterExpression> *Expressions, - coverage::CounterExpression::ExprKind Kind, - unsigned LeftIndex, - unsigned RightIndex) { - auto LHS = coverage::Counter::getCounter(LeftIndex); - auto RHS = coverage::Counter::getCounter(RightIndex); - Expressions->push_back(coverage::CounterExpression { Kind, LHS, RHS }); -} - -extern "C" SmallVectorTemplateBase<coverage::CounterMappingRegion> - *LLVMRustCoverageSmallVectorCounterMappingRegionCreate() { - return new SmallVector<coverage::CounterMappingRegion, 32>(); -} - -extern "C" void LLVMRustCoverageSmallVectorCounterMappingRegionDispose( - SmallVectorTemplateBase<coverage::CounterMappingRegion> *Vector) { - delete Vector; -} - -extern "C" void LLVMRustCoverageSmallVectorCounterMappingRegionAdd( - SmallVectorTemplateBase<coverage::CounterMappingRegion> *MappingRegions, - unsigned Index, - unsigned FileID, - unsigned LineStart, - unsigned ColumnStart, - unsigned LineEnd, - unsigned ColumnEnd) { - auto Counter = coverage::Counter::getCounter(Index); - MappingRegions->push_back(coverage::CounterMappingRegion::makeRegion( - Counter, FileID, LineStart, - ColumnStart, LineEnd, ColumnEnd)); - - // FIXME(richkadel): As applicable, implement additional CounterMappingRegion types using the - // static method alternatives to `coverage::CounterMappingRegion::makeRegion`: - // - // makeExpansion(unsigned FileID, unsigned ExpandedFileID, unsigned LineStart, - // unsigned ColumnStart, unsigned LineEnd, unsigned ColumnEnd) { - // makeSkipped(unsigned FileID, unsigned LineStart, unsigned ColumnStart, - // unsigned LineEnd, unsigned ColumnEnd) { - // makeGapRegion(Counter Count, unsigned FileID, unsigned LineStart, - // unsigned ColumnStart, unsigned LineEnd, unsigned ColumnEnd) { -} - extern "C" void LLVMRustCoverageWriteFilenamesSectionToBuffer( const char* const Filenames[], size_t FilenamesLen, @@ -79,13 +25,15 @@ extern "C" void LLVMRustCoverageWriteFilenamesSectionToBuffer( extern "C" void LLVMRustCoverageWriteMappingToBuffer( const unsigned *VirtualFileMappingIDs, unsigned NumVirtualFileMappingIDs, - const SmallVectorImpl<coverage::CounterExpression> *Expressions, - SmallVectorImpl<coverage::CounterMappingRegion> *MappingRegions, + const coverage::CounterExpression *Expressions, + unsigned NumExpressions, + coverage::CounterMappingRegion *MappingRegions, + unsigned NumMappingRegions, RustStringRef BufferOut) { auto CoverageMappingWriter = coverage::CoverageMappingWriter( - makeArrayRef(VirtualFileMappingIDs, NumVirtualFileMappingIDs), - makeArrayRef(*Expressions), - MutableArrayRef<coverage::CounterMappingRegion> { *MappingRegions }); + makeArrayRef(VirtualFileMappingIDs, NumVirtualFileMappingIDs), + makeArrayRef(Expressions, NumExpressions), + makeMutableArrayRef(MappingRegions, NumMappingRegions)); RawRustStringOstream OS(BufferOut); CoverageMappingWriter.write(OS); } diff --git a/src/test/assembly/asm/aarch64-modifiers.rs b/src/test/assembly/asm/aarch64-modifiers.rs index c2484e9b6d0..150997ee807 100644 --- a/src/test/assembly/asm/aarch64-modifiers.rs +++ b/src/test/assembly/asm/aarch64-modifiers.rs @@ -2,6 +2,7 @@ // assembly-output: emit-asm // compile-flags: -O // compile-flags: --target aarch64-unknown-linux-gnu +// needs-llvm-components: aarch64 #![feature(no_core, lang_items, rustc_attrs)] #![crate_type = "rlib"] diff --git a/src/test/assembly/asm/aarch64-types.rs b/src/test/assembly/asm/aarch64-types.rs index ce2f0082a06..b78a8cbb559 100644 --- a/src/test/assembly/asm/aarch64-types.rs +++ b/src/test/assembly/asm/aarch64-types.rs @@ -1,6 +1,7 @@ // no-system-llvm // assembly-output: emit-asm // compile-flags: --target aarch64-unknown-linux-gnu +// needs-llvm-components: aarch64 #![feature(no_core, lang_items, rustc_attrs, repr_simd)] #![crate_type = "rlib"] diff --git a/src/test/assembly/asm/arm-modifiers.rs b/src/test/assembly/asm/arm-modifiers.rs index b71503d0a53..ad4ab63f265 100644 --- a/src/test/assembly/asm/arm-modifiers.rs +++ b/src/test/assembly/asm/arm-modifiers.rs @@ -3,6 +3,7 @@ // compile-flags: -O // compile-flags: --target armv7-unknown-linux-gnueabihf // compile-flags: -C target-feature=+neon +// needs-llvm-components: arm #![feature(no_core, lang_items, rustc_attrs, repr_simd)] #![crate_type = "rlib"] diff --git a/src/test/assembly/asm/arm-types.rs b/src/test/assembly/asm/arm-types.rs index 1e338f56c4d..07e25a38e45 100644 --- a/src/test/assembly/asm/arm-types.rs +++ b/src/test/assembly/asm/arm-types.rs @@ -2,6 +2,7 @@ // assembly-output: emit-asm // compile-flags: --target armv7-unknown-linux-gnueabihf // compile-flags: -C target-feature=+neon +// needs-llvm-components: arm #![feature(no_core, lang_items, rustc_attrs, repr_simd)] #![crate_type = "rlib"] diff --git a/src/test/assembly/asm/hexagon-types.rs b/src/test/assembly/asm/hexagon-types.rs index ba2d8a363cd..b6b3b54cd71 100644 --- a/src/test/assembly/asm/hexagon-types.rs +++ b/src/test/assembly/asm/hexagon-types.rs @@ -1,6 +1,7 @@ // no-system-llvm // assembly-output: emit-asm // compile-flags: --target hexagon-unknown-linux-musl +// needs-llvm-components: hexagon #![feature(no_core, lang_items, rustc_attrs, repr_simd)] #![crate_type = "rlib"] diff --git a/src/test/assembly/asm/nvptx-types.rs b/src/test/assembly/asm/nvptx-types.rs index 4ee79d1bcc8..77fd5141357 100644 --- a/src/test/assembly/asm/nvptx-types.rs +++ b/src/test/assembly/asm/nvptx-types.rs @@ -2,6 +2,7 @@ // assembly-output: emit-asm // compile-flags: --target nvptx64-nvidia-cuda // compile-flags: --crate-type cdylib +// needs-llvm-components: nvptx #![feature(no_core, lang_items, rustc_attrs)] #![no_core] diff --git a/src/test/assembly/asm/riscv-modifiers.rs b/src/test/assembly/asm/riscv-modifiers.rs index 8c816e3220b..b6735153b5d 100644 --- a/src/test/assembly/asm/riscv-modifiers.rs +++ b/src/test/assembly/asm/riscv-modifiers.rs @@ -3,6 +3,7 @@ // compile-flags: -O // compile-flags: --target riscv64gc-unknown-linux-gnu // compile-flags: -C target-feature=+f +// needs-llvm-components: riscv #![feature(no_core, lang_items, rustc_attrs)] #![crate_type = "rlib"] diff --git a/src/test/assembly/asm/riscv-types.rs b/src/test/assembly/asm/riscv-types.rs index 449213471cc..0ff0bf1f949 100644 --- a/src/test/assembly/asm/riscv-types.rs +++ b/src/test/assembly/asm/riscv-types.rs @@ -4,6 +4,7 @@ //[riscv64] compile-flags: --target riscv64imac-unknown-none-elf //[riscv32] compile-flags: --target riscv32imac-unknown-none-elf // compile-flags: -C target-feature=+d +// needs-llvm-components: riscv #![feature(no_core, lang_items, rustc_attrs)] #![crate_type = "rlib"] diff --git a/src/test/codegen/abi-efiapi.rs b/src/test/codegen/abi-efiapi.rs index 7c61b780990..1c0b77ad9c7 100644 --- a/src/test/codegen/abi-efiapi.rs +++ b/src/test/codegen/abi-efiapi.rs @@ -1,12 +1,14 @@ // Checks if the correct annotation for the efiapi ABI is passed to llvm. -// revisions:x86_64 i686 arm - +// revisions:x86_64 i686 aarch64 arm riscv // min-llvm-version: 9.0 +// needs-llvm-components: aarch64 arm riscv //[x86_64] compile-flags: --target x86_64-unknown-uefi //[i686] compile-flags: --target i686-unknown-linux-musl +//[aarch64] compile-flags: --target aarch64-unknown-none //[arm] compile-flags: --target armv7r-none-eabi +//[riscv] compile-flags: --target riscv64gc-unknown-none-elf // compile-flags: -C no-prepopulate-passes #![crate_type = "lib"] @@ -22,6 +24,8 @@ trait Copy { } //x86_64: define win64cc void @has_efiapi //i686: define void @has_efiapi +//aarch64: define void @has_efiapi //arm: define void @has_efiapi +//riscv: define void @has_efiapi #[no_mangle] pub extern "efiapi" fn has_efiapi() {} diff --git a/src/test/codegen/avr/avr-func-addrspace.rs b/src/test/codegen/avr/avr-func-addrspace.rs index 7759d9603a5..6d25ca56f14 100644 --- a/src/test/codegen/avr/avr-func-addrspace.rs +++ b/src/test/codegen/avr/avr-func-addrspace.rs @@ -1,4 +1,5 @@ // compile-flags: -O --target=avr-unknown-unknown --crate-type=rlib +// needs-llvm-components: avr // This test validates that function pointers can be stored in global variables // and called upon. It ensures that Rust emits function pointers in the correct diff --git a/src/test/codegen/naked-functions.rs b/src/test/codegen/naked-functions.rs index 493c1b9f0ba..758c6c4da92 100644 --- a/src/test/codegen/naked-functions.rs +++ b/src/test/codegen/naked-functions.rs @@ -18,7 +18,7 @@ pub fn naked_empty() { // CHECK-NEXT: define void @naked_with_args(i{{[0-9]+( %0)?}}) pub fn naked_with_args(a: isize) { // CHECK-NEXT: {{.+}}: - // CHECK-NEXT: %a = alloca i{{[0-9]+}} + // CHECK-NEXT: %_1 = alloca i{{[0-9]+}} &a; // keep variable in an alloca // CHECK: ret void } @@ -39,7 +39,7 @@ pub fn naked_with_return() -> isize { #[naked] pub fn naked_with_args_and_return(a: isize) -> isize { // CHECK-NEXT: {{.+}}: - // CHECK-NEXT: %a = alloca i{{[0-9]+}} + // CHECK-NEXT: %_1 = alloca i{{[0-9]+}} &a; // keep variable in an alloca // CHECK: ret i{{[0-9]+}} %{{[0-9]+}} a diff --git a/src/test/debuginfo/function-arguments-naked.rs b/src/test/debuginfo/function-arguments-naked.rs new file mode 100644 index 00000000000..e88a99b322e --- /dev/null +++ b/src/test/debuginfo/function-arguments-naked.rs @@ -0,0 +1,40 @@ +// min-lldb-version: 310 + +// We have to ignore android because of this issue: +// https://github.com/rust-lang/rust/issues/74847 +// ignore-android + +// compile-flags:-g + +// === GDB TESTS =================================================================================== + +// gdb-command:run + +// gdb-command:info args +// gdb-check:No arguments. +// gdb-command:continue + +// === LLDB TESTS ================================================================================== + +// lldb-command:run + +// lldb-command:frame variable +// lldbg-check:(unsigned long) = 111 (unsigned long) = 222 +// lldbr-check:(unsigned long) = 111 (unsigned long) = 222 +// lldb-command:continue + + +#![feature(naked_functions)] +#![feature(omit_gdb_pretty_printer_section)] +#![omit_gdb_pretty_printer_section] + +fn main() { + naked(111, 222); +} + +#[naked] +fn naked(x: usize, y: usize) { + zzz(); // #break +} + +fn zzz() { () } diff --git a/src/test/mir-opt/address-of.rs b/src/test/mir-opt/address-of.rs index 6cd14ccf434..c4bea5613e4 100644 --- a/src/test/mir-opt/address-of.rs +++ b/src/test/mir-opt/address-of.rs @@ -1,4 +1,4 @@ -// EMIT_MIR rustc.address_of_reborrow.SimplifyCfg-initial.after.mir +// EMIT_MIR address_of.address_of_reborrow.SimplifyCfg-initial.after.mir fn address_of_reborrow() { let y = &[0; 10]; @@ -37,7 +37,7 @@ fn address_of_reborrow() { } // The normal borrows here should be preserved -// EMIT_MIR rustc.borrow_and_cast.SimplifyCfg-initial.after.mir +// EMIT_MIR address_of.borrow_and_cast.SimplifyCfg-initial.after.mir fn borrow_and_cast(mut x: i32) { let p = &x as *const i32; let q = &mut x as *const i32; diff --git a/src/test/mir-opt/address-of/rustc.address_of_reborrow.SimplifyCfg-initial.after.mir b/src/test/mir-opt/address_of.address_of_reborrow.SimplifyCfg-initial.after.mir index 07793b3598f..07793b3598f 100644 --- a/src/test/mir-opt/address-of/rustc.address_of_reborrow.SimplifyCfg-initial.after.mir +++ b/src/test/mir-opt/address_of.address_of_reborrow.SimplifyCfg-initial.after.mir diff --git a/src/test/mir-opt/address-of/rustc.borrow_and_cast.SimplifyCfg-initial.after.mir b/src/test/mir-opt/address_of.borrow_and_cast.SimplifyCfg-initial.after.mir index 4a7e8de29ec..4a7e8de29ec 100644 --- a/src/test/mir-opt/address-of/rustc.borrow_and_cast.SimplifyCfg-initial.after.mir +++ b/src/test/mir-opt/address_of.borrow_and_cast.SimplifyCfg-initial.after.mir diff --git a/src/test/mir-opt/array-index-is-temporary.rs b/src/test/mir-opt/array-index-is-temporary.rs index 4667c4f66b2..0e4c486e464 100644 --- a/src/test/mir-opt/array-index-is-temporary.rs +++ b/src/test/mir-opt/array-index-is-temporary.rs @@ -8,7 +8,7 @@ unsafe fn foo(z: *mut usize) -> u32 { } // EMIT_MIR_FOR_EACH_BIT_WIDTH -// EMIT_MIR rustc.main.SimplifyCfg-elaborate-drops.after.mir +// EMIT_MIR array_index_is_temporary.main.SimplifyCfg-elaborate-drops.after.mir fn main() { let mut x = [42, 43, 44]; let mut y = 1; diff --git a/src/test/mir-opt/array-index-is-temporary/32bit/rustc.main.SimplifyCfg-elaborate-drops.after.mir b/src/test/mir-opt/array_index_is_temporary.main.SimplifyCfg-elaborate-drops.after.mir.32bit index 2a3a18d6c5b..2a3a18d6c5b 100644 --- a/src/test/mir-opt/array-index-is-temporary/32bit/rustc.main.SimplifyCfg-elaborate-drops.after.mir +++ b/src/test/mir-opt/array_index_is_temporary.main.SimplifyCfg-elaborate-drops.after.mir.32bit diff --git a/src/test/mir-opt/array-index-is-temporary/64bit/rustc.main.SimplifyCfg-elaborate-drops.after.mir b/src/test/mir-opt/array_index_is_temporary.main.SimplifyCfg-elaborate-drops.after.mir.64bit index 093c170cf7a..093c170cf7a 100644 --- a/src/test/mir-opt/array-index-is-temporary/64bit/rustc.main.SimplifyCfg-elaborate-drops.after.mir +++ b/src/test/mir-opt/array_index_is_temporary.main.SimplifyCfg-elaborate-drops.after.mir.64bit diff --git a/src/test/mir-opt/basic_assignment/rustc.main.SimplifyCfg-initial.after.mir b/src/test/mir-opt/basic_assignment.main.SimplifyCfg-initial.after.mir index de423cd907a..de423cd907a 100644 --- a/src/test/mir-opt/basic_assignment/rustc.main.SimplifyCfg-initial.after.mir +++ b/src/test/mir-opt/basic_assignment.main.SimplifyCfg-initial.after.mir diff --git a/src/test/mir-opt/basic_assignment.rs b/src/test/mir-opt/basic_assignment.rs index 17141b6334c..ac350271e9f 100644 --- a/src/test/mir-opt/basic_assignment.rs +++ b/src/test/mir-opt/basic_assignment.rs @@ -1,6 +1,6 @@ // this tests move up progration, which is not yet implemented -// EMIT_MIR rustc.main.SimplifyCfg-initial.after.mir +// EMIT_MIR basic_assignment.main.SimplifyCfg-initial.after.mir // Check codegen for assignments (`a = b`) where the left-hand-side is // not yet initialized. Assignments tend to be absent in simple code, diff --git a/src/test/mir-opt/box_expr/rustc.main.ElaborateDrops.before.mir b/src/test/mir-opt/box_expr.main.ElaborateDrops.before.mir index 259501c7de9..259501c7de9 100644 --- a/src/test/mir-opt/box_expr/rustc.main.ElaborateDrops.before.mir +++ b/src/test/mir-opt/box_expr.main.ElaborateDrops.before.mir diff --git a/src/test/mir-opt/box_expr.rs b/src/test/mir-opt/box_expr.rs index beaf0baf12c..a214504f6dd 100644 --- a/src/test/mir-opt/box_expr.rs +++ b/src/test/mir-opt/box_expr.rs @@ -2,7 +2,7 @@ #![feature(box_syntax)] -// EMIT_MIR rustc.main.ElaborateDrops.before.mir +// EMIT_MIR box_expr.main.ElaborateDrops.before.mir fn main() { let x = box S::new(); drop(x); diff --git a/src/test/mir-opt/byte_slice/rustc.main.SimplifyCfg-elaborate-drops.after.mir b/src/test/mir-opt/byte_slice.main.SimplifyCfg-elaborate-drops.after.mir index 54e01dceb50..54e01dceb50 100644 --- a/src/test/mir-opt/byte_slice/rustc.main.SimplifyCfg-elaborate-drops.after.mir +++ b/src/test/mir-opt/byte_slice.main.SimplifyCfg-elaborate-drops.after.mir diff --git a/src/test/mir-opt/byte_slice.rs b/src/test/mir-opt/byte_slice.rs index 317e96d6f52..48e9c48c120 100644 --- a/src/test/mir-opt/byte_slice.rs +++ b/src/test/mir-opt/byte_slice.rs @@ -1,6 +1,6 @@ // compile-flags: -Z mir-opt-level=0 -// EMIT_MIR rustc.main.SimplifyCfg-elaborate-drops.after.mir +// EMIT_MIR byte_slice.main.SimplifyCfg-elaborate-drops.after.mir fn main() { let x = b"foo"; let y = [5u8, b'x']; diff --git a/src/test/mir-opt/combine_array_len/32bit/rustc.norm2.InstCombine.diff b/src/test/mir-opt/combine_array_len.norm2.InstCombine.diff.32bit index 65db967fe5f..65db967fe5f 100644 --- a/src/test/mir-opt/combine_array_len/32bit/rustc.norm2.InstCombine.diff +++ b/src/test/mir-opt/combine_array_len.norm2.InstCombine.diff.32bit diff --git a/src/test/mir-opt/combine_array_len/64bit/rustc.norm2.InstCombine.diff b/src/test/mir-opt/combine_array_len.norm2.InstCombine.diff.64bit index 712c4eb230c..712c4eb230c 100644 --- a/src/test/mir-opt/combine_array_len/64bit/rustc.norm2.InstCombine.diff +++ b/src/test/mir-opt/combine_array_len.norm2.InstCombine.diff.64bit diff --git a/src/test/mir-opt/combine_array_len.rs b/src/test/mir-opt/combine_array_len.rs index aa1c7459ea1..93490c14fd6 100644 --- a/src/test/mir-opt/combine_array_len.rs +++ b/src/test/mir-opt/combine_array_len.rs @@ -1,5 +1,5 @@ // EMIT_MIR_FOR_EACH_BIT_WIDTH -// EMIT_MIR rustc.norm2.InstCombine.diff +// EMIT_MIR combine_array_len.norm2.InstCombine.diff fn norm2(x: [f32; 2]) -> f32 { let a = x[0]; diff --git a/src/test/mir-opt/const-promotion-extern-static.rs b/src/test/mir-opt/const-promotion-extern-static.rs index c9d350a98fd..e63309a9bd2 100644 --- a/src/test/mir-opt/const-promotion-extern-static.rs +++ b/src/test/mir-opt/const-promotion-extern-static.rs @@ -4,12 +4,12 @@ extern "C" { static Y: i32 = 42; -// EMIT_MIR rustc.BAR.PromoteTemps.diff -// EMIT_MIR rustc.BAR-promoted[0].ConstProp.after.mir +// EMIT_MIR const_promotion_extern_static.BAR.PromoteTemps.diff +// EMIT_MIR const_promotion_extern_static.BAR-promoted[0].ConstProp.after.mir static mut BAR: *const &i32 = [&Y].as_ptr(); -// EMIT_MIR rustc.FOO.PromoteTemps.diff -// EMIT_MIR rustc.FOO-promoted[0].ConstProp.after.mir +// EMIT_MIR const_promotion_extern_static.FOO.PromoteTemps.diff +// EMIT_MIR const_promotion_extern_static.FOO-promoted[0].ConstProp.after.mir static mut FOO: *const &i32 = [unsafe { &X }].as_ptr(); fn main() {} diff --git a/src/test/mir-opt/const_allocation/32bit/rustc.main.ConstProp.after.mir b/src/test/mir-opt/const_allocation.main.ConstProp.after.mir.32bit index 30a383fd162..30a383fd162 100644 --- a/src/test/mir-opt/const_allocation/32bit/rustc.main.ConstProp.after.mir +++ b/src/test/mir-opt/const_allocation.main.ConstProp.after.mir.32bit diff --git a/src/test/mir-opt/const_allocation/64bit/rustc.main.ConstProp.after.mir b/src/test/mir-opt/const_allocation.main.ConstProp.after.mir.64bit index 5fa54ae5a58..5fa54ae5a58 100644 --- a/src/test/mir-opt/const_allocation/64bit/rustc.main.ConstProp.after.mir +++ b/src/test/mir-opt/const_allocation.main.ConstProp.after.mir.64bit diff --git a/src/test/mir-opt/const_allocation.rs b/src/test/mir-opt/const_allocation.rs index aaf996ee8e1..bb1c48e8e3c 100644 --- a/src/test/mir-opt/const_allocation.rs +++ b/src/test/mir-opt/const_allocation.rs @@ -3,7 +3,7 @@ static FOO: &[(Option<i32>, &[&str])] = &[(None, &[]), (None, &["foo", "bar"]), (Some(42), &["meh", "mop", "möp"])]; -// EMIT_MIR rustc.main.ConstProp.after.mir +// EMIT_MIR const_allocation.main.ConstProp.after.mir fn main() { FOO; } diff --git a/src/test/mir-opt/const_allocation2/32bit/rustc.main.ConstProp.after.mir b/src/test/mir-opt/const_allocation2.main.ConstProp.after.mir.32bit index d386d247829..d386d247829 100644 --- a/src/test/mir-opt/const_allocation2/32bit/rustc.main.ConstProp.after.mir +++ b/src/test/mir-opt/const_allocation2.main.ConstProp.after.mir.32bit diff --git a/src/test/mir-opt/const_allocation2/64bit/rustc.main.ConstProp.after.mir b/src/test/mir-opt/const_allocation2.main.ConstProp.after.mir.64bit index d7acd0f0f43..d7acd0f0f43 100644 --- a/src/test/mir-opt/const_allocation2/64bit/rustc.main.ConstProp.after.mir +++ b/src/test/mir-opt/const_allocation2.main.ConstProp.after.mir.64bit diff --git a/src/test/mir-opt/const_allocation2.rs b/src/test/mir-opt/const_allocation2.rs index ca61b84c0bc..56839255c0e 100644 --- a/src/test/mir-opt/const_allocation2.rs +++ b/src/test/mir-opt/const_allocation2.rs @@ -1,6 +1,6 @@ // EMIT_MIR_FOR_EACH_BIT_WIDTH -// EMIT_MIR rustc.main.ConstProp.after.mir +// EMIT_MIR const_allocation2.main.ConstProp.after.mir fn main() { FOO; } diff --git a/src/test/mir-opt/const_allocation3/32bit/rustc.main.ConstProp.after.mir b/src/test/mir-opt/const_allocation3.main.ConstProp.after.mir.32bit index 39c60ad987a..39c60ad987a 100644 --- a/src/test/mir-opt/const_allocation3/32bit/rustc.main.ConstProp.after.mir +++ b/src/test/mir-opt/const_allocation3.main.ConstProp.after.mir.32bit diff --git a/src/test/mir-opt/const_allocation3/64bit/rustc.main.ConstProp.after.mir b/src/test/mir-opt/const_allocation3.main.ConstProp.after.mir.64bit index 96024f1c82c..96024f1c82c 100644 --- a/src/test/mir-opt/const_allocation3/64bit/rustc.main.ConstProp.after.mir +++ b/src/test/mir-opt/const_allocation3.main.ConstProp.after.mir.64bit diff --git a/src/test/mir-opt/const_allocation3.rs b/src/test/mir-opt/const_allocation3.rs index 73bb58e1a98..2ce289aea3f 100644 --- a/src/test/mir-opt/const_allocation3.rs +++ b/src/test/mir-opt/const_allocation3.rs @@ -1,6 +1,6 @@ // EMIT_MIR_FOR_EACH_BIT_WIDTH -// EMIT_MIR rustc.main.ConstProp.after.mir +// EMIT_MIR const_allocation3.main.ConstProp.after.mir fn main() { FOO; } diff --git a/src/test/mir-opt/const-promotion-extern-static/rustc.BAR-promoted[0].ConstProp.after.mir b/src/test/mir-opt/const_promotion_extern_static.BAR-promoted[0].ConstProp.after.mir index 509947071b0..509947071b0 100644 --- a/src/test/mir-opt/const-promotion-extern-static/rustc.BAR-promoted[0].ConstProp.after.mir +++ b/src/test/mir-opt/const_promotion_extern_static.BAR-promoted[0].ConstProp.after.mir diff --git a/src/test/mir-opt/const-promotion-extern-static/rustc.BAR.PromoteTemps.diff b/src/test/mir-opt/const_promotion_extern_static.BAR.PromoteTemps.diff index 0e0d8ea9063..0e0d8ea9063 100644 --- a/src/test/mir-opt/const-promotion-extern-static/rustc.BAR.PromoteTemps.diff +++ b/src/test/mir-opt/const_promotion_extern_static.BAR.PromoteTemps.diff diff --git a/src/test/mir-opt/const-promotion-extern-static/rustc.FOO-promoted[0].ConstProp.after.mir b/src/test/mir-opt/const_promotion_extern_static.FOO-promoted[0].ConstProp.after.mir index d9c6b4f0029..d9c6b4f0029 100644 --- a/src/test/mir-opt/const-promotion-extern-static/rustc.FOO-promoted[0].ConstProp.after.mir +++ b/src/test/mir-opt/const_promotion_extern_static.FOO-promoted[0].ConstProp.after.mir diff --git a/src/test/mir-opt/const-promotion-extern-static/rustc.FOO.PromoteTemps.diff b/src/test/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff index a885b4d3bae..a885b4d3bae 100644 --- a/src/test/mir-opt/const-promotion-extern-static/rustc.FOO.PromoteTemps.diff +++ b/src/test/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff diff --git a/src/test/mir-opt/const_prop/aggregate/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/aggregate.main.ConstProp.diff index e84e88b93fc..e84e88b93fc 100644 --- a/src/test/mir-opt/const_prop/aggregate/rustc.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/aggregate.main.ConstProp.diff diff --git a/src/test/mir-opt/const_prop/aggregate.rs b/src/test/mir-opt/const_prop/aggregate.rs index 928ed8265d3..7a3b26a7317 100644 --- a/src/test/mir-opt/const_prop/aggregate.rs +++ b/src/test/mir-opt/const_prop/aggregate.rs @@ -1,6 +1,6 @@ // compile-flags: -O -// EMIT_MIR rustc.main.ConstProp.diff +// EMIT_MIR aggregate.main.ConstProp.diff fn main() { let x = (0, 1, 2).1 + 0; } diff --git a/src/test/mir-opt/const_prop/array_index/32bit/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/array_index.main.ConstProp.diff.32bit index bbd6c8042f1..bbd6c8042f1 100644 --- a/src/test/mir-opt/const_prop/array_index/32bit/rustc.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/array_index.main.ConstProp.diff.32bit diff --git a/src/test/mir-opt/const_prop/array_index/64bit/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/array_index.main.ConstProp.diff.64bit index d9096e5f3f1..d9096e5f3f1 100644 --- a/src/test/mir-opt/const_prop/array_index/64bit/rustc.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/array_index.main.ConstProp.diff.64bit diff --git a/src/test/mir-opt/const_prop/array_index.rs b/src/test/mir-opt/const_prop/array_index.rs index 9301e6f5d03..2c5254b5deb 100644 --- a/src/test/mir-opt/const_prop/array_index.rs +++ b/src/test/mir-opt/const_prop/array_index.rs @@ -1,6 +1,6 @@ // EMIT_MIR_FOR_EACH_BIT_WIDTH -// EMIT_MIR rustc.main.ConstProp.diff +// EMIT_MIR array_index.main.ConstProp.diff fn main() { let x: u32 = [0, 1, 2, 3][2]; } diff --git a/src/test/mir-opt/const_prop/bad_op_div_by_zero/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/bad_op_div_by_zero.main.ConstProp.diff index 4bd4bb0dd7d..4bd4bb0dd7d 100644 --- a/src/test/mir-opt/const_prop/bad_op_div_by_zero/rustc.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/bad_op_div_by_zero.main.ConstProp.diff diff --git a/src/test/mir-opt/const_prop/bad_op_div_by_zero.rs b/src/test/mir-opt/const_prop/bad_op_div_by_zero.rs index 0cd1f37c9a7..6f39209b970 100644 --- a/src/test/mir-opt/const_prop/bad_op_div_by_zero.rs +++ b/src/test/mir-opt/const_prop/bad_op_div_by_zero.rs @@ -1,4 +1,4 @@ -// EMIT_MIR rustc.main.ConstProp.diff +// EMIT_MIR bad_op_div_by_zero.main.ConstProp.diff #[allow(unconditional_panic)] fn main() { let y = 0; diff --git a/src/test/mir-opt/const_prop/bad_op_mod_by_zero/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/bad_op_mod_by_zero.main.ConstProp.diff index ecd030e32b4..ecd030e32b4 100644 --- a/src/test/mir-opt/const_prop/bad_op_mod_by_zero/rustc.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/bad_op_mod_by_zero.main.ConstProp.diff diff --git a/src/test/mir-opt/const_prop/bad_op_mod_by_zero.rs b/src/test/mir-opt/const_prop/bad_op_mod_by_zero.rs index 26bccbb90ec..cc16a4a5aa7 100644 --- a/src/test/mir-opt/const_prop/bad_op_mod_by_zero.rs +++ b/src/test/mir-opt/const_prop/bad_op_mod_by_zero.rs @@ -1,4 +1,4 @@ -// EMIT_MIR rustc.main.ConstProp.diff +// EMIT_MIR bad_op_mod_by_zero.main.ConstProp.diff #[allow(unconditional_panic)] fn main() { let y = 0; diff --git a/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices/32bit/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.diff.32bit index 2b5010759d7..2b5010759d7 100644 --- a/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices/32bit/rustc.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.diff.32bit diff --git a/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices/64bit/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.diff.64bit index 301aaf29247..301aaf29247 100644 --- a/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices/64bit/rustc.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.diff.64bit diff --git a/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.rs b/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.rs index e517e467c37..cf22b06d5e5 100644 --- a/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.rs +++ b/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.rs @@ -1,5 +1,5 @@ // EMIT_MIR_FOR_EACH_BIT_WIDTH -// EMIT_MIR rustc.main.ConstProp.diff +// EMIT_MIR bad_op_unsafe_oob_for_slices.main.ConstProp.diff #[allow(unconditional_panic)] fn main() { let a: *const [_] = &[1, 2, 3]; diff --git a/src/test/mir-opt/const_prop/boolean_identities.rs b/src/test/mir-opt/const_prop/boolean_identities.rs index 4e09acbaa53..6dae07dfbd1 100644 --- a/src/test/mir-opt/const_prop/boolean_identities.rs +++ b/src/test/mir-opt/const_prop/boolean_identities.rs @@ -1,6 +1,6 @@ // compile-flags: -O -Zmir-opt-level=3 -// EMIT_MIR rustc.test.ConstProp.diff +// EMIT_MIR boolean_identities.test.ConstProp.diff pub fn test(x: bool, y: bool) -> bool { (y | true) & (x & false) } diff --git a/src/test/mir-opt/const_prop/boolean_identities/rustc.test.ConstProp.diff b/src/test/mir-opt/const_prop/boolean_identities.test.ConstProp.diff index b8f0ad4d434..b8f0ad4d434 100644 --- a/src/test/mir-opt/const_prop/boolean_identities/rustc.test.ConstProp.diff +++ b/src/test/mir-opt/const_prop/boolean_identities.test.ConstProp.diff diff --git a/src/test/mir-opt/const_prop/boxes/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/boxes.main.ConstProp.diff index f271188ebfd..f271188ebfd 100644 --- a/src/test/mir-opt/const_prop/boxes/rustc.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/boxes.main.ConstProp.diff diff --git a/src/test/mir-opt/const_prop/boxes.rs b/src/test/mir-opt/const_prop/boxes.rs index d45804ebb6c..fea666a4455 100644 --- a/src/test/mir-opt/const_prop/boxes.rs +++ b/src/test/mir-opt/const_prop/boxes.rs @@ -7,7 +7,7 @@ // Note: this test verifies that we, in fact, do not const prop `box` -// EMIT_MIR rustc.main.ConstProp.diff +// EMIT_MIR boxes.main.ConstProp.diff fn main() { let x = *(box 42) + 0; } diff --git a/src/test/mir-opt/const_prop/cast/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/cast.main.ConstProp.diff index 54af804d19b..54af804d19b 100644 --- a/src/test/mir-opt/const_prop/cast/rustc.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/cast.main.ConstProp.diff diff --git a/src/test/mir-opt/const_prop/cast.rs b/src/test/mir-opt/const_prop/cast.rs index 2af5f32a668..680cab00740 100644 --- a/src/test/mir-opt/const_prop/cast.rs +++ b/src/test/mir-opt/const_prop/cast.rs @@ -1,4 +1,4 @@ -// EMIT_MIR rustc.main.ConstProp.diff +// EMIT_MIR cast.main.ConstProp.diff fn main() { let x = 42u8 as u32; diff --git a/src/test/mir-opt/const_prop/checked_add/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/checked_add.main.ConstProp.diff index e3690d71294..e3690d71294 100644 --- a/src/test/mir-opt/const_prop/checked_add/rustc.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/checked_add.main.ConstProp.diff diff --git a/src/test/mir-opt/const_prop/checked_add.rs b/src/test/mir-opt/const_prop/checked_add.rs index 439bd2df91f..08d59b6fbc3 100644 --- a/src/test/mir-opt/const_prop/checked_add.rs +++ b/src/test/mir-opt/const_prop/checked_add.rs @@ -1,6 +1,6 @@ // compile-flags: -C overflow-checks=on -// EMIT_MIR rustc.main.ConstProp.diff +// EMIT_MIR checked_add.main.ConstProp.diff fn main() { let x: u32 = 1 + 1; } diff --git a/src/test/mir-opt/const_prop/const_prop_fails_gracefully/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/const_prop_fails_gracefully.main.ConstProp.diff index f3efef387a3..f3efef387a3 100644 --- a/src/test/mir-opt/const_prop/const_prop_fails_gracefully/rustc.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/const_prop_fails_gracefully.main.ConstProp.diff diff --git a/src/test/mir-opt/const_prop/const_prop_fails_gracefully.rs b/src/test/mir-opt/const_prop/const_prop_fails_gracefully.rs index c6c006c0809..8bd68527f37 100644 --- a/src/test/mir-opt/const_prop/const_prop_fails_gracefully.rs +++ b/src/test/mir-opt/const_prop/const_prop_fails_gracefully.rs @@ -1,7 +1,7 @@ #[inline(never)] fn read(_: usize) { } -// EMIT_MIR rustc.main.ConstProp.diff +// EMIT_MIR const_prop_fails_gracefully.main.ConstProp.diff fn main() { const FOO: &i32 = &1; let x = FOO as *const i32 as usize; diff --git a/src/test/mir-opt/const_prop/control-flow-simplification.rs b/src/test/mir-opt/const_prop/control-flow-simplification.rs index 1071590dd9e..aa4ce19f620 100644 --- a/src/test/mir-opt/const_prop/control-flow-simplification.rs +++ b/src/test/mir-opt/const_prop/control-flow-simplification.rs @@ -6,8 +6,8 @@ trait NeedsDrop:Sized{ impl<This> NeedsDrop for This{} -// EMIT_MIR rustc.hello.ConstProp.diff -// EMIT_MIR rustc.hello.PreCodegen.before.mir +// EMIT_MIR control_flow_simplification.hello.ConstProp.diff +// EMIT_MIR control_flow_simplification.hello.PreCodegen.before.mir fn hello<T>(){ if <bool>::NEEDS { panic!() diff --git a/src/test/mir-opt/const_prop/control-flow-simplification/rustc.hello.ConstProp.diff b/src/test/mir-opt/const_prop/control_flow_simplification.hello.ConstProp.diff index 474b9ffefba..474b9ffefba 100644 --- a/src/test/mir-opt/const_prop/control-flow-simplification/rustc.hello.ConstProp.diff +++ b/src/test/mir-opt/const_prop/control_flow_simplification.hello.ConstProp.diff diff --git a/src/test/mir-opt/const_prop/control-flow-simplification/rustc.hello.PreCodegen.before.mir b/src/test/mir-opt/const_prop/control_flow_simplification.hello.PreCodegen.before.mir index 3569b9897f9..3569b9897f9 100644 --- a/src/test/mir-opt/const_prop/control-flow-simplification/rustc.hello.PreCodegen.before.mir +++ b/src/test/mir-opt/const_prop/control_flow_simplification.hello.PreCodegen.before.mir diff --git a/src/test/mir-opt/const_prop/discriminant/32bit/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/discriminant.main.ConstProp.diff.32bit index 539a16f52dc..539a16f52dc 100644 --- a/src/test/mir-opt/const_prop/discriminant/32bit/rustc.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/discriminant.main.ConstProp.diff.32bit diff --git a/src/test/mir-opt/const_prop/discriminant/64bit/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/discriminant.main.ConstProp.diff.64bit index 20875448edd..20875448edd 100644 --- a/src/test/mir-opt/const_prop/discriminant/64bit/rustc.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/discriminant.main.ConstProp.diff.64bit diff --git a/src/test/mir-opt/const_prop/discriminant.rs b/src/test/mir-opt/const_prop/discriminant.rs index 13e8eb3e44e..67538b3c7a5 100644 --- a/src/test/mir-opt/const_prop/discriminant.rs +++ b/src/test/mir-opt/const_prop/discriminant.rs @@ -6,7 +6,7 @@ // Fixing either of those will allow us to const-prop this away. // EMIT_MIR_FOR_EACH_BIT_WIDTH -// EMIT_MIR rustc.main.ConstProp.diff +// EMIT_MIR discriminant.main.ConstProp.diff fn main() { let x = (if let Some(true) = Some(true) { 42 } else { 10 }) + 0; } diff --git a/src/test/mir-opt/const_prop/indirect/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/indirect.main.ConstProp.diff index 57906b1cabd..57906b1cabd 100644 --- a/src/test/mir-opt/const_prop/indirect/rustc.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/indirect.main.ConstProp.diff diff --git a/src/test/mir-opt/const_prop/indirect.rs b/src/test/mir-opt/const_prop/indirect.rs index 961e4447d8b..37217ca8134 100644 --- a/src/test/mir-opt/const_prop/indirect.rs +++ b/src/test/mir-opt/const_prop/indirect.rs @@ -1,6 +1,6 @@ // compile-flags: -C overflow-checks=on -// EMIT_MIR rustc.main.ConstProp.diff +// EMIT_MIR indirect.main.ConstProp.diff fn main() { let x = (2u32 as u8) + 1; } diff --git a/src/test/mir-opt/const_prop/issue-66971.rs b/src/test/mir-opt/const_prop/issue-66971.rs index 50a1405b77b..986177b5c0a 100644 --- a/src/test/mir-opt/const_prop/issue-66971.rs +++ b/src/test/mir-opt/const_prop/issue-66971.rs @@ -11,7 +11,7 @@ fn encode(this: ((), u8, u8)) { assert!(this.2 == 0); } -// EMIT_MIR rustc.main.ConstProp.diff +// EMIT_MIR issue_66971.main.ConstProp.diff fn main() { encode(((), 0, 0)); } diff --git a/src/test/mir-opt/const_prop/issue-67019.rs b/src/test/mir-opt/const_prop/issue-67019.rs index 3c832eb1344..d277bd5869c 100644 --- a/src/test/mir-opt/const_prop/issue-67019.rs +++ b/src/test/mir-opt/const_prop/issue-67019.rs @@ -6,7 +6,7 @@ fn test(this: ((u8, u8),)) { assert!((this.0).0 == 1); } -// EMIT_MIR rustc.main.ConstProp.diff +// EMIT_MIR issue_67019.main.ConstProp.diff fn main() { test(((1, 2),)); } diff --git a/src/test/mir-opt/const_prop/issue-66971/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/issue_66971.main.ConstProp.diff index 242907b5599..242907b5599 100644 --- a/src/test/mir-opt/const_prop/issue-66971/rustc.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/issue_66971.main.ConstProp.diff diff --git a/src/test/mir-opt/const_prop/issue-67019/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/issue_67019.main.ConstProp.diff index d5c1105d7ca..d5c1105d7ca 100644 --- a/src/test/mir-opt/const_prop/issue-67019/rustc.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/issue_67019.main.ConstProp.diff diff --git a/src/test/mir-opt/const_prop/mult_by_zero.rs b/src/test/mir-opt/const_prop/mult_by_zero.rs index f40faee3110..1cb50155b5e 100644 --- a/src/test/mir-opt/const_prop/mult_by_zero.rs +++ b/src/test/mir-opt/const_prop/mult_by_zero.rs @@ -1,6 +1,6 @@ // compile-flags: -O -Zmir-opt-level=3 -// EMIT_MIR rustc.test.ConstProp.diff +// EMIT_MIR mult_by_zero.test.ConstProp.diff fn test(x : i32) -> i32 { x * 0 } diff --git a/src/test/mir-opt/const_prop/mult_by_zero/rustc.test.ConstProp.diff b/src/test/mir-opt/const_prop/mult_by_zero.test.ConstProp.diff index 7b36669bf15..7b36669bf15 100644 --- a/src/test/mir-opt/const_prop/mult_by_zero/rustc.test.ConstProp.diff +++ b/src/test/mir-opt/const_prop/mult_by_zero.test.ConstProp.diff diff --git a/src/test/mir-opt/const_prop/mutable_variable/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/mutable_variable.main.ConstProp.diff index 3d4309a8aec..3d4309a8aec 100644 --- a/src/test/mir-opt/const_prop/mutable_variable/rustc.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/mutable_variable.main.ConstProp.diff diff --git a/src/test/mir-opt/const_prop/mutable_variable.rs b/src/test/mir-opt/const_prop/mutable_variable.rs index b3a2d80fa95..801e7a9fcbb 100644 --- a/src/test/mir-opt/const_prop/mutable_variable.rs +++ b/src/test/mir-opt/const_prop/mutable_variable.rs @@ -1,6 +1,6 @@ // compile-flags: -O -// EMIT_MIR rustc.main.ConstProp.diff +// EMIT_MIR mutable_variable.main.ConstProp.diff fn main() { let mut x = 42; x = 99; diff --git a/src/test/mir-opt/const_prop/mutable_variable_aggregate/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/mutable_variable_aggregate.main.ConstProp.diff index f581b222c83..f581b222c83 100644 --- a/src/test/mir-opt/const_prop/mutable_variable_aggregate/rustc.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/mutable_variable_aggregate.main.ConstProp.diff diff --git a/src/test/mir-opt/const_prop/mutable_variable_aggregate.rs b/src/test/mir-opt/const_prop/mutable_variable_aggregate.rs index 3c5fb4574b6..e0b4b77bac4 100644 --- a/src/test/mir-opt/const_prop/mutable_variable_aggregate.rs +++ b/src/test/mir-opt/const_prop/mutable_variable_aggregate.rs @@ -1,6 +1,6 @@ // compile-flags: -O -// EMIT_MIR rustc.main.ConstProp.diff +// EMIT_MIR mutable_variable_aggregate.main.ConstProp.diff fn main() { let mut x = (42, 43); x.1 = 99; diff --git a/src/test/mir-opt/const_prop/mutable_variable_aggregate_mut_ref/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/mutable_variable_aggregate_mut_ref.main.ConstProp.diff index e78bc31b774..e78bc31b774 100644 --- a/src/test/mir-opt/const_prop/mutable_variable_aggregate_mut_ref/rustc.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/mutable_variable_aggregate_mut_ref.main.ConstProp.diff diff --git a/src/test/mir-opt/const_prop/mutable_variable_aggregate_mut_ref.rs b/src/test/mir-opt/const_prop/mutable_variable_aggregate_mut_ref.rs index fc13cbf2abd..79ac497c783 100644 --- a/src/test/mir-opt/const_prop/mutable_variable_aggregate_mut_ref.rs +++ b/src/test/mir-opt/const_prop/mutable_variable_aggregate_mut_ref.rs @@ -1,6 +1,6 @@ // compile-flags: -O -// EMIT_MIR rustc.main.ConstProp.diff +// EMIT_MIR mutable_variable_aggregate_mut_ref.main.ConstProp.diff fn main() { let mut x = (42, 43); let z = &mut x; diff --git a/src/test/mir-opt/const_prop/mutable_variable_aggregate_partial_read/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/mutable_variable_aggregate_partial_read.main.ConstProp.diff index b1a0ab88fcc..b1a0ab88fcc 100644 --- a/src/test/mir-opt/const_prop/mutable_variable_aggregate_partial_read/rustc.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/mutable_variable_aggregate_partial_read.main.ConstProp.diff diff --git a/src/test/mir-opt/const_prop/mutable_variable_aggregate_partial_read.rs b/src/test/mir-opt/const_prop/mutable_variable_aggregate_partial_read.rs index 4f43ec8c947..9bb62b8973c 100644 --- a/src/test/mir-opt/const_prop/mutable_variable_aggregate_partial_read.rs +++ b/src/test/mir-opt/const_prop/mutable_variable_aggregate_partial_read.rs @@ -1,6 +1,6 @@ // compile-flags: -O -// EMIT_MIR rustc.main.ConstProp.diff +// EMIT_MIR mutable_variable_aggregate_partial_read.main.ConstProp.diff fn main() { let mut x: (i32, i32) = foo(); x.1 = 99; diff --git a/src/test/mir-opt/const_prop/mutable_variable_no_prop/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/mutable_variable_no_prop.main.ConstProp.diff index 3b72af2d0b9..3b72af2d0b9 100644 --- a/src/test/mir-opt/const_prop/mutable_variable_no_prop/rustc.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/mutable_variable_no_prop.main.ConstProp.diff diff --git a/src/test/mir-opt/const_prop/mutable_variable_no_prop.rs b/src/test/mir-opt/const_prop/mutable_variable_no_prop.rs index 8c9cd005096..4126fb3c68c 100644 --- a/src/test/mir-opt/const_prop/mutable_variable_no_prop.rs +++ b/src/test/mir-opt/const_prop/mutable_variable_no_prop.rs @@ -2,7 +2,7 @@ static mut STATIC: u32 = 42; -// EMIT_MIR rustc.main.ConstProp.diff +// EMIT_MIR mutable_variable_no_prop.main.ConstProp.diff fn main() { let mut x = 42; unsafe { diff --git a/src/test/mir-opt/const_prop/mutable_variable_unprop_assign/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/mutable_variable_unprop_assign.main.ConstProp.diff index b59b180b07d..b59b180b07d 100644 --- a/src/test/mir-opt/const_prop/mutable_variable_unprop_assign/rustc.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/mutable_variable_unprop_assign.main.ConstProp.diff diff --git a/src/test/mir-opt/const_prop/mutable_variable_unprop_assign.rs b/src/test/mir-opt/const_prop/mutable_variable_unprop_assign.rs index 40f801b1b5e..13f1b3f47f2 100644 --- a/src/test/mir-opt/const_prop/mutable_variable_unprop_assign.rs +++ b/src/test/mir-opt/const_prop/mutable_variable_unprop_assign.rs @@ -1,6 +1,6 @@ // compile-flags: -O -// EMIT_MIR rustc.main.ConstProp.diff +// EMIT_MIR mutable_variable_unprop_assign.main.ConstProp.diff fn main() { let a = foo(); let mut x: (i32, i32) = (1, 2); diff --git a/src/test/mir-opt/const_prop/optimizes_into_variable/32bit/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.diff.32bit index 5312784bc8a..5312784bc8a 100644 --- a/src/test/mir-opt/const_prop/optimizes_into_variable/32bit/rustc.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.diff.32bit diff --git a/src/test/mir-opt/const_prop/optimizes_into_variable/64bit/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.diff.64bit index 7af99841366..7af99841366 100644 --- a/src/test/mir-opt/const_prop/optimizes_into_variable/64bit/rustc.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.diff.64bit diff --git a/src/test/mir-opt/const_prop/optimizes_into_variable/32bit/rustc.main.SimplifyLocals.after.mir b/src/test/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals.after.mir.32bit index 7b74bf81d96..7b74bf81d96 100644 --- a/src/test/mir-opt/const_prop/optimizes_into_variable/32bit/rustc.main.SimplifyLocals.after.mir +++ b/src/test/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals.after.mir.32bit diff --git a/src/test/mir-opt/const_prop/optimizes_into_variable/64bit/rustc.main.SimplifyLocals.after.mir b/src/test/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals.after.mir.64bit index 7b74bf81d96..7b74bf81d96 100644 --- a/src/test/mir-opt/const_prop/optimizes_into_variable/64bit/rustc.main.SimplifyLocals.after.mir +++ b/src/test/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals.after.mir.64bit diff --git a/src/test/mir-opt/const_prop/optimizes_into_variable.rs b/src/test/mir-opt/const_prop/optimizes_into_variable.rs index 0ae172e777b..17265b7eb85 100644 --- a/src/test/mir-opt/const_prop/optimizes_into_variable.rs +++ b/src/test/mir-opt/const_prop/optimizes_into_variable.rs @@ -6,8 +6,8 @@ struct Point { } // EMIT_MIR_FOR_EACH_BIT_WIDTH -// EMIT_MIR rustc.main.ConstProp.diff -// EMIT_MIR rustc.main.SimplifyLocals.after.mir +// EMIT_MIR optimizes_into_variable.main.ConstProp.diff +// EMIT_MIR optimizes_into_variable.main.SimplifyLocals.after.mir fn main() { let x = 2 + 2; let y = [0, 1, 2, 3, 4, 5][3]; diff --git a/src/test/mir-opt/const_prop/read_immutable_static/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/read_immutable_static.main.ConstProp.diff index 36edfc42b9a..36edfc42b9a 100644 --- a/src/test/mir-opt/const_prop/read_immutable_static/rustc.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/read_immutable_static.main.ConstProp.diff diff --git a/src/test/mir-opt/const_prop/read_immutable_static.rs b/src/test/mir-opt/const_prop/read_immutable_static.rs index 9635f7050a6..8a5f12c6f3d 100644 --- a/src/test/mir-opt/const_prop/read_immutable_static.rs +++ b/src/test/mir-opt/const_prop/read_immutable_static.rs @@ -2,7 +2,7 @@ static FOO: u8 = 2; -// EMIT_MIR rustc.main.ConstProp.diff +// EMIT_MIR read_immutable_static.main.ConstProp.diff fn main() { let x = FOO + FOO; } diff --git a/src/test/mir-opt/const_prop/ref_deref/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/ref_deref.main.ConstProp.diff index ba5ac8d3ddf..ba5ac8d3ddf 100644 --- a/src/test/mir-opt/const_prop/ref_deref/rustc.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/ref_deref.main.ConstProp.diff diff --git a/src/test/mir-opt/const_prop/ref_deref/rustc.main.PromoteTemps.diff b/src/test/mir-opt/const_prop/ref_deref.main.PromoteTemps.diff index fa68eb34818..fa68eb34818 100644 --- a/src/test/mir-opt/const_prop/ref_deref/rustc.main.PromoteTemps.diff +++ b/src/test/mir-opt/const_prop/ref_deref.main.PromoteTemps.diff diff --git a/src/test/mir-opt/const_prop/ref_deref.rs b/src/test/mir-opt/const_prop/ref_deref.rs index fc33e0e1f3b..30ec9766367 100644 --- a/src/test/mir-opt/const_prop/ref_deref.rs +++ b/src/test/mir-opt/const_prop/ref_deref.rs @@ -1,5 +1,5 @@ -// EMIT_MIR rustc.main.PromoteTemps.diff -// EMIT_MIR rustc.main.ConstProp.diff +// EMIT_MIR ref_deref.main.PromoteTemps.diff +// EMIT_MIR ref_deref.main.ConstProp.diff fn main() { *(&4); diff --git a/src/test/mir-opt/const_prop/ref_deref_project/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/ref_deref_project.main.ConstProp.diff index 483e5f1b9a4..483e5f1b9a4 100644 --- a/src/test/mir-opt/const_prop/ref_deref_project/rustc.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/ref_deref_project.main.ConstProp.diff diff --git a/src/test/mir-opt/const_prop/ref_deref_project/rustc.main.PromoteTemps.diff b/src/test/mir-opt/const_prop/ref_deref_project.main.PromoteTemps.diff index 86e6aacab45..86e6aacab45 100644 --- a/src/test/mir-opt/const_prop/ref_deref_project/rustc.main.PromoteTemps.diff +++ b/src/test/mir-opt/const_prop/ref_deref_project.main.PromoteTemps.diff diff --git a/src/test/mir-opt/const_prop/ref_deref_project.rs b/src/test/mir-opt/const_prop/ref_deref_project.rs index 0322e300643..c7cc73651f6 100644 --- a/src/test/mir-opt/const_prop/ref_deref_project.rs +++ b/src/test/mir-opt/const_prop/ref_deref_project.rs @@ -1,5 +1,5 @@ -// EMIT_MIR rustc.main.PromoteTemps.diff -// EMIT_MIR rustc.main.ConstProp.diff +// EMIT_MIR ref_deref_project.main.PromoteTemps.diff +// EMIT_MIR ref_deref_project.main.ConstProp.diff fn main() { *(&(4, 5).1); // This does not currently propagate (#67862) diff --git a/src/test/mir-opt/const_prop/reify_fn_ptr/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/reify_fn_ptr.main.ConstProp.diff index 93fe856c8e8..93fe856c8e8 100644 --- a/src/test/mir-opt/const_prop/reify_fn_ptr/rustc.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/reify_fn_ptr.main.ConstProp.diff diff --git a/src/test/mir-opt/const_prop/reify_fn_ptr.rs b/src/test/mir-opt/const_prop/reify_fn_ptr.rs index 834eb0cb1e9..bfe2563ad8a 100644 --- a/src/test/mir-opt/const_prop/reify_fn_ptr.rs +++ b/src/test/mir-opt/const_prop/reify_fn_ptr.rs @@ -1,4 +1,4 @@ -// EMIT_MIR rustc.main.ConstProp.diff +// EMIT_MIR reify_fn_ptr.main.ConstProp.diff fn main() { let _ = main as usize as *const fn(); diff --git a/src/test/mir-opt/const_prop/repeat/32bit/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/repeat.main.ConstProp.diff.32bit index c30075bbb05..c30075bbb05 100644 --- a/src/test/mir-opt/const_prop/repeat/32bit/rustc.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/repeat.main.ConstProp.diff.32bit diff --git a/src/test/mir-opt/const_prop/repeat/64bit/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/repeat.main.ConstProp.diff.64bit index cadce59cf95..cadce59cf95 100644 --- a/src/test/mir-opt/const_prop/repeat/64bit/rustc.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/repeat.main.ConstProp.diff.64bit diff --git a/src/test/mir-opt/const_prop/repeat.rs b/src/test/mir-opt/const_prop/repeat.rs index cdbfc46d6ca..36d9b9fc62d 100644 --- a/src/test/mir-opt/const_prop/repeat.rs +++ b/src/test/mir-opt/const_prop/repeat.rs @@ -1,7 +1,7 @@ // compile-flags: -O // EMIT_MIR_FOR_EACH_BIT_WIDTH -// EMIT_MIR rustc.main.ConstProp.diff +// EMIT_MIR repeat.main.ConstProp.diff fn main() { let x: u32 = [42; 8][2] + 0; } diff --git a/src/test/mir-opt/const_prop/return_place/rustc.add.ConstProp.diff b/src/test/mir-opt/const_prop/return_place.add.ConstProp.diff index 5e39c8e6d52..5e39c8e6d52 100644 --- a/src/test/mir-opt/const_prop/return_place/rustc.add.ConstProp.diff +++ b/src/test/mir-opt/const_prop/return_place.add.ConstProp.diff diff --git a/src/test/mir-opt/const_prop/return_place/rustc.add.PreCodegen.before.mir b/src/test/mir-opt/const_prop/return_place.add.PreCodegen.before.mir index 23ad8d057ba..23ad8d057ba 100644 --- a/src/test/mir-opt/const_prop/return_place/rustc.add.PreCodegen.before.mir +++ b/src/test/mir-opt/const_prop/return_place.add.PreCodegen.before.mir diff --git a/src/test/mir-opt/const_prop/return_place.rs b/src/test/mir-opt/const_prop/return_place.rs index 8d5b63b9afd..06a85369679 100644 --- a/src/test/mir-opt/const_prop/return_place.rs +++ b/src/test/mir-opt/const_prop/return_place.rs @@ -1,7 +1,7 @@ // compile-flags: -C overflow-checks=on -// EMIT_MIR rustc.add.ConstProp.diff -// EMIT_MIR rustc.add.PreCodegen.before.mir +// EMIT_MIR return_place.add.ConstProp.diff +// EMIT_MIR return_place.add.PreCodegen.before.mir fn add() -> u32 { 2 + 2 } diff --git a/src/test/mir-opt/const_prop/scalar_literal_propagation/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/scalar_literal_propagation.main.ConstProp.diff index 43e0eb09a2e..43e0eb09a2e 100644 --- a/src/test/mir-opt/const_prop/scalar_literal_propagation/rustc.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/scalar_literal_propagation.main.ConstProp.diff diff --git a/src/test/mir-opt/const_prop/scalar_literal_propagation.rs b/src/test/mir-opt/const_prop/scalar_literal_propagation.rs index a740e69dca2..8724e4d5711 100644 --- a/src/test/mir-opt/const_prop/scalar_literal_propagation.rs +++ b/src/test/mir-opt/const_prop/scalar_literal_propagation.rs @@ -1,4 +1,4 @@ -// EMIT_MIR rustc.main.ConstProp.diff +// EMIT_MIR scalar_literal_propagation.main.ConstProp.diff fn main() { let x = 1; consume(x); diff --git a/src/test/mir-opt/const_prop/slice_len/32bit/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/slice_len.main.ConstProp.diff.32bit index 0a07a1a11f2..0a07a1a11f2 100644 --- a/src/test/mir-opt/const_prop/slice_len/32bit/rustc.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/slice_len.main.ConstProp.diff.32bit diff --git a/src/test/mir-opt/const_prop/slice_len/64bit/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/slice_len.main.ConstProp.diff.64bit index f8c6f29e854..f8c6f29e854 100644 --- a/src/test/mir-opt/const_prop/slice_len/64bit/rustc.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/slice_len.main.ConstProp.diff.64bit diff --git a/src/test/mir-opt/const_prop/slice_len.rs b/src/test/mir-opt/const_prop/slice_len.rs index 0312f5e8e3a..fa9eafa8b0b 100644 --- a/src/test/mir-opt/const_prop/slice_len.rs +++ b/src/test/mir-opt/const_prop/slice_len.rs @@ -1,6 +1,6 @@ // EMIT_MIR_FOR_EACH_BIT_WIDTH -// EMIT_MIR rustc.main.ConstProp.diff +// EMIT_MIR slice_len.main.ConstProp.diff fn main() { (&[1u32, 2, 3] as &[u32])[1]; } diff --git a/src/test/mir-opt/const_prop/switch_int/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/switch_int.main.ConstProp.diff index 9580b99da9e..9580b99da9e 100644 --- a/src/test/mir-opt/const_prop/switch_int/rustc.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/switch_int.main.ConstProp.diff diff --git a/src/test/mir-opt/const_prop/switch_int/rustc.main.SimplifyBranches-after-const-prop.diff b/src/test/mir-opt/const_prop/switch_int.main.SimplifyBranches-after-const-prop.diff index 54f37e609ec..54f37e609ec 100644 --- a/src/test/mir-opt/const_prop/switch_int/rustc.main.SimplifyBranches-after-const-prop.diff +++ b/src/test/mir-opt/const_prop/switch_int.main.SimplifyBranches-after-const-prop.diff diff --git a/src/test/mir-opt/const_prop/switch_int.rs b/src/test/mir-opt/const_prop/switch_int.rs index 46e6efb8180..9e7c7340448 100644 --- a/src/test/mir-opt/const_prop/switch_int.rs +++ b/src/test/mir-opt/const_prop/switch_int.rs @@ -1,8 +1,8 @@ #[inline(never)] fn foo(_: i32) { } -// EMIT_MIR rustc.main.ConstProp.diff -// EMIT_MIR rustc.main.SimplifyBranches-after-const-prop.diff +// EMIT_MIR switch_int.main.ConstProp.diff +// EMIT_MIR switch_int.main.SimplifyBranches-after-const-prop.diff fn main() { match 1 { 1 => foo(0), diff --git a/src/test/mir-opt/const_prop/tuple_literal_propagation/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/tuple_literal_propagation.main.ConstProp.diff index 941ec64a3cc..941ec64a3cc 100644 --- a/src/test/mir-opt/const_prop/tuple_literal_propagation/rustc.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/tuple_literal_propagation.main.ConstProp.diff diff --git a/src/test/mir-opt/const_prop/tuple_literal_propagation.rs b/src/test/mir-opt/const_prop/tuple_literal_propagation.rs index 015607cbab1..e644baec4a8 100644 --- a/src/test/mir-opt/const_prop/tuple_literal_propagation.rs +++ b/src/test/mir-opt/const_prop/tuple_literal_propagation.rs @@ -1,4 +1,4 @@ -// EMIT_MIR rustc.main.ConstProp.diff +// EMIT_MIR tuple_literal_propagation.main.ConstProp.diff fn main() { let x = (1, 2); diff --git a/src/test/mir-opt/const_prop_miscompile/rustc.bar.ConstProp.diff b/src/test/mir-opt/const_prop_miscompile.bar.ConstProp.diff index 5fe35b479c1..5fe35b479c1 100644 --- a/src/test/mir-opt/const_prop_miscompile/rustc.bar.ConstProp.diff +++ b/src/test/mir-opt/const_prop_miscompile.bar.ConstProp.diff diff --git a/src/test/mir-opt/const_prop_miscompile/rustc.foo.ConstProp.diff b/src/test/mir-opt/const_prop_miscompile.foo.ConstProp.diff index 98e9825c1c4..98e9825c1c4 100644 --- a/src/test/mir-opt/const_prop_miscompile/rustc.foo.ConstProp.diff +++ b/src/test/mir-opt/const_prop_miscompile.foo.ConstProp.diff diff --git a/src/test/mir-opt/const_prop_miscompile.rs b/src/test/mir-opt/const_prop_miscompile.rs index 043b22870f4..bc54556b349 100644 --- a/src/test/mir-opt/const_prop_miscompile.rs +++ b/src/test/mir-opt/const_prop_miscompile.rs @@ -1,13 +1,13 @@ #![feature(raw_ref_op)] -// EMIT_MIR rustc.foo.ConstProp.diff +// EMIT_MIR const_prop_miscompile.foo.ConstProp.diff fn foo() { let mut u = (1,); *&mut u.0 = 5; let y = { u.0 } == 5; } -// EMIT_MIR rustc.bar.ConstProp.diff +// EMIT_MIR const_prop_miscompile.bar.ConstProp.diff fn bar() { let mut v = (1,); unsafe { diff --git a/src/test/mir-opt/copy_propagation.rs b/src/test/mir-opt/copy_propagation.rs index b5db5497d48..ee460a488b6 100644 --- a/src/test/mir-opt/copy_propagation.rs +++ b/src/test/mir-opt/copy_propagation.rs @@ -1,4 +1,4 @@ -// EMIT_MIR rustc.test.CopyPropagation.diff +// EMIT_MIR copy_propagation.test.CopyPropagation.diff fn test(x: u32) -> u32 { let y = x; diff --git a/src/test/mir-opt/copy_propagation/rustc.test.CopyPropagation.diff b/src/test/mir-opt/copy_propagation.test.CopyPropagation.diff index f2838638aca..f2838638aca 100644 --- a/src/test/mir-opt/copy_propagation/rustc.test.CopyPropagation.diff +++ b/src/test/mir-opt/copy_propagation.test.CopyPropagation.diff diff --git a/src/test/mir-opt/copy_propagation_arg/rustc.arg_src.CopyPropagation.diff b/src/test/mir-opt/copy_propagation_arg.arg_src.CopyPropagation.diff index 22fbf4e836b..22fbf4e836b 100644 --- a/src/test/mir-opt/copy_propagation_arg/rustc.arg_src.CopyPropagation.diff +++ b/src/test/mir-opt/copy_propagation_arg.arg_src.CopyPropagation.diff diff --git a/src/test/mir-opt/copy_propagation_arg/rustc.bar.CopyPropagation.diff b/src/test/mir-opt/copy_propagation_arg.bar.CopyPropagation.diff index 6953a80a5f0..6953a80a5f0 100644 --- a/src/test/mir-opt/copy_propagation_arg/rustc.bar.CopyPropagation.diff +++ b/src/test/mir-opt/copy_propagation_arg.bar.CopyPropagation.diff diff --git a/src/test/mir-opt/copy_propagation_arg/rustc.baz.CopyPropagation.diff b/src/test/mir-opt/copy_propagation_arg.baz.CopyPropagation.diff index ee20553f7cc..ee20553f7cc 100644 --- a/src/test/mir-opt/copy_propagation_arg/rustc.baz.CopyPropagation.diff +++ b/src/test/mir-opt/copy_propagation_arg.baz.CopyPropagation.diff diff --git a/src/test/mir-opt/copy_propagation_arg/rustc.foo.CopyPropagation.diff b/src/test/mir-opt/copy_propagation_arg.foo.CopyPropagation.diff index 33aaa748678..33aaa748678 100644 --- a/src/test/mir-opt/copy_propagation_arg/rustc.foo.CopyPropagation.diff +++ b/src/test/mir-opt/copy_propagation_arg.foo.CopyPropagation.diff diff --git a/src/test/mir-opt/copy_propagation_arg.rs b/src/test/mir-opt/copy_propagation_arg.rs index c4858be7f2b..3a00fc58a4e 100644 --- a/src/test/mir-opt/copy_propagation_arg.rs +++ b/src/test/mir-opt/copy_propagation_arg.rs @@ -5,25 +5,25 @@ fn dummy(x: u8) -> u8 { x } -// EMIT_MIR rustc.foo.CopyPropagation.diff +// EMIT_MIR copy_propagation_arg.foo.CopyPropagation.diff fn foo(mut x: u8) { // calling `dummy` to make an use of `x` that copyprop cannot eliminate x = dummy(x); // this will assign a local to `x` } -// EMIT_MIR rustc.bar.CopyPropagation.diff +// EMIT_MIR copy_propagation_arg.bar.CopyPropagation.diff fn bar(mut x: u8) { dummy(x); x = 5; } -// EMIT_MIR rustc.baz.CopyPropagation.diff +// EMIT_MIR copy_propagation_arg.baz.CopyPropagation.diff fn baz(mut x: i32) { // self-assignment to a function argument should be eliminated x = x; } -// EMIT_MIR rustc.arg_src.CopyPropagation.diff +// EMIT_MIR copy_propagation_arg.arg_src.CopyPropagation.diff fn arg_src(mut x: i32) -> i32 { let y = x; x = 123; // Don't propagate this assignment to `y` diff --git a/src/test/mir-opt/deaggregator_test/rustc.bar.Deaggregator.diff b/src/test/mir-opt/deaggregator_test.bar.Deaggregator.diff index 524156e0b92..524156e0b92 100644 --- a/src/test/mir-opt/deaggregator_test/rustc.bar.Deaggregator.diff +++ b/src/test/mir-opt/deaggregator_test.bar.Deaggregator.diff diff --git a/src/test/mir-opt/deaggregator_test.rs b/src/test/mir-opt/deaggregator_test.rs index 9004a631291..342e222431b 100644 --- a/src/test/mir-opt/deaggregator_test.rs +++ b/src/test/mir-opt/deaggregator_test.rs @@ -4,7 +4,7 @@ struct Baz { z: bool, } -// EMIT_MIR rustc.bar.Deaggregator.diff +// EMIT_MIR deaggregator_test.bar.Deaggregator.diff fn bar(a: usize) -> Baz { Baz { x: a, y: 0.0, z: false } } diff --git a/src/test/mir-opt/deaggregator_test_enum/rustc.bar.Deaggregator.diff b/src/test/mir-opt/deaggregator_test_enum.bar.Deaggregator.diff index 5af9a536693..5af9a536693 100644 --- a/src/test/mir-opt/deaggregator_test_enum/rustc.bar.Deaggregator.diff +++ b/src/test/mir-opt/deaggregator_test_enum.bar.Deaggregator.diff diff --git a/src/test/mir-opt/deaggregator_test_enum.rs b/src/test/mir-opt/deaggregator_test_enum.rs index e74eafd011f..02b63a1f55d 100644 --- a/src/test/mir-opt/deaggregator_test_enum.rs +++ b/src/test/mir-opt/deaggregator_test_enum.rs @@ -3,7 +3,7 @@ enum Baz { Foo { x: usize }, } -// EMIT_MIR rustc.bar.Deaggregator.diff +// EMIT_MIR deaggregator_test_enum.bar.Deaggregator.diff fn bar(a: usize) -> Baz { Baz::Foo { x: a } } diff --git a/src/test/mir-opt/deaggregator_test_enum_2.rs b/src/test/mir-opt/deaggregator_test_enum_2.rs index d5201ed72a8..489854ff0aa 100644 --- a/src/test/mir-opt/deaggregator_test_enum_2.rs +++ b/src/test/mir-opt/deaggregator_test_enum_2.rs @@ -5,7 +5,7 @@ enum Foo { B(i32), } -// EMIT_MIR rustc.test1.Deaggregator.diff +// EMIT_MIR deaggregator_test_enum_2.test1.Deaggregator.diff fn test1(x: bool, y: i32) -> Foo { if x { Foo::A(y) diff --git a/src/test/mir-opt/deaggregator_test_enum_2/rustc.test1.Deaggregator.diff b/src/test/mir-opt/deaggregator_test_enum_2.test1.Deaggregator.diff index bf99f7efb4d..bf99f7efb4d 100644 --- a/src/test/mir-opt/deaggregator_test_enum_2/rustc.test1.Deaggregator.diff +++ b/src/test/mir-opt/deaggregator_test_enum_2.test1.Deaggregator.diff diff --git a/src/test/mir-opt/deaggregator_test_multiple.rs b/src/test/mir-opt/deaggregator_test_multiple.rs index 824a970ce2f..9730b9aa8e5 100644 --- a/src/test/mir-opt/deaggregator_test_multiple.rs +++ b/src/test/mir-opt/deaggregator_test_multiple.rs @@ -5,7 +5,7 @@ enum Foo { B, } -// EMIT_MIR rustc.test.Deaggregator.diff +// EMIT_MIR deaggregator_test_multiple.test.Deaggregator.diff fn test(x: i32) -> [Foo; 2] { [Foo::A(x), Foo::A(x)] } diff --git a/src/test/mir-opt/deaggregator_test_multiple/rustc.test.Deaggregator.diff b/src/test/mir-opt/deaggregator_test_multiple.test.Deaggregator.diff index f5d8d0607c6..f5d8d0607c6 100644 --- a/src/test/mir-opt/deaggregator_test_multiple/rustc.test.Deaggregator.diff +++ b/src/test/mir-opt/deaggregator_test_multiple.test.Deaggregator.diff diff --git a/src/test/mir-opt/exponential-or.rs b/src/test/mir-opt/exponential-or.rs index 9fce7928f6a..1d6f7b81890 100644 --- a/src/test/mir-opt/exponential-or.rs +++ b/src/test/mir-opt/exponential-or.rs @@ -2,7 +2,7 @@ #![feature(or_patterns)] -// EMIT_MIR rustc.match_tuple.SimplifyCfg-initial.after.mir +// EMIT_MIR exponential_or.match_tuple.SimplifyCfg-initial.after.mir fn match_tuple(x: (u32, bool, Option<i32>, u32)) -> u32 { match x { (y @ (1 | 4), true | false, Some(1 | 8) | None, z @ (6..=9 | 13..=16)) => y ^ z, diff --git a/src/test/mir-opt/exponential-or/rustc.match_tuple.SimplifyCfg-initial.after.mir b/src/test/mir-opt/exponential_or.match_tuple.SimplifyCfg-initial.after.mir index 00942cd12b4..00942cd12b4 100644 --- a/src/test/mir-opt/exponential-or/rustc.match_tuple.SimplifyCfg-initial.after.mir +++ b/src/test/mir-opt/exponential_or.match_tuple.SimplifyCfg-initial.after.mir diff --git a/src/test/mir-opt/fn-ptr-shim.rs b/src/test/mir-opt/fn-ptr-shim.rs index 08413c9f6fc..796bec0be1e 100644 --- a/src/test/mir-opt/fn-ptr-shim.rs +++ b/src/test/mir-opt/fn-ptr-shim.rs @@ -3,7 +3,7 @@ // Tests that the `<fn() as Fn>` shim does not create a `Call` terminator with a `Self` callee // (as only `FnDef` and `FnPtr` callees are allowed in MIR). -// EMIT_MIR rustc.ops-function-Fn-call.AddMovesForPackedDrops.before.mir +// EMIT_MIR core.ops-function-Fn-call.AddMovesForPackedDrops.before.mir fn main() { call(noop as fn()); } diff --git a/src/test/mir-opt/fn-ptr-shim/rustc.ops-function-Fn-call.AddMovesForPackedDrops.before.mir b/src/test/mir-opt/fn_ptr_shim.core.ops-function-Fn-call.AddMovesForPackedDrops.before.mir index 199cbcf8375..199cbcf8375 100644 --- a/src/test/mir-opt/fn-ptr-shim/rustc.ops-function-Fn-call.AddMovesForPackedDrops.before.mir +++ b/src/test/mir-opt/fn_ptr_shim.core.ops-function-Fn-call.AddMovesForPackedDrops.before.mir diff --git a/src/test/mir-opt/generator-drop-cleanup.rs b/src/test/mir-opt/generator-drop-cleanup.rs index 3e9707c6491..f4fc2aec706 100644 --- a/src/test/mir-opt/generator-drop-cleanup.rs +++ b/src/test/mir-opt/generator-drop-cleanup.rs @@ -5,7 +5,7 @@ // Regression test for #58892, generator drop shims should not have blocks // spuriously marked as cleanup -// EMIT_MIR rustc.main-{{closure}}.generator_drop.0.mir +// EMIT_MIR generator_drop_cleanup.main-{{closure}}.generator_drop.0.mir fn main() { let gen = || { let _s = String::new(); diff --git a/src/test/mir-opt/generator-storage-dead-unwind.rs b/src/test/mir-opt/generator-storage-dead-unwind.rs index abfb39c77d6..ae9faaefdd5 100644 --- a/src/test/mir-opt/generator-storage-dead-unwind.rs +++ b/src/test/mir-opt/generator-storage-dead-unwind.rs @@ -17,7 +17,7 @@ struct Bar(i32); fn take<T>(_x: T) {} -// EMIT_MIR rustc.main-{{closure}}.StateTransform.before.mir +// EMIT_MIR generator_storage_dead_unwind.main-{{closure}}.StateTransform.before.mir fn main() { let _gen = || { let a = Foo(5); diff --git a/src/test/mir-opt/generator-tiny.rs b/src/test/mir-opt/generator-tiny.rs index c86e2865ca8..0e79f16255b 100644 --- a/src/test/mir-opt/generator-tiny.rs +++ b/src/test/mir-opt/generator-tiny.rs @@ -14,7 +14,7 @@ impl Drop for HasDrop { fn callee() {} -// EMIT_MIR rustc.main-{{closure}}.generator_resume.0.mir +// EMIT_MIR generator_tiny.main-{{closure}}.generator_resume.0.mir fn main() { let _gen = |_x: u8| { let _d = HasDrop; diff --git a/src/test/mir-opt/generator-drop-cleanup/rustc.main-{{closure}}.generator_drop.0.mir b/src/test/mir-opt/generator_drop_cleanup.main-{{closure}}.generator_drop.0.mir index bd64a31663a..bd64a31663a 100644 --- a/src/test/mir-opt/generator-drop-cleanup/rustc.main-{{closure}}.generator_drop.0.mir +++ b/src/test/mir-opt/generator_drop_cleanup.main-{{closure}}.generator_drop.0.mir diff --git a/src/test/mir-opt/generator-storage-dead-unwind/rustc.main-{{closure}}.StateTransform.before.mir b/src/test/mir-opt/generator_storage_dead_unwind.main-{{closure}}.StateTransform.before.mir index 7dcfda32ca4..7dcfda32ca4 100644 --- a/src/test/mir-opt/generator-storage-dead-unwind/rustc.main-{{closure}}.StateTransform.before.mir +++ b/src/test/mir-opt/generator_storage_dead_unwind.main-{{closure}}.StateTransform.before.mir diff --git a/src/test/mir-opt/generator-tiny/rustc.main-{{closure}}.generator_resume.0.mir b/src/test/mir-opt/generator_tiny.main-{{closure}}.generator_resume.0.mir index 8776e5919bd..8776e5919bd 100644 --- a/src/test/mir-opt/generator-tiny/rustc.main-{{closure}}.generator_resume.0.mir +++ b/src/test/mir-opt/generator_tiny.main-{{closure}}.generator_resume.0.mir diff --git a/src/test/mir-opt/graphviz/rustc.main.mir_map.0.dot b/src/test/mir-opt/graphviz.main.mir_map.0.dot index f5d8b84812a..f5d8b84812a 100644 --- a/src/test/mir-opt/graphviz/rustc.main.mir_map.0.dot +++ b/src/test/mir-opt/graphviz.main.mir_map.0.dot diff --git a/src/test/mir-opt/graphviz.rs b/src/test/mir-opt/graphviz.rs index b1c0f0dd3c8..074dba2c373 100644 --- a/src/test/mir-opt/graphviz.rs +++ b/src/test/mir-opt/graphviz.rs @@ -1,5 +1,5 @@ // Test graphviz output // compile-flags: -Z dump-mir-graphviz -// EMIT_MIR rustc.main.mir_map.0.dot +// EMIT_MIR graphviz.main.mir_map.0.dot fn main() {} diff --git a/src/test/mir-opt/inline/inline-any-operand.rs b/src/test/mir-opt/inline/inline-any-operand.rs index 2edde12d72e..fb0de020f73 100644 --- a/src/test/mir-opt/inline/inline-any-operand.rs +++ b/src/test/mir-opt/inline/inline-any-operand.rs @@ -6,7 +6,7 @@ fn main() { println!("{}", bar()); } -// EMIT_MIR rustc.bar.Inline.after.mir +// EMIT_MIR inline_any_operand.bar.Inline.after.mir fn bar() -> bool { let f = foo; f(1, -1) diff --git a/src/test/mir-opt/inline/inline-closure-borrows-arg.rs b/src/test/mir-opt/inline/inline-closure-borrows-arg.rs index a82a91945d8..218bc3553a1 100644 --- a/src/test/mir-opt/inline/inline-closure-borrows-arg.rs +++ b/src/test/mir-opt/inline/inline-closure-borrows-arg.rs @@ -7,7 +7,7 @@ fn main() { println!("{}", foo(0, &14)); } -// EMIT_MIR rustc.foo.Inline.after.mir +// EMIT_MIR inline_closure_borrows_arg.foo.Inline.after.mir fn foo<T: Copy>(_t: T, q: &i32) -> i32 { let x = |r: &i32, _s: &i32| { let variable = &*r; diff --git a/src/test/mir-opt/inline/inline-closure-captures.rs b/src/test/mir-opt/inline/inline-closure-captures.rs index 4a0aad9b0e6..52b6817e401 100644 --- a/src/test/mir-opt/inline/inline-closure-captures.rs +++ b/src/test/mir-opt/inline/inline-closure-captures.rs @@ -6,7 +6,7 @@ fn main() { println!("{:?}", foo(0, 14)); } -// EMIT_MIR rustc.foo.Inline.after.mir +// EMIT_MIR inline_closure_captures.foo.Inline.after.mir fn foo<T: Copy>(t: T, q: i32) -> (i32, T) { let x = |_q| (q, t); x(q) diff --git a/src/test/mir-opt/inline/inline-closure.rs b/src/test/mir-opt/inline/inline-closure.rs index 77e424a2bb3..715fd0138a7 100644 --- a/src/test/mir-opt/inline/inline-closure.rs +++ b/src/test/mir-opt/inline/inline-closure.rs @@ -6,7 +6,7 @@ fn main() { println!("{}", foo(0, 14)); } -// EMIT_MIR rustc.foo.Inline.after.mir +// EMIT_MIR inline_closure.foo.Inline.after.mir fn foo<T: Copy>(_t: T, q: i32) -> i32 { let x = |_t, _q| _t; x(q, q) diff --git a/src/test/mir-opt/inline/inline-into-box-place.rs b/src/test/mir-opt/inline/inline-into-box-place.rs index 77834e9661c..30c9a5d6b8f 100644 --- a/src/test/mir-opt/inline/inline-into-box-place.rs +++ b/src/test/mir-opt/inline/inline-into-box-place.rs @@ -3,7 +3,7 @@ // EMIT_MIR_FOR_EACH_BIT_WIDTH #![feature(box_syntax)] -// EMIT_MIR rustc.main.Inline.diff +// EMIT_MIR inline_into_box_place.main.Inline.diff fn main() { let _x: Box<Vec<u32>> = box Vec::new(); } diff --git a/src/test/mir-opt/inline/inline-retag.rs b/src/test/mir-opt/inline/inline-retag.rs index d7e425ec658..c6950f26925 100644 --- a/src/test/mir-opt/inline/inline-retag.rs +++ b/src/test/mir-opt/inline/inline-retag.rs @@ -6,7 +6,7 @@ fn main() { println!("{}", bar()); } -// EMIT_MIR rustc.bar.Inline.after.mir +// EMIT_MIR inline_retag.bar.Inline.after.mir fn bar() -> bool { let f = foo; f(&1, &-1) diff --git a/src/test/mir-opt/inline/inline-specialization.rs b/src/test/mir-opt/inline/inline-specialization.rs index fcdaca460a9..87275b4e514 100644 --- a/src/test/mir-opt/inline/inline-specialization.rs +++ b/src/test/mir-opt/inline/inline-specialization.rs @@ -1,6 +1,6 @@ #![feature(specialization)] -// EMIT_MIR rustc.main.Inline.diff +// EMIT_MIR inline_specialization.main.Inline.diff fn main() { let x = <Vec::<()> as Foo>::bar(); } diff --git a/src/test/mir-opt/inline/inline-trait-method.rs b/src/test/mir-opt/inline/inline-trait-method.rs index cb3db9b5592..74be53f5512 100644 --- a/src/test/mir-opt/inline/inline-trait-method.rs +++ b/src/test/mir-opt/inline/inline-trait-method.rs @@ -4,7 +4,7 @@ fn main() { println!("{}", test(&())); } -// EMIT_MIR rustc.test.Inline.after.mir +// EMIT_MIR inline_trait_method.test.Inline.after.mir fn test(x: &dyn X) -> u32 { x.y() } diff --git a/src/test/mir-opt/inline/inline-trait-method_2.rs b/src/test/mir-opt/inline/inline-trait-method_2.rs index e37f091c5cd..6e5de8315a1 100644 --- a/src/test/mir-opt/inline/inline-trait-method_2.rs +++ b/src/test/mir-opt/inline/inline-trait-method_2.rs @@ -1,6 +1,6 @@ // compile-flags: -Z span_free_formats -Z mir-opt-level=3 -// EMIT_MIR rustc.test2.Inline.after.mir +// EMIT_MIR inline_trait_method_2.test2.Inline.after.mir fn test2(x: &dyn X) -> bool { test(x) } diff --git a/src/test/mir-opt/inline/inline-any-operand/rustc.bar.Inline.after.mir b/src/test/mir-opt/inline/inline_any_operand.bar.Inline.after.mir index c9ff1fe29f5..c9ff1fe29f5 100644 --- a/src/test/mir-opt/inline/inline-any-operand/rustc.bar.Inline.after.mir +++ b/src/test/mir-opt/inline/inline_any_operand.bar.Inline.after.mir diff --git a/src/test/mir-opt/inline/inline-closure/rustc.foo.Inline.after.mir b/src/test/mir-opt/inline/inline_closure.foo.Inline.after.mir index bd0ec8c7ddb..bd0ec8c7ddb 100644 --- a/src/test/mir-opt/inline/inline-closure/rustc.foo.Inline.after.mir +++ b/src/test/mir-opt/inline/inline_closure.foo.Inline.after.mir diff --git a/src/test/mir-opt/inline/inline-closure-borrows-arg/rustc.foo.Inline.after.mir b/src/test/mir-opt/inline/inline_closure_borrows_arg.foo.Inline.after.mir index cea3c59a3e4..cea3c59a3e4 100644 --- a/src/test/mir-opt/inline/inline-closure-borrows-arg/rustc.foo.Inline.after.mir +++ b/src/test/mir-opt/inline/inline_closure_borrows_arg.foo.Inline.after.mir diff --git a/src/test/mir-opt/inline/inline-closure-captures/rustc.foo.Inline.after.mir b/src/test/mir-opt/inline/inline_closure_captures.foo.Inline.after.mir index eeff914ccff..eeff914ccff 100644 --- a/src/test/mir-opt/inline/inline-closure-captures/rustc.foo.Inline.after.mir +++ b/src/test/mir-opt/inline/inline_closure_captures.foo.Inline.after.mir diff --git a/src/test/mir-opt/inline/inline-into-box-place/32bit/rustc.main.Inline.diff b/src/test/mir-opt/inline/inline_into_box_place.main.Inline.diff.32bit index 855811964b1..855811964b1 100644 --- a/src/test/mir-opt/inline/inline-into-box-place/32bit/rustc.main.Inline.diff +++ b/src/test/mir-opt/inline/inline_into_box_place.main.Inline.diff.32bit diff --git a/src/test/mir-opt/inline/inline-into-box-place/64bit/rustc.main.Inline.diff b/src/test/mir-opt/inline/inline_into_box_place.main.Inline.diff.64bit index 507e45a445b..507e45a445b 100644 --- a/src/test/mir-opt/inline/inline-into-box-place/64bit/rustc.main.Inline.diff +++ b/src/test/mir-opt/inline/inline_into_box_place.main.Inline.diff.64bit diff --git a/src/test/mir-opt/inline/inline-retag/rustc.bar.Inline.after.mir b/src/test/mir-opt/inline/inline_retag.bar.Inline.after.mir index d6ac1c57a63..d6ac1c57a63 100644 --- a/src/test/mir-opt/inline/inline-retag/rustc.bar.Inline.after.mir +++ b/src/test/mir-opt/inline/inline_retag.bar.Inline.after.mir diff --git a/src/test/mir-opt/inline/inline-specialization/rustc.main.Inline.diff b/src/test/mir-opt/inline/inline_specialization.main.Inline.diff index c273c43c429..c273c43c429 100644 --- a/src/test/mir-opt/inline/inline-specialization/rustc.main.Inline.diff +++ b/src/test/mir-opt/inline/inline_specialization.main.Inline.diff diff --git a/src/test/mir-opt/inline/inline-trait-method/rustc.test.Inline.after.mir b/src/test/mir-opt/inline/inline_trait_method.test.Inline.after.mir index 8acc5ad5c09..8acc5ad5c09 100644 --- a/src/test/mir-opt/inline/inline-trait-method/rustc.test.Inline.after.mir +++ b/src/test/mir-opt/inline/inline_trait_method.test.Inline.after.mir diff --git a/src/test/mir-opt/inline/inline-trait-method_2/rustc.test2.Inline.after.mir b/src/test/mir-opt/inline/inline_trait_method_2.test2.Inline.after.mir index afea1d5ebff..afea1d5ebff 100644 --- a/src/test/mir-opt/inline/inline-trait-method_2/rustc.test2.Inline.after.mir +++ b/src/test/mir-opt/inline/inline_trait_method_2.test2.Inline.after.mir diff --git a/src/test/mir-opt/inline/issue-58867-inline-as-ref-as-mut.rs b/src/test/mir-opt/inline/issue-58867-inline-as-ref-as-mut.rs index 317705f7612..94f926d3964 100644 --- a/src/test/mir-opt/inline/issue-58867-inline-as-ref-as-mut.rs +++ b/src/test/mir-opt/inline/issue-58867-inline-as-ref-as-mut.rs @@ -1,19 +1,19 @@ -// EMIT_MIR rustc.a.Inline.after.mir +// EMIT_MIR issue_58867_inline_as_ref_as_mut.a.Inline.after.mir pub fn a<T>(x: &mut [T]) -> &mut [T] { x.as_mut() } -// EMIT_MIR rustc.b.Inline.after.mir +// EMIT_MIR issue_58867_inline_as_ref_as_mut.b.Inline.after.mir pub fn b<T>(x: &mut Box<T>) -> &mut T { x.as_mut() } -// EMIT_MIR rustc.c.Inline.after.mir +// EMIT_MIR issue_58867_inline_as_ref_as_mut.c.Inline.after.mir pub fn c<T>(x: &[T]) -> &[T] { x.as_ref() } -// EMIT_MIR rustc.d.Inline.after.mir +// EMIT_MIR issue_58867_inline_as_ref_as_mut.d.Inline.after.mir pub fn d<T>(x: &Box<T>) -> &T { x.as_ref() } diff --git a/src/test/mir-opt/inline/issue-58867-inline-as-ref-as-mut/rustc.a.Inline.after.mir b/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.a.Inline.after.mir index 501e3e9cf96..501e3e9cf96 100644 --- a/src/test/mir-opt/inline/issue-58867-inline-as-ref-as-mut/rustc.a.Inline.after.mir +++ b/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.a.Inline.after.mir diff --git a/src/test/mir-opt/inline/issue-58867-inline-as-ref-as-mut/rustc.b.Inline.after.mir b/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir index 6add8d9d75a..6add8d9d75a 100644 --- a/src/test/mir-opt/inline/issue-58867-inline-as-ref-as-mut/rustc.b.Inline.after.mir +++ b/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir diff --git a/src/test/mir-opt/inline/issue-58867-inline-as-ref-as-mut/rustc.c.Inline.after.mir b/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.c.Inline.after.mir index 77492c89379..77492c89379 100644 --- a/src/test/mir-opt/inline/issue-58867-inline-as-ref-as-mut/rustc.c.Inline.after.mir +++ b/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.c.Inline.after.mir diff --git a/src/test/mir-opt/inline/issue-58867-inline-as-ref-as-mut/rustc.d.Inline.after.mir b/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir index 51bda6d334c..51bda6d334c 100644 --- a/src/test/mir-opt/inline/issue-58867-inline-as-ref-as-mut/rustc.d.Inline.after.mir +++ b/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir diff --git a/src/test/mir-opt/instrument_coverage/rustc.bar.InstrumentCoverage.diff b/src/test/mir-opt/instrument_coverage.bar.InstrumentCoverage.diff index e7fef4622b1..96df5c6a518 100644 --- a/src/test/mir-opt/instrument_coverage/rustc.bar.InstrumentCoverage.diff +++ b/src/test/mir-opt/instrument_coverage.bar.InstrumentCoverage.diff @@ -7,7 +7,7 @@ bb0: { + StorageLive(_1); // scope 0 at $DIR/instrument_coverage.rs:18:18: 18:18 -+ _1 = const std::intrinsics::count_code_region(const 10208505205182607101_u64, const 0_u32, const 501_u32, const 513_u32) -> bb2; // scope 0 at $DIR/instrument_coverage.rs:18:18: 18:18 ++ _1 = const std::intrinsics::count_code_region(const 10208505205182607101_u64, const 0_u32, const 529_u32, const 541_u32) -> bb2; // scope 0 at $DIR/instrument_coverage.rs:18:18: 18:18 + // ty::Const + // + ty: unsafe extern "rust-intrinsic" fn(u64, u32, u32, u32) {std::intrinsics::count_code_region} + // + val: Value(Scalar(<ZST>)) @@ -28,16 +28,16 @@ + // + literal: Const { ty: u32, val: Value(Scalar(0x00000000)) } + // ty::Const + // + ty: u32 -+ // + val: Value(Scalar(0x000001f5)) ++ // + val: Value(Scalar(0x00000211)) + // mir::Constant + // + span: $DIR/instrument_coverage.rs:18:18: 18:18 -+ // + literal: Const { ty: u32, val: Value(Scalar(0x000001f5)) } ++ // + literal: Const { ty: u32, val: Value(Scalar(0x00000211)) } + // ty::Const + // + ty: u32 -+ // + val: Value(Scalar(0x00000201)) ++ // + val: Value(Scalar(0x0000021d)) + // mir::Constant + // + span: $DIR/instrument_coverage.rs:18:18: 18:18 -+ // + literal: Const { ty: u32, val: Value(Scalar(0x00000201)) } ++ // + literal: Const { ty: u32, val: Value(Scalar(0x0000021d)) } + } + + bb1 (cleanup): { diff --git a/src/test/mir-opt/instrument_coverage/rustc.main.InstrumentCoverage.diff b/src/test/mir-opt/instrument_coverage.main.InstrumentCoverage.diff index 51378c216da..1bcc98de8d4 100644 --- a/src/test/mir-opt/instrument_coverage/rustc.main.InstrumentCoverage.diff +++ b/src/test/mir-opt/instrument_coverage.main.InstrumentCoverage.diff @@ -11,7 +11,7 @@ bb0: { - falseUnwind -> [real: bb1, cleanup: bb2]; // scope 0 at $DIR/instrument_coverage.rs:10:5: 14:6 + StorageLive(_4); // scope 0 at $DIR/instrument_coverage.rs:9:11: 9:11 -+ _4 = const std::intrinsics::count_code_region(const 16004455475339839479_u64, const 0_u32, const 397_u32, const 465_u32) -> bb7; // scope 0 at $DIR/instrument_coverage.rs:9:11: 9:11 ++ _4 = const std::intrinsics::count_code_region(const 16004455475339839479_u64, const 0_u32, const 425_u32, const 493_u32) -> bb7; // scope 0 at $DIR/instrument_coverage.rs:9:11: 9:11 + // ty::Const + // + ty: unsafe extern "rust-intrinsic" fn(u64, u32, u32, u32) {std::intrinsics::count_code_region} + // + val: Value(Scalar(<ZST>)) @@ -32,16 +32,16 @@ + // + literal: Const { ty: u32, val: Value(Scalar(0x00000000)) } + // ty::Const + // + ty: u32 -+ // + val: Value(Scalar(0x0000018d)) ++ // + val: Value(Scalar(0x000001a9)) + // mir::Constant + // + span: $DIR/instrument_coverage.rs:9:11: 9:11 -+ // + literal: Const { ty: u32, val: Value(Scalar(0x0000018d)) } ++ // + literal: Const { ty: u32, val: Value(Scalar(0x000001a9)) } + // ty::Const + // + ty: u32 -+ // + val: Value(Scalar(0x000001d1)) ++ // + val: Value(Scalar(0x000001ed)) + // mir::Constant + // + span: $DIR/instrument_coverage.rs:9:11: 9:11 -+ // + literal: Const { ty: u32, val: Value(Scalar(0x000001d1)) } ++ // + literal: Const { ty: u32, val: Value(Scalar(0x000001ed)) } } bb1: { diff --git a/src/test/mir-opt/instrument_coverage.rs b/src/test/mir-opt/instrument_coverage.rs index 3fe010ef68f..4770ec9b66e 100644 --- a/src/test/mir-opt/instrument_coverage.rs +++ b/src/test/mir-opt/instrument_coverage.rs @@ -4,8 +4,8 @@ // needs-profiler-support // compile-flags: -Zinstrument-coverage -// EMIT_MIR rustc.main.InstrumentCoverage.diff -// EMIT_MIR rustc.bar.InstrumentCoverage.diff +// EMIT_MIR instrument_coverage.main.InstrumentCoverage.diff +// EMIT_MIR instrument_coverage.bar.InstrumentCoverage.diff fn main() { loop { if bar() { diff --git a/src/test/mir-opt/issue-38669.rs b/src/test/mir-opt/issue-38669.rs index f6883ac8086..db3f89472c9 100644 --- a/src/test/mir-opt/issue-38669.rs +++ b/src/test/mir-opt/issue-38669.rs @@ -1,6 +1,6 @@ // check that we don't StorageDead booleans before they are used -// EMIT_MIR rustc.main.SimplifyCfg-initial.after.mir +// EMIT_MIR issue_38669.main.SimplifyCfg-initial.after.mir fn main() { let mut should_break = false; loop { diff --git a/src/test/mir-opt/issue-41110.rs b/src/test/mir-opt/issue-41110.rs index cc35b8785a7..638dc601ec8 100644 --- a/src/test/mir-opt/issue-41110.rs +++ b/src/test/mir-opt/issue-41110.rs @@ -3,14 +3,14 @@ // check that we don't emit multiple drop flags when they are not needed. -// EMIT_MIR rustc.main.ElaborateDrops.after.mir +// EMIT_MIR issue_41110.main.ElaborateDrops.after.mir fn main() { let x = S.other(S.id()); } // no_mangle to make sure this gets instantiated even in an executable. #[no_mangle] -// EMIT_MIR rustc.test.ElaborateDrops.after.mir +// EMIT_MIR issue_41110.test.ElaborateDrops.after.mir pub fn test() { let u = S; let mut v = S; diff --git a/src/test/mir-opt/issue-41697.rs b/src/test/mir-opt/issue-41697.rs index 07b9d175677..c90cfc792a9 100644 --- a/src/test/mir-opt/issue-41697.rs +++ b/src/test/mir-opt/issue-41697.rs @@ -14,7 +14,7 @@ trait Foo { } // EMIT_MIR_FOR_EACH_BIT_WIDTH -// EMIT_MIR rustc.{{impl}}-{{constant}}.SimplifyCfg-qualify-consts.after.mir +// EMIT_MIR issue_41697.{{impl}}-{{constant}}.SimplifyCfg-qualify-consts.after.mir impl Foo for [u8; 1+1] { fn get(&self) -> [u8; 2] { *self diff --git a/src/test/mir-opt/issue-41888.rs b/src/test/mir-opt/issue-41888.rs index 6caaa59d0af..c1046c14dbf 100644 --- a/src/test/mir-opt/issue-41888.rs +++ b/src/test/mir-opt/issue-41888.rs @@ -2,7 +2,7 @@ // check that we clear the "ADT master drop flag" even when there are // no fields to be dropped. -// EMIT_MIR rustc.main.ElaborateDrops.after.mir +// EMIT_MIR issue_41888.main.ElaborateDrops.after.mir fn main() { let e; if cond() { diff --git a/src/test/mir-opt/issue-49232.rs b/src/test/mir-opt/issue-49232.rs index 7d308980b90..86494c76aec 100644 --- a/src/test/mir-opt/issue-49232.rs +++ b/src/test/mir-opt/issue-49232.rs @@ -1,7 +1,7 @@ // We must mark a variable whose initialization fails due to an // abort statement as StorageDead. -// EMIT_MIR rustc.main.mir_map.0.mir +// EMIT_MIR issue_49232.main.mir_map.0.mir fn main() { loop { let beacon = { diff --git a/src/test/mir-opt/issue-62289.rs b/src/test/mir-opt/issue-62289.rs index f0d57c572b3..37e3390d5fc 100644 --- a/src/test/mir-opt/issue-62289.rs +++ b/src/test/mir-opt/issue-62289.rs @@ -4,7 +4,7 @@ #![feature(box_syntax)] -// EMIT_MIR rustc.test.ElaborateDrops.before.mir +// EMIT_MIR issue_62289.test.ElaborateDrops.before.mir fn test() -> Option<Box<u32>> { Some(box (None?)) } diff --git a/src/test/mir-opt/issue-72181-1.rs b/src/test/mir-opt/issue-72181-1.rs index 6d65f847a2c..91e98adbe80 100644 --- a/src/test/mir-opt/issue-72181-1.rs +++ b/src/test/mir-opt/issue-72181-1.rs @@ -6,12 +6,12 @@ enum Void {} -// EMIT_MIR rustc.f.mir_map.0.mir +// EMIT_MIR issue_72181_1.f.mir_map.0.mir fn f(v: Void) -> ! { match v {} } -// EMIT_MIR rustc.main.mir_map.0.mir +// EMIT_MIR issue_72181_1.main.mir_map.0.mir fn main() { let v: Void = unsafe { std::mem::transmute::<(), Void>(()) diff --git a/src/test/mir-opt/issue-72181.rs b/src/test/mir-opt/issue-72181.rs index 9373ce12032..844d53a4b2b 100644 --- a/src/test/mir-opt/issue-72181.rs +++ b/src/test/mir-opt/issue-72181.rs @@ -12,14 +12,14 @@ union Foo { } // EMIT_MIR_FOR_EACH_BIT_WIDTH -// EMIT_MIR rustc.foo.mir_map.0.mir +// EMIT_MIR issue_72181.foo.mir_map.0.mir fn foo(xs: [(Never, u32); 1]) -> u32 { xs[0].1 } -// EMIT_MIR rustc.bar.mir_map.0.mir +// EMIT_MIR issue_72181.bar.mir_map.0.mir fn bar([(_, x)]: [(Never, u32); 1]) -> u32 { x } // EMIT_MIR_FOR_EACH_BIT_WIDTH -// EMIT_MIR rustc.main.mir_map.0.mir +// EMIT_MIR issue_72181.main.mir_map.0.mir fn main() { let _ = mem::size_of::<Foo>(); diff --git a/src/test/mir-opt/issue-72181/rustc.bar.mir_map.0.mir b/src/test/mir-opt/issue-72181/rustc.bar.mir_map.0.mir deleted file mode 100644 index 3b6dc46d055..00000000000 --- a/src/test/mir-opt/issue-72181/rustc.bar.mir_map.0.mir +++ /dev/null @@ -1,25 +0,0 @@ -// MIR for `bar` 0 mir_map - -fn bar(_1: [(Never, u32); 1]) -> u32 { - let mut _0: u32; // return place in scope 0 at $DIR/issue-72181.rs:18:40: 18:43 - let _2: u32; // in scope 0 at $DIR/issue-72181.rs:18:13: 18:14 - scope 1 { - debug x => _2; // in scope 1 at $DIR/issue-72181.rs:18:13: 18:14 - } - - bb0: { - StorageLive(_2); // scope 0 at $DIR/issue-72181.rs:18:13: 18:14 - _2 = (_1[0 of 1].1: u32); // scope 0 at $DIR/issue-72181.rs:18:13: 18:14 - _0 = _2; // scope 1 at $DIR/issue-72181.rs:18:46: 18:47 - StorageDead(_2); // scope 0 at $DIR/issue-72181.rs:18:48: 18:49 - goto -> bb2; // scope 0 at $DIR/issue-72181.rs:18:49: 18:49 - } - - bb1 (cleanup): { - resume; // scope 0 at $DIR/issue-72181.rs:18:1: 18:49 - } - - bb2: { - return; // scope 0 at $DIR/issue-72181.rs:18:49: 18:49 - } -} diff --git a/src/test/mir-opt/issue-72181/rustc.foo.mir_map.0.mir b/src/test/mir-opt/issue-72181/rustc.foo.mir_map.0.mir deleted file mode 100644 index 2941e282cf4..00000000000 --- a/src/test/mir-opt/issue-72181/rustc.foo.mir_map.0.mir +++ /dev/null @@ -1,37 +0,0 @@ -// MIR for `foo` 0 mir_map - -fn foo(_1: [(Never, u32); 1]) -> u32 { - debug xs => _1; // in scope 0 at $DIR/issue-72181.rs:15:8: 15:10 - let mut _0: u32; // return place in scope 0 at $DIR/issue-72181.rs:15:34: 15:37 - let _2: usize; // in scope 0 at $DIR/issue-72181.rs:15:43: 15:44 - let mut _3: usize; // in scope 0 at $DIR/issue-72181.rs:15:40: 15:45 - let mut _4: bool; // in scope 0 at $DIR/issue-72181.rs:15:40: 15:45 - - bb0: { - StorageLive(_2); // scope 0 at $DIR/issue-72181.rs:15:43: 15:44 - _2 = const 0usize; // scope 0 at $DIR/issue-72181.rs:15:43: 15:44 - // ty::Const - // + ty: usize - // + val: Value(Scalar(0x0000000000000000)) - // mir::Constant - // + span: $DIR/issue-72181.rs:15:43: 15:44 - // + literal: Const { ty: usize, val: Value(Scalar(0x0000000000000000)) } - _3 = Len(_1); // scope 0 at $DIR/issue-72181.rs:15:40: 15:45 - _4 = Lt(_2, _3); // scope 0 at $DIR/issue-72181.rs:15:40: 15:45 - assert(move _4, "index out of bounds: the len is {} but the index is {}", move _3, _2) -> [success: bb2, unwind: bb1]; // scope 0 at $DIR/issue-72181.rs:15:40: 15:45 - } - - bb1 (cleanup): { - resume; // scope 0 at $DIR/issue-72181.rs:15:1: 15:49 - } - - bb2: { - _0 = (_1[_2].1: u32); // scope 0 at $DIR/issue-72181.rs:15:40: 15:47 - StorageDead(_2); // scope 0 at $DIR/issue-72181.rs:15:48: 15:49 - goto -> bb3; // scope 0 at $DIR/issue-72181.rs:15:49: 15:49 - } - - bb3: { - return; // scope 0 at $DIR/issue-72181.rs:15:49: 15:49 - } -} diff --git a/src/test/mir-opt/issue-72181/rustc.main.mir_map.0.mir b/src/test/mir-opt/issue-72181/rustc.main.mir_map.0.mir deleted file mode 100644 index 65f4de0e235..00000000000 --- a/src/test/mir-opt/issue-72181/rustc.main.mir_map.0.mir +++ /dev/null @@ -1,93 +0,0 @@ -// MIR for `main` 0 mir_map - -fn main() -> () { - let mut _0: (); // return place in scope 0 at $DIR/issue-72181.rs:21:11: 21:11 - let mut _1: usize; // in scope 0 at $DIR/issue-72181.rs:22:13: 22:34 - let mut _3: Foo; // in scope 0 at $DIR/issue-72181.rs:24:14: 24:27 - let mut _4: Foo; // in scope 0 at $DIR/issue-72181.rs:24:29: 24:42 - let mut _5: u64; // in scope 0 at $DIR/issue-72181.rs:25:13: 25:30 - let _6: usize; // in scope 0 at $DIR/issue-72181.rs:25:24: 25:25 - let mut _7: usize; // in scope 0 at $DIR/issue-72181.rs:25:22: 25:26 - let mut _8: bool; // in scope 0 at $DIR/issue-72181.rs:25:22: 25:26 - scope 1 { - let _2: [Foo; 2]; // in scope 1 at $DIR/issue-72181.rs:24:9: 24:10 - scope 2 { - debug f => _2; // in scope 2 at $DIR/issue-72181.rs:24:9: 24:10 - scope 3 { - } - scope 4 { - } - } - } - - bb0: { - StorageLive(_1); // scope 0 at $DIR/issue-72181.rs:22:13: 22:34 - _1 = const std::mem::size_of::<Foo>() -> [return: bb2, unwind: bb1]; // scope 0 at $DIR/issue-72181.rs:22:13: 22:34 - // ty::Const - // + ty: fn() -> usize {std::mem::size_of::<Foo>} - // + val: Value(Scalar(<ZST>)) - // mir::Constant - // + span: $DIR/issue-72181.rs:22:13: 22:32 - // + literal: Const { ty: fn() -> usize {std::mem::size_of::<Foo>}, val: Value(Scalar(<ZST>)) } - } - - bb1 (cleanup): { - resume; // scope 0 at $DIR/issue-72181.rs:21:1: 26:2 - } - - bb2: { - StorageDead(_1); // scope 0 at $DIR/issue-72181.rs:22:34: 22:35 - StorageLive(_2); // scope 1 at $DIR/issue-72181.rs:24:9: 24:10 - StorageLive(_3); // scope 1 at $DIR/issue-72181.rs:24:14: 24:27 - _3 = Foo { a: const 42u64 }; // scope 1 at $DIR/issue-72181.rs:24:14: 24:27 - // ty::Const - // + ty: u64 - // + val: Value(Scalar(0x000000000000002a)) - // mir::Constant - // + span: $DIR/issue-72181.rs:24:23: 24:25 - // + literal: Const { ty: u64, val: Value(Scalar(0x000000000000002a)) } - StorageLive(_4); // scope 1 at $DIR/issue-72181.rs:24:29: 24:42 - _4 = Foo { a: const 10u64 }; // scope 1 at $DIR/issue-72181.rs:24:29: 24:42 - // ty::Const - // + ty: u64 - // + val: Value(Scalar(0x000000000000000a)) - // mir::Constant - // + span: $DIR/issue-72181.rs:24:38: 24:40 - // + literal: Const { ty: u64, val: Value(Scalar(0x000000000000000a)) } - _2 = [move _3, move _4]; // scope 1 at $DIR/issue-72181.rs:24:13: 24:43 - StorageDead(_4); // scope 1 at $DIR/issue-72181.rs:24:42: 24:43 - StorageDead(_3); // scope 1 at $DIR/issue-72181.rs:24:42: 24:43 - FakeRead(ForLet, _2); // scope 1 at $DIR/issue-72181.rs:24:9: 24:10 - StorageLive(_5); // scope 2 at $DIR/issue-72181.rs:25:13: 25:30 - StorageLive(_6); // scope 4 at $DIR/issue-72181.rs:25:24: 25:25 - _6 = const 0usize; // scope 4 at $DIR/issue-72181.rs:25:24: 25:25 - // ty::Const - // + ty: usize - // + val: Value(Scalar(0x0000000000000000)) - // mir::Constant - // + span: $DIR/issue-72181.rs:25:24: 25:25 - // + literal: Const { ty: usize, val: Value(Scalar(0x0000000000000000)) } - _7 = Len(_2); // scope 4 at $DIR/issue-72181.rs:25:22: 25:26 - _8 = Lt(_6, _7); // scope 4 at $DIR/issue-72181.rs:25:22: 25:26 - assert(move _8, "index out of bounds: the len is {} but the index is {}", move _7, _6) -> [success: bb3, unwind: bb1]; // scope 4 at $DIR/issue-72181.rs:25:22: 25:26 - } - - bb3: { - _5 = (_2[_6].0: u64); // scope 4 at $DIR/issue-72181.rs:25:22: 25:28 - StorageDead(_6); // scope 2 at $DIR/issue-72181.rs:25:30: 25:31 - StorageDead(_5); // scope 2 at $DIR/issue-72181.rs:25:30: 25:31 - _0 = const (); // scope 0 at $DIR/issue-72181.rs:21:11: 26:2 - // ty::Const - // + ty: () - // + val: Value(Scalar(<ZST>)) - // mir::Constant - // + span: $DIR/issue-72181.rs:21:11: 26:2 - // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } - StorageDead(_2); // scope 1 at $DIR/issue-72181.rs:26:1: 26:2 - goto -> bb4; // scope 0 at $DIR/issue-72181.rs:26:2: 26:2 - } - - bb4: { - return; // scope 0 at $DIR/issue-72181.rs:26:2: 26:2 - } -} diff --git a/src/test/mir-opt/issue-73223.rs b/src/test/mir-opt/issue-73223.rs index d93805e6cd1..703b8761231 100644 --- a/src/test/mir-opt/issue-73223.rs +++ b/src/test/mir-opt/issue-73223.rs @@ -9,5 +9,5 @@ fn main() { } // EMIT_MIR_FOR_EACH_BIT_WIDTH -// EMIT_MIR rustc.main.SimplifyArmIdentity.diff -// EMIT_MIR rustc.main.PreCodegen.diff +// EMIT_MIR issue_73223.main.SimplifyArmIdentity.diff +// EMIT_MIR issue_73223.main.PreCodegen.diff diff --git a/src/test/mir-opt/issue-38669/rustc.main.SimplifyCfg-initial.after.mir b/src/test/mir-opt/issue_38669.main.SimplifyCfg-initial.after.mir index 7b58dc1f624..7b58dc1f624 100644 --- a/src/test/mir-opt/issue-38669/rustc.main.SimplifyCfg-initial.after.mir +++ b/src/test/mir-opt/issue_38669.main.SimplifyCfg-initial.after.mir diff --git a/src/test/mir-opt/issue-41110/rustc.main.ElaborateDrops.after.mir b/src/test/mir-opt/issue_41110.main.ElaborateDrops.after.mir index 77763f2d3a0..77763f2d3a0 100644 --- a/src/test/mir-opt/issue-41110/rustc.main.ElaborateDrops.after.mir +++ b/src/test/mir-opt/issue_41110.main.ElaborateDrops.after.mir diff --git a/src/test/mir-opt/issue-41110/rustc.test.ElaborateDrops.after.mir b/src/test/mir-opt/issue_41110.test.ElaborateDrops.after.mir index a99846bd15d..a99846bd15d 100644 --- a/src/test/mir-opt/issue-41110/rustc.test.ElaborateDrops.after.mir +++ b/src/test/mir-opt/issue_41110.test.ElaborateDrops.after.mir diff --git a/src/test/mir-opt/issue-41697/32bit/rustc.{{impl}}-{{constant}}.SimplifyCfg-qualify-consts.after.mir b/src/test/mir-opt/issue_41697.{{impl}}-{{constant}}.SimplifyCfg-qualify-consts.after.mir.32bit index 403555964ca..403555964ca 100644 --- a/src/test/mir-opt/issue-41697/32bit/rustc.{{impl}}-{{constant}}.SimplifyCfg-qualify-consts.after.mir +++ b/src/test/mir-opt/issue_41697.{{impl}}-{{constant}}.SimplifyCfg-qualify-consts.after.mir.32bit diff --git a/src/test/mir-opt/issue-41697/64bit/rustc.{{impl}}-{{constant}}.SimplifyCfg-qualify-consts.after.mir b/src/test/mir-opt/issue_41697.{{impl}}-{{constant}}.SimplifyCfg-qualify-consts.after.mir.64bit index df933d3ac25..df933d3ac25 100644 --- a/src/test/mir-opt/issue-41697/64bit/rustc.{{impl}}-{{constant}}.SimplifyCfg-qualify-consts.after.mir +++ b/src/test/mir-opt/issue_41697.{{impl}}-{{constant}}.SimplifyCfg-qualify-consts.after.mir.64bit diff --git a/src/test/mir-opt/issue-41888/rustc.main.ElaborateDrops.after.mir b/src/test/mir-opt/issue_41888.main.ElaborateDrops.after.mir index 76ad865bcc8..76ad865bcc8 100644 --- a/src/test/mir-opt/issue-41888/rustc.main.ElaborateDrops.after.mir +++ b/src/test/mir-opt/issue_41888.main.ElaborateDrops.after.mir diff --git a/src/test/mir-opt/issue-49232/rustc.main.mir_map.0.mir b/src/test/mir-opt/issue_49232.main.mir_map.0.mir index 918dc5ec387..918dc5ec387 100644 --- a/src/test/mir-opt/issue-49232/rustc.main.mir_map.0.mir +++ b/src/test/mir-opt/issue_49232.main.mir_map.0.mir diff --git a/src/test/mir-opt/issue-62289/rustc.test.ElaborateDrops.before.mir b/src/test/mir-opt/issue_62289.test.ElaborateDrops.before.mir index 56916d676ed..56916d676ed 100644 --- a/src/test/mir-opt/issue-62289/rustc.test.ElaborateDrops.before.mir +++ b/src/test/mir-opt/issue_62289.test.ElaborateDrops.before.mir diff --git a/src/test/mir-opt/issue-72181/32bit/rustc.bar.mir_map.0.mir b/src/test/mir-opt/issue_72181.bar.mir_map.0.mir.32bit index 29654c2b1f8..29654c2b1f8 100644 --- a/src/test/mir-opt/issue-72181/32bit/rustc.bar.mir_map.0.mir +++ b/src/test/mir-opt/issue_72181.bar.mir_map.0.mir.32bit diff --git a/src/test/mir-opt/issue-72181/64bit/rustc.bar.mir_map.0.mir b/src/test/mir-opt/issue_72181.bar.mir_map.0.mir.64bit index 29654c2b1f8..29654c2b1f8 100644 --- a/src/test/mir-opt/issue-72181/64bit/rustc.bar.mir_map.0.mir +++ b/src/test/mir-opt/issue_72181.bar.mir_map.0.mir.64bit diff --git a/src/test/mir-opt/issue-72181/32bit/rustc.foo.mir_map.0.mir b/src/test/mir-opt/issue_72181.foo.mir_map.0.mir.32bit index 9f8810e752c..9f8810e752c 100644 --- a/src/test/mir-opt/issue-72181/32bit/rustc.foo.mir_map.0.mir +++ b/src/test/mir-opt/issue_72181.foo.mir_map.0.mir.32bit diff --git a/src/test/mir-opt/issue-72181/64bit/rustc.foo.mir_map.0.mir b/src/test/mir-opt/issue_72181.foo.mir_map.0.mir.64bit index aab8efb415c..aab8efb415c 100644 --- a/src/test/mir-opt/issue-72181/64bit/rustc.foo.mir_map.0.mir +++ b/src/test/mir-opt/issue_72181.foo.mir_map.0.mir.64bit diff --git a/src/test/mir-opt/issue-72181/32bit/rustc.main.mir_map.0.mir b/src/test/mir-opt/issue_72181.main.mir_map.0.mir.32bit index e3fb5eb193a..e3fb5eb193a 100644 --- a/src/test/mir-opt/issue-72181/32bit/rustc.main.mir_map.0.mir +++ b/src/test/mir-opt/issue_72181.main.mir_map.0.mir.32bit diff --git a/src/test/mir-opt/issue-72181/64bit/rustc.main.mir_map.0.mir b/src/test/mir-opt/issue_72181.main.mir_map.0.mir.64bit index d9e791b86bc..d9e791b86bc 100644 --- a/src/test/mir-opt/issue-72181/64bit/rustc.main.mir_map.0.mir +++ b/src/test/mir-opt/issue_72181.main.mir_map.0.mir.64bit diff --git a/src/test/mir-opt/issue-72181-1/rustc.f.mir_map.0.mir b/src/test/mir-opt/issue_72181_1.f.mir_map.0.mir index 1821365898e..1821365898e 100644 --- a/src/test/mir-opt/issue-72181-1/rustc.f.mir_map.0.mir +++ b/src/test/mir-opt/issue_72181_1.f.mir_map.0.mir diff --git a/src/test/mir-opt/issue-72181-1/rustc.main.mir_map.0.mir b/src/test/mir-opt/issue_72181_1.main.mir_map.0.mir index b87d0294fb8..b87d0294fb8 100644 --- a/src/test/mir-opt/issue-72181-1/rustc.main.mir_map.0.mir +++ b/src/test/mir-opt/issue_72181_1.main.mir_map.0.mir diff --git a/src/test/mir-opt/issue-73223/32bit/rustc.main.PreCodegen.diff b/src/test/mir-opt/issue_73223.main.PreCodegen.diff.32bit index 4c9da471f0b..4c9da471f0b 100644 --- a/src/test/mir-opt/issue-73223/32bit/rustc.main.PreCodegen.diff +++ b/src/test/mir-opt/issue_73223.main.PreCodegen.diff.32bit diff --git a/src/test/mir-opt/issue-73223/64bit/rustc.main.PreCodegen.diff b/src/test/mir-opt/issue_73223.main.PreCodegen.diff.64bit index 4c9da471f0b..4c9da471f0b 100644 --- a/src/test/mir-opt/issue-73223/64bit/rustc.main.PreCodegen.diff +++ b/src/test/mir-opt/issue_73223.main.PreCodegen.diff.64bit diff --git a/src/test/mir-opt/issue-73223/32bit/rustc.main.SimplifyArmIdentity.diff b/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.diff.32bit index dd0e8f4b2ad..dd0e8f4b2ad 100644 --- a/src/test/mir-opt/issue-73223/32bit/rustc.main.SimplifyArmIdentity.diff +++ b/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.diff.32bit diff --git a/src/test/mir-opt/issue-73223/64bit/rustc.main.SimplifyArmIdentity.diff b/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.diff.64bit index d465f60f34d..d465f60f34d 100644 --- a/src/test/mir-opt/issue-73223/64bit/rustc.main.SimplifyArmIdentity.diff +++ b/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.diff.64bit diff --git a/src/test/mir-opt/loop_test/rustc.main.SimplifyCfg-qualify-consts.after.mir b/src/test/mir-opt/loop_test.main.SimplifyCfg-qualify-consts.after.mir index e699abf421d..e699abf421d 100644 --- a/src/test/mir-opt/loop_test/rustc.main.SimplifyCfg-qualify-consts.after.mir +++ b/src/test/mir-opt/loop_test.main.SimplifyCfg-qualify-consts.after.mir diff --git a/src/test/mir-opt/loop_test.rs b/src/test/mir-opt/loop_test.rs index cb23a4c671b..5d0c30d4410 100644 --- a/src/test/mir-opt/loop_test.rs +++ b/src/test/mir-opt/loop_test.rs @@ -2,7 +2,7 @@ // Tests to make sure we correctly generate falseUnwind edges in loops -// EMIT_MIR rustc.main.SimplifyCfg-qualify-consts.after.mir +// EMIT_MIR loop_test.main.SimplifyCfg-qualify-consts.after.mir fn main() { // Exit early at runtime. Since only care about the generated MIR // and not the runtime behavior (which is exercised by other tests) diff --git a/src/test/mir-opt/match-arm-scopes.rs b/src/test/mir-opt/match-arm-scopes.rs index 2c5816c51e3..7b7de7788c2 100644 --- a/src/test/mir-opt/match-arm-scopes.rs +++ b/src/test/mir-opt/match-arm-scopes.rs @@ -9,7 +9,7 @@ // all of the bindings for that scope. // * No drop flags are used. -// EMIT_MIR rustc.complicated_match SimplifyCfg-initial.after ElaborateDrops.after +// EMIT_MIR match_arm_scopes.complicated_match SimplifyCfg-initial.after ElaborateDrops.after fn complicated_match(cond: bool, items: (bool, bool, String)) -> i32 { match items { (false, a, s) | (a, false, s) if if cond { return 3 } else { a } => 1, diff --git a/src/test/mir-opt/match-arm-scopes/rustc.complicated_match.SimplifyCfg-initial.after-ElaborateDrops.after.diff b/src/test/mir-opt/match_arm_scopes.complicated_match.SimplifyCfg-initial.after-ElaborateDrops.after.diff index 58847e1bcee..58847e1bcee 100644 --- a/src/test/mir-opt/match-arm-scopes/rustc.complicated_match.SimplifyCfg-initial.after-ElaborateDrops.after.diff +++ b/src/test/mir-opt/match_arm_scopes.complicated_match.SimplifyCfg-initial.after-ElaborateDrops.after.diff diff --git a/src/test/mir-opt/match_false_edges/rustc.full_tested_match.PromoteTemps.after.mir b/src/test/mir-opt/match_false_edges.full_tested_match.PromoteTemps.after.mir index c53c9cf1db7..c53c9cf1db7 100644 --- a/src/test/mir-opt/match_false_edges/rustc.full_tested_match.PromoteTemps.after.mir +++ b/src/test/mir-opt/match_false_edges.full_tested_match.PromoteTemps.after.mir diff --git a/src/test/mir-opt/match_false_edges/rustc.full_tested_match2.PromoteTemps.before.mir b/src/test/mir-opt/match_false_edges.full_tested_match2.PromoteTemps.before.mir index b79416fe31a..b79416fe31a 100644 --- a/src/test/mir-opt/match_false_edges/rustc.full_tested_match2.PromoteTemps.before.mir +++ b/src/test/mir-opt/match_false_edges.full_tested_match2.PromoteTemps.before.mir diff --git a/src/test/mir-opt/match_false_edges/rustc.main.PromoteTemps.before.mir b/src/test/mir-opt/match_false_edges.main.PromoteTemps.before.mir index 5b449da93d4..5b449da93d4 100644 --- a/src/test/mir-opt/match_false_edges/rustc.main.PromoteTemps.before.mir +++ b/src/test/mir-opt/match_false_edges.main.PromoteTemps.before.mir diff --git a/src/test/mir-opt/match_false_edges.rs b/src/test/mir-opt/match_false_edges.rs index 91f4aad165e..42dea9c7082 100644 --- a/src/test/mir-opt/match_false_edges.rs +++ b/src/test/mir-opt/match_false_edges.rs @@ -10,7 +10,7 @@ fn guard2(_: i32) -> bool { // no_mangle to make sure this gets instantiated even in an executable. #[no_mangle] -// EMIT_MIR rustc.full_tested_match.PromoteTemps.after.mir +// EMIT_MIR match_false_edges.full_tested_match.PromoteTemps.after.mir pub fn full_tested_match() { let _ = match Some(42) { Some(x) if guard() => (1, x), @@ -21,7 +21,7 @@ pub fn full_tested_match() { // no_mangle to make sure this gets instantiated even in an executable. #[no_mangle] -// EMIT_MIR rustc.full_tested_match2.PromoteTemps.before.mir +// EMIT_MIR match_false_edges.full_tested_match2.PromoteTemps.before.mir pub fn full_tested_match2() { let _ = match Some(42) { Some(x) if guard() => (1, x), @@ -30,7 +30,7 @@ pub fn full_tested_match2() { }; } -// EMIT_MIR rustc.main.PromoteTemps.before.mir +// EMIT_MIR match_false_edges.main.PromoteTemps.before.mir fn main() { let _ = match Some(1) { Some(_w) if guard() => 1, diff --git a/src/test/mir-opt/match_test/rustc.main.SimplifyCfg-initial.after.mir b/src/test/mir-opt/match_test.main.SimplifyCfg-initial.after.mir index 16895942cb8..16895942cb8 100644 --- a/src/test/mir-opt/match_test/rustc.main.SimplifyCfg-initial.after.mir +++ b/src/test/mir-opt/match_test.main.SimplifyCfg-initial.after.mir diff --git a/src/test/mir-opt/match_test.rs b/src/test/mir-opt/match_test.rs index c3b07d42f5e..3a21077905b 100644 --- a/src/test/mir-opt/match_test.rs +++ b/src/test/mir-opt/match_test.rs @@ -2,7 +2,7 @@ #![feature(exclusive_range_pattern)] -// EMIT_MIR rustc.main.SimplifyCfg-initial.after.mir +// EMIT_MIR match_test.main.SimplifyCfg-initial.after.mir fn main() { let x = 3; let b = true; diff --git a/src/test/mir-opt/nll/named-lifetimes-basic.rs b/src/test/mir-opt/nll/named-lifetimes-basic.rs index 073ccf7e6c6..73bd6d64e86 100644 --- a/src/test/mir-opt/nll/named-lifetimes-basic.rs +++ b/src/test/mir-opt/nll/named-lifetimes-basic.rs @@ -8,7 +8,7 @@ #![allow(warnings)] -// EMIT_MIR rustc.use_x.nll.0.mir +// EMIT_MIR named_lifetimes_basic.use_x.nll.0.mir fn use_x<'a, 'b: 'a, 'c>(w: &'a mut i32, x: &'b u32, y: &'a u32, z: &'c u32) -> bool { true } fn main() { diff --git a/src/test/mir-opt/nll/named-lifetimes-basic/rustc.use_x.nll.0.mir b/src/test/mir-opt/nll/named_lifetimes_basic.use_x.nll.0.mir index dcfb069b84a..dcfb069b84a 100644 --- a/src/test/mir-opt/nll/named-lifetimes-basic/rustc.use_x.nll.0.mir +++ b/src/test/mir-opt/nll/named_lifetimes_basic.use_x.nll.0.mir diff --git a/src/test/mir-opt/nll/region-subtyping-basic.rs b/src/test/mir-opt/nll/region-subtyping-basic.rs index 66d7cda2b85..224a495c788 100644 --- a/src/test/mir-opt/nll/region-subtyping-basic.rs +++ b/src/test/mir-opt/nll/region-subtyping-basic.rs @@ -12,7 +12,7 @@ fn use_x(_: usize) -> bool { } // EMIT_MIR_FOR_EACH_BIT_WIDTH -// EMIT_MIR rustc.main.nll.0.mir +// EMIT_MIR region_subtyping_basic.main.nll.0.mir fn main() { let mut v = [1, 2, 3]; let p = &v[0]; diff --git a/src/test/mir-opt/nll/region-subtyping-basic/32bit/rustc.main.nll.0.mir b/src/test/mir-opt/nll/region_subtyping_basic.main.nll.0.mir.32bit index e3f113fea28..e3f113fea28 100644 --- a/src/test/mir-opt/nll/region-subtyping-basic/32bit/rustc.main.nll.0.mir +++ b/src/test/mir-opt/nll/region_subtyping_basic.main.nll.0.mir.32bit diff --git a/src/test/mir-opt/nll/region-subtyping-basic/64bit/rustc.main.nll.0.mir b/src/test/mir-opt/nll/region_subtyping_basic.main.nll.0.mir.64bit index a69952ff07f..a69952ff07f 100644 --- a/src/test/mir-opt/nll/region-subtyping-basic/64bit/rustc.main.nll.0.mir +++ b/src/test/mir-opt/nll/region_subtyping_basic.main.nll.0.mir.64bit diff --git a/src/test/mir-opt/no-drop-for-inactive-variant.rs b/src/test/mir-opt/no-drop-for-inactive-variant.rs index cf6426b878a..34e2b1a134f 100644 --- a/src/test/mir-opt/no-drop-for-inactive-variant.rs +++ b/src/test/mir-opt/no-drop-for-inactive-variant.rs @@ -3,7 +3,7 @@ // Ensure that there are no drop terminators in `unwrap<T>` (except the one along the cleanup // path). -// EMIT_MIR rustc.unwrap.SimplifyCfg-elaborate-drops.after.mir +// EMIT_MIR no_drop_for_inactive_variant.unwrap.SimplifyCfg-elaborate-drops.after.mir fn unwrap<T>(opt: Option<T>) -> T { match opt { Some(x) => x, diff --git a/src/test/mir-opt/no-spurious-drop-after-call.rs b/src/test/mir-opt/no-spurious-drop-after-call.rs index ab58654e07c..bb5bb9aa4e5 100644 --- a/src/test/mir-opt/no-spurious-drop-after-call.rs +++ b/src/test/mir-opt/no-spurious-drop-after-call.rs @@ -4,7 +4,7 @@ // MIR drop of the argument. (We used to have a `DROP(_2)` in the code // below, as part of bb3.) -// EMIT_MIR rustc.main.ElaborateDrops.before.mir +// EMIT_MIR no_spurious_drop_after_call.main.ElaborateDrops.before.mir fn main() { std::mem::drop("".to_string()); } diff --git a/src/test/mir-opt/no-drop-for-inactive-variant/rustc.unwrap.SimplifyCfg-elaborate-drops.after.mir b/src/test/mir-opt/no_drop_for_inactive_variant.unwrap.SimplifyCfg-elaborate-drops.after.mir index f59390ba84e..f59390ba84e 100644 --- a/src/test/mir-opt/no-drop-for-inactive-variant/rustc.unwrap.SimplifyCfg-elaborate-drops.after.mir +++ b/src/test/mir-opt/no_drop_for_inactive_variant.unwrap.SimplifyCfg-elaborate-drops.after.mir diff --git a/src/test/mir-opt/no-spurious-drop-after-call/rustc.main.ElaborateDrops.before.mir b/src/test/mir-opt/no_spurious_drop_after_call.main.ElaborateDrops.before.mir index 0af213e425f..0af213e425f 100644 --- a/src/test/mir-opt/no-spurious-drop-after-call/rustc.main.ElaborateDrops.before.mir +++ b/src/test/mir-opt/no_spurious_drop_after_call.main.ElaborateDrops.before.mir diff --git a/src/test/mir-opt/nrvo-simple.rs b/src/test/mir-opt/nrvo-simple.rs index bf3a0efeada..f0eb711b3f0 100644 --- a/src/test/mir-opt/nrvo-simple.rs +++ b/src/test/mir-opt/nrvo-simple.rs @@ -1,4 +1,4 @@ -// EMIT_MIR rustc.nrvo.RenameReturnPlace.diff +// EMIT_MIR nrvo_simple.nrvo.RenameReturnPlace.diff fn nrvo(init: fn(&mut [u8; 1024])) -> [u8; 1024] { let mut buf = [0; 1024]; init(&mut buf); diff --git a/src/test/mir-opt/nrvo-simple/rustc.nrvo.RenameReturnPlace.diff b/src/test/mir-opt/nrvo_simple.nrvo.RenameReturnPlace.diff index 18fbffb4630..18fbffb4630 100644 --- a/src/test/mir-opt/nrvo-simple/rustc.nrvo.RenameReturnPlace.diff +++ b/src/test/mir-opt/nrvo_simple.nrvo.RenameReturnPlace.diff diff --git a/src/test/mir-opt/packed-struct-drop-aligned.rs b/src/test/mir-opt/packed-struct-drop-aligned.rs index daf397c3d9c..6c2e265d514 100644 --- a/src/test/mir-opt/packed-struct-drop-aligned.rs +++ b/src/test/mir-opt/packed-struct-drop-aligned.rs @@ -1,7 +1,7 @@ // ignore-wasm32-bare compiled with panic=abort by default // EMIT_MIR_FOR_EACH_BIT_WIDTH -// EMIT_MIR rustc.main.SimplifyCfg-elaborate-drops.after.mir +// EMIT_MIR packed_struct_drop_aligned.main.SimplifyCfg-elaborate-drops.after.mir fn main() { let mut x = Packed(Aligned(Droppy(0))); x.0 = Aligned(Droppy(0)); diff --git a/src/test/mir-opt/packed-struct-drop-aligned/32bit/rustc.main.SimplifyCfg-elaborate-drops.after.mir b/src/test/mir-opt/packed_struct_drop_aligned.main.SimplifyCfg-elaborate-drops.after.mir.32bit index 075c7647c67..075c7647c67 100644 --- a/src/test/mir-opt/packed-struct-drop-aligned/32bit/rustc.main.SimplifyCfg-elaborate-drops.after.mir +++ b/src/test/mir-opt/packed_struct_drop_aligned.main.SimplifyCfg-elaborate-drops.after.mir.32bit diff --git a/src/test/mir-opt/packed-struct-drop-aligned/64bit/rustc.main.SimplifyCfg-elaborate-drops.after.mir b/src/test/mir-opt/packed_struct_drop_aligned.main.SimplifyCfg-elaborate-drops.after.mir.64bit index 99a74b6b24f..99a74b6b24f 100644 --- a/src/test/mir-opt/packed-struct-drop-aligned/64bit/rustc.main.SimplifyCfg-elaborate-drops.after.mir +++ b/src/test/mir-opt/packed_struct_drop_aligned.main.SimplifyCfg-elaborate-drops.after.mir.64bit diff --git a/src/test/mir-opt/remove-never-const.rs b/src/test/mir-opt/remove-never-const.rs index b2d4f14aa4c..1673f14b45c 100644 --- a/src/test/mir-opt/remove-never-const.rs +++ b/src/test/mir-opt/remove-never-const.rs @@ -15,7 +15,7 @@ impl<T> PrintName<T> { const VOID: ! = panic!(); } -// EMIT_MIR rustc.no_codegen.PreCodegen.after.mir +// EMIT_MIR remove_never_const.no_codegen.PreCodegen.after.mir fn no_codegen<T>() { let _ = PrintName::<T>::VOID; } diff --git a/src/test/mir-opt/remove_fake_borrows/rustc.match_guard.CleanupNonCodegenStatements.diff b/src/test/mir-opt/remove_fake_borrows.match_guard.CleanupNonCodegenStatements.diff index 0822d8cc03c..0822d8cc03c 100644 --- a/src/test/mir-opt/remove_fake_borrows/rustc.match_guard.CleanupNonCodegenStatements.diff +++ b/src/test/mir-opt/remove_fake_borrows.match_guard.CleanupNonCodegenStatements.diff diff --git a/src/test/mir-opt/remove_fake_borrows.rs b/src/test/mir-opt/remove_fake_borrows.rs index fd2f1d0dbff..a980f386b69 100644 --- a/src/test/mir-opt/remove_fake_borrows.rs +++ b/src/test/mir-opt/remove_fake_borrows.rs @@ -2,7 +2,7 @@ // ignore-wasm32-bare compiled with panic=abort by default -// EMIT_MIR rustc.match_guard.CleanupNonCodegenStatements.diff +// EMIT_MIR remove_fake_borrows.match_guard.CleanupNonCodegenStatements.diff fn match_guard(x: Option<&&i32>, c: bool) -> i32 { match x { Some(0) if c => 0, diff --git a/src/test/mir-opt/remove-never-const/rustc.no_codegen.PreCodegen.after.mir b/src/test/mir-opt/remove_never_const.no_codegen.PreCodegen.after.mir index 6f4a024d20f..6f4a024d20f 100644 --- a/src/test/mir-opt/remove-never-const/rustc.no_codegen.PreCodegen.after.mir +++ b/src/test/mir-opt/remove_never_const.no_codegen.PreCodegen.after.mir diff --git a/src/test/mir-opt/retag/rustc.ptr-drop_in_place.Test.SimplifyCfg-make_shim.after.mir b/src/test/mir-opt/retag.core.ptr-drop_in_place.Test.SimplifyCfg-make_shim.after.mir index 694c387986f..694c387986f 100644 --- a/src/test/mir-opt/retag/rustc.ptr-drop_in_place.Test.SimplifyCfg-make_shim.after.mir +++ b/src/test/mir-opt/retag.core.ptr-drop_in_place.Test.SimplifyCfg-make_shim.after.mir diff --git a/src/test/mir-opt/retag/rustc.main-{{closure}}.SimplifyCfg-elaborate-drops.after.mir b/src/test/mir-opt/retag.main-{{closure}}.SimplifyCfg-elaborate-drops.after.mir index 01f5fbb7d23..01f5fbb7d23 100644 --- a/src/test/mir-opt/retag/rustc.main-{{closure}}.SimplifyCfg-elaborate-drops.after.mir +++ b/src/test/mir-opt/retag.main-{{closure}}.SimplifyCfg-elaborate-drops.after.mir diff --git a/src/test/mir-opt/retag/rustc.main.SimplifyCfg-elaborate-drops.after.mir b/src/test/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.mir index b61d9368375..b61d9368375 100644 --- a/src/test/mir-opt/retag/rustc.main.SimplifyCfg-elaborate-drops.after.mir +++ b/src/test/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.mir diff --git a/src/test/mir-opt/retag.rs b/src/test/mir-opt/retag.rs index eba0f567c4a..12d7cb30d97 100644 --- a/src/test/mir-opt/retag.rs +++ b/src/test/mir-opt/retag.rs @@ -6,8 +6,8 @@ struct Test(i32); -// EMIT_MIR rustc.{{impl}}-foo.SimplifyCfg-elaborate-drops.after.mir -// EMIT_MIR rustc.{{impl}}-foo_shr.SimplifyCfg-elaborate-drops.after.mir +// EMIT_MIR retag.{{impl}}-foo.SimplifyCfg-elaborate-drops.after.mir +// EMIT_MIR retag.{{impl}}-foo_shr.SimplifyCfg-elaborate-drops.after.mir impl Test { // Make sure we run the pass on a method, not just on bare functions. fn foo<'x>(&self, x: &'x mut i32) -> &'x mut i32 { @@ -18,14 +18,14 @@ impl Test { } } -// EMIT_MIR rustc.ptr-drop_in_place.Test.SimplifyCfg-make_shim.after.mir +// EMIT_MIR core.ptr-drop_in_place.Test.SimplifyCfg-make_shim.after.mir impl Drop for Test { fn drop(&mut self) {} } -// EMIT_MIR rustc.main.SimplifyCfg-elaborate-drops.after.mir -// EMIT_MIR rustc.main-{{closure}}.SimplifyCfg-elaborate-drops.after.mir +// EMIT_MIR retag.main.SimplifyCfg-elaborate-drops.after.mir +// EMIT_MIR retag.main-{{closure}}.SimplifyCfg-elaborate-drops.after.mir fn main() { let mut x = 0; { diff --git a/src/test/mir-opt/retag/rustc.{{impl}}-foo.SimplifyCfg-elaborate-drops.after.mir b/src/test/mir-opt/retag.{{impl}}-foo.SimplifyCfg-elaborate-drops.after.mir index f9ed3932d33..f9ed3932d33 100644 --- a/src/test/mir-opt/retag/rustc.{{impl}}-foo.SimplifyCfg-elaborate-drops.after.mir +++ b/src/test/mir-opt/retag.{{impl}}-foo.SimplifyCfg-elaborate-drops.after.mir diff --git a/src/test/mir-opt/retag/rustc.{{impl}}-foo_shr.SimplifyCfg-elaborate-drops.after.mir b/src/test/mir-opt/retag.{{impl}}-foo_shr.SimplifyCfg-elaborate-drops.after.mir index 87a8603a931..87a8603a931 100644 --- a/src/test/mir-opt/retag/rustc.{{impl}}-foo_shr.SimplifyCfg-elaborate-drops.after.mir +++ b/src/test/mir-opt/retag.{{impl}}-foo_shr.SimplifyCfg-elaborate-drops.after.mir diff --git a/src/test/mir-opt/simple-match.rs b/src/test/mir-opt/simple-match.rs index c8c7e9188c2..44adc55b6f7 100644 --- a/src/test/mir-opt/simple-match.rs +++ b/src/test/mir-opt/simple-match.rs @@ -1,7 +1,7 @@ // Test that we don't generate unnecessarily large MIR for very simple matches // EMIT_MIR_FOR_EACH_BIT_WIDTH -// EMIT_MIR rustc.match_bool.mir_map.0.mir +// EMIT_MIR simple_match.match_bool.mir_map.0.mir fn match_bool(x: bool) -> usize { match x { true => 10, diff --git a/src/test/mir-opt/simple-match/32bit/rustc.match_bool.mir_map.0.mir b/src/test/mir-opt/simple_match.match_bool.mir_map.0.mir.32bit index da3191554f0..da3191554f0 100644 --- a/src/test/mir-opt/simple-match/32bit/rustc.match_bool.mir_map.0.mir +++ b/src/test/mir-opt/simple_match.match_bool.mir_map.0.mir.32bit diff --git a/src/test/mir-opt/simple-match/64bit/rustc.match_bool.mir_map.0.mir b/src/test/mir-opt/simple_match.match_bool.mir_map.0.mir.64bit index 55b51a899bc..55b51a899bc 100644 --- a/src/test/mir-opt/simple-match/64bit/rustc.match_bool.mir_map.0.mir +++ b/src/test/mir-opt/simple_match.match_bool.mir_map.0.mir.64bit diff --git a/src/test/mir-opt/simplify-arm-identity.rs b/src/test/mir-opt/simplify-arm-identity.rs index 24e91b3ff61..0a59032e87b 100644 --- a/src/test/mir-opt/simplify-arm-identity.rs +++ b/src/test/mir-opt/simplify-arm-identity.rs @@ -13,7 +13,7 @@ enum Dst { Foo(u8), } -// EMIT_MIR rustc.main.SimplifyArmIdentity.diff +// EMIT_MIR simplify_arm_identity.main.SimplifyArmIdentity.diff fn main() { let e: Src = Src::Foo(0); let _: Dst = match e { diff --git a/src/test/mir-opt/simplify-arm-identity/rustc.main.SimplifyArmIdentity.diff b/src/test/mir-opt/simplify-arm-identity/rustc.main.SimplifyArmIdentity.diff deleted file mode 100644 index e7373391b79..00000000000 --- a/src/test/mir-opt/simplify-arm-identity/rustc.main.SimplifyArmIdentity.diff +++ /dev/null @@ -1,70 +0,0 @@ -- // MIR for `main` before SimplifyArmIdentity -+ // MIR for `main` after SimplifyArmIdentity - - fn main() -> () { - let mut _0: (); // return place in scope 0 at $DIR/simplify-arm-identity.rs:16:11: 16:11 - let _1: Src as UserTypeProjection { base: UserType(0), projs: [] }; // in scope 0 at $DIR/simplify-arm-identity.rs:17:9: 17:10 - let mut _2: Dst; // in scope 0 at $DIR/simplify-arm-identity.rs:18:18: 21:6 - let mut _3: isize; // in scope 0 at $DIR/simplify-arm-identity.rs:19:9: 19:20 - let mut _5: u8; // in scope 0 at $DIR/simplify-arm-identity.rs:19:33: 19:34 - scope 1 { - debug e => _1; // in scope 1 at $DIR/simplify-arm-identity.rs:17:9: 17:10 - let _4: u8; // in scope 1 at $DIR/simplify-arm-identity.rs:19:18: 19:19 - scope 2 { - } - scope 3 { - debug x => _4; // in scope 3 at $DIR/simplify-arm-identity.rs:19:18: 19:19 - } - } - - bb0: { - StorageLive(_1); // scope 0 at $DIR/simplify-arm-identity.rs:17:9: 17:10 - ((_1 as Foo).0: u8) = const 0u8; // scope 0 at $DIR/simplify-arm-identity.rs:17:18: 17:29 - // ty::Const - // + ty: u8 - // + val: Value(Scalar(0x00)) - // mir::Constant - // + span: $DIR/simplify-arm-identity.rs:17:27: 17:28 - // + literal: Const { ty: u8, val: Value(Scalar(0x00)) } - discriminant(_1) = 0; // scope 0 at $DIR/simplify-arm-identity.rs:17:18: 17:29 - StorageLive(_2); // scope 1 at $DIR/simplify-arm-identity.rs:18:18: 21:6 - _3 = discriminant(_1); // scope 1 at $DIR/simplify-arm-identity.rs:19:9: 19:20 - switchInt(move _3) -> [0isize: bb3, 1isize: bb1, otherwise: bb2]; // scope 1 at $DIR/simplify-arm-identity.rs:19:9: 19:20 - } - - bb1: { - _2 = const Dst::Foo(0u8); // bb1[0]: scope 1 at $DIR/simplify-arm-identity.rs:20:21: 20:32 - // ty::Const - // + ty: Dst - // + val: Value(Scalar(0x00)) - // mir::Constant - // + span: $DIR/simplify-arm-identity.rs:20:21: 20:32 - // + literal: Const { ty: Dst, val: Value(Scalar(0x00)) } - goto -> bb4; // bb1[1]: scope 1 at $DIR/simplify-arm-identity.rs:18:18: 21:6 - } - - bb2: { - unreachable; // scope 1 at $DIR/simplify-arm-identity.rs:18:24: 18:25 - } - - bb3: { - _4 = ((_1 as Foo).0: u8); // scope 1 at $DIR/simplify-arm-identity.rs:19:18: 19:19 - ((_2 as Foo).0: u8) = move _4; // scope 3 at $DIR/simplify-arm-identity.rs:19:24: 19:35 - discriminant(_2) = 0; // scope 3 at $DIR/simplify-arm-identity.rs:19:24: 19:35 - goto -> bb4; // scope 1 at $DIR/simplify-arm-identity.rs:18:18: 21:6 - } - - bb4: { - StorageDead(_2); // scope 1 at $DIR/simplify-arm-identity.rs:21:6: 21:7 - _0 = const (); // scope 0 at $DIR/simplify-arm-identity.rs:16:11: 22:2 - // ty::Const - // + ty: () - // + val: Value(Scalar(<ZST>)) - // mir::Constant - // + span: $DIR/simplify-arm-identity.rs:16:11: 22:2 - // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } - StorageDead(_1); // scope 0 at $DIR/simplify-arm-identity.rs:22:1: 22:2 - return; // scope 0 at $DIR/simplify-arm-identity.rs:22:2: 22:2 - } - } - diff --git a/src/test/mir-opt/simplify-arm.rs b/src/test/mir-opt/simplify-arm.rs index 0e3f86501bb..20b4e67f53b 100644 --- a/src/test/mir-opt/simplify-arm.rs +++ b/src/test/mir-opt/simplify-arm.rs @@ -1,10 +1,10 @@ // compile-flags: -Z mir-opt-level=1 -// EMIT_MIR rustc.id.SimplifyArmIdentity.diff -// EMIT_MIR rustc.id.SimplifyBranchSame.diff -// EMIT_MIR rustc.id_result.SimplifyArmIdentity.diff -// EMIT_MIR rustc.id_result.SimplifyBranchSame.diff -// EMIT_MIR rustc.id_try.SimplifyArmIdentity.diff -// EMIT_MIR rustc.id_try.SimplifyBranchSame.diff +// EMIT_MIR simplify_arm.id.SimplifyArmIdentity.diff +// EMIT_MIR simplify_arm.id.SimplifyBranchSame.diff +// EMIT_MIR simplify_arm.id_result.SimplifyArmIdentity.diff +// EMIT_MIR simplify_arm.id_result.SimplifyBranchSame.diff +// EMIT_MIR simplify_arm.id_try.SimplifyArmIdentity.diff +// EMIT_MIR simplify_arm.id_try.SimplifyBranchSame.diff fn id(o: Option<u8>) -> Option<u8> { match o { diff --git a/src/test/mir-opt/simplify-locals-fixedpoint.rs b/src/test/mir-opt/simplify-locals-fixedpoint.rs index aa5bc345359..78b1f9f55e5 100644 --- a/src/test/mir-opt/simplify-locals-fixedpoint.rs +++ b/src/test/mir-opt/simplify-locals-fixedpoint.rs @@ -12,4 +12,4 @@ fn main() { foo::<()>(); } -// EMIT_MIR rustc.foo.SimplifyLocals.diff +// EMIT_MIR simplify_locals_fixedpoint.foo.SimplifyLocals.diff diff --git a/src/test/mir-opt/simplify-locals-removes-unused-consts.rs b/src/test/mir-opt/simplify-locals-removes-unused-consts.rs index 48cee3c30d2..17999454472 100644 --- a/src/test/mir-opt/simplify-locals-removes-unused-consts.rs +++ b/src/test/mir-opt/simplify-locals-removes-unused-consts.rs @@ -8,7 +8,7 @@ struct Temp { fn use_u8(_: u8) {} -// EMIT_MIR rustc.main.SimplifyLocals.diff +// EMIT_MIR simplify_locals_removes_unused_consts.main.SimplifyLocals.diff fn main() { let ((), ()) = ((), ()); use_zst(((), ())); diff --git a/src/test/mir-opt/simplify-locals-removes-unused-discriminant-reads.rs b/src/test/mir-opt/simplify-locals-removes-unused-discriminant-reads.rs index 7047b542aa6..cf8940ec330 100644 --- a/src/test/mir-opt/simplify-locals-removes-unused-discriminant-reads.rs +++ b/src/test/mir-opt/simplify-locals-removes-unused-discriminant-reads.rs @@ -10,4 +10,4 @@ fn main() { } // EMIT_MIR_FOR_EACH_BIT_WIDTH -// EMIT_MIR rustc.map.SimplifyLocals.diff +// EMIT_MIR simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals.diff diff --git a/src/test/mir-opt/simplify-arm/rustc.id.SimplifyArmIdentity.diff b/src/test/mir-opt/simplify_arm.id.SimplifyArmIdentity.diff index 0cddcb061cf..0cddcb061cf 100644 --- a/src/test/mir-opt/simplify-arm/rustc.id.SimplifyArmIdentity.diff +++ b/src/test/mir-opt/simplify_arm.id.SimplifyArmIdentity.diff diff --git a/src/test/mir-opt/simplify-arm/rustc.id.SimplifyBranchSame.diff b/src/test/mir-opt/simplify_arm.id.SimplifyBranchSame.diff index cd5962c682a..cd5962c682a 100644 --- a/src/test/mir-opt/simplify-arm/rustc.id.SimplifyBranchSame.diff +++ b/src/test/mir-opt/simplify_arm.id.SimplifyBranchSame.diff diff --git a/src/test/mir-opt/simplify-arm/rustc.id_result.SimplifyArmIdentity.diff b/src/test/mir-opt/simplify_arm.id_result.SimplifyArmIdentity.diff index 642ccc1ab14..642ccc1ab14 100644 --- a/src/test/mir-opt/simplify-arm/rustc.id_result.SimplifyArmIdentity.diff +++ b/src/test/mir-opt/simplify_arm.id_result.SimplifyArmIdentity.diff diff --git a/src/test/mir-opt/simplify-arm/rustc.id_result.SimplifyBranchSame.diff b/src/test/mir-opt/simplify_arm.id_result.SimplifyBranchSame.diff index 95ce09a39ed..95ce09a39ed 100644 --- a/src/test/mir-opt/simplify-arm/rustc.id_result.SimplifyBranchSame.diff +++ b/src/test/mir-opt/simplify_arm.id_result.SimplifyBranchSame.diff diff --git a/src/test/mir-opt/simplify-arm/rustc.id_try.SimplifyArmIdentity.diff b/src/test/mir-opt/simplify_arm.id_try.SimplifyArmIdentity.diff index b46ca21fb90..b46ca21fb90 100644 --- a/src/test/mir-opt/simplify-arm/rustc.id_try.SimplifyArmIdentity.diff +++ b/src/test/mir-opt/simplify_arm.id_try.SimplifyArmIdentity.diff diff --git a/src/test/mir-opt/simplify-arm/rustc.id_try.SimplifyBranchSame.diff b/src/test/mir-opt/simplify_arm.id_try.SimplifyBranchSame.diff index 93412d1a74f..93412d1a74f 100644 --- a/src/test/mir-opt/simplify-arm/rustc.id_try.SimplifyBranchSame.diff +++ b/src/test/mir-opt/simplify_arm.id_try.SimplifyBranchSame.diff diff --git a/src/test/mir-opt/simplify-arm-identity/32bit/rustc.main.SimplifyArmIdentity.diff b/src/test/mir-opt/simplify_arm_identity.main.SimplifyArmIdentity.diff.32bit index 0de80f72a1e..0de80f72a1e 100644 --- a/src/test/mir-opt/simplify-arm-identity/32bit/rustc.main.SimplifyArmIdentity.diff +++ b/src/test/mir-opt/simplify_arm_identity.main.SimplifyArmIdentity.diff.32bit diff --git a/src/test/mir-opt/simplify-arm-identity/64bit/rustc.main.SimplifyArmIdentity.diff b/src/test/mir-opt/simplify_arm_identity.main.SimplifyArmIdentity.diff.64bit index 4fa0aff8fa0..4fa0aff8fa0 100644 --- a/src/test/mir-opt/simplify-arm-identity/64bit/rustc.main.SimplifyArmIdentity.diff +++ b/src/test/mir-opt/simplify_arm_identity.main.SimplifyArmIdentity.diff.64bit diff --git a/src/test/mir-opt/simplify_cfg/rustc.main.SimplifyCfg-early-opt.diff b/src/test/mir-opt/simplify_cfg.main.SimplifyCfg-early-opt.diff index 3b472ed3a03..3b472ed3a03 100644 --- a/src/test/mir-opt/simplify_cfg/rustc.main.SimplifyCfg-early-opt.diff +++ b/src/test/mir-opt/simplify_cfg.main.SimplifyCfg-early-opt.diff diff --git a/src/test/mir-opt/simplify_cfg/rustc.main.SimplifyCfg-initial.diff b/src/test/mir-opt/simplify_cfg.main.SimplifyCfg-initial.diff index 1ba05b1cb38..1ba05b1cb38 100644 --- a/src/test/mir-opt/simplify_cfg/rustc.main.SimplifyCfg-initial.diff +++ b/src/test/mir-opt/simplify_cfg.main.SimplifyCfg-initial.diff diff --git a/src/test/mir-opt/simplify_cfg.rs b/src/test/mir-opt/simplify_cfg.rs index 8d588a39d65..c464005c448 100644 --- a/src/test/mir-opt/simplify_cfg.rs +++ b/src/test/mir-opt/simplify_cfg.rs @@ -1,7 +1,7 @@ // Test that the goto chain starting from bb0 is collapsed. -// EMIT_MIR rustc.main.SimplifyCfg-initial.diff -// EMIT_MIR rustc.main.SimplifyCfg-early-opt.diff +// EMIT_MIR simplify_cfg.main.SimplifyCfg-initial.diff +// EMIT_MIR simplify_cfg.main.SimplifyCfg-early-opt.diff fn main() { loop { if bar() { diff --git a/src/test/mir-opt/simplify_if/rustc.main.SimplifyBranches-after-const-prop.diff b/src/test/mir-opt/simplify_if.main.SimplifyBranches-after-const-prop.diff index e94e49bf0cb..e94e49bf0cb 100644 --- a/src/test/mir-opt/simplify_if/rustc.main.SimplifyBranches-after-const-prop.diff +++ b/src/test/mir-opt/simplify_if.main.SimplifyBranches-after-const-prop.diff diff --git a/src/test/mir-opt/simplify_if.rs b/src/test/mir-opt/simplify_if.rs index e2d3ebe69c4..67b2027b710 100644 --- a/src/test/mir-opt/simplify_if.rs +++ b/src/test/mir-opt/simplify_if.rs @@ -1,7 +1,7 @@ #[inline(never)] fn noop() {} -// EMIT_MIR rustc.main.SimplifyBranches-after-const-prop.diff +// EMIT_MIR simplify_if.main.SimplifyBranches-after-const-prop.diff fn main() { if false { noop(); diff --git a/src/test/mir-opt/simplify-locals-fixedpoint/rustc.foo.SimplifyLocals.diff b/src/test/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals.diff index 720296a2c66..720296a2c66 100644 --- a/src/test/mir-opt/simplify-locals-fixedpoint/rustc.foo.SimplifyLocals.diff +++ b/src/test/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals.diff diff --git a/src/test/mir-opt/simplify-locals-removes-unused-consts/rustc.main.SimplifyLocals.diff b/src/test/mir-opt/simplify_locals_removes_unused_consts.main.SimplifyLocals.diff index db06b0392df..db06b0392df 100644 --- a/src/test/mir-opt/simplify-locals-removes-unused-consts/rustc.main.SimplifyLocals.diff +++ b/src/test/mir-opt/simplify_locals_removes_unused_consts.main.SimplifyLocals.diff diff --git a/src/test/mir-opt/simplify-locals-removes-unused-discriminant-reads/32bit/rustc.map.SimplifyLocals.diff b/src/test/mir-opt/simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals.diff.32bit index 440c5f8772e..440c5f8772e 100644 --- a/src/test/mir-opt/simplify-locals-removes-unused-discriminant-reads/32bit/rustc.map.SimplifyLocals.diff +++ b/src/test/mir-opt/simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals.diff.32bit diff --git a/src/test/mir-opt/simplify-locals-removes-unused-discriminant-reads/64bit/rustc.map.SimplifyLocals.diff b/src/test/mir-opt/simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals.diff.64bit index c12d1715b48..c12d1715b48 100644 --- a/src/test/mir-opt/simplify-locals-removes-unused-discriminant-reads/64bit/rustc.map.SimplifyLocals.diff +++ b/src/test/mir-opt/simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals.diff.64bit diff --git a/src/test/mir-opt/simplify_match/rustc.main.ConstProp.diff b/src/test/mir-opt/simplify_match.main.ConstProp.diff index 8003112c46c..8003112c46c 100644 --- a/src/test/mir-opt/simplify_match/rustc.main.ConstProp.diff +++ b/src/test/mir-opt/simplify_match.main.ConstProp.diff diff --git a/src/test/mir-opt/simplify_match.rs b/src/test/mir-opt/simplify_match.rs index b8e1ea6f981..216203f9ff0 100644 --- a/src/test/mir-opt/simplify_match.rs +++ b/src/test/mir-opt/simplify_match.rs @@ -1,7 +1,7 @@ #[inline(never)] fn noop() {} -// EMIT_MIR rustc.main.ConstProp.diff +// EMIT_MIR simplify_match.main.ConstProp.diff fn main() { match { let x = false; x } { true => noop(), diff --git a/src/test/mir-opt/simplify_try.rs b/src/test/mir-opt/simplify_try.rs index 88a0451a76f..fa127de13df 100644 --- a/src/test/mir-opt/simplify_try.rs +++ b/src/test/mir-opt/simplify_try.rs @@ -1,6 +1,6 @@ -// EMIT_MIR rustc.try_identity.SimplifyArmIdentity.diff -// EMIT_MIR rustc.try_identity.SimplifyBranchSame.after.mir -// EMIT_MIR rustc.try_identity.SimplifyLocals.after.mir +// EMIT_MIR simplify_try.try_identity.SimplifyArmIdentity.diff +// EMIT_MIR simplify_try.try_identity.SimplifyBranchSame.after.mir +// EMIT_MIR simplify_try.try_identity.SimplifyLocals.after.mir fn try_identity(x: Result<u32, i32>) -> Result<u32, i32> { let y = x?; diff --git a/src/test/mir-opt/simplify_try/rustc.try_identity.SimplifyArmIdentity.diff b/src/test/mir-opt/simplify_try.try_identity.SimplifyArmIdentity.diff index 26ce290b549..26ce290b549 100644 --- a/src/test/mir-opt/simplify_try/rustc.try_identity.SimplifyArmIdentity.diff +++ b/src/test/mir-opt/simplify_try.try_identity.SimplifyArmIdentity.diff diff --git a/src/test/mir-opt/simplify_try/rustc.try_identity.SimplifyBranchSame.after.mir b/src/test/mir-opt/simplify_try.try_identity.SimplifyBranchSame.after.mir index dc4aae176f2..dc4aae176f2 100644 --- a/src/test/mir-opt/simplify_try/rustc.try_identity.SimplifyBranchSame.after.mir +++ b/src/test/mir-opt/simplify_try.try_identity.SimplifyBranchSame.after.mir diff --git a/src/test/mir-opt/simplify_try/rustc.try_identity.SimplifyLocals.after.mir b/src/test/mir-opt/simplify_try.try_identity.SimplifyLocals.after.mir index d65a2b12c0f..d65a2b12c0f 100644 --- a/src/test/mir-opt/simplify_try/rustc.try_identity.SimplifyLocals.after.mir +++ b/src/test/mir-opt/simplify_try.try_identity.SimplifyLocals.after.mir diff --git a/src/test/mir-opt/simplify_try_if_let.rs b/src/test/mir-opt/simplify_try_if_let.rs index daa961c3c8c..b37db738421 100644 --- a/src/test/mir-opt/simplify_try_if_let.rs +++ b/src/test/mir-opt/simplify_try_if_let.rs @@ -1,5 +1,5 @@ // compile-flags: -Zmir-opt-level=1 -// EMIT_MIR rustc.{{impl}}-append.SimplifyArmIdentity.diff +// EMIT_MIR simplify_try_if_let.{{impl}}-append.SimplifyArmIdentity.diff use std::ptr::NonNull; diff --git a/src/test/mir-opt/simplify_try_if_let/rustc.{{impl}}-append.SimplifyArmIdentity.diff b/src/test/mir-opt/simplify_try_if_let.{{impl}}-append.SimplifyArmIdentity.diff index 4471f4d206c..4471f4d206c 100644 --- a/src/test/mir-opt/simplify_try_if_let/rustc.{{impl}}-append.SimplifyArmIdentity.diff +++ b/src/test/mir-opt/simplify_try_if_let.{{impl}}-append.SimplifyArmIdentity.diff diff --git a/src/test/mir-opt/slice-drop-shim.rs b/src/test/mir-opt/slice-drop-shim.rs index 5d8d37e0bc5..3b98b8474e5 100644 --- a/src/test/mir-opt/slice-drop-shim.rs +++ b/src/test/mir-opt/slice-drop-shim.rs @@ -1,7 +1,7 @@ // compile-flags: -Zmir-opt-level=0 // EMIT_MIR_FOR_EACH_BIT_WIDTH -// EMIT_MIR rustc.ptr-drop_in_place.[std__string__String].AddMovesForPackedDrops.before.mir +// EMIT_MIR core.ptr-drop_in_place.[std__string__String].AddMovesForPackedDrops.before.mir fn main() { let _fn = std::ptr::drop_in_place::<[String]> as unsafe fn(_); } diff --git a/src/test/mir-opt/slice-drop-shim/32bit/rustc.ptr-drop_in_place.[std__string__String].AddMovesForPackedDrops.before.mir b/src/test/mir-opt/slice_drop_shim.core.ptr-drop_in_place.[std__string__String].AddMovesForPackedDrops.before.mir.32bit index b3ee08c3e03..b3ee08c3e03 100644 --- a/src/test/mir-opt/slice-drop-shim/32bit/rustc.ptr-drop_in_place.[std__string__String].AddMovesForPackedDrops.before.mir +++ b/src/test/mir-opt/slice_drop_shim.core.ptr-drop_in_place.[std__string__String].AddMovesForPackedDrops.before.mir.32bit diff --git a/src/test/mir-opt/slice-drop-shim/64bit/rustc.ptr-drop_in_place.[std__string__String].AddMovesForPackedDrops.before.mir b/src/test/mir-opt/slice_drop_shim.core.ptr-drop_in_place.[std__string__String].AddMovesForPackedDrops.before.mir.64bit index ea22af65dda..ea22af65dda 100644 --- a/src/test/mir-opt/slice-drop-shim/64bit/rustc.ptr-drop_in_place.[std__string__String].AddMovesForPackedDrops.before.mir +++ b/src/test/mir-opt/slice_drop_shim.core.ptr-drop_in_place.[std__string__String].AddMovesForPackedDrops.before.mir.64bit diff --git a/src/test/mir-opt/storage_live_dead_in_statics/rustc.XXX.mir_map.0.mir b/src/test/mir-opt/storage_live_dead_in_statics.XXX.mir_map.0.mir index d7f73a22c26..d7f73a22c26 100644 --- a/src/test/mir-opt/storage_live_dead_in_statics/rustc.XXX.mir_map.0.mir +++ b/src/test/mir-opt/storage_live_dead_in_statics.XXX.mir_map.0.mir diff --git a/src/test/mir-opt/storage_live_dead_in_statics.rs b/src/test/mir-opt/storage_live_dead_in_statics.rs index a269914f262..b03de8612fc 100644 --- a/src/test/mir-opt/storage_live_dead_in_statics.rs +++ b/src/test/mir-opt/storage_live_dead_in_statics.rs @@ -1,7 +1,7 @@ // Check that when we compile the static `XXX` into MIR, we do not // generate `StorageStart` or `StorageEnd` statements. -// EMIT_MIR rustc.XXX.mir_map.0.mir +// EMIT_MIR storage_live_dead_in_statics.XXX.mir_map.0.mir static XXX: &'static Foo = &Foo { tup: "hi", data: &[ diff --git a/src/test/mir-opt/storage_ranges/rustc.main.nll.0.mir b/src/test/mir-opt/storage_ranges.main.nll.0.mir index 099535c0ad2..099535c0ad2 100644 --- a/src/test/mir-opt/storage_ranges/rustc.main.nll.0.mir +++ b/src/test/mir-opt/storage_ranges.main.nll.0.mir diff --git a/src/test/mir-opt/storage_ranges.rs b/src/test/mir-opt/storage_ranges.rs index 7b3c77aca27..996051a2941 100644 --- a/src/test/mir-opt/storage_ranges.rs +++ b/src/test/mir-opt/storage_ranges.rs @@ -1,4 +1,4 @@ -// EMIT_MIR rustc.main.nll.0.mir +// EMIT_MIR storage_ranges.main.nll.0.mir fn main() { let a = 0; diff --git a/src/test/mir-opt/tls-access.rs b/src/test/mir-opt/tls-access.rs index 4f3f6b1b3ac..b585fd0c808 100644 --- a/src/test/mir-opt/tls-access.rs +++ b/src/test/mir-opt/tls-access.rs @@ -10,4 +10,4 @@ fn main() { } } -// EMIT_MIR rustc.main.SimplifyCfg-final.after.mir +// EMIT_MIR tls_access.main.SimplifyCfg-final.after.mir diff --git a/src/test/mir-opt/tls-access/rustc.main.SimplifyCfg-final.after.mir b/src/test/mir-opt/tls_access.main.SimplifyCfg-final.after.mir index 5ceca2d091e..5ceca2d091e 100644 --- a/src/test/mir-opt/tls-access/rustc.main.SimplifyCfg-final.after.mir +++ b/src/test/mir-opt/tls_access.main.SimplifyCfg-final.after.mir diff --git a/src/test/mir-opt/uniform_array_move_out/rustc.move_out_by_subslice.mir_map.0.mir b/src/test/mir-opt/uniform_array_move_out.move_out_by_subslice.mir_map.0.mir index eb40baa2000..eb40baa2000 100644 --- a/src/test/mir-opt/uniform_array_move_out/rustc.move_out_by_subslice.mir_map.0.mir +++ b/src/test/mir-opt/uniform_array_move_out.move_out_by_subslice.mir_map.0.mir diff --git a/src/test/mir-opt/uniform_array_move_out/rustc.move_out_from_end.mir_map.0.mir b/src/test/mir-opt/uniform_array_move_out.move_out_from_end.mir_map.0.mir index 7beceb66577..7beceb66577 100644 --- a/src/test/mir-opt/uniform_array_move_out/rustc.move_out_from_end.mir_map.0.mir +++ b/src/test/mir-opt/uniform_array_move_out.move_out_from_end.mir_map.0.mir diff --git a/src/test/mir-opt/uniform_array_move_out.rs b/src/test/mir-opt/uniform_array_move_out.rs index c1b7ebdbc3a..35e42552870 100644 --- a/src/test/mir-opt/uniform_array_move_out.rs +++ b/src/test/mir-opt/uniform_array_move_out.rs @@ -1,12 +1,12 @@ #![feature(box_syntax)] -// EMIT_MIR rustc.move_out_from_end.mir_map.0.mir +// EMIT_MIR uniform_array_move_out.move_out_from_end.mir_map.0.mir fn move_out_from_end() { let a = [box 1, box 2]; let [.., _y] = a; } -// EMIT_MIR rustc.move_out_by_subslice.mir_map.0.mir +// EMIT_MIR uniform_array_move_out.move_out_by_subslice.mir_map.0.mir fn move_out_by_subslice() { let a = [box 1, box 2]; let [_y @ ..] = a; diff --git a/src/test/mir-opt/uninhabited-enum.rs b/src/test/mir-opt/uninhabited-enum.rs index 6503e193608..97c6e8cd531 100644 --- a/src/test/mir-opt/uninhabited-enum.rs +++ b/src/test/mir-opt/uninhabited-enum.rs @@ -2,13 +2,13 @@ pub enum Void {} -// EMIT_MIR rustc.process_never.SimplifyLocals.after.mir +// EMIT_MIR uninhabited_enum.process_never.SimplifyLocals.after.mir #[no_mangle] pub fn process_never(input: *const !) { let _input = unsafe { &*input }; } -// EMIT_MIR rustc.process_void.SimplifyLocals.after.mir +// EMIT_MIR uninhabited_enum.process_void.SimplifyLocals.after.mir #[no_mangle] pub fn process_void(input: *const Void) { let _input = unsafe { &*input }; diff --git a/src/test/mir-opt/uninhabited-enum/rustc.process_never.SimplifyLocals.after.mir b/src/test/mir-opt/uninhabited_enum.process_never.SimplifyLocals.after.mir index c17fe3bb757..c17fe3bb757 100644 --- a/src/test/mir-opt/uninhabited-enum/rustc.process_never.SimplifyLocals.after.mir +++ b/src/test/mir-opt/uninhabited_enum.process_never.SimplifyLocals.after.mir diff --git a/src/test/mir-opt/uninhabited-enum/rustc.process_void.SimplifyLocals.after.mir b/src/test/mir-opt/uninhabited_enum.process_void.SimplifyLocals.after.mir index 8cfcd64a70f..8cfcd64a70f 100644 --- a/src/test/mir-opt/uninhabited-enum/rustc.process_void.SimplifyLocals.after.mir +++ b/src/test/mir-opt/uninhabited_enum.process_void.SimplifyLocals.after.mir diff --git a/src/test/mir-opt/uninhabited_enum_branching/rustc.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir b/src/test/mir-opt/uninhabited_enum_branching.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir index 4f4fb7defc3..4f4fb7defc3 100644 --- a/src/test/mir-opt/uninhabited_enum_branching/rustc.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir +++ b/src/test/mir-opt/uninhabited_enum_branching.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir diff --git a/src/test/mir-opt/uninhabited_enum_branching/rustc.main.UninhabitedEnumBranching.diff b/src/test/mir-opt/uninhabited_enum_branching.main.UninhabitedEnumBranching.diff index d262c9432ca..d262c9432ca 100644 --- a/src/test/mir-opt/uninhabited_enum_branching/rustc.main.UninhabitedEnumBranching.diff +++ b/src/test/mir-opt/uninhabited_enum_branching.main.UninhabitedEnumBranching.diff diff --git a/src/test/mir-opt/uninhabited_enum_branching.rs b/src/test/mir-opt/uninhabited_enum_branching.rs index daf1156d20e..0ef604c3088 100644 --- a/src/test/mir-opt/uninhabited_enum_branching.rs +++ b/src/test/mir-opt/uninhabited_enum_branching.rs @@ -14,8 +14,8 @@ enum Test2 { E = 5, } -// EMIT_MIR rustc.main.UninhabitedEnumBranching.diff -// EMIT_MIR rustc.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir +// EMIT_MIR uninhabited_enum_branching.main.UninhabitedEnumBranching.diff +// EMIT_MIR uninhabited_enum_branching.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir fn main() { match Test1::C { Test1::A(_) => "A(Empty)", diff --git a/src/test/mir-opt/unreachable/rustc.main.UnreachablePropagation.diff b/src/test/mir-opt/unreachable.main.UnreachablePropagation.diff index e7abf578800..e7abf578800 100644 --- a/src/test/mir-opt/unreachable/rustc.main.UnreachablePropagation.diff +++ b/src/test/mir-opt/unreachable.main.UnreachablePropagation.diff diff --git a/src/test/mir-opt/unreachable.rs b/src/test/mir-opt/unreachable.rs index 6f0c4ca3cf5..6098b525b55 100644 --- a/src/test/mir-opt/unreachable.rs +++ b/src/test/mir-opt/unreachable.rs @@ -4,7 +4,7 @@ fn empty() -> Option<Empty> { None } -// EMIT_MIR rustc.main.UnreachablePropagation.diff +// EMIT_MIR unreachable.main.UnreachablePropagation.diff fn main() { if let Some(_x) = empty() { let mut _y; diff --git a/src/test/mir-opt/unreachable_asm/rustc.main.UnreachablePropagation.diff b/src/test/mir-opt/unreachable_asm.main.UnreachablePropagation.diff index 50694900024..50694900024 100644 --- a/src/test/mir-opt/unreachable_asm/rustc.main.UnreachablePropagation.diff +++ b/src/test/mir-opt/unreachable_asm.main.UnreachablePropagation.diff diff --git a/src/test/mir-opt/unreachable_asm.rs b/src/test/mir-opt/unreachable_asm.rs index 4bbf22b8227..cbef05a3c05 100644 --- a/src/test/mir-opt/unreachable_asm.rs +++ b/src/test/mir-opt/unreachable_asm.rs @@ -6,7 +6,7 @@ fn empty() -> Option<Empty> { None } -// EMIT_MIR rustc.main.UnreachablePropagation.diff +// EMIT_MIR unreachable_asm.main.UnreachablePropagation.diff fn main() { if let Some(_x) = empty() { let mut _y; diff --git a/src/test/mir-opt/unreachable_asm_2/rustc.main.UnreachablePropagation.diff b/src/test/mir-opt/unreachable_asm_2.main.UnreachablePropagation.diff index 9be05aefcf6..9be05aefcf6 100644 --- a/src/test/mir-opt/unreachable_asm_2/rustc.main.UnreachablePropagation.diff +++ b/src/test/mir-opt/unreachable_asm_2.main.UnreachablePropagation.diff diff --git a/src/test/mir-opt/unreachable_asm_2.rs b/src/test/mir-opt/unreachable_asm_2.rs index f1610db999e..e0d8e725147 100644 --- a/src/test/mir-opt/unreachable_asm_2.rs +++ b/src/test/mir-opt/unreachable_asm_2.rs @@ -6,7 +6,7 @@ fn empty() -> Option<Empty> { None } -// EMIT_MIR rustc.main.UnreachablePropagation.diff +// EMIT_MIR unreachable_asm_2.main.UnreachablePropagation.diff fn main() { if let Some(_x) = empty() { let mut _y; diff --git a/src/test/mir-opt/unreachable_diverging/rustc.main.UnreachablePropagation.diff b/src/test/mir-opt/unreachable_diverging.main.UnreachablePropagation.diff index e7886f683c0..e7886f683c0 100644 --- a/src/test/mir-opt/unreachable_diverging/rustc.main.UnreachablePropagation.diff +++ b/src/test/mir-opt/unreachable_diverging.main.UnreachablePropagation.diff diff --git a/src/test/mir-opt/unreachable_diverging.rs b/src/test/mir-opt/unreachable_diverging.rs index 53c753f717b..bbf28efc7dd 100644 --- a/src/test/mir-opt/unreachable_diverging.rs +++ b/src/test/mir-opt/unreachable_diverging.rs @@ -8,7 +8,7 @@ fn loop_forever() { loop {} } -// EMIT_MIR rustc.main.UnreachablePropagation.diff +// EMIT_MIR unreachable_diverging.main.UnreachablePropagation.diff fn main() { let x = true; if let Some(bomb) = empty() { diff --git a/src/test/mir-opt/unusual-item-types.rs b/src/test/mir-opt/unusual-item-types.rs index ffe8ca01dfb..249a851af25 100644 --- a/src/test/mir-opt/unusual-item-types.rs +++ b/src/test/mir-opt/unusual-item-types.rs @@ -5,25 +5,25 @@ struct A; -// EMIT_MIR rustc.{{impl}}-ASSOCIATED_CONSTANT.mir_map.0.mir +// EMIT_MIR unusual_item_types.{{impl}}-ASSOCIATED_CONSTANT.mir_map.0.mir impl A { const ASSOCIATED_CONSTANT: i32 = 2; } // See #59021 -// EMIT_MIR rustc.Test-X-{{constructor}}.mir_map.0.mir +// EMIT_MIR unusual_item_types.Test-X-{{constructor}}.mir_map.0.mir enum Test { X(usize), Y { a: usize }, } -// EMIT_MIR rustc.E-V-{{constant}}.mir_map.0.mir +// EMIT_MIR unusual_item_types.E-V-{{constant}}.mir_map.0.mir enum E { V = 5, } fn main() { let f = Test::X as fn(usize) -> Test; -// EMIT_MIR rustc.ptr-drop_in_place.std__vec__Vec_i32_.AddMovesForPackedDrops.before.mir +// EMIT_MIR core.ptr-drop_in_place.std__vec__Vec_i32_.AddMovesForPackedDrops.before.mir let v = Vec::<i32>::new(); } diff --git a/src/test/mir-opt/unusual-item-types/32bit/rustc.E-V-{{constant}}.mir_map.0.mir b/src/test/mir-opt/unusual_item_types.E-V-{{constant}}.mir_map.0.mir.32bit index 7f0266d6589..7f0266d6589 100644 --- a/src/test/mir-opt/unusual-item-types/32bit/rustc.E-V-{{constant}}.mir_map.0.mir +++ b/src/test/mir-opt/unusual_item_types.E-V-{{constant}}.mir_map.0.mir.32bit diff --git a/src/test/mir-opt/unusual-item-types/64bit/rustc.E-V-{{constant}}.mir_map.0.mir b/src/test/mir-opt/unusual_item_types.E-V-{{constant}}.mir_map.0.mir.64bit index f2c1e9c97dd..f2c1e9c97dd 100644 --- a/src/test/mir-opt/unusual-item-types/64bit/rustc.E-V-{{constant}}.mir_map.0.mir +++ b/src/test/mir-opt/unusual_item_types.E-V-{{constant}}.mir_map.0.mir.64bit diff --git a/src/test/mir-opt/unusual-item-types/32bit/rustc.Test-X-{{constructor}}.mir_map.0.mir b/src/test/mir-opt/unusual_item_types.Test-X-{{constructor}}.mir_map.0.mir.32bit index 832f18e14c2..832f18e14c2 100644 --- a/src/test/mir-opt/unusual-item-types/32bit/rustc.Test-X-{{constructor}}.mir_map.0.mir +++ b/src/test/mir-opt/unusual_item_types.Test-X-{{constructor}}.mir_map.0.mir.32bit diff --git a/src/test/mir-opt/unusual-item-types/64bit/rustc.Test-X-{{constructor}}.mir_map.0.mir b/src/test/mir-opt/unusual_item_types.Test-X-{{constructor}}.mir_map.0.mir.64bit index 832f18e14c2..832f18e14c2 100644 --- a/src/test/mir-opt/unusual-item-types/64bit/rustc.Test-X-{{constructor}}.mir_map.0.mir +++ b/src/test/mir-opt/unusual_item_types.Test-X-{{constructor}}.mir_map.0.mir.64bit diff --git a/src/test/mir-opt/unusual-item-types/32bit/rustc.ptr-drop_in_place.std__vec__Vec_i32_.AddMovesForPackedDrops.before.mir b/src/test/mir-opt/unusual_item_types.core.ptr-drop_in_place.std__vec__Vec_i32_.AddMovesForPackedDrops.before.mir.32bit index 321f13b4927..321f13b4927 100644 --- a/src/test/mir-opt/unusual-item-types/32bit/rustc.ptr-drop_in_place.std__vec__Vec_i32_.AddMovesForPackedDrops.before.mir +++ b/src/test/mir-opt/unusual_item_types.core.ptr-drop_in_place.std__vec__Vec_i32_.AddMovesForPackedDrops.before.mir.32bit diff --git a/src/test/mir-opt/unusual-item-types/64bit/rustc.ptr-drop_in_place.std__vec__Vec_i32_.AddMovesForPackedDrops.before.mir b/src/test/mir-opt/unusual_item_types.core.ptr-drop_in_place.std__vec__Vec_i32_.AddMovesForPackedDrops.before.mir.64bit index 321f13b4927..321f13b4927 100644 --- a/src/test/mir-opt/unusual-item-types/64bit/rustc.ptr-drop_in_place.std__vec__Vec_i32_.AddMovesForPackedDrops.before.mir +++ b/src/test/mir-opt/unusual_item_types.core.ptr-drop_in_place.std__vec__Vec_i32_.AddMovesForPackedDrops.before.mir.64bit diff --git a/src/test/mir-opt/unusual-item-types/32bit/rustc.{{impl}}-ASSOCIATED_CONSTANT.mir_map.0.mir b/src/test/mir-opt/unusual_item_types.{{impl}}-ASSOCIATED_CONSTANT.mir_map.0.mir.32bit index 4af856c654e..4af856c654e 100644 --- a/src/test/mir-opt/unusual-item-types/32bit/rustc.{{impl}}-ASSOCIATED_CONSTANT.mir_map.0.mir +++ b/src/test/mir-opt/unusual_item_types.{{impl}}-ASSOCIATED_CONSTANT.mir_map.0.mir.32bit diff --git a/src/test/mir-opt/unusual-item-types/64bit/rustc.{{impl}}-ASSOCIATED_CONSTANT.mir_map.0.mir b/src/test/mir-opt/unusual_item_types.{{impl}}-ASSOCIATED_CONSTANT.mir_map.0.mir.64bit index 4af856c654e..4af856c654e 100644 --- a/src/test/mir-opt/unusual-item-types/64bit/rustc.{{impl}}-ASSOCIATED_CONSTANT.mir_map.0.mir +++ b/src/test/mir-opt/unusual_item_types.{{impl}}-ASSOCIATED_CONSTANT.mir_map.0.mir.64bit diff --git a/src/test/mir-opt/while-storage.rs b/src/test/mir-opt/while-storage.rs index 56f6c3380a7..afd083acb34 100644 --- a/src/test/mir-opt/while-storage.rs +++ b/src/test/mir-opt/while-storage.rs @@ -5,7 +5,7 @@ fn get_bool(c: bool) -> bool { c } -// EMIT_MIR rustc.while_loop.PreCodegen.after.mir +// EMIT_MIR while_storage.while_loop.PreCodegen.after.mir fn while_loop(c: bool) { while get_bool(c) { if get_bool(c) { diff --git a/src/test/mir-opt/while-storage/rustc.while_loop.PreCodegen.after.mir b/src/test/mir-opt/while_storage.while_loop.PreCodegen.after.mir index 3ddf82c2fb2..3ddf82c2fb2 100644 --- a/src/test/mir-opt/while-storage/rustc.while_loop.PreCodegen.after.mir +++ b/src/test/mir-opt/while_storage.while_loop.PreCodegen.after.mir diff --git a/src/test/pretty/block-comment-wchar.pp b/src/test/pretty/block-comment-wchar.pp index 9317b36ba49..2bfcdd75e15 100644 --- a/src/test/pretty/block-comment-wchar.pp +++ b/src/test/pretty/block-comment-wchar.pp @@ -73,7 +73,6 @@ fn f() { */ - /* */ /* @@ -81,7 +80,6 @@ fn f() { Space 6+2: compare A Ogham Space Mark 6+2: compare B */ - /* */ /* diff --git a/src/test/pretty/issue-74745.rs b/src/test/pretty/issue-74745.rs new file mode 100644 index 00000000000..e255cd6caa8 --- /dev/null +++ b/src/test/pretty/issue-74745.rs @@ -0,0 +1,5 @@ +// ignore-tidy-trailing-newlines +// pretty-compare-only + +/* +*/ \ No newline at end of file diff --git a/src/test/run-make-fulldeps/exit-code/lint-failure.rs b/src/test/run-make-fulldeps/exit-code/lint-failure.rs index 70bdddc6246..df876ec237f 100644 --- a/src/test/run-make-fulldeps/exit-code/lint-failure.rs +++ b/src/test/run-make-fulldeps/exit-code/lint-failure.rs @@ -1,4 +1,4 @@ -#![deny(intra_doc_link_resolution_failure)] +#![deny(broken_intra_doc_links)] /// [intradoc::failure] pub fn main() { diff --git a/src/test/run-make-fulldeps/mingw-export-call-convention/Makefile b/src/test/run-make-fulldeps/mingw-export-call-convention/Makefile new file mode 100644 index 00000000000..4a60059cc54 --- /dev/null +++ b/src/test/run-make-fulldeps/mingw-export-call-convention/Makefile @@ -0,0 +1,9 @@ +include ../tools.mk + +# only-windows-gnu + +all: + $(RUSTC) foo.rs + # FIXME: we should make sure __stdcall calling convention is used here + # but that only works with LLD right now + nm -g "$(call IMPLIB,foo)" | $(CGREP) bar diff --git a/src/test/run-make-fulldeps/mingw-export-call-convention/foo.rs b/src/test/run-make-fulldeps/mingw-export-call-convention/foo.rs new file mode 100644 index 00000000000..1fec00311ef --- /dev/null +++ b/src/test/run-make-fulldeps/mingw-export-call-convention/foo.rs @@ -0,0 +1,4 @@ +#![crate_type = "cdylib"] + +#[no_mangle] +pub extern "system" fn bar() {} diff --git a/src/test/run-make-fulldeps/tools.mk b/src/test/run-make-fulldeps/tools.mk index 8b885f1dc6d..f9b6d342295 100644 --- a/src/test/run-make-fulldeps/tools.mk +++ b/src/test/run-make-fulldeps/tools.mk @@ -51,6 +51,7 @@ ifdef IS_MSVC STATICLIB = $(TMPDIR)/$(1).lib STATICLIB_GLOB = $(1)*.lib else +IMPLIB = $(TMPDIR)/lib$(1).dll.a STATICLIB = $(TMPDIR)/lib$(1).a STATICLIB_GLOB = lib$(1)*.a endif diff --git a/src/test/rustdoc-ui/deny-intra-link-resolution-failure.rs b/src/test/rustdoc-ui/deny-intra-link-resolution-failure.rs index 9e64e6eb399..54e7689f316 100644 --- a/src/test/rustdoc-ui/deny-intra-link-resolution-failure.rs +++ b/src/test/rustdoc-ui/deny-intra-link-resolution-failure.rs @@ -1,4 +1,4 @@ -#![deny(intra_doc_link_resolution_failure)] +#![deny(broken_intra_doc_links)] /// [v2] //~ ERROR pub fn foo() {} diff --git a/src/test/rustdoc-ui/deny-intra-link-resolution-failure.stderr b/src/test/rustdoc-ui/deny-intra-link-resolution-failure.stderr index 894518faa31..7530e3ad0f5 100644 --- a/src/test/rustdoc-ui/deny-intra-link-resolution-failure.stderr +++ b/src/test/rustdoc-ui/deny-intra-link-resolution-failure.stderr @@ -7,8 +7,8 @@ LL | /// [v2] note: the lint level is defined here --> $DIR/deny-intra-link-resolution-failure.rs:1:9 | -LL | #![deny(intra_doc_link_resolution_failure)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #![deny(broken_intra_doc_links)] + | ^^^^^^^^^^^^^^^^^^^^^^ = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` error: aborting due to previous error diff --git a/src/test/rustdoc-ui/intra-doc-alias-ice.rs b/src/test/rustdoc-ui/intra-doc-alias-ice.rs index 9657d573d50..c053e378e71 100644 --- a/src/test/rustdoc-ui/intra-doc-alias-ice.rs +++ b/src/test/rustdoc-ui/intra-doc-alias-ice.rs @@ -1,4 +1,4 @@ -#![deny(intra_doc_link_resolution_failure)] +#![deny(broken_intra_doc_links)] pub type TypeAlias = usize; diff --git a/src/test/rustdoc-ui/intra-doc-alias-ice.stderr b/src/test/rustdoc-ui/intra-doc-alias-ice.stderr index d2b2b90a4e5..f1c07e31cd7 100644 --- a/src/test/rustdoc-ui/intra-doc-alias-ice.stderr +++ b/src/test/rustdoc-ui/intra-doc-alias-ice.stderr @@ -7,8 +7,8 @@ LL | /// [broken cross-reference](TypeAlias::hoge) note: the lint level is defined here --> $DIR/intra-doc-alias-ice.rs:1:9 | -LL | #![deny(intra_doc_link_resolution_failure)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #![deny(broken_intra_doc_links)] + | ^^^^^^^^^^^^^^^^^^^^^^ = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` error: aborting due to previous error diff --git a/src/test/rustdoc-ui/intra-link-span-ice-55723.rs b/src/test/rustdoc-ui/intra-link-span-ice-55723.rs index 95388003f84..7764a6df6ee 100644 --- a/src/test/rustdoc-ui/intra-link-span-ice-55723.rs +++ b/src/test/rustdoc-ui/intra-link-span-ice-55723.rs @@ -1,4 +1,4 @@ -#![deny(intra_doc_link_resolution_failure)] +#![deny(broken_intra_doc_links)] // An error in calculating spans while reporting intra-doc link resolution errors caused rustdoc to // attempt to slice in the middle of a multibyte character. See diff --git a/src/test/rustdoc-ui/intra-link-span-ice-55723.stderr b/src/test/rustdoc-ui/intra-link-span-ice-55723.stderr index 156e214a79f..6b0ff8f1162 100644 --- a/src/test/rustdoc-ui/intra-link-span-ice-55723.stderr +++ b/src/test/rustdoc-ui/intra-link-span-ice-55723.stderr @@ -7,8 +7,8 @@ LL | /// (arr[i]) note: the lint level is defined here --> $DIR/intra-link-span-ice-55723.rs:1:9 | -LL | #![deny(intra_doc_link_resolution_failure)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #![deny(broken_intra_doc_links)] + | ^^^^^^^^^^^^^^^^^^^^^^ = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` error: aborting due to previous error diff --git a/src/test/rustdoc-ui/intra-links-ambiguity.rs b/src/test/rustdoc-ui/intra-links-ambiguity.rs index 7316fcdad67..d1597cdca66 100644 --- a/src/test/rustdoc-ui/intra-links-ambiguity.rs +++ b/src/test/rustdoc-ui/intra-links-ambiguity.rs @@ -1,4 +1,4 @@ -#![deny(intra_doc_link_resolution_failure)] +#![deny(broken_intra_doc_links)] #![allow(non_camel_case_types)] #![allow(non_upper_case_globals)] diff --git a/src/test/rustdoc-ui/intra-links-ambiguity.stderr b/src/test/rustdoc-ui/intra-links-ambiguity.stderr index 7b9821b3d04..35262c1b612 100644 --- a/src/test/rustdoc-ui/intra-links-ambiguity.stderr +++ b/src/test/rustdoc-ui/intra-links-ambiguity.stderr @@ -7,8 +7,8 @@ LL | /// [`ambiguous`] is ambiguous. note: the lint level is defined here --> $DIR/intra-links-ambiguity.rs:1:9 | -LL | #![deny(intra_doc_link_resolution_failure)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #![deny(broken_intra_doc_links)] + | ^^^^^^^^^^^^^^^^^^^^^^ help: to link to the struct, prefix with the item type | LL | /// [`struct@ambiguous`] is ambiguous. diff --git a/src/test/rustdoc-ui/intra-links-anchors.rs b/src/test/rustdoc-ui/intra-links-anchors.rs index 7e61bd72535..ccefd2e6fab 100644 --- a/src/test/rustdoc-ui/intra-links-anchors.rs +++ b/src/test/rustdoc-ui/intra-links-anchors.rs @@ -1,4 +1,4 @@ -#![deny(intra_doc_link_resolution_failure)] +#![deny(broken_intra_doc_links)] // A few tests on anchors. diff --git a/src/test/rustdoc-ui/intra-links-anchors.stderr b/src/test/rustdoc-ui/intra-links-anchors.stderr index ef33d8f3e06..e737b84320d 100644 --- a/src/test/rustdoc-ui/intra-links-anchors.stderr +++ b/src/test/rustdoc-ui/intra-links-anchors.stderr @@ -7,8 +7,8 @@ LL | /// Or maybe [Foo::f#hola]. note: the lint level is defined here --> $DIR/intra-links-anchors.rs:1:9 | -LL | #![deny(intra_doc_link_resolution_failure)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #![deny(broken_intra_doc_links)] + | ^^^^^^^^^^^^^^^^^^^^^^ error: `hello#people#!` contains multiple anchors --> $DIR/intra-links-anchors.rs:31:28 diff --git a/src/test/rustdoc-ui/intra-links-private.private.stderr b/src/test/rustdoc-ui/intra-links-private.private.stderr index a2148b82f81..77c4b67a652 100644 --- a/src/test/rustdoc-ui/intra-links-private.private.stderr +++ b/src/test/rustdoc-ui/intra-links-private.private.stderr @@ -4,7 +4,7 @@ warning: public documentation for `DocMe` links to private item `DontDocMe` LL | /// docs [DontDocMe] | ^^^^^^^^^ this item is private | - = note: `#[warn(intra_doc_link_resolution_failure)]` on by default + = note: `#[warn(broken_intra_doc_links)]` on by default = note: this link resolves only because you passed `--document-private-items`, but will break without warning: 1 warning emitted diff --git a/src/test/rustdoc-ui/intra-links-private.public.stderr b/src/test/rustdoc-ui/intra-links-private.public.stderr index 56742406992..312a78e8c3e 100644 --- a/src/test/rustdoc-ui/intra-links-private.public.stderr +++ b/src/test/rustdoc-ui/intra-links-private.public.stderr @@ -4,7 +4,7 @@ warning: public documentation for `DocMe` links to private item `DontDocMe` LL | /// docs [DontDocMe] | ^^^^^^^^^ this item is private | - = note: `#[warn(intra_doc_link_resolution_failure)]` on by default + = note: `#[warn(broken_intra_doc_links)]` on by default = note: this link will resolve properly if you pass `--document-private-items` warning: 1 warning emitted diff --git a/src/test/rustdoc-ui/intra-links-warning-crlf.stderr b/src/test/rustdoc-ui/intra-links-warning-crlf.stderr index bc31264c170..1e3a26fadfa 100644 --- a/src/test/rustdoc-ui/intra-links-warning-crlf.stderr +++ b/src/test/rustdoc-ui/intra-links-warning-crlf.stderr @@ -4,7 +4,7 @@ warning: unresolved link to `error` LL | /// [error] | ^^^^^ unresolved link | - = note: `#[warn(intra_doc_link_resolution_failure)]` on by default + = note: `#[warn(broken_intra_doc_links)]` on by default = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` warning: unresolved link to `error1` diff --git a/src/test/rustdoc-ui/intra-links-warning.stderr b/src/test/rustdoc-ui/intra-links-warning.stderr index 81931399c24..53f2476295e 100644 --- a/src/test/rustdoc-ui/intra-links-warning.stderr +++ b/src/test/rustdoc-ui/intra-links-warning.stderr @@ -4,7 +4,7 @@ warning: unresolved link to `Foo::baz` LL | //! Test with [Foo::baz], [Bar::foo], ... | ^^^^^^^^ unresolved link | - = note: `#[warn(intra_doc_link_resolution_failure)]` on by default + = note: `#[warn(broken_intra_doc_links)]` on by default = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` warning: unresolved link to `Bar::foo` diff --git a/src/test/rustdoc-ui/issue-74134.private.stderr b/src/test/rustdoc-ui/issue-74134.private.stderr index 9c5cdf0117c..58772109140 100644 --- a/src/test/rustdoc-ui/issue-74134.private.stderr +++ b/src/test/rustdoc-ui/issue-74134.private.stderr @@ -4,7 +4,7 @@ warning: public documentation for `public_item` links to private item `PrivateTy LL | /// [`PrivateType`] | ^^^^^^^^^^^^^ this item is private | - = note: `#[warn(intra_doc_link_resolution_failure)]` on by default + = note: `#[warn(broken_intra_doc_links)]` on by default = note: this link resolves only because you passed `--document-private-items`, but will break without warning: 1 warning emitted diff --git a/src/test/rustdoc-ui/issue-74134.public.stderr b/src/test/rustdoc-ui/issue-74134.public.stderr index ff2951d864e..b5bea190941 100644 --- a/src/test/rustdoc-ui/issue-74134.public.stderr +++ b/src/test/rustdoc-ui/issue-74134.public.stderr @@ -4,7 +4,7 @@ warning: public documentation for `public_item` links to private item `PrivateTy LL | /// [`PrivateType`] | ^^^^^^^^^^^^^ this item is private | - = note: `#[warn(intra_doc_link_resolution_failure)]` on by default + = note: `#[warn(broken_intra_doc_links)]` on by default = note: this link will resolve properly if you pass `--document-private-items` warning: 1 warning emitted diff --git a/src/test/rustdoc-ui/lint-group.stderr b/src/test/rustdoc-ui/lint-group.stderr index ad923c714da..04296d2e44a 100644 --- a/src/test/rustdoc-ui/lint-group.stderr +++ b/src/test/rustdoc-ui/lint-group.stderr @@ -39,7 +39,7 @@ note: the lint level is defined here | LL | #![deny(rustdoc)] | ^^^^^^^ - = note: `#[deny(intra_doc_link_resolution_failure)]` implied by `#[deny(rustdoc)]` + = note: `#[deny(broken_intra_doc_links)]` implied by `#[deny(rustdoc)]` = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` error: aborting due to 3 previous errors diff --git a/src/test/rustdoc-ui/reference-link-has-one-warning.stderr b/src/test/rustdoc-ui/reference-link-has-one-warning.stderr index 5bbc62b76dd..a1eeb60f178 100644 --- a/src/test/rustdoc-ui/reference-link-has-one-warning.stderr +++ b/src/test/rustdoc-ui/reference-link-has-one-warning.stderr @@ -4,7 +4,7 @@ warning: `[with#anchor#error]` has an issue with the link anchor. LL | /// docs [label][with#anchor#error] | ^^^^^^^^^^^^^^^^^ only one `#` is allowed in a link | - = note: `#[warn(intra_doc_link_resolution_failure)]` on by default + = note: `#[warn(broken_intra_doc_links)]` on by default warning: 1 warning emitted diff --git a/src/test/rustdoc/const-generics/const-impl.rs b/src/test/rustdoc/const-generics/const-impl.rs index 7361b22b747..03f5bb2ca43 100644 --- a/src/test/rustdoc/const-generics/const-impl.rs +++ b/src/test/rustdoc/const-generics/const-impl.rs @@ -11,8 +11,8 @@ pub enum Order { } // @has foo/struct.VSet.html '//pre[@class="rust struct"]' 'pub struct VSet<T, const ORDER: Order>' -// @has foo/struct.VSet.html '//h3[@id="impl-Send"]/code' 'impl<const ORDER: Order, T> Send for VSet<T, ORDER>' -// @has foo/struct.VSet.html '//h3[@id="impl-Sync"]/code' 'impl<const ORDER: Order, T> Sync for VSet<T, ORDER>' +// @has foo/struct.VSet.html '//h3[@id="impl-Send"]/code' 'impl<T, const ORDER: Order> Send for VSet<T, ORDER>' +// @has foo/struct.VSet.html '//h3[@id="impl-Sync"]/code' 'impl<T, const ORDER: Order> Sync for VSet<T, ORDER>' pub struct VSet<T, const ORDER: Order> { inner: Vec<T>, } diff --git a/src/test/rustdoc/intra-doc-crate/additional_doc.rs b/src/test/rustdoc/intra-doc-crate/additional_doc.rs index adfa7f5754e..837390b3c71 100644 --- a/src/test/rustdoc/intra-doc-crate/additional_doc.rs +++ b/src/test/rustdoc/intra-doc-crate/additional_doc.rs @@ -1,6 +1,6 @@ // aux-build:additional_doc.rs // build-aux-docs -#![deny(intra_doc_link_resolution_failure)] +#![deny(broken_intra_doc_links)] extern crate my_rand; diff --git a/src/test/rustdoc/intra-doc-crate/auxiliary/additional_doc.rs b/src/test/rustdoc/intra-doc-crate/auxiliary/additional_doc.rs index 8b8793e75ed..849d2568733 100644 --- a/src/test/rustdoc/intra-doc-crate/auxiliary/additional_doc.rs +++ b/src/test/rustdoc/intra-doc-crate/auxiliary/additional_doc.rs @@ -1,5 +1,5 @@ #![crate_name = "my_rand"] -#![deny(intra_doc_link_resolution_failure)] +#![deny(broken_intra_doc_links)] pub trait RngCore {} /// Rng extends [`RngCore`]. diff --git a/src/test/rustdoc/intra-doc-crate/auxiliary/hidden.rs b/src/test/rustdoc/intra-doc-crate/auxiliary/hidden.rs index 23e38523a4f..b543ae764c0 100644 --- a/src/test/rustdoc/intra-doc-crate/auxiliary/hidden.rs +++ b/src/test/rustdoc/intra-doc-crate/auxiliary/hidden.rs @@ -1,5 +1,5 @@ #![crate_name = "hidden_dep"] -#![deny(intra_doc_link_resolution_failure)] +#![deny(broken_intra_doc_links)] #[doc(hidden)] pub mod __reexport { diff --git a/src/test/rustdoc/intra-doc-crate/auxiliary/intra-doc-basic.rs b/src/test/rustdoc/intra-doc-crate/auxiliary/intra-doc-basic.rs index 2ee5835a7df..5342baecbc4 100644 --- a/src/test/rustdoc/intra-doc-crate/auxiliary/intra-doc-basic.rs +++ b/src/test/rustdoc/intra-doc-crate/auxiliary/intra-doc-basic.rs @@ -1,5 +1,5 @@ #![crate_name = "a"] -#![deny(intra_doc_link_resolution_failure)] +#![deny(broken_intra_doc_links)] pub struct Foo; diff --git a/src/test/rustdoc/intra-doc-crate/auxiliary/macro_inner.rs b/src/test/rustdoc/intra-doc-crate/auxiliary/macro_inner.rs index abd41fec130..a94f9e5dcca 100644 --- a/src/test/rustdoc/intra-doc-crate/auxiliary/macro_inner.rs +++ b/src/test/rustdoc/intra-doc-crate/auxiliary/macro_inner.rs @@ -1,5 +1,5 @@ #![crate_name = "macro_inner"] -#![deny(intra_doc_link_resolution_failure)] +#![deny(broken_intra_doc_links)] pub struct Foo; diff --git a/src/test/rustdoc/intra-doc-crate/auxiliary/module.rs b/src/test/rustdoc/intra-doc-crate/auxiliary/module.rs index 5d63d7e37b6..b7e3913f108 100644 --- a/src/test/rustdoc/intra-doc-crate/auxiliary/module.rs +++ b/src/test/rustdoc/intra-doc-crate/auxiliary/module.rs @@ -1,5 +1,5 @@ #![crate_name = "module_inner"] -#![deny(intra_doc_link_resolution_failure)] +#![deny(broken_intra_doc_links)] /// [SomeType] links to [bar] pub struct SomeType; pub trait SomeTrait {} diff --git a/src/test/rustdoc/intra-doc-crate/auxiliary/submodule-inner.rs b/src/test/rustdoc/intra-doc-crate/auxiliary/submodule-inner.rs index 3a22d13e673..8ae0f6c16b3 100644 --- a/src/test/rustdoc/intra-doc-crate/auxiliary/submodule-inner.rs +++ b/src/test/rustdoc/intra-doc-crate/auxiliary/submodule-inner.rs @@ -1,5 +1,5 @@ #![crate_name = "a"] -#![deny(intra_doc_link_resolution_failure)] +#![deny(broken_intra_doc_links)] pub mod bar { pub struct Bar; diff --git a/src/test/rustdoc/intra-doc-crate/auxiliary/submodule-outer.rs b/src/test/rustdoc/intra-doc-crate/auxiliary/submodule-outer.rs index b8ca4e44e1f..d90c529e385 100644 --- a/src/test/rustdoc/intra-doc-crate/auxiliary/submodule-outer.rs +++ b/src/test/rustdoc/intra-doc-crate/auxiliary/submodule-outer.rs @@ -1,5 +1,5 @@ #![crate_name = "bar"] -#![deny(intra_doc_link_resolution_failure)] +#![deny(broken_intra_doc_links)] pub trait Foo { /// [`Bar`] [`Baz`] diff --git a/src/test/rustdoc/intra-doc-crate/basic.rs b/src/test/rustdoc/intra-doc-crate/basic.rs index a245a0f8453..6ab9140c3c3 100644 --- a/src/test/rustdoc/intra-doc-crate/basic.rs +++ b/src/test/rustdoc/intra-doc-crate/basic.rs @@ -1,6 +1,6 @@ // aux-build:intra-doc-basic.rs // build-aux-docs -#![deny(intra_doc_link_resolution_failure)] +#![deny(broken_intra_doc_links)] // from https://github.com/rust-lang/rust/issues/65983 extern crate a; diff --git a/src/test/rustdoc/intra-doc-crate/hidden.rs b/src/test/rustdoc/intra-doc-crate/hidden.rs index e3d2af16db1..9c9d4c64945 100644 --- a/src/test/rustdoc/intra-doc-crate/hidden.rs +++ b/src/test/rustdoc/intra-doc-crate/hidden.rs @@ -1,6 +1,6 @@ // aux-build:hidden.rs // build-aux-docs -#![deny(intra_doc_link_resolution_failure)] +#![deny(broken_intra_doc_links)] // tests https://github.com/rust-lang/rust/issues/73363 diff --git a/src/test/rustdoc/intra-doc-crate/macro.rs b/src/test/rustdoc/intra-doc-crate/macro.rs index 72fd57b6b0c..311b16dff13 100644 --- a/src/test/rustdoc/intra-doc-crate/macro.rs +++ b/src/test/rustdoc/intra-doc-crate/macro.rs @@ -2,7 +2,7 @@ // aux-build:macro_inner.rs // aux-build:proc_macro.rs // build-aux-docs -#![deny(intra_doc_link_resolution_failure)] +#![deny(broken_intra_doc_links)] extern crate macro_inner; extern crate proc_macro_inner; diff --git a/src/test/rustdoc/intra-doc-crate/module.rs b/src/test/rustdoc/intra-doc-crate/module.rs index 67fa7293f37..9039e344f7b 100644 --- a/src/test/rustdoc/intra-doc-crate/module.rs +++ b/src/test/rustdoc/intra-doc-crate/module.rs @@ -1,7 +1,7 @@ // outer.rs // aux-build: module.rs // build-aux-docs -#![deny(intra_doc_link_resolution_failure)] +#![deny(broken_intra_doc_links)] extern crate module_inner; // @has 'module/bar/index.html' '//a[@href="../../module_inner/trait.SomeTrait.html"]' 'SomeTrait' // @has 'module/bar/index.html' '//a[@href="../../module_inner/struct.SomeType.html"]' 'SomeType' diff --git a/src/test/rustdoc/intra-doc-crate/submodule-inner.rs b/src/test/rustdoc/intra-doc-crate/submodule-inner.rs index b4b615bf9ed..e1465816368 100644 --- a/src/test/rustdoc/intra-doc-crate/submodule-inner.rs +++ b/src/test/rustdoc/intra-doc-crate/submodule-inner.rs @@ -1,6 +1,6 @@ // aux-build:submodule-inner.rs // build-aux-docs -#![deny(intra_doc_link_resolution_failure)] +#![deny(broken_intra_doc_links)] extern crate a; diff --git a/src/test/rustdoc/intra-doc-crate/submodule-outer.rs b/src/test/rustdoc/intra-doc-crate/submodule-outer.rs index 6b30ef8b3de..45f561328f2 100644 --- a/src/test/rustdoc/intra-doc-crate/submodule-outer.rs +++ b/src/test/rustdoc/intra-doc-crate/submodule-outer.rs @@ -1,6 +1,6 @@ // aux-build:submodule-outer.rs // edition:2018 -#![deny(intra_doc_link_resolution_failure)] +#![deny(broken_intra_doc_links)] extern crate bar as bar_; diff --git a/src/test/rustdoc/intra-doc-crate/traits.rs b/src/test/rustdoc/intra-doc-crate/traits.rs index 61733123690..07f9fb63313 100644 --- a/src/test/rustdoc/intra-doc-crate/traits.rs +++ b/src/test/rustdoc/intra-doc-crate/traits.rs @@ -3,7 +3,7 @@ // aux-build:traits.rs // build-aux-docs // ignore-tidy-line-length -#![deny(intra_doc_link_resolution_failure)] +#![deny(broken_intra_doc_links)] extern crate inner; use inner::SomeTrait; diff --git a/src/test/rustdoc/intra-doc-link-mod-ambiguity.rs b/src/test/rustdoc/intra-doc-link-mod-ambiguity.rs index 65187f48539..bd733e10230 100644 --- a/src/test/rustdoc/intra-doc-link-mod-ambiguity.rs +++ b/src/test/rustdoc/intra-doc-link-mod-ambiguity.rs @@ -1,6 +1,6 @@ // ignore-tidy-linelength -#![deny(intra_doc_link_resolution_failure)] +#![deny(broken_intra_doc_links)] pub fn foo() { diff --git a/src/test/rustdoc/intra-link-extern-crate.rs b/src/test/rustdoc/intra-link-extern-crate.rs index bbe3edaea8c..193bca704bf 100644 --- a/src/test/rustdoc/intra-link-extern-crate.rs +++ b/src/test/rustdoc/intra-link-extern-crate.rs @@ -4,6 +4,6 @@ // though they would never actually get displayed. This tripped intra-doc-link resolution failures, // for items that aren't under our control, and not actually getting documented! -#![deny(intra_doc_link_resolution_failure)] +#![deny(broken_intra_doc_links)] extern crate inner; diff --git a/src/test/rustdoc/intra-link-in-bodies.rs b/src/test/rustdoc/intra-link-in-bodies.rs index 4c693907226..ec965a99dc2 100644 --- a/src/test/rustdoc/intra-link-in-bodies.rs +++ b/src/test/rustdoc/intra-link-in-bodies.rs @@ -1,6 +1,6 @@ // we need to make sure that intra-doc links on trait impls get resolved in the right scope -#![deny(intra_doc_link_resolution_failure)] +#![deny(broken_intra_doc_links)] pub mod inner { pub struct SomethingOutOfScope; diff --git a/src/test/rustdoc/intra-link-libstd-re-export.rs b/src/test/rustdoc/intra-link-libstd-re-export.rs index 6f239292ec2..d0af3aec660 100644 --- a/src/test/rustdoc/intra-link-libstd-re-export.rs +++ b/src/test/rustdoc/intra-link-libstd-re-export.rs @@ -1,3 +1,3 @@ -#![deny(intra_doc_link_resolution_failure)] +#![deny(broken_intra_doc_links)] pub use std::*; diff --git a/src/test/rustdoc/intra-link-prim-methods-external-core.rs b/src/test/rustdoc/intra-link-prim-methods-external-core.rs index e09d36594ed..c8ef4c01599 100644 --- a/src/test/rustdoc/intra-link-prim-methods-external-core.rs +++ b/src/test/rustdoc/intra-link-prim-methods-external-core.rs @@ -4,7 +4,7 @@ // ignore-windows // ignore-tidy-linelength -#![deny(intra_doc_link_resolution_failure)] +#![deny(broken_intra_doc_links)] #![feature(no_core, lang_items)] #![no_core] #![crate_type = "rlib"] diff --git a/src/test/rustdoc/intra-link-prim-methods-local.rs b/src/test/rustdoc/intra-link-prim-methods-local.rs index d24cd2cbb5e..d448acf7f96 100644 --- a/src/test/rustdoc/intra-link-prim-methods-local.rs +++ b/src/test/rustdoc/intra-link-prim-methods-local.rs @@ -1,4 +1,4 @@ -#![deny(intra_doc_link_resolution_failure)] +#![deny(broken_intra_doc_links)] #![feature(no_core, lang_items)] #![no_core] #![crate_type = "rlib"] diff --git a/src/test/rustdoc/intra-link-prim-methods.rs b/src/test/rustdoc/intra-link-prim-methods.rs index 76636b80b5e..94c80c996c1 100644 --- a/src/test/rustdoc/intra-link-prim-methods.rs +++ b/src/test/rustdoc/intra-link-prim-methods.rs @@ -1,4 +1,4 @@ -#![deny(intra_doc_link_resolution_failure)] +#![deny(broken_intra_doc_links)] // ignore-tidy-linelength diff --git a/src/test/rustdoc/intra-link-prim-precedence.rs b/src/test/rustdoc/intra-link-prim-precedence.rs index d7ebb73b3be..5f10c1ec4a7 100644 --- a/src/test/rustdoc/intra-link-prim-precedence.rs +++ b/src/test/rustdoc/intra-link-prim-precedence.rs @@ -1,5 +1,5 @@ // ignore-tidy-linelength -#![deny(intra_doc_link_resolution_failure)] +#![deny(broken_intra_doc_links)] pub mod char {} diff --git a/src/test/rustdoc/intra-link-private.rs b/src/test/rustdoc/intra-link-private.rs index c99b4d70684..cf8bc0b1586 100644 --- a/src/test/rustdoc/intra-link-private.rs +++ b/src/test/rustdoc/intra-link-private.rs @@ -2,7 +2,7 @@ // These failures were legitimate, but not truly relevant - the docs in question couldn't be // checked for accuracy anyway. -#![deny(intra_doc_link_resolution_failure)] +#![deny(broken_intra_doc_links)] /// ooh, i'm a [rebel] just for kicks struct SomeStruct; diff --git a/src/test/rustdoc/intra-link-proc-macro.rs b/src/test/rustdoc/intra-link-proc-macro.rs index 7b6ea5d60f8..7a8403255ed 100644 --- a/src/test/rustdoc/intra-link-proc-macro.rs +++ b/src/test/rustdoc/intra-link-proc-macro.rs @@ -1,6 +1,6 @@ // aux-build:intra-link-proc-macro-macro.rs // build-aux-docs -#![deny(intra_doc_link_resolution_failure)] +#![deny(broken_intra_doc_links)] extern crate intra_link_proc_macro_macro; diff --git a/src/test/rustdoc/intra-links-external-traits.rs b/src/test/rustdoc/intra-links-external-traits.rs index d6b4a8ad58a..de76f29476c 100644 --- a/src/test/rustdoc/intra-links-external-traits.rs +++ b/src/test/rustdoc/intra-links-external-traits.rs @@ -2,7 +2,7 @@ // ignore-cross-compile #![crate_name = "outer"] -#![deny(intra_doc_link_resolution_failure)] +#![deny(broken_intra_doc_links)] // using a trait that has intra-doc links on it from another crate (whether re-exporting or just // implementing it) used to give spurious resolution failure warnings diff --git a/src/test/rustdoc/lazy_normalization_consts/const-equate-pred.rs b/src/test/rustdoc/lazy_normalization_consts/const-equate-pred.rs new file mode 100644 index 00000000000..6cc02f78c62 --- /dev/null +++ b/src/test/rustdoc/lazy_normalization_consts/const-equate-pred.rs @@ -0,0 +1,18 @@ +#![crate_name = "foo"] +#![feature(lazy_normalization_consts)] +#![allow(incomplete_features)] + +// Checking if `Send` is implemented for `Hasher` requires us to evaluate a `ConstEquate` predicate, +// which previously caused an ICE. + +pub struct Hasher<T> { + cv_stack: T, +} + +unsafe impl<T: Default> Send for Hasher<T> {} + +// @has foo/struct.Foo.html +// @has - '//code' 'impl Send for Foo' +pub struct Foo { + hasher: Hasher<[u8; 3]>, +} diff --git a/src/test/rustdoc/through-proc-macro.rs b/src/test/rustdoc/through-proc-macro.rs index 348c9eea2dc..613410871f0 100644 --- a/src/test/rustdoc/through-proc-macro.rs +++ b/src/test/rustdoc/through-proc-macro.rs @@ -1,6 +1,6 @@ // aux-build:through-proc-macro-aux.rs // build-aux-docs -#![warn(intra_doc_link_resolution_failure)] +#![warn(broken_intra_doc_links)] extern crate some_macros; #[some_macros::second] diff --git a/src/test/ui/conditional-compilation/cfg-attr-multi-true.rs b/src/test/ui/conditional-compilation/cfg-attr-multi-true.rs index cd635c6a722..876d8b079a1 100644 --- a/src/test/ui/conditional-compilation/cfg-attr-multi-true.rs +++ b/src/test/ui/conditional-compilation/cfg-attr-multi-true.rs @@ -9,13 +9,13 @@ #[cfg_attr(all(), deprecated, must_use)] struct MustUseDeprecated {} -impl MustUseDeprecated { //~ warning: use of deprecated item - fn new() -> MustUseDeprecated { //~ warning: use of deprecated item - MustUseDeprecated {} //~ warning: use of deprecated item +impl MustUseDeprecated { //~ warning: use of deprecated + fn new() -> MustUseDeprecated { //~ warning: use of deprecated + MustUseDeprecated {} //~ warning: use of deprecated } } fn main() { - MustUseDeprecated::new(); //~ warning: use of deprecated item + MustUseDeprecated::new(); //~ warning: use of deprecated //~| warning: unused `MustUseDeprecated` that must be used } diff --git a/src/test/ui/conditional-compilation/cfg-attr-multi-true.stderr b/src/test/ui/conditional-compilation/cfg-attr-multi-true.stderr index d7b5d2d263a..21b3a6f1f33 100644 --- a/src/test/ui/conditional-compilation/cfg-attr-multi-true.stderr +++ b/src/test/ui/conditional-compilation/cfg-attr-multi-true.stderr @@ -1,4 +1,4 @@ -warning: use of deprecated item 'MustUseDeprecated' +warning: use of deprecated struct `MustUseDeprecated` --> $DIR/cfg-attr-multi-true.rs:12:6 | LL | impl MustUseDeprecated { @@ -6,19 +6,19 @@ LL | impl MustUseDeprecated { | = note: `#[warn(deprecated)]` on by default -warning: use of deprecated item 'MustUseDeprecated' +warning: use of deprecated struct `MustUseDeprecated` --> $DIR/cfg-attr-multi-true.rs:19:5 | LL | MustUseDeprecated::new(); | ^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'MustUseDeprecated' +warning: use of deprecated struct `MustUseDeprecated` --> $DIR/cfg-attr-multi-true.rs:13:17 | LL | fn new() -> MustUseDeprecated { | ^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'MustUseDeprecated' +warning: use of deprecated struct `MustUseDeprecated` --> $DIR/cfg-attr-multi-true.rs:14:9 | LL | MustUseDeprecated {} diff --git a/src/test/ui/const-generics/coerce_unsized_array.rs b/src/test/ui/const-generics/coerce_unsized_array.rs new file mode 100644 index 00000000000..b28768a5163 --- /dev/null +++ b/src/test/ui/const-generics/coerce_unsized_array.rs @@ -0,0 +1,11 @@ +// run-pass +#![feature(const_generics)] +#![allow(incomplete_features)] + +fn foo<const N: usize>(v: &[u8; N]) -> &[u8] { + v +} + +fn main() { + assert_eq!(foo(&[1, 2]), &[1, 2]); +} diff --git a/src/test/ui/const-generics/nested-type.rs b/src/test/ui/const-generics/nested-type.rs new file mode 100644 index 00000000000..12ea850c8f6 --- /dev/null +++ b/src/test/ui/const-generics/nested-type.rs @@ -0,0 +1,18 @@ +#![feature(const_generics)] +#![allow(incomplete_features)] + +struct Foo<const N: [u8; { +//~^ ERROR cycle detected +//~| ERROR cycle detected + struct Foo<const N: usize>; + + impl<const N: usize> Foo<N> { + fn value() -> usize { + N + } + } + + Foo::<17>::value() +}]>; + +fn main() {} diff --git a/src/test/ui/const-generics/nested-type.stderr b/src/test/ui/const-generics/nested-type.stderr new file mode 100644 index 00000000000..da0e8032404 --- /dev/null +++ b/src/test/ui/const-generics/nested-type.stderr @@ -0,0 +1,159 @@ +error[E0391]: cycle detected when computing type of `Foo` + --> $DIR/nested-type.rs:4:1 + | +LL | struct Foo<const N: [u8; { + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: ...which requires computing type of `Foo::N`... + --> $DIR/nested-type.rs:4:18 + | +LL | struct Foo<const N: [u8; { + | ^ +note: ...which requires const-evaluating + checking `Foo::{{constant}}#0`... + --> $DIR/nested-type.rs:4:26 + | +LL | struct Foo<const N: [u8; { + | __________________________^ +LL | | +LL | | +LL | | struct Foo<const N: usize>; +... | +LL | | Foo::<17>::value() +LL | | }]>; + | |_^ +note: ...which requires const-evaluating + checking `Foo::{{constant}}#0`... + --> $DIR/nested-type.rs:4:26 + | +LL | struct Foo<const N: [u8; { + | __________________________^ +LL | | +LL | | +LL | | struct Foo<const N: usize>; +... | +LL | | Foo::<17>::value() +LL | | }]>; + | |_^ +note: ...which requires const-evaluating `Foo::{{constant}}#0`... + --> $DIR/nested-type.rs:4:26 + | +LL | struct Foo<const N: [u8; { + | __________________________^ +LL | | +LL | | +LL | | struct Foo<const N: usize>; +... | +LL | | Foo::<17>::value() +LL | | }]>; + | |_^ +note: ...which requires type-checking `Foo::{{constant}}#0`... + --> $DIR/nested-type.rs:4:26 + | +LL | struct Foo<const N: [u8; { + | __________________________^ +LL | | +LL | | +LL | | struct Foo<const N: usize>; +... | +LL | | Foo::<17>::value() +LL | | }]>; + | |_^ +note: ...which requires computing the variances of `Foo::{{constant}}#0::Foo`... + --> $DIR/nested-type.rs:7:5 + | +LL | struct Foo<const N: usize>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: ...which requires computing the variances for items in this crate... + = note: ...which again requires computing type of `Foo`, completing the cycle +note: cycle used when collecting item types in top-level module + --> $DIR/nested-type.rs:1:1 + | +LL | / #![feature(const_generics)] +LL | | #![allow(incomplete_features)] +LL | | +LL | | struct Foo<const N: [u8; { +... | +LL | | +LL | | fn main() {} + | |____________^ + +error[E0391]: cycle detected when computing type of `Foo` + --> $DIR/nested-type.rs:4:1 + | +LL | struct Foo<const N: [u8; { + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: ...which requires computing type of `Foo::N`... + --> $DIR/nested-type.rs:4:18 + | +LL | struct Foo<const N: [u8; { + | ^ +note: ...which requires const-evaluating + checking `Foo::{{constant}}#0`... + --> $DIR/nested-type.rs:4:26 + | +LL | struct Foo<const N: [u8; { + | __________________________^ +LL | | +LL | | +LL | | struct Foo<const N: usize>; +... | +LL | | Foo::<17>::value() +LL | | }]>; + | |_^ +note: ...which requires const-evaluating + checking `Foo::{{constant}}#0`... + --> $DIR/nested-type.rs:4:26 + | +LL | struct Foo<const N: [u8; { + | __________________________^ +LL | | +LL | | +LL | | struct Foo<const N: usize>; +... | +LL | | Foo::<17>::value() +LL | | }]>; + | |_^ +note: ...which requires const-evaluating `Foo::{{constant}}#0`... + --> $DIR/nested-type.rs:4:26 + | +LL | struct Foo<const N: [u8; { + | __________________________^ +LL | | +LL | | +LL | | struct Foo<const N: usize>; +... | +LL | | Foo::<17>::value() +LL | | }]>; + | |_^ +note: ...which requires type-checking `Foo::{{constant}}#0`... + --> $DIR/nested-type.rs:4:26 + | +LL | struct Foo<const N: [u8; { + | __________________________^ +LL | | +LL | | +LL | | struct Foo<const N: usize>; +... | +LL | | Foo::<17>::value() +LL | | }]>; + | |_^ +note: ...which requires computing the variances of `Foo::{{constant}}#0::Foo`... + --> $DIR/nested-type.rs:7:5 + | +LL | struct Foo<const N: usize>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: ...which requires computing the variances for items in this crate... + = note: ...which again requires computing type of `Foo`, completing the cycle +note: cycle used when collecting item types in top-level module + --> $DIR/nested-type.rs:1:1 + | +LL | / #![feature(const_generics)] +LL | | #![allow(incomplete_features)] +LL | | +LL | | struct Foo<const N: [u8; { +... | +LL | | +LL | | fn main() {} + | |____________^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0391`. diff --git a/src/test/ui/consts/const-size_of_val-align_of_val-extern-type.rs b/src/test/ui/consts/const-size_of_val-align_of_val-extern-type.rs new file mode 100644 index 00000000000..96a8a8452ed --- /dev/null +++ b/src/test/ui/consts/const-size_of_val-align_of_val-extern-type.rs @@ -0,0 +1,14 @@ +#![feature(extern_types)] +#![feature(core_intrinsics)] +#![feature(const_size_of_val, const_align_of_val)] + +use std::intrinsics::{size_of_val, min_align_of_val}; + +extern { + type Opaque; +} + +const _SIZE: usize = unsafe { size_of_val(&4 as *const i32 as *const Opaque) }; //~ ERROR +const _ALIGN: usize = unsafe { min_align_of_val(&4 as *const i32 as *const Opaque) }; //~ ERROR + +fn main() {} diff --git a/src/test/ui/consts/const-size_of_val-align_of_val-extern-type.stderr b/src/test/ui/consts/const-size_of_val-align_of_val-extern-type.stderr new file mode 100644 index 00000000000..d3f1b04d251 --- /dev/null +++ b/src/test/ui/consts/const-size_of_val-align_of_val-extern-type.stderr @@ -0,0 +1,20 @@ +error: any use of this value will cause an error + --> $DIR/const-size_of_val-align_of_val-extern-type.rs:11:31 + | +LL | const _SIZE: usize = unsafe { size_of_val(&4 as *const i32 as *const Opaque) }; + | ------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- + | | + | `extern type` does not have known layout + | + = note: `#[deny(const_err)]` on by default + +error: any use of this value will cause an error + --> $DIR/const-size_of_val-align_of_val-extern-type.rs:12:32 + | +LL | const _ALIGN: usize = unsafe { min_align_of_val(&4 as *const i32 as *const Opaque) }; + | -------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- + | | + | `extern type` does not have known layout + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/consts/const-size_of_val-align_of_val.rs b/src/test/ui/consts/const-size_of_val-align_of_val.rs new file mode 100644 index 00000000000..e8e6f1d3900 --- /dev/null +++ b/src/test/ui/consts/const-size_of_val-align_of_val.rs @@ -0,0 +1,45 @@ +// run-pass + +#![feature(const_size_of_val, const_align_of_val)] + +use std::mem; + +struct Foo(u32); + +#[derive(Clone, Copy)] +struct Bar { + _x: u8, + _y: u16, + _z: u8, +} + +union Ugh { + _a: [u8; 3], + _b: Bar, +} + +const FOO: Foo = Foo(4); +const BAR: Bar = Bar { _x: 4, _y: 1, _z: 2 }; +const UGH: Ugh = Ugh { _a: [0; 3] }; + +const SIZE_OF_FOO: usize = mem::size_of_val(&FOO); +const SIZE_OF_BAR: usize = mem::size_of_val(&BAR); +const SIZE_OF_UGH: usize = mem::size_of_val(&UGH); + +const ALIGN_OF_FOO: usize = mem::align_of_val(&FOO); +const ALIGN_OF_BAR: usize = mem::align_of_val(&BAR); +const ALIGN_OF_UGH: usize = mem::align_of_val(&UGH); + +const SIZE_OF_SLICE: usize = mem::size_of_val("foobar".as_bytes()); + +fn main() { + assert_eq!(SIZE_OF_FOO, mem::size_of::<Foo>()); + assert_eq!(SIZE_OF_BAR, mem::size_of::<Bar>()); + assert_eq!(SIZE_OF_UGH, mem::size_of::<Ugh>()); + + assert_eq!(ALIGN_OF_FOO, mem::align_of::<Foo>()); + assert_eq!(ALIGN_OF_BAR, mem::align_of::<Bar>()); + assert_eq!(ALIGN_OF_UGH, mem::align_of::<Ugh>()); + + assert_eq!(SIZE_OF_SLICE, "foobar".len()); +} diff --git a/src/test/ui/consts/const-typeid-of-rpass.rs b/src/test/ui/consts/const-typeid-of-rpass.rs index 225acb60ac4..c49141050b2 100644 --- a/src/test/ui/consts/const-typeid-of-rpass.rs +++ b/src/test/ui/consts/const-typeid-of-rpass.rs @@ -1,6 +1,5 @@ // run-pass #![feature(core_intrinsics)] -#![feature(const_type_id)] use std::any::TypeId; diff --git a/src/test/ui/consts/const-typeid-of.rs b/src/test/ui/consts/const-typeid-of.rs deleted file mode 100644 index 3829c481da8..00000000000 --- a/src/test/ui/consts/const-typeid-of.rs +++ /dev/null @@ -1,8 +0,0 @@ -use std::any::TypeId; - -struct A; - -fn main() { - const A_ID: TypeId = TypeId::of::<A>(); - //~^ ERROR `std::any::TypeId::of` is not yet stable as a const fn -} diff --git a/src/test/ui/consts/const-typeid-of.stderr b/src/test/ui/consts/const-typeid-of.stderr deleted file mode 100644 index 05347fbc819..00000000000 --- a/src/test/ui/consts/const-typeid-of.stderr +++ /dev/null @@ -1,10 +0,0 @@ -error: `std::any::TypeId::of` is not yet stable as a const fn - --> $DIR/const-typeid-of.rs:6:26 - | -LL | const A_ID: TypeId = TypeId::of::<A>(); - | ^^^^^^^^^^^^^^^^^ - | - = help: add `#![feature(const_type_id)]` to the crate attributes to enable - -error: aborting due to previous error - diff --git a/src/test/ui/consts/const-unwrap.rs b/src/test/ui/consts/const-unwrap.rs new file mode 100644 index 00000000000..6ed60ed87bf --- /dev/null +++ b/src/test/ui/consts/const-unwrap.rs @@ -0,0 +1,14 @@ +// check-fail + +#![feature(const_option)] + +const FOO: i32 = Some(42i32).unwrap(); + +// This causes an error, but it is attributed to the `panic` *inside* `Option::unwrap` (maybe due +// to `track_caller`?). A note points to the originating `const`. +const BAR: i32 = Option::<i32>::None.unwrap(); //~ NOTE + +fn main() { + println!("{}", FOO); + println!("{}", BAR); +} diff --git a/src/test/ui/consts/const-unwrap.stderr b/src/test/ui/consts/const-unwrap.stderr new file mode 100644 index 00000000000..7f2c1f41510 --- /dev/null +++ b/src/test/ui/consts/const-unwrap.stderr @@ -0,0 +1,20 @@ +error: any use of this value will cause an error + --> $SRC_DIR/core/src/option.rs:LL:COL + | +LL | None => panic!("called `Option::unwrap()` on a `None` value"), + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | the evaluated program panicked at 'called `Option::unwrap()` on a `None` value', $DIR/const-unwrap.rs:9:38 + | inside `std::option::Option::<i32>::unwrap` at $SRC_DIR/core/src/macros/mod.rs:LL:COL + | inside `BAR` at $DIR/const-unwrap.rs:9:18 + | + ::: $DIR/const-unwrap.rs:9:1 + | +LL | const BAR: i32 = Option::<i32>::None.unwrap(); + | ---------------------------------------------- + | + = note: `#[deny(const_err)]` on by default + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to previous error + diff --git a/src/test/ui/consts/const_constructor/const-construct-call.rs b/src/test/ui/consts/const_constructor/const-construct-call.rs index d883d3fa6e4..d3e6cf78bc9 100644 --- a/src/test/ui/consts/const_constructor/const-construct-call.rs +++ b/src/test/ui/consts/const_constructor/const-construct-call.rs @@ -6,7 +6,7 @@ #![cfg_attr(const_fn, feature(const_fn))] -// Ctor(..) is transformed to Ctor { 0: ... } in HAIR lowering, so directly +// Ctor(..) is transformed to Ctor { 0: ... } in THIR lowering, so directly // calling constructors doesn't require them to be const. type ExternalType = std::panic::AssertUnwindSafe<(Option<i32>, Result<i32, bool>)>; diff --git a/src/test/ui/consts/const_in_pattern/warn_corner_cases.rs b/src/test/ui/consts/const_in_pattern/warn_corner_cases.rs index c6b794de195..51e1af359cd 100644 --- a/src/test/ui/consts/const_in_pattern/warn_corner_cases.rs +++ b/src/test/ui/consts/const_in_pattern/warn_corner_cases.rs @@ -10,7 +10,7 @@ // const-evaluator computes a value that *does* meet the conditions for // structural-match, but the const expression itself has abstractions (like // calls to const functions) that may fit better with a type-based analysis -// rather than a committment to a specific value. +// rather than a commitment to a specific value. #![warn(indirect_structural_match)] diff --git a/src/test/ui/consts/issue-73976-monomorphic.rs b/src/test/ui/consts/issue-73976-monomorphic.rs index 7706a97f23b..1db0fdc87c3 100644 --- a/src/test/ui/consts/issue-73976-monomorphic.rs +++ b/src/test/ui/consts/issue-73976-monomorphic.rs @@ -5,7 +5,6 @@ // will be properly rejected. This test will ensure that monomorphic use of these // would not be wrongly rejected in patterns. -#![feature(const_type_id)] #![feature(const_type_name)] use std::any::{self, TypeId}; diff --git a/src/test/ui/consts/issue-73976-polymorphic.rs b/src/test/ui/consts/issue-73976-polymorphic.rs index 28b84518719..b3d8610ff51 100644 --- a/src/test/ui/consts/issue-73976-polymorphic.rs +++ b/src/test/ui/consts/issue-73976-polymorphic.rs @@ -1,11 +1,10 @@ // This test is from #73976. We previously did not check if a type is monomorphized -// before calculating its type id, which leads to the bizzare behaviour below that +// before calculating its type id, which leads to the bizarre behaviour below that // TypeId of a generic type does not match itself. // // This test case should either run-pass or be rejected at compile time. // Currently we just disallow this usage and require pattern is monomorphic. -#![feature(const_type_id)] #![feature(const_type_name)] use std::any::{self, TypeId}; @@ -18,8 +17,8 @@ impl<T: 'static> GetTypeId<T> { const fn check_type_id<T: 'static>() -> bool { matches!(GetTypeId::<T>::VALUE, GetTypeId::<T>::VALUE) - //~^ ERROR could not evaluate constant pattern - //~| ERROR could not evaluate constant pattern + //~^ ERROR constant pattern depends on a generic parameter + //~| ERROR constant pattern depends on a generic parameter } pub struct GetTypeNameLen<T>(T); @@ -30,8 +29,8 @@ impl<T: 'static> GetTypeNameLen<T> { const fn check_type_name_len<T: 'static>() -> bool { matches!(GetTypeNameLen::<T>::VALUE, GetTypeNameLen::<T>::VALUE) - //~^ ERROR could not evaluate constant pattern - //~| ERROR could not evaluate constant pattern + //~^ ERROR constant pattern depends on a generic parameter + //~| ERROR constant pattern depends on a generic parameter } fn main() { diff --git a/src/test/ui/consts/issue-73976-polymorphic.stderr b/src/test/ui/consts/issue-73976-polymorphic.stderr index c90ce2bd06a..250f1536d85 100644 --- a/src/test/ui/consts/issue-73976-polymorphic.stderr +++ b/src/test/ui/consts/issue-73976-polymorphic.stderr @@ -1,23 +1,23 @@ -error: could not evaluate constant pattern - --> $DIR/issue-73976-polymorphic.rs:20:37 +error: constant pattern depends on a generic parameter + --> $DIR/issue-73976-polymorphic.rs:19:37 | LL | matches!(GetTypeId::<T>::VALUE, GetTypeId::<T>::VALUE) | ^^^^^^^^^^^^^^^^^^^^^ -error: could not evaluate constant pattern - --> $DIR/issue-73976-polymorphic.rs:32:42 +error: constant pattern depends on a generic parameter + --> $DIR/issue-73976-polymorphic.rs:31:42 | LL | matches!(GetTypeNameLen::<T>::VALUE, GetTypeNameLen::<T>::VALUE) | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: could not evaluate constant pattern - --> $DIR/issue-73976-polymorphic.rs:20:37 +error: constant pattern depends on a generic parameter + --> $DIR/issue-73976-polymorphic.rs:19:37 | LL | matches!(GetTypeId::<T>::VALUE, GetTypeId::<T>::VALUE) | ^^^^^^^^^^^^^^^^^^^^^ -error: could not evaluate constant pattern - --> $DIR/issue-73976-polymorphic.rs:32:42 +error: constant pattern depends on a generic parameter + --> $DIR/issue-73976-polymorphic.rs:31:42 | LL | matches!(GetTypeNameLen::<T>::VALUE, GetTypeNameLen::<T>::VALUE) | ^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/deprecation/atomic_initializers.fixed b/src/test/ui/deprecation/atomic_initializers.fixed index d8485ed7da1..4fb0aeeb573 100644 --- a/src/test/ui/deprecation/atomic_initializers.fixed +++ b/src/test/ui/deprecation/atomic_initializers.fixed @@ -6,6 +6,6 @@ use std::sync::atomic::{AtomicIsize, ATOMIC_ISIZE_INIT}; #[allow(dead_code)] static FOO: AtomicIsize = AtomicIsize::new(0); -//~^ WARN use of deprecated item +//~^ WARN use of deprecated constant fn main() {} diff --git a/src/test/ui/deprecation/atomic_initializers.rs b/src/test/ui/deprecation/atomic_initializers.rs index b15a1bbfd92..1dcfd36d7d5 100644 --- a/src/test/ui/deprecation/atomic_initializers.rs +++ b/src/test/ui/deprecation/atomic_initializers.rs @@ -6,6 +6,6 @@ use std::sync::atomic::{AtomicIsize, ATOMIC_ISIZE_INIT}; #[allow(dead_code)] static FOO: AtomicIsize = ATOMIC_ISIZE_INIT; -//~^ WARN use of deprecated item +//~^ WARN use of deprecated constant fn main() {} diff --git a/src/test/ui/deprecation/atomic_initializers.stderr b/src/test/ui/deprecation/atomic_initializers.stderr index 75baf4a1bf9..eaf5c61b440 100644 --- a/src/test/ui/deprecation/atomic_initializers.stderr +++ b/src/test/ui/deprecation/atomic_initializers.stderr @@ -1,8 +1,8 @@ -warning: use of deprecated item 'std::sync::atomic::ATOMIC_ISIZE_INIT': the `new` function is now preferred +warning: use of deprecated constant `std::sync::atomic::ATOMIC_ISIZE_INIT`: the `new` function is now preferred --> $DIR/atomic_initializers.rs:8:27 | LL | static FOO: AtomicIsize = ATOMIC_ISIZE_INIT; - | ^^^^^^^^^^^^^^^^^ help: replace the use of the deprecated item: `AtomicIsize::new(0)` + | ^^^^^^^^^^^^^^^^^ help: replace the use of the deprecated constant: `AtomicIsize::new(0)` | = note: `#[warn(deprecated)]` on by default diff --git a/src/test/ui/deprecation/deprecation-in-future.rs b/src/test/ui/deprecation/deprecation-in-future.rs index bfeab49548f..53826183d06 100644 --- a/src/test/ui/deprecation/deprecation-in-future.rs +++ b/src/test/ui/deprecation/deprecation-in-future.rs @@ -7,7 +7,7 @@ pub fn deprecated_future() {} fn test() { deprecated_future(); // ok; deprecated_in_future only applies to rustc_deprecated - //~^ WARNING use of deprecated item 'deprecated_future': text [deprecated] + //~^ WARNING use of deprecated function `deprecated_future`: text [deprecated] } fn main() {} diff --git a/src/test/ui/deprecation/deprecation-in-future.stderr b/src/test/ui/deprecation/deprecation-in-future.stderr index 3040dcd9939..6561ec74349 100644 --- a/src/test/ui/deprecation/deprecation-in-future.stderr +++ b/src/test/ui/deprecation/deprecation-in-future.stderr @@ -1,4 +1,4 @@ -warning: use of deprecated item 'deprecated_future': text +warning: use of deprecated function `deprecated_future`: text --> $DIR/deprecation-in-future.rs:9:5 | LL | deprecated_future(); // ok; deprecated_in_future only applies to rustc_deprecated diff --git a/src/test/ui/deprecation/deprecation-lint-2.rs b/src/test/ui/deprecation/deprecation-lint-2.rs index 2aa0d0c64d2..16ed6d4ecd6 100644 --- a/src/test/ui/deprecation/deprecation-lint-2.rs +++ b/src/test/ui/deprecation/deprecation-lint-2.rs @@ -1,5 +1,5 @@ // aux-build:deprecation-lint.rs -// error-pattern: use of deprecated item +// error-pattern: use of deprecated function #![deny(deprecated)] diff --git a/src/test/ui/deprecation/deprecation-lint-2.stderr b/src/test/ui/deprecation/deprecation-lint-2.stderr index 65152a2f9ab..b81d4bf402a 100644 --- a/src/test/ui/deprecation/deprecation-lint-2.stderr +++ b/src/test/ui/deprecation/deprecation-lint-2.stderr @@ -1,4 +1,4 @@ -error: use of deprecated item 'deprecation_lint::deprecated': text +error: use of deprecated function `deprecation_lint::deprecated`: text --> $DIR/deprecation-lint-2.rs:12:5 | LL | macro_test!(); diff --git a/src/test/ui/deprecation/deprecation-lint-3.rs b/src/test/ui/deprecation/deprecation-lint-3.rs index ae2dd7aac81..e6e1587daeb 100644 --- a/src/test/ui/deprecation/deprecation-lint-3.rs +++ b/src/test/ui/deprecation/deprecation-lint-3.rs @@ -1,5 +1,5 @@ // aux-build:deprecation-lint.rs -// error-pattern: use of deprecated item +// error-pattern: use of deprecated function #![deny(deprecated)] #![allow(warnings)] diff --git a/src/test/ui/deprecation/deprecation-lint-3.stderr b/src/test/ui/deprecation/deprecation-lint-3.stderr index b450f74d7f3..6f7cd9be2dd 100644 --- a/src/test/ui/deprecation/deprecation-lint-3.stderr +++ b/src/test/ui/deprecation/deprecation-lint-3.stderr @@ -1,4 +1,4 @@ -error: use of deprecated item 'deprecation_lint::deprecated_text': text +error: use of deprecated function `deprecation_lint::deprecated_text`: text --> $DIR/deprecation-lint-3.rs:13:5 | LL | macro_test_arg_nested!(deprecated_text); diff --git a/src/test/ui/deprecation/deprecation-lint-nested.rs b/src/test/ui/deprecation/deprecation-lint-nested.rs index ee6f0a22363..589522cdbdf 100644 --- a/src/test/ui/deprecation/deprecation-lint-nested.rs +++ b/src/test/ui/deprecation/deprecation-lint-nested.rs @@ -52,19 +52,19 @@ mod loud { #[deprecated] const DEPRECATED_CONST: u8 = 1; - struct Foo(DeprecatedType); //~ ERROR use of deprecated item + struct Foo(DeprecatedType); //~ ERROR use of deprecated type alias - impl DeprecatedTrait for Foo {} //~ ERROR use of deprecated item + impl DeprecatedTrait for Foo {} //~ ERROR use of deprecated trait impl Foo { - fn bar<T: DeprecatedTrait>() { //~ ERROR use of deprecated item - deprecated_fn(); //~ ERROR use of deprecated item + fn bar<T: DeprecatedTrait>() { //~ ERROR use of deprecated trait + deprecated_fn(); //~ ERROR use of deprecated function } } fn foo() -> u8 { - DEPRECATED_STATIC + //~ ERROR use of deprecated item - DEPRECATED_CONST //~ ERROR use of deprecated item + DEPRECATED_STATIC + //~ ERROR use of deprecated static + DEPRECATED_CONST //~ ERROR use of deprecated const } } diff --git a/src/test/ui/deprecation/deprecation-lint-nested.stderr b/src/test/ui/deprecation/deprecation-lint-nested.stderr index b71f90014fe..47607b8cc7c 100644 --- a/src/test/ui/deprecation/deprecation-lint-nested.stderr +++ b/src/test/ui/deprecation/deprecation-lint-nested.stderr @@ -1,4 +1,4 @@ -error: use of deprecated item 'loud::DeprecatedType' +error: use of deprecated type alias `loud::DeprecatedType` --> $DIR/deprecation-lint-nested.rs:55:16 | LL | struct Foo(DeprecatedType); @@ -10,31 +10,31 @@ note: the lint level is defined here LL | #![deny(deprecated)] | ^^^^^^^^^^ -error: use of deprecated item 'loud::DeprecatedTrait' +error: use of deprecated trait `loud::DeprecatedTrait` --> $DIR/deprecation-lint-nested.rs:57:10 | LL | impl DeprecatedTrait for Foo {} | ^^^^^^^^^^^^^^^ -error: use of deprecated item 'loud::DEPRECATED_STATIC' +error: use of deprecated static `loud::DEPRECATED_STATIC` --> $DIR/deprecation-lint-nested.rs:66:9 | LL | DEPRECATED_STATIC + | ^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'loud::DEPRECATED_CONST' +error: use of deprecated constant `loud::DEPRECATED_CONST` --> $DIR/deprecation-lint-nested.rs:67:9 | LL | DEPRECATED_CONST | ^^^^^^^^^^^^^^^^ -error: use of deprecated item 'loud::DeprecatedTrait' +error: use of deprecated trait `loud::DeprecatedTrait` --> $DIR/deprecation-lint-nested.rs:60:19 | LL | fn bar<T: DeprecatedTrait>() { | ^^^^^^^^^^^^^^^ -error: use of deprecated item 'loud::deprecated_fn' +error: use of deprecated function `loud::deprecated_fn` --> $DIR/deprecation-lint-nested.rs:61:13 | LL | deprecated_fn(); diff --git a/src/test/ui/deprecation/deprecation-lint.rs b/src/test/ui/deprecation/deprecation-lint.rs index 26271395005..1932344fc57 100644 --- a/src/test/ui/deprecation/deprecation-lint.rs +++ b/src/test/ui/deprecation/deprecation-lint.rs @@ -14,86 +14,86 @@ mod cross_crate { type Foo = MethodTester; let foo = MethodTester; - deprecated(); //~ ERROR use of deprecated item 'deprecation_lint::deprecated' - foo.method_deprecated(); //~ ERROR use of deprecated item 'deprecation_lint::MethodTester::method_deprecated' - Foo::method_deprecated(&foo); //~ ERROR use of deprecated item 'deprecation_lint::MethodTester::method_deprecated' - <Foo>::method_deprecated(&foo); //~ ERROR use of deprecated item 'deprecation_lint::MethodTester::method_deprecated' - foo.trait_deprecated(); //~ ERROR use of deprecated item 'deprecation_lint::Trait::trait_deprecated' - Trait::trait_deprecated(&foo); //~ ERROR use of deprecated item 'deprecation_lint::Trait::trait_deprecated' - <Foo>::trait_deprecated(&foo); //~ ERROR use of deprecated item 'deprecation_lint::Trait::trait_deprecated' - <Foo as Trait>::trait_deprecated(&foo); //~ ERROR use of deprecated item 'deprecation_lint::Trait::trait_deprecated' - - deprecated_text(); //~ ERROR use of deprecated item 'deprecation_lint::deprecated_text': text - foo.method_deprecated_text(); //~ ERROR use of deprecated item 'deprecation_lint::MethodTester::method_deprecated_text': text - Foo::method_deprecated_text(&foo); //~ ERROR use of deprecated item 'deprecation_lint::MethodTester::method_deprecated_text': text - <Foo>::method_deprecated_text(&foo); //~ ERROR use of deprecated item 'deprecation_lint::MethodTester::method_deprecated_text': text - foo.trait_deprecated_text(); //~ ERROR use of deprecated item 'deprecation_lint::Trait::trait_deprecated_text': text - Trait::trait_deprecated_text(&foo); //~ ERROR use of deprecated item 'deprecation_lint::Trait::trait_deprecated_text': text - <Foo>::trait_deprecated_text(&foo); //~ ERROR use of deprecated item 'deprecation_lint::Trait::trait_deprecated_text': text - <Foo as Trait>::trait_deprecated_text(&foo); //~ ERROR use of deprecated item 'deprecation_lint::Trait::trait_deprecated_text': text - - let _ = DeprecatedStruct { //~ ERROR use of deprecated item 'deprecation_lint::DeprecatedStruct': text - i: 0 //~ ERROR use of deprecated item 'deprecation_lint::DeprecatedStruct::i': text + deprecated(); //~ ERROR use of deprecated function `deprecation_lint::deprecated` + foo.method_deprecated(); //~ ERROR use of deprecated associated function `deprecation_lint::MethodTester::method_deprecated` + Foo::method_deprecated(&foo); //~ ERROR use of deprecated associated function `deprecation_lint::MethodTester::method_deprecated` + <Foo>::method_deprecated(&foo); //~ ERROR use of deprecated associated function `deprecation_lint::MethodTester::method_deprecated` + foo.trait_deprecated(); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated` + Trait::trait_deprecated(&foo); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated` + <Foo>::trait_deprecated(&foo); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated` + <Foo as Trait>::trait_deprecated(&foo); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated` + + deprecated_text(); //~ ERROR use of deprecated function `deprecation_lint::deprecated_text`: text + foo.method_deprecated_text(); //~ ERROR use of deprecated associated function `deprecation_lint::MethodTester::method_deprecated_text`: text + Foo::method_deprecated_text(&foo); //~ ERROR use of deprecated associated function `deprecation_lint::MethodTester::method_deprecated_text`: text + <Foo>::method_deprecated_text(&foo); //~ ERROR use of deprecated associated function `deprecation_lint::MethodTester::method_deprecated_text`: text + foo.trait_deprecated_text(); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text + Trait::trait_deprecated_text(&foo); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text + <Foo>::trait_deprecated_text(&foo); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text + <Foo as Trait>::trait_deprecated_text(&foo); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text + + let _ = DeprecatedStruct { //~ ERROR use of deprecated struct `deprecation_lint::DeprecatedStruct`: text + i: 0 //~ ERROR use of deprecated field `deprecation_lint::DeprecatedStruct::i`: text }; - let _ = DeprecatedUnitStruct; //~ ERROR use of deprecated item 'deprecation_lint::DeprecatedUnitStruct': text + let _ = DeprecatedUnitStruct; //~ ERROR use of deprecated struct `deprecation_lint::DeprecatedUnitStruct`: text - let _ = Enum::DeprecatedVariant; //~ ERROR use of deprecated item 'deprecation_lint::Enum::DeprecatedVariant': text + let _ = Enum::DeprecatedVariant; //~ ERROR use of deprecated variant `deprecation_lint::Enum::DeprecatedVariant`: text - let _ = DeprecatedTupleStruct (1); //~ ERROR use of deprecated item 'deprecation_lint::DeprecatedTupleStruct': text + let _ = DeprecatedTupleStruct (1); //~ ERROR use of deprecated struct `deprecation_lint::DeprecatedTupleStruct`: text - let _ = nested::DeprecatedStruct { //~ ERROR use of deprecated item 'deprecation_lint::nested::DeprecatedStruct': text - i: 0 //~ ERROR use of deprecated item 'deprecation_lint::nested::DeprecatedStruct::i': text + let _ = nested::DeprecatedStruct { //~ ERROR use of deprecated struct `deprecation_lint::nested::DeprecatedStruct`: text + i: 0 //~ ERROR use of deprecated field `deprecation_lint::nested::DeprecatedStruct::i`: text }; - let _ = nested::DeprecatedUnitStruct; //~ ERROR use of deprecated item 'deprecation_lint::nested::DeprecatedUnitStruct': text + let _ = nested::DeprecatedUnitStruct; //~ ERROR use of deprecated struct `deprecation_lint::nested::DeprecatedUnitStruct`: text - let _ = nested::Enum::DeprecatedVariant; //~ ERROR use of deprecated item 'deprecation_lint::nested::Enum::DeprecatedVariant': text + let _ = nested::Enum::DeprecatedVariant; //~ ERROR use of deprecated variant `deprecation_lint::nested::Enum::DeprecatedVariant`: text - let _ = nested::DeprecatedTupleStruct (1); //~ ERROR use of deprecated item 'deprecation_lint::nested::DeprecatedTupleStruct': text + let _ = nested::DeprecatedTupleStruct (1); //~ ERROR use of deprecated struct `deprecation_lint::nested::DeprecatedTupleStruct`: text // At the moment, the lint checker only checks stability in // in the arguments of macros. // Eventually, we will want to lint the contents of the // macro in the module *defining* it. Also, stability levels // on macros themselves are not yet linted. - macro_test_arg!(deprecated_text()); //~ ERROR use of deprecated item 'deprecation_lint::deprecated_text': text - macro_test_arg!(macro_test_arg!(deprecated_text())); //~ ERROR use of deprecated item 'deprecation_lint::deprecated_text': text + macro_test_arg!(deprecated_text()); //~ ERROR use of deprecated function `deprecation_lint::deprecated_text`: text + macro_test_arg!(macro_test_arg!(deprecated_text())); //~ ERROR use of deprecated function `deprecation_lint::deprecated_text`: text } fn test_method_param<Foo: Trait>(foo: Foo) { - foo.trait_deprecated(); //~ ERROR use of deprecated item 'deprecation_lint::Trait::trait_deprecated' - Trait::trait_deprecated(&foo); //~ ERROR use of deprecated item 'deprecation_lint::Trait::trait_deprecated' - <Foo>::trait_deprecated(&foo); //~ ERROR use of deprecated item 'deprecation_lint::Trait::trait_deprecated' - <Foo as Trait>::trait_deprecated(&foo); //~ ERROR use of deprecated item 'deprecation_lint::Trait::trait_deprecated' - foo.trait_deprecated_text(); //~ ERROR use of deprecated item 'deprecation_lint::Trait::trait_deprecated_text': text - Trait::trait_deprecated_text(&foo); //~ ERROR use of deprecated item 'deprecation_lint::Trait::trait_deprecated_text': text - <Foo>::trait_deprecated_text(&foo); //~ ERROR use of deprecated item 'deprecation_lint::Trait::trait_deprecated_text': text - <Foo as Trait>::trait_deprecated_text(&foo); //~ ERROR use of deprecated item 'deprecation_lint::Trait::trait_deprecated_text': text + foo.trait_deprecated(); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated` + Trait::trait_deprecated(&foo); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated` + <Foo>::trait_deprecated(&foo); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated` + <Foo as Trait>::trait_deprecated(&foo); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated` + foo.trait_deprecated_text(); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text + Trait::trait_deprecated_text(&foo); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text + <Foo>::trait_deprecated_text(&foo); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text + <Foo as Trait>::trait_deprecated_text(&foo); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text } fn test_method_object(foo: &Trait) { - foo.trait_deprecated(); //~ ERROR use of deprecated item 'deprecation_lint::Trait::trait_deprecated' - foo.trait_deprecated_text(); //~ ERROR use of deprecated item 'deprecation_lint::Trait::trait_deprecated_text': text + foo.trait_deprecated(); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated` + foo.trait_deprecated_text(); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text } struct S; - impl DeprecatedTrait for S {} //~ ERROR use of deprecated item 'deprecation_lint::DeprecatedTrait': text - trait LocalTrait : DeprecatedTrait { } //~ ERROR use of deprecated item 'deprecation_lint::DeprecatedTrait': text + impl DeprecatedTrait for S {} //~ ERROR use of deprecated trait `deprecation_lint::DeprecatedTrait`: text + trait LocalTrait : DeprecatedTrait { } //~ ERROR use of deprecated trait `deprecation_lint::DeprecatedTrait`: text pub fn foo() { let x = Stable { override2: 3, - //~^ ERROR use of deprecated item 'deprecation_lint::Stable::override2': text + //~^ ERROR use of deprecated field `deprecation_lint::Stable::override2`: text }; let _ = x.override2; - //~^ ERROR use of deprecated item 'deprecation_lint::Stable::override2': text + //~^ ERROR use of deprecated field `deprecation_lint::Stable::override2`: text let Stable { override2: _ - //~^ ERROR use of deprecated item 'deprecation_lint::Stable::override2': text + //~^ ERROR use of deprecated field `deprecation_lint::Stable::override2`: text } = x; // all fine let Stable { .. } = x; @@ -101,56 +101,56 @@ mod cross_crate { let x = Stable2(1, 2, 3); let _ = x.2; - //~^ ERROR use of deprecated item 'deprecation_lint::Stable2::2': text + //~^ ERROR use of deprecated field `deprecation_lint::Stable2::2`: text let Stable2(_, _, _) - //~^ ERROR use of deprecated item 'deprecation_lint::Stable2::2': text + //~^ ERROR use of deprecated field `deprecation_lint::Stable2::2`: text = x; // all fine let Stable2(..) = x; let x = Deprecated { - //~^ ERROR use of deprecated item 'deprecation_lint::Deprecated': text + //~^ ERROR use of deprecated struct `deprecation_lint::Deprecated`: text inherit: 1, - //~^ ERROR use of deprecated item 'deprecation_lint::Deprecated::inherit': text + //~^ ERROR use of deprecated field `deprecation_lint::Deprecated::inherit`: text }; let _ = x.inherit; - //~^ ERROR use of deprecated item 'deprecation_lint::Deprecated::inherit': text + //~^ ERROR use of deprecated field `deprecation_lint::Deprecated::inherit`: text let Deprecated { - //~^ ERROR use of deprecated item 'deprecation_lint::Deprecated': text + //~^ ERROR use of deprecated struct `deprecation_lint::Deprecated`: text inherit: _, - //~^ ERROR use of deprecated item 'deprecation_lint::Deprecated::inherit': text + //~^ ERROR use of deprecated field `deprecation_lint::Deprecated::inherit`: text } = x; let Deprecated - //~^ ERROR use of deprecated item 'deprecation_lint::Deprecated': text + //~^ ERROR use of deprecated struct `deprecation_lint::Deprecated`: text { .. } = x; let x = Deprecated2(1, 2, 3); - //~^ ERROR use of deprecated item 'deprecation_lint::Deprecated2': text + //~^ ERROR use of deprecated struct `deprecation_lint::Deprecated2`: text let _ = x.0; - //~^ ERROR use of deprecated item 'deprecation_lint::Deprecated2::0': text + //~^ ERROR use of deprecated field `deprecation_lint::Deprecated2::0`: text let _ = x.1; - //~^ ERROR use of deprecated item 'deprecation_lint::Deprecated2::1': text + //~^ ERROR use of deprecated field `deprecation_lint::Deprecated2::1`: text let _ = x.2; - //~^ ERROR use of deprecated item 'deprecation_lint::Deprecated2::2': text + //~^ ERROR use of deprecated field `deprecation_lint::Deprecated2::2`: text let Deprecated2 - //~^ ERROR use of deprecated item 'deprecation_lint::Deprecated2': text + //~^ ERROR use of deprecated struct `deprecation_lint::Deprecated2`: text (_, - //~^ ERROR use of deprecated item 'deprecation_lint::Deprecated2::0': text + //~^ ERROR use of deprecated field `deprecation_lint::Deprecated2::0`: text _, - //~^ ERROR use of deprecated item 'deprecation_lint::Deprecated2::1': text + //~^ ERROR use of deprecated field `deprecation_lint::Deprecated2::1`: text _) - //~^ ERROR use of deprecated item 'deprecation_lint::Deprecated2::2': text + //~^ ERROR use of deprecated field `deprecation_lint::Deprecated2::2`: text = x; let Deprecated2 - //~^ ERROR use of deprecated item 'deprecation_lint::Deprecated2': text + //~^ ERROR use of deprecated struct `deprecation_lint::Deprecated2`: text // the patterns are all fine: (..) = x; } @@ -160,7 +160,7 @@ mod inheritance { use deprecation_lint::*; fn test_inheritance() { - deprecated_mod::deprecated(); //~ ERROR use of deprecated item 'deprecation_lint::deprecated_mod::deprecated': text + deprecated_mod::deprecated(); //~ ERROR use of deprecated function `deprecation_lint::deprecated_mod::deprecated`: text } } @@ -243,65 +243,65 @@ mod this_crate { type Foo = MethodTester; let foo = MethodTester; - deprecated(); //~ ERROR use of deprecated item 'this_crate::deprecated' - foo.method_deprecated(); //~ ERROR use of deprecated item 'this_crate::MethodTester::method_deprecated' - Foo::method_deprecated(&foo); //~ ERROR use of deprecated item 'this_crate::MethodTester::method_deprecated' - <Foo>::method_deprecated(&foo); //~ ERROR use of deprecated item 'this_crate::MethodTester::method_deprecated' - foo.trait_deprecated(); //~ ERROR use of deprecated item 'this_crate::Trait::trait_deprecated' - Trait::trait_deprecated(&foo); //~ ERROR use of deprecated item 'this_crate::Trait::trait_deprecated' - <Foo>::trait_deprecated(&foo); //~ ERROR use of deprecated item 'this_crate::Trait::trait_deprecated' - <Foo as Trait>::trait_deprecated(&foo); //~ ERROR use of deprecated item 'this_crate::Trait::trait_deprecated' - - deprecated_text(); //~ ERROR use of deprecated item 'this_crate::deprecated_text': text - foo.method_deprecated_text(); //~ ERROR use of deprecated item 'this_crate::MethodTester::method_deprecated_text': text - Foo::method_deprecated_text(&foo); //~ ERROR use of deprecated item 'this_crate::MethodTester::method_deprecated_text': text - <Foo>::method_deprecated_text(&foo); //~ ERROR use of deprecated item 'this_crate::MethodTester::method_deprecated_text': text - foo.trait_deprecated_text(); //~ ERROR use of deprecated item 'this_crate::Trait::trait_deprecated_text': text - Trait::trait_deprecated_text(&foo); //~ ERROR use of deprecated item 'this_crate::Trait::trait_deprecated_text': text - <Foo>::trait_deprecated_text(&foo); //~ ERROR use of deprecated item 'this_crate::Trait::trait_deprecated_text': text - <Foo as Trait>::trait_deprecated_text(&foo); //~ ERROR use of deprecated item 'this_crate::Trait::trait_deprecated_text': text + deprecated(); //~ ERROR use of deprecated function `this_crate::deprecated` + foo.method_deprecated(); //~ ERROR use of deprecated associated function `this_crate::MethodTester::method_deprecated` + Foo::method_deprecated(&foo); //~ ERROR use of deprecated associated function `this_crate::MethodTester::method_deprecated` + <Foo>::method_deprecated(&foo); //~ ERROR use of deprecated associated function `this_crate::MethodTester::method_deprecated` + foo.trait_deprecated(); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated` + Trait::trait_deprecated(&foo); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated` + <Foo>::trait_deprecated(&foo); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated` + <Foo as Trait>::trait_deprecated(&foo); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated` + + deprecated_text(); //~ ERROR use of deprecated function `this_crate::deprecated_text`: text + foo.method_deprecated_text(); //~ ERROR use of deprecated associated function `this_crate::MethodTester::method_deprecated_text`: text + Foo::method_deprecated_text(&foo); //~ ERROR use of deprecated associated function `this_crate::MethodTester::method_deprecated_text`: text + <Foo>::method_deprecated_text(&foo); //~ ERROR use of deprecated associated function `this_crate::MethodTester::method_deprecated_text`: text + foo.trait_deprecated_text(); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text + Trait::trait_deprecated_text(&foo); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text + <Foo>::trait_deprecated_text(&foo); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text + <Foo as Trait>::trait_deprecated_text(&foo); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text // Future deprecations are only permitted for rustc_deprecated. - deprecated_future(); //~ ERROR use of deprecated item - deprecated_future_text(); //~ ERROR use of deprecated item + deprecated_future(); //~ ERROR use of deprecated function + deprecated_future_text(); //~ ERROR use of deprecated function let _ = DeprecatedStruct { - //~^ ERROR use of deprecated item 'this_crate::DeprecatedStruct': text - i: 0 //~ ERROR use of deprecated item 'this_crate::DeprecatedStruct::i': text + //~^ ERROR use of deprecated struct `this_crate::DeprecatedStruct`: text + i: 0 //~ ERROR use of deprecated field `this_crate::DeprecatedStruct::i`: text }; - let _ = DeprecatedUnitStruct; //~ ERROR use of deprecated item 'this_crate::DeprecatedUnitStruct': text + let _ = DeprecatedUnitStruct; //~ ERROR use of deprecated unit struct `this_crate::DeprecatedUnitStruct`: text - let _ = Enum::DeprecatedVariant; //~ ERROR use of deprecated item 'this_crate::Enum::DeprecatedVariant': text + let _ = Enum::DeprecatedVariant; //~ ERROR use of deprecated unit variant `this_crate::Enum::DeprecatedVariant`: text - let _ = DeprecatedTupleStruct (1); //~ ERROR use of deprecated item 'this_crate::DeprecatedTupleStruct': text + let _ = DeprecatedTupleStruct (1); //~ ERROR use of deprecated tuple struct `this_crate::DeprecatedTupleStruct`: text let _ = nested::DeprecatedStruct { - //~^ ERROR use of deprecated item 'this_crate::nested::DeprecatedStruct': text - i: 0 //~ ERROR use of deprecated item 'this_crate::nested::DeprecatedStruct::i': text + //~^ ERROR use of deprecated struct `this_crate::nested::DeprecatedStruct`: text + i: 0 //~ ERROR use of deprecated field `this_crate::nested::DeprecatedStruct::i`: text }; - let _ = nested::DeprecatedUnitStruct; //~ ERROR use of deprecated item 'this_crate::nested::DeprecatedUnitStruct': text + let _ = nested::DeprecatedUnitStruct; //~ ERROR use of deprecated unit struct `this_crate::nested::DeprecatedUnitStruct`: text - let _ = nested::Enum::DeprecatedVariant; //~ ERROR use of deprecated item 'this_crate::nested::Enum::DeprecatedVariant': text + let _ = nested::Enum::DeprecatedVariant; //~ ERROR use of deprecated unit variant `this_crate::nested::Enum::DeprecatedVariant`: text - let _ = nested::DeprecatedTupleStruct (1); //~ ERROR use of deprecated item 'this_crate::nested::DeprecatedTupleStruct': text + let _ = nested::DeprecatedTupleStruct (1); //~ ERROR use of deprecated tuple struct `this_crate::nested::DeprecatedTupleStruct`: text } fn test_method_param<Foo: Trait>(foo: Foo) { - foo.trait_deprecated(); //~ ERROR use of deprecated item 'this_crate::Trait::trait_deprecated' - Trait::trait_deprecated(&foo); //~ ERROR use of deprecated item 'this_crate::Trait::trait_deprecated' - <Foo>::trait_deprecated(&foo); //~ ERROR use of deprecated item 'this_crate::Trait::trait_deprecated' - <Foo as Trait>::trait_deprecated(&foo); //~ ERROR use of deprecated item 'this_crate::Trait::trait_deprecated' - foo.trait_deprecated_text(); //~ ERROR use of deprecated item 'this_crate::Trait::trait_deprecated_text': text - Trait::trait_deprecated_text(&foo); //~ ERROR use of deprecated item 'this_crate::Trait::trait_deprecated_text': text - <Foo>::trait_deprecated_text(&foo); //~ ERROR use of deprecated item 'this_crate::Trait::trait_deprecated_text': text - <Foo as Trait>::trait_deprecated_text(&foo); //~ ERROR use of deprecated item 'this_crate::Trait::trait_deprecated_text': text + foo.trait_deprecated(); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated` + Trait::trait_deprecated(&foo); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated` + <Foo>::trait_deprecated(&foo); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated` + <Foo as Trait>::trait_deprecated(&foo); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated` + foo.trait_deprecated_text(); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text + Trait::trait_deprecated_text(&foo); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text + <Foo>::trait_deprecated_text(&foo); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text + <Foo as Trait>::trait_deprecated_text(&foo); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text } fn test_method_object(foo: &Trait) { - foo.trait_deprecated(); //~ ERROR use of deprecated item 'this_crate::Trait::trait_deprecated' - foo.trait_deprecated_text(); //~ ERROR use of deprecated item 'this_crate::Trait::trait_deprecated_text': text + foo.trait_deprecated(); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated` + foo.trait_deprecated_text(); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text } #[deprecated(since = "1.0.0", note = "text")] @@ -314,7 +314,7 @@ mod this_crate { let _ = || { #[deprecated] fn bar() { } - bar(); //~ ERROR use of deprecated item 'this_crate::test_fn_closure_body::{{closure}}#0::bar' + bar(); //~ ERROR use of deprecated function `this_crate::test_fn_closure_body::{{closure}}#0::bar` }; } @@ -333,9 +333,9 @@ mod this_crate { struct S; - impl DeprecatedTrait for S { } //~ ERROR use of deprecated item 'this_crate::DeprecatedTrait': text + impl DeprecatedTrait for S { } //~ ERROR use of deprecated trait `this_crate::DeprecatedTrait`: text - trait LocalTrait : DeprecatedTrait { } //~ ERROR use of deprecated item 'this_crate::DeprecatedTrait': text + trait LocalTrait : DeprecatedTrait { } //~ ERROR use of deprecated trait `this_crate::DeprecatedTrait`: text } mod this_crate2 { @@ -361,15 +361,15 @@ mod this_crate2 { pub fn foo() { let x = Stable { override2: 3, - //~^ ERROR use of deprecated item 'this_crate2::Stable::override2': text + //~^ ERROR use of deprecated field `this_crate2::Stable::override2`: text }; let _ = x.override2; - //~^ ERROR use of deprecated item 'this_crate2::Stable::override2': text + //~^ ERROR use of deprecated field `this_crate2::Stable::override2`: text let Stable { override2: _ - //~^ ERROR use of deprecated item 'this_crate2::Stable::override2': text + //~^ ERROR use of deprecated field `this_crate2::Stable::override2`: text } = x; // all fine let Stable { .. } = x; @@ -377,57 +377,57 @@ mod this_crate2 { let x = Stable2(1, 2, 3); let _ = x.2; - //~^ ERROR use of deprecated item 'this_crate2::Stable2::2': text + //~^ ERROR use of deprecated field `this_crate2::Stable2::2`: text let Stable2(_, _, _) - //~^ ERROR use of deprecated item 'this_crate2::Stable2::2': text + //~^ ERROR use of deprecated field `this_crate2::Stable2::2`: text = x; // all fine let Stable2(..) = x; let x = Deprecated { - //~^ ERROR use of deprecated item 'this_crate2::Deprecated': text + //~^ ERROR use of deprecated struct `this_crate2::Deprecated`: text inherit: 1, - //~^ ERROR use of deprecated item 'this_crate2::Deprecated::inherit': text + //~^ ERROR use of deprecated field `this_crate2::Deprecated::inherit`: text }; let _ = x.inherit; - //~^ ERROR use of deprecated item 'this_crate2::Deprecated::inherit': text + //~^ ERROR use of deprecated field `this_crate2::Deprecated::inherit`: text let Deprecated { - //~^ ERROR use of deprecated item 'this_crate2::Deprecated': text + //~^ ERROR use of deprecated struct `this_crate2::Deprecated`: text inherit: _, - //~^ ERROR use of deprecated item 'this_crate2::Deprecated::inherit': text + //~^ ERROR use of deprecated field `this_crate2::Deprecated::inherit`: text } = x; let Deprecated - //~^ ERROR use of deprecated item 'this_crate2::Deprecated': text + //~^ ERROR use of deprecated struct `this_crate2::Deprecated`: text // the patterns are all fine: { .. } = x; let x = Deprecated2(1, 2, 3); - //~^ ERROR use of deprecated item 'this_crate2::Deprecated2': text + //~^ ERROR use of deprecated tuple struct `this_crate2::Deprecated2`: text let _ = x.0; - //~^ ERROR use of deprecated item 'this_crate2::Deprecated2::0': text + //~^ ERROR use of deprecated field `this_crate2::Deprecated2::0`: text let _ = x.1; - //~^ ERROR use of deprecated item 'this_crate2::Deprecated2::1': text + //~^ ERROR use of deprecated field `this_crate2::Deprecated2::1`: text let _ = x.2; - //~^ ERROR use of deprecated item 'this_crate2::Deprecated2::2': text + //~^ ERROR use of deprecated field `this_crate2::Deprecated2::2`: text let Deprecated2 - //~^ ERROR use of deprecated item 'this_crate2::Deprecated2': text + //~^ ERROR use of deprecated tuple struct `this_crate2::Deprecated2`: text (_, - //~^ ERROR use of deprecated item 'this_crate2::Deprecated2::0': text + //~^ ERROR use of deprecated field `this_crate2::Deprecated2::0`: text _, - //~^ ERROR use of deprecated item 'this_crate2::Deprecated2::1': text + //~^ ERROR use of deprecated field `this_crate2::Deprecated2::1`: text _) - //~^ ERROR use of deprecated item 'this_crate2::Deprecated2::2': text + //~^ ERROR use of deprecated field `this_crate2::Deprecated2::2`: text = x; let Deprecated2 - //~^ ERROR use of deprecated item 'this_crate2::Deprecated2': text + //~^ ERROR use of deprecated tuple struct `this_crate2::Deprecated2`: text // the patterns are all fine: (..) = x; } diff --git a/src/test/ui/deprecation/deprecation-lint.stderr b/src/test/ui/deprecation/deprecation-lint.stderr index 362a901d77d..03a2ec7edc9 100644 --- a/src/test/ui/deprecation/deprecation-lint.stderr +++ b/src/test/ui/deprecation/deprecation-lint.stderr @@ -1,4 +1,4 @@ -error: use of deprecated item 'deprecation_lint::deprecated': text +error: use of deprecated function `deprecation_lint::deprecated`: text --> $DIR/deprecation-lint.rs:17:9 | LL | deprecated(); @@ -10,727 +10,727 @@ note: the lint level is defined here LL | #![deny(deprecated)] | ^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::Trait::trait_deprecated': text +error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated`: text --> $DIR/deprecation-lint.rs:22:9 | LL | Trait::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::Trait::trait_deprecated': text +error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated`: text --> $DIR/deprecation-lint.rs:24:9 | LL | <Foo as Trait>::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::deprecated_text': text +error: use of deprecated function `deprecation_lint::deprecated_text`: text --> $DIR/deprecation-lint.rs:26:9 | LL | deprecated_text(); | ^^^^^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::Trait::trait_deprecated_text': text +error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text --> $DIR/deprecation-lint.rs:31:9 | -LL | Trait::trait_deprecated_text(&foo); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... Trait::trait_deprecated_text(&foo); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::Trait::trait_deprecated_text': text +error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text --> $DIR/deprecation-lint.rs:33:9 | -LL | <Foo as Trait>::trait_deprecated_text(&foo); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... <Foo as Trait>::trait_deprecated_text(&foo); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::DeprecatedStruct': text +error: use of deprecated struct `deprecation_lint::DeprecatedStruct`: text --> $DIR/deprecation-lint.rs:35:17 | LL | let _ = DeprecatedStruct { | ^^^^^^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::DeprecatedUnitStruct': text +error: use of deprecated struct `deprecation_lint::DeprecatedUnitStruct`: text --> $DIR/deprecation-lint.rs:39:17 | LL | let _ = DeprecatedUnitStruct; | ^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::Enum::DeprecatedVariant': text +error: use of deprecated variant `deprecation_lint::Enum::DeprecatedVariant`: text --> $DIR/deprecation-lint.rs:41:17 | LL | let _ = Enum::DeprecatedVariant; | ^^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::DeprecatedTupleStruct': text +error: use of deprecated struct `deprecation_lint::DeprecatedTupleStruct`: text --> $DIR/deprecation-lint.rs:43:17 | LL | let _ = DeprecatedTupleStruct (1); | ^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::nested::DeprecatedStruct': text +error: use of deprecated struct `deprecation_lint::nested::DeprecatedStruct`: text --> $DIR/deprecation-lint.rs:45:17 | LL | let _ = nested::DeprecatedStruct { | ^^^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::nested::DeprecatedUnitStruct': text +error: use of deprecated struct `deprecation_lint::nested::DeprecatedUnitStruct`: text --> $DIR/deprecation-lint.rs:49:17 | LL | let _ = nested::DeprecatedUnitStruct; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::nested::Enum::DeprecatedVariant': text +error: use of deprecated variant `deprecation_lint::nested::Enum::DeprecatedVariant`: text --> $DIR/deprecation-lint.rs:51:17 | -LL | let _ = nested::Enum::DeprecatedVariant; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... let _ = nested::Enum::DeprecatedVariant; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::nested::DeprecatedTupleStruct': text +error: use of deprecated struct `deprecation_lint::nested::DeprecatedTupleStruct`: text --> $DIR/deprecation-lint.rs:53:17 | -LL | let _ = nested::DeprecatedTupleStruct (1); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... let _ = nested::DeprecatedTupleStruct (1); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::deprecated_text': text +error: use of deprecated function `deprecation_lint::deprecated_text`: text --> $DIR/deprecation-lint.rs:60:25 | LL | macro_test_arg!(deprecated_text()); | ^^^^^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::deprecated_text': text +error: use of deprecated function `deprecation_lint::deprecated_text`: text --> $DIR/deprecation-lint.rs:61:41 | LL | macro_test_arg!(macro_test_arg!(deprecated_text())); | ^^^^^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::Trait::trait_deprecated': text +error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated`: text --> $DIR/deprecation-lint.rs:66:9 | LL | Trait::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::Trait::trait_deprecated': text +error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated`: text --> $DIR/deprecation-lint.rs:68:9 | LL | <Foo as Trait>::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::Trait::trait_deprecated_text': text +error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text --> $DIR/deprecation-lint.rs:70:9 | -LL | Trait::trait_deprecated_text(&foo); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... Trait::trait_deprecated_text(&foo); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::Trait::trait_deprecated_text': text +error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text --> $DIR/deprecation-lint.rs:72:9 | -LL | <Foo as Trait>::trait_deprecated_text(&foo); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... <Foo as Trait>::trait_deprecated_text(&foo); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::DeprecatedTrait': text +error: use of deprecated trait `deprecation_lint::DeprecatedTrait`: text --> $DIR/deprecation-lint.rs:82:10 | LL | impl DeprecatedTrait for S {} | ^^^^^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::DeprecatedTrait': text +error: use of deprecated trait `deprecation_lint::DeprecatedTrait`: text --> $DIR/deprecation-lint.rs:83:24 | LL | trait LocalTrait : DeprecatedTrait { } | ^^^^^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::Deprecated': text +error: use of deprecated struct `deprecation_lint::Deprecated`: text --> $DIR/deprecation-lint.rs:114:17 | LL | let x = Deprecated { | ^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::Deprecated': text +error: use of deprecated struct `deprecation_lint::Deprecated`: text --> $DIR/deprecation-lint.rs:123:13 | LL | let Deprecated { | ^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::Deprecated': text +error: use of deprecated struct `deprecation_lint::Deprecated`: text --> $DIR/deprecation-lint.rs:129:13 | LL | let Deprecated | ^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::Deprecated2': text +error: use of deprecated struct `deprecation_lint::Deprecated2`: text --> $DIR/deprecation-lint.rs:133:17 | LL | let x = Deprecated2(1, 2, 3); | ^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::Deprecated2': text +error: use of deprecated struct `deprecation_lint::Deprecated2`: text --> $DIR/deprecation-lint.rs:143:13 | LL | let Deprecated2 | ^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::Deprecated2': text +error: use of deprecated struct `deprecation_lint::Deprecated2`: text --> $DIR/deprecation-lint.rs:152:13 | LL | let Deprecated2 | ^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::deprecated_mod::deprecated': text +error: use of deprecated function `deprecation_lint::deprecated_mod::deprecated`: text --> $DIR/deprecation-lint.rs:163:9 | LL | deprecated_mod::deprecated(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::deprecated': text +error: use of deprecated function `this_crate::deprecated`: text --> $DIR/deprecation-lint.rs:246:9 | LL | deprecated(); | ^^^^^^^^^^ -error: use of deprecated item 'this_crate::Trait::trait_deprecated': text +error: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text --> $DIR/deprecation-lint.rs:251:9 | LL | Trait::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::Trait::trait_deprecated': text +error: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text --> $DIR/deprecation-lint.rs:253:9 | LL | <Foo as Trait>::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::deprecated_text': text +error: use of deprecated function `this_crate::deprecated_text`: text --> $DIR/deprecation-lint.rs:255:9 | LL | deprecated_text(); | ^^^^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::Trait::trait_deprecated_text': text +error: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text --> $DIR/deprecation-lint.rs:260:9 | LL | Trait::trait_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::Trait::trait_deprecated_text': text +error: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text --> $DIR/deprecation-lint.rs:262:9 | -LL | <Foo as Trait>::trait_deprecated_text(&foo); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... <Foo as Trait>::trait_deprecated_text(&foo); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::deprecated_future': text +error: use of deprecated function `this_crate::deprecated_future`: text --> $DIR/deprecation-lint.rs:265:9 | LL | deprecated_future(); | ^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::deprecated_future_text': text +error: use of deprecated function `this_crate::deprecated_future_text`: text --> $DIR/deprecation-lint.rs:266:9 | LL | deprecated_future_text(); | ^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::DeprecatedStruct': text +error: use of deprecated struct `this_crate::DeprecatedStruct`: text --> $DIR/deprecation-lint.rs:268:17 | LL | let _ = DeprecatedStruct { | ^^^^^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::DeprecatedUnitStruct': text +error: use of deprecated unit struct `this_crate::DeprecatedUnitStruct`: text --> $DIR/deprecation-lint.rs:273:17 | LL | let _ = DeprecatedUnitStruct; | ^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::Enum::DeprecatedVariant': text +error: use of deprecated unit variant `this_crate::Enum::DeprecatedVariant`: text --> $DIR/deprecation-lint.rs:275:17 | LL | let _ = Enum::DeprecatedVariant; | ^^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::DeprecatedTupleStruct': text +error: use of deprecated tuple struct `this_crate::DeprecatedTupleStruct`: text --> $DIR/deprecation-lint.rs:277:17 | LL | let _ = DeprecatedTupleStruct (1); | ^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::nested::DeprecatedStruct': text +error: use of deprecated struct `this_crate::nested::DeprecatedStruct`: text --> $DIR/deprecation-lint.rs:279:17 | LL | let _ = nested::DeprecatedStruct { | ^^^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::nested::DeprecatedUnitStruct': text +error: use of deprecated unit struct `this_crate::nested::DeprecatedUnitStruct`: text --> $DIR/deprecation-lint.rs:284:17 | LL | let _ = nested::DeprecatedUnitStruct; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::nested::Enum::DeprecatedVariant': text +error: use of deprecated unit variant `this_crate::nested::Enum::DeprecatedVariant`: text --> $DIR/deprecation-lint.rs:286:17 | -LL | let _ = nested::Enum::DeprecatedVariant; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... let _ = nested::Enum::DeprecatedVariant; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::nested::DeprecatedTupleStruct': text +error: use of deprecated tuple struct `this_crate::nested::DeprecatedTupleStruct`: text --> $DIR/deprecation-lint.rs:288:17 | -LL | let _ = nested::DeprecatedTupleStruct (1); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... let _ = nested::DeprecatedTupleStruct (1); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::Trait::trait_deprecated': text +error: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text --> $DIR/deprecation-lint.rs:293:9 | LL | Trait::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::Trait::trait_deprecated': text +error: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text --> $DIR/deprecation-lint.rs:295:9 | LL | <Foo as Trait>::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::Trait::trait_deprecated_text': text +error: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text --> $DIR/deprecation-lint.rs:297:9 | LL | Trait::trait_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::Trait::trait_deprecated_text': text +error: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text --> $DIR/deprecation-lint.rs:299:9 | -LL | <Foo as Trait>::trait_deprecated_text(&foo); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... <Foo as Trait>::trait_deprecated_text(&foo); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::test_fn_closure_body::{{closure}}#0::bar' +error: use of deprecated function `this_crate::test_fn_closure_body::{{closure}}#0::bar` --> $DIR/deprecation-lint.rs:317:13 | LL | bar(); | ^^^ -error: use of deprecated item 'this_crate::DeprecatedTrait': text +error: use of deprecated trait `this_crate::DeprecatedTrait`: text --> $DIR/deprecation-lint.rs:336:10 | LL | impl DeprecatedTrait for S { } | ^^^^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::DeprecatedTrait': text +error: use of deprecated trait `this_crate::DeprecatedTrait`: text --> $DIR/deprecation-lint.rs:338:24 | LL | trait LocalTrait : DeprecatedTrait { } | ^^^^^^^^^^^^^^^ -error: use of deprecated item 'this_crate2::Deprecated': text +error: use of deprecated struct `this_crate2::Deprecated`: text --> $DIR/deprecation-lint.rs:390:17 | LL | let x = Deprecated { | ^^^^^^^^^^ -error: use of deprecated item 'this_crate2::Deprecated': text +error: use of deprecated struct `this_crate2::Deprecated`: text --> $DIR/deprecation-lint.rs:399:13 | LL | let Deprecated { | ^^^^^^^^^^ -error: use of deprecated item 'this_crate2::Deprecated': text +error: use of deprecated struct `this_crate2::Deprecated`: text --> $DIR/deprecation-lint.rs:405:13 | LL | let Deprecated | ^^^^^^^^^^ -error: use of deprecated item 'this_crate2::Deprecated2': text +error: use of deprecated tuple struct `this_crate2::Deprecated2`: text --> $DIR/deprecation-lint.rs:410:17 | LL | let x = Deprecated2(1, 2, 3); | ^^^^^^^^^^^ -error: use of deprecated item 'this_crate2::Deprecated2': text +error: use of deprecated tuple struct `this_crate2::Deprecated2`: text --> $DIR/deprecation-lint.rs:420:13 | LL | let Deprecated2 | ^^^^^^^^^^^ -error: use of deprecated item 'this_crate2::Deprecated2': text +error: use of deprecated tuple struct `this_crate2::Deprecated2`: text --> $DIR/deprecation-lint.rs:429:13 | LL | let Deprecated2 | ^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::MethodTester::method_deprecated': text +error: use of deprecated associated function `deprecation_lint::MethodTester::method_deprecated`: text --> $DIR/deprecation-lint.rs:18:13 | LL | foo.method_deprecated(); | ^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::MethodTester::method_deprecated': text +error: use of deprecated associated function `deprecation_lint::MethodTester::method_deprecated`: text --> $DIR/deprecation-lint.rs:19:9 | LL | Foo::method_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::MethodTester::method_deprecated': text +error: use of deprecated associated function `deprecation_lint::MethodTester::method_deprecated`: text --> $DIR/deprecation-lint.rs:20:9 | LL | <Foo>::method_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::Trait::trait_deprecated': text +error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated`: text --> $DIR/deprecation-lint.rs:21:13 | LL | foo.trait_deprecated(); | ^^^^^^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::Trait::trait_deprecated': text +error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated`: text --> $DIR/deprecation-lint.rs:23:9 | LL | <Foo>::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::MethodTester::method_deprecated_text': text +error: use of deprecated associated function `deprecation_lint::MethodTester::method_deprecated_text`: text --> $DIR/deprecation-lint.rs:27:13 | -LL | foo.method_deprecated_text(); - | ^^^^^^^^^^^^^^^^^^^^^^ +LL | ... foo.method_deprecated_text(); + | ^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::MethodTester::method_deprecated_text': text +error: use of deprecated associated function `deprecation_lint::MethodTester::method_deprecated_text`: text --> $DIR/deprecation-lint.rs:28:9 | -LL | Foo::method_deprecated_text(&foo); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... Foo::method_deprecated_text(&foo); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::MethodTester::method_deprecated_text': text +error: use of deprecated associated function `deprecation_lint::MethodTester::method_deprecated_text`: text --> $DIR/deprecation-lint.rs:29:9 | -LL | <Foo>::method_deprecated_text(&foo); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... <Foo>::method_deprecated_text(&foo); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::Trait::trait_deprecated_text': text +error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text --> $DIR/deprecation-lint.rs:30:13 | LL | foo.trait_deprecated_text(); | ^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::Trait::trait_deprecated_text': text +error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text --> $DIR/deprecation-lint.rs:32:9 | -LL | <Foo>::trait_deprecated_text(&foo); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... <Foo>::trait_deprecated_text(&foo); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::DeprecatedStruct::i': text +error: use of deprecated field `deprecation_lint::DeprecatedStruct::i`: text --> $DIR/deprecation-lint.rs:36:13 | LL | i: 0 | ^^^^ -error: use of deprecated item 'deprecation_lint::nested::DeprecatedStruct::i': text +error: use of deprecated field `deprecation_lint::nested::DeprecatedStruct::i`: text --> $DIR/deprecation-lint.rs:46:13 | LL | i: 0 | ^^^^ -error: use of deprecated item 'deprecation_lint::Trait::trait_deprecated': text +error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated`: text --> $DIR/deprecation-lint.rs:65:13 | LL | foo.trait_deprecated(); | ^^^^^^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::Trait::trait_deprecated': text +error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated`: text --> $DIR/deprecation-lint.rs:67:9 | LL | <Foo>::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::Trait::trait_deprecated_text': text +error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text --> $DIR/deprecation-lint.rs:69:13 | LL | foo.trait_deprecated_text(); | ^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::Trait::trait_deprecated_text': text +error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text --> $DIR/deprecation-lint.rs:71:9 | -LL | <Foo>::trait_deprecated_text(&foo); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... <Foo>::trait_deprecated_text(&foo); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::Trait::trait_deprecated': text +error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated`: text --> $DIR/deprecation-lint.rs:76:13 | LL | foo.trait_deprecated(); | ^^^^^^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::Trait::trait_deprecated_text': text +error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text --> $DIR/deprecation-lint.rs:77:13 | LL | foo.trait_deprecated_text(); | ^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::Stable::override2': text +error: use of deprecated field `deprecation_lint::Stable::override2`: text --> $DIR/deprecation-lint.rs:87:13 | LL | override2: 3, | ^^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::Stable::override2': text +error: use of deprecated field `deprecation_lint::Stable::override2`: text --> $DIR/deprecation-lint.rs:91:17 | LL | let _ = x.override2; | ^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::Stable::override2': text +error: use of deprecated field `deprecation_lint::Stable::override2`: text --> $DIR/deprecation-lint.rs:95:13 | LL | override2: _ | ^^^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::Stable2::2': text +error: use of deprecated field `deprecation_lint::Stable2::2`: text --> $DIR/deprecation-lint.rs:103:17 | LL | let _ = x.2; | ^^^ -error: use of deprecated item 'deprecation_lint::Stable2::2': text +error: use of deprecated field `deprecation_lint::Stable2::2`: text --> $DIR/deprecation-lint.rs:108:20 | LL | _) | ^ -error: use of deprecated item 'deprecation_lint::Deprecated::inherit': text +error: use of deprecated field `deprecation_lint::Deprecated::inherit`: text --> $DIR/deprecation-lint.rs:116:13 | LL | inherit: 1, | ^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::Deprecated::inherit': text +error: use of deprecated field `deprecation_lint::Deprecated::inherit`: text --> $DIR/deprecation-lint.rs:120:17 | LL | let _ = x.inherit; | ^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::Deprecated::inherit': text +error: use of deprecated field `deprecation_lint::Deprecated::inherit`: text --> $DIR/deprecation-lint.rs:125:13 | LL | inherit: _, | ^^^^^^^^^^ -error: use of deprecated item 'deprecation_lint::Deprecated2::0': text +error: use of deprecated field `deprecation_lint::Deprecated2::0`: text --> $DIR/deprecation-lint.rs:136:17 | LL | let _ = x.0; | ^^^ -error: use of deprecated item 'deprecation_lint::Deprecated2::1': text +error: use of deprecated field `deprecation_lint::Deprecated2::1`: text --> $DIR/deprecation-lint.rs:138:17 | LL | let _ = x.1; | ^^^ -error: use of deprecated item 'deprecation_lint::Deprecated2::2': text +error: use of deprecated field `deprecation_lint::Deprecated2::2`: text --> $DIR/deprecation-lint.rs:140:17 | LL | let _ = x.2; | ^^^ -error: use of deprecated item 'deprecation_lint::Deprecated2::0': text +error: use of deprecated field `deprecation_lint::Deprecated2::0`: text --> $DIR/deprecation-lint.rs:145:14 | LL | (_, | ^ -error: use of deprecated item 'deprecation_lint::Deprecated2::1': text +error: use of deprecated field `deprecation_lint::Deprecated2::1`: text --> $DIR/deprecation-lint.rs:147:14 | LL | _, | ^ -error: use of deprecated item 'deprecation_lint::Deprecated2::2': text +error: use of deprecated field `deprecation_lint::Deprecated2::2`: text --> $DIR/deprecation-lint.rs:149:14 | LL | _) | ^ -error: use of deprecated item 'this_crate::MethodTester::method_deprecated': text +error: use of deprecated associated function `this_crate::MethodTester::method_deprecated`: text --> $DIR/deprecation-lint.rs:247:13 | LL | foo.method_deprecated(); | ^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::MethodTester::method_deprecated': text +error: use of deprecated associated function `this_crate::MethodTester::method_deprecated`: text --> $DIR/deprecation-lint.rs:248:9 | LL | Foo::method_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::MethodTester::method_deprecated': text +error: use of deprecated associated function `this_crate::MethodTester::method_deprecated`: text --> $DIR/deprecation-lint.rs:249:9 | LL | <Foo>::method_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::Trait::trait_deprecated': text +error: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text --> $DIR/deprecation-lint.rs:250:13 | LL | foo.trait_deprecated(); | ^^^^^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::Trait::trait_deprecated': text +error: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text --> $DIR/deprecation-lint.rs:252:9 | LL | <Foo>::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::MethodTester::method_deprecated_text': text +error: use of deprecated associated function `this_crate::MethodTester::method_deprecated_text`: text --> $DIR/deprecation-lint.rs:256:13 | -LL | foo.method_deprecated_text(); - | ^^^^^^^^^^^^^^^^^^^^^^ +LL | ... foo.method_deprecated_text(); + | ^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::MethodTester::method_deprecated_text': text +error: use of deprecated associated function `this_crate::MethodTester::method_deprecated_text`: text --> $DIR/deprecation-lint.rs:257:9 | -LL | Foo::method_deprecated_text(&foo); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... Foo::method_deprecated_text(&foo); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::MethodTester::method_deprecated_text': text +error: use of deprecated associated function `this_crate::MethodTester::method_deprecated_text`: text --> $DIR/deprecation-lint.rs:258:9 | -LL | <Foo>::method_deprecated_text(&foo); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... <Foo>::method_deprecated_text(&foo); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::Trait::trait_deprecated_text': text +error: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text --> $DIR/deprecation-lint.rs:259:13 | LL | foo.trait_deprecated_text(); | ^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::Trait::trait_deprecated_text': text +error: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text --> $DIR/deprecation-lint.rs:261:9 | LL | <Foo>::trait_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::DeprecatedStruct::i': text +error: use of deprecated field `this_crate::DeprecatedStruct::i`: text --> $DIR/deprecation-lint.rs:270:13 | LL | i: 0 | ^^^^ -error: use of deprecated item 'this_crate::nested::DeprecatedStruct::i': text +error: use of deprecated field `this_crate::nested::DeprecatedStruct::i`: text --> $DIR/deprecation-lint.rs:281:13 | LL | i: 0 | ^^^^ -error: use of deprecated item 'this_crate::Trait::trait_deprecated': text +error: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text --> $DIR/deprecation-lint.rs:292:13 | LL | foo.trait_deprecated(); | ^^^^^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::Trait::trait_deprecated': text +error: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text --> $DIR/deprecation-lint.rs:294:9 | LL | <Foo>::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::Trait::trait_deprecated_text': text +error: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text --> $DIR/deprecation-lint.rs:296:13 | LL | foo.trait_deprecated_text(); | ^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::Trait::trait_deprecated_text': text +error: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text --> $DIR/deprecation-lint.rs:298:9 | LL | <Foo>::trait_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::Trait::trait_deprecated': text +error: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text --> $DIR/deprecation-lint.rs:303:13 | LL | foo.trait_deprecated(); | ^^^^^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::Trait::trait_deprecated_text': text +error: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text --> $DIR/deprecation-lint.rs:304:13 | LL | foo.trait_deprecated_text(); | ^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated item 'this_crate2::Stable::override2': text +error: use of deprecated field `this_crate2::Stable::override2`: text --> $DIR/deprecation-lint.rs:363:13 | LL | override2: 3, | ^^^^^^^^^^^^ -error: use of deprecated item 'this_crate2::Stable::override2': text +error: use of deprecated field `this_crate2::Stable::override2`: text --> $DIR/deprecation-lint.rs:367:17 | LL | let _ = x.override2; | ^^^^^^^^^^^ -error: use of deprecated item 'this_crate2::Stable::override2': text +error: use of deprecated field `this_crate2::Stable::override2`: text --> $DIR/deprecation-lint.rs:371:13 | LL | override2: _ | ^^^^^^^^^^^^ -error: use of deprecated item 'this_crate2::Stable2::2': text +error: use of deprecated field `this_crate2::Stable2::2`: text --> $DIR/deprecation-lint.rs:379:17 | LL | let _ = x.2; | ^^^ -error: use of deprecated item 'this_crate2::Stable2::2': text +error: use of deprecated field `this_crate2::Stable2::2`: text --> $DIR/deprecation-lint.rs:384:20 | LL | _) | ^ -error: use of deprecated item 'this_crate2::Deprecated::inherit': text +error: use of deprecated field `this_crate2::Deprecated::inherit`: text --> $DIR/deprecation-lint.rs:392:13 | LL | inherit: 1, | ^^^^^^^^^^ -error: use of deprecated item 'this_crate2::Deprecated::inherit': text +error: use of deprecated field `this_crate2::Deprecated::inherit`: text --> $DIR/deprecation-lint.rs:396:17 | LL | let _ = x.inherit; | ^^^^^^^^^ -error: use of deprecated item 'this_crate2::Deprecated::inherit': text +error: use of deprecated field `this_crate2::Deprecated::inherit`: text --> $DIR/deprecation-lint.rs:401:13 | LL | inherit: _, | ^^^^^^^^^^ -error: use of deprecated item 'this_crate2::Deprecated2::0': text +error: use of deprecated field `this_crate2::Deprecated2::0`: text --> $DIR/deprecation-lint.rs:413:17 | LL | let _ = x.0; | ^^^ -error: use of deprecated item 'this_crate2::Deprecated2::1': text +error: use of deprecated field `this_crate2::Deprecated2::1`: text --> $DIR/deprecation-lint.rs:415:17 | LL | let _ = x.1; | ^^^ -error: use of deprecated item 'this_crate2::Deprecated2::2': text +error: use of deprecated field `this_crate2::Deprecated2::2`: text --> $DIR/deprecation-lint.rs:417:17 | LL | let _ = x.2; | ^^^ -error: use of deprecated item 'this_crate2::Deprecated2::0': text +error: use of deprecated field `this_crate2::Deprecated2::0`: text --> $DIR/deprecation-lint.rs:422:14 | LL | (_, | ^ -error: use of deprecated item 'this_crate2::Deprecated2::1': text +error: use of deprecated field `this_crate2::Deprecated2::1`: text --> $DIR/deprecation-lint.rs:424:14 | LL | _, | ^ -error: use of deprecated item 'this_crate2::Deprecated2::2': text +error: use of deprecated field `this_crate2::Deprecated2::2`: text --> $DIR/deprecation-lint.rs:426:14 | LL | _) diff --git a/src/test/ui/deprecation/rustc_deprecation-in-future.rs b/src/test/ui/deprecation/rustc_deprecation-in-future.rs index a19363c5129..6a619bcc49c 100644 --- a/src/test/ui/deprecation/rustc_deprecation-in-future.rs +++ b/src/test/ui/deprecation/rustc_deprecation-in-future.rs @@ -11,5 +11,5 @@ pub struct S; fn main() { - let _ = S; //~ ERROR use of item 'S' that will be deprecated in future version 99.99.99: effectively never + let _ = S; //~ ERROR use of unit struct `S` that will be deprecated in future version 99.99.99: effectively never } diff --git a/src/test/ui/deprecation/rustc_deprecation-in-future.stderr b/src/test/ui/deprecation/rustc_deprecation-in-future.stderr index 4aff11ad66f..e4f50d10dad 100644 --- a/src/test/ui/deprecation/rustc_deprecation-in-future.stderr +++ b/src/test/ui/deprecation/rustc_deprecation-in-future.stderr @@ -1,4 +1,4 @@ -error: use of item 'S' that will be deprecated in future version 99.99.99: effectively never +error: use of unit struct `S` that will be deprecated in future version 99.99.99: effectively never --> $DIR/rustc_deprecation-in-future.rs:14:13 | LL | let _ = S; diff --git a/src/test/ui/deprecation/suggestion.stderr b/src/test/ui/deprecation/suggestion.stderr index b60d420b546..8a7cb1def90 100644 --- a/src/test/ui/deprecation/suggestion.stderr +++ b/src/test/ui/deprecation/suggestion.stderr @@ -1,8 +1,8 @@ -error: use of deprecated item 'Foo::deprecated': replaced by `replacement` +error: use of deprecated associated function `Foo::deprecated`: replaced by `replacement` --> $DIR/suggestion.rs:27:9 | LL | foo.deprecated(); - | ^^^^^^^^^^ help: replace the use of the deprecated item: `replacement` + | ^^^^^^^^^^ help: replace the use of the deprecated associated function: `replacement` | note: the lint level is defined here --> $DIR/suggestion.rs:7:9 diff --git a/src/test/ui/generator/issue-52398.rs b/src/test/ui/generator/issue-52398.rs index 54a1912582c..ada380d116c 100644 --- a/src/test/ui/generator/issue-52398.rs +++ b/src/test/ui/generator/issue-52398.rs @@ -14,14 +14,14 @@ impl A { fn main() { // Test that the MIR local with type &A created for the auto-borrow adjustment // is caught by typeck - move || { + move || { //~ WARN unused generator that must be used A.test(yield); }; // Test that the std::cell::Ref temporary returned from the `borrow` call // is caught by typeck let y = RefCell::new(true); - static move || { + static move || { //~ WARN unused generator that must be used yield *y.borrow(); return "Done"; }; diff --git a/src/test/ui/generator/issue-52398.stderr b/src/test/ui/generator/issue-52398.stderr new file mode 100644 index 00000000000..3f8ebb5a738 --- /dev/null +++ b/src/test/ui/generator/issue-52398.stderr @@ -0,0 +1,24 @@ +warning: unused generator that must be used + --> $DIR/issue-52398.rs:17:5 + | +LL | / move || { +LL | | A.test(yield); +LL | | }; + | |______^ + | + = note: `#[warn(unused_must_use)]` on by default + = note: generators are lazy and do nothing unless resumed + +warning: unused generator that must be used + --> $DIR/issue-52398.rs:24:5 + | +LL | / static move || { +LL | | yield *y.borrow(); +LL | | return "Done"; +LL | | }; + | |______^ + | + = note: generators are lazy and do nothing unless resumed + +warning: 2 warnings emitted + diff --git a/src/test/ui/generator/issue-57084.rs b/src/test/ui/generator/issue-57084.rs index 8aaa6a0e427..2a5c3dd0570 100644 --- a/src/test/ui/generator/issue-57084.rs +++ b/src/test/ui/generator/issue-57084.rs @@ -19,7 +19,7 @@ where F: Fn() -> () fn main() { let data = &vec![1]; - || { + || { //~ WARN unused generator that must be used let _to_pin = with(move || println!("{:p}", data)); loop { yield diff --git a/src/test/ui/generator/issue-57084.stderr b/src/test/ui/generator/issue-57084.stderr new file mode 100644 index 00000000000..32a04f94dcb --- /dev/null +++ b/src/test/ui/generator/issue-57084.stderr @@ -0,0 +1,16 @@ +warning: unused generator that must be used + --> $DIR/issue-57084.rs:22:5 + | +LL | / || { +LL | | let _to_pin = with(move || println!("{:p}", data)); +LL | | loop { +LL | | yield +LL | | } +LL | | }; + | |______^ + | + = note: `#[warn(unused_must_use)]` on by default + = note: generators are lazy and do nothing unless resumed + +warning: 1 warning emitted + diff --git a/src/test/ui/generator/match-bindings.rs b/src/test/ui/generator/match-bindings.rs index 560d8e7103c..865904a57d4 100644 --- a/src/test/ui/generator/match-bindings.rs +++ b/src/test/ui/generator/match-bindings.rs @@ -9,7 +9,7 @@ enum Enum { } fn main() { - || { + || { //~ WARN unused generator that must be used loop { if let true = true { match Enum::A(String::new()) { diff --git a/src/test/ui/generator/match-bindings.stderr b/src/test/ui/generator/match-bindings.stderr new file mode 100644 index 00000000000..4fd1e26f0c8 --- /dev/null +++ b/src/test/ui/generator/match-bindings.stderr @@ -0,0 +1,17 @@ +warning: unused generator that must be used + --> $DIR/match-bindings.rs:12:5 + | +LL | / || { +LL | | loop { +LL | | if let true = true { +LL | | match Enum::A(String::new()) { +... | +LL | | } +LL | | }; + | |______^ + | + = note: `#[warn(unused_must_use)]` on by default + = note: generators are lazy and do nothing unless resumed + +warning: 1 warning emitted + diff --git a/src/test/ui/generator/reborrow-mut-upvar.rs b/src/test/ui/generator/reborrow-mut-upvar.rs index 785e38a7eb8..dbd9e24e205 100644 --- a/src/test/ui/generator/reborrow-mut-upvar.rs +++ b/src/test/ui/generator/reborrow-mut-upvar.rs @@ -3,7 +3,7 @@ #![feature(generators)] fn _run(bar: &mut i32) { - || { + || { //~ WARN unused generator that must be used { let _baz = &*bar; yield; diff --git a/src/test/ui/generator/reborrow-mut-upvar.stderr b/src/test/ui/generator/reborrow-mut-upvar.stderr new file mode 100644 index 00000000000..ff511b76672 --- /dev/null +++ b/src/test/ui/generator/reborrow-mut-upvar.stderr @@ -0,0 +1,17 @@ +warning: unused generator that must be used + --> $DIR/reborrow-mut-upvar.rs:6:5 + | +LL | / || { +LL | | { +LL | | let _baz = &*bar; +LL | | yield; +... | +LL | | *bar = 2; +LL | | }; + | |______^ + | + = note: `#[warn(unused_must_use)]` on by default + = note: generators are lazy and do nothing unless resumed + +warning: 1 warning emitted + diff --git a/src/test/ui/generator/too-live-local-in-immovable-gen.rs b/src/test/ui/generator/too-live-local-in-immovable-gen.rs index f299a8aa72b..7f118c88e5e 100644 --- a/src/test/ui/generator/too-live-local-in-immovable-gen.rs +++ b/src/test/ui/generator/too-live-local-in-immovable-gen.rs @@ -5,7 +5,7 @@ fn main() { unsafe { - static move || { + static move || { //~ WARN unused generator that must be used // Tests that the generator transformation finds out that `a` is not live // during the yield expression. Type checking will also compute liveness // and it should also find out that `a` is not live. diff --git a/src/test/ui/generator/too-live-local-in-immovable-gen.stderr b/src/test/ui/generator/too-live-local-in-immovable-gen.stderr new file mode 100644 index 00000000000..88dacff7b55 --- /dev/null +++ b/src/test/ui/generator/too-live-local-in-immovable-gen.stderr @@ -0,0 +1,17 @@ +warning: unused generator that must be used + --> $DIR/too-live-local-in-immovable-gen.rs:8:9 + | +LL | / static move || { +LL | | // Tests that the generator transformation finds out that `a` is not live +LL | | // during the yield expression. Type checking will also compute liveness +LL | | // and it should also find out that `a` is not live. +... | +LL | | &a; +LL | | }; + | |__________^ + | + = note: `#[warn(unused_must_use)]` on by default + = note: generators are lazy and do nothing unless resumed + +warning: 1 warning emitted + diff --git a/src/test/ui/generator/yield-in-args-rev.rs b/src/test/ui/generator/yield-in-args-rev.rs index f9ab981121a..4c99bb3ef5e 100644 --- a/src/test/ui/generator/yield-in-args-rev.rs +++ b/src/test/ui/generator/yield-in-args-rev.rs @@ -10,7 +10,7 @@ fn foo(_a: (), _b: &bool) {} fn bar() { - || { + || { //~ WARN unused generator that must be used let b = true; foo(yield, &b); }; diff --git a/src/test/ui/generator/yield-in-args-rev.stderr b/src/test/ui/generator/yield-in-args-rev.stderr new file mode 100644 index 00000000000..a575bf88678 --- /dev/null +++ b/src/test/ui/generator/yield-in-args-rev.stderr @@ -0,0 +1,14 @@ +warning: unused generator that must be used + --> $DIR/yield-in-args-rev.rs:13:5 + | +LL | / || { +LL | | let b = true; +LL | | foo(yield, &b); +LL | | }; + | |______^ + | + = note: `#[warn(unused_must_use)]` on by default + = note: generators are lazy and do nothing unless resumed + +warning: 1 warning emitted + diff --git a/src/test/ui/generator/yield-in-box.rs b/src/test/ui/generator/yield-in-box.rs index d8475715c7c..65f368df9cb 100644 --- a/src/test/ui/generator/yield-in-box.rs +++ b/src/test/ui/generator/yield-in-box.rs @@ -6,7 +6,7 @@ fn main() { let x = 0i32; - || { + || { //~ WARN unused generator that must be used let y = 2u32; { let _t = box (&x, yield 0, &y); diff --git a/src/test/ui/generator/yield-in-box.stderr b/src/test/ui/generator/yield-in-box.stderr new file mode 100644 index 00000000000..24de18edb0f --- /dev/null +++ b/src/test/ui/generator/yield-in-box.stderr @@ -0,0 +1,17 @@ +warning: unused generator that must be used + --> $DIR/yield-in-box.rs:9:5 + | +LL | / || { +LL | | let y = 2u32; +LL | | { +LL | | let _t = box (&x, yield 0, &y); +... | +LL | | } +LL | | }; + | |______^ + | + = note: `#[warn(unused_must_use)]` on by default + = note: generators are lazy and do nothing unless resumed + +warning: 1 warning emitted + diff --git a/src/test/ui/generator/yield-in-initializer.rs b/src/test/ui/generator/yield-in-initializer.rs index 8ff35d8ddf1..2f8754c9571 100644 --- a/src/test/ui/generator/yield-in-initializer.rs +++ b/src/test/ui/generator/yield-in-initializer.rs @@ -3,7 +3,7 @@ #![feature(generators)] fn main() { - static || { + static || { //~ WARN unused generator that must be used loop { // Test that `opt` is not live across the yield, even when borrowed in a loop // See https://github.com/rust-lang/rust/issues/52792 diff --git a/src/test/ui/generator/yield-in-initializer.stderr b/src/test/ui/generator/yield-in-initializer.stderr new file mode 100644 index 00000000000..e79047ae701 --- /dev/null +++ b/src/test/ui/generator/yield-in-initializer.stderr @@ -0,0 +1,17 @@ +warning: unused generator that must be used + --> $DIR/yield-in-initializer.rs:6:5 + | +LL | / static || { +LL | | loop { +LL | | // Test that `opt` is not live across the yield, even when borrowed in a loop +LL | | // See https://github.com/rust-lang/rust/issues/52792 +... | +LL | | } +LL | | }; + | |______^ + | + = note: `#[warn(unused_must_use)]` on by default + = note: generators are lazy and do nothing unless resumed + +warning: 1 warning emitted + diff --git a/src/test/ui/generator/yield-subtype.rs b/src/test/ui/generator/yield-subtype.rs index fe88d424dd1..cb3fc909145 100644 --- a/src/test/ui/generator/yield-subtype.rs +++ b/src/test/ui/generator/yield-subtype.rs @@ -8,7 +8,7 @@ fn bar<'a>() { let a: &'static str = "hi"; let b: &'a str = a; - || { + || { //~ WARN unused generator that must be used yield a; yield b; }; diff --git a/src/test/ui/generator/yield-subtype.stderr b/src/test/ui/generator/yield-subtype.stderr new file mode 100644 index 00000000000..bded36a4cda --- /dev/null +++ b/src/test/ui/generator/yield-subtype.stderr @@ -0,0 +1,14 @@ +warning: unused generator that must be used + --> $DIR/yield-subtype.rs:11:5 + | +LL | / || { +LL | | yield a; +LL | | yield b; +LL | | }; + | |______^ + | + = note: `#[warn(unused_must_use)]` on by default + = note: generators are lazy and do nothing unless resumed + +warning: 1 warning emitted + diff --git a/src/test/ui/half-open-range-patterns/half-open-range-pats-hair-lower-empty.rs b/src/test/ui/half-open-range-patterns/half-open-range-pats-thir-lower-empty.rs index 904efda903c..904efda903c 100644 --- a/src/test/ui/half-open-range-patterns/half-open-range-pats-hair-lower-empty.rs +++ b/src/test/ui/half-open-range-patterns/half-open-range-pats-thir-lower-empty.rs diff --git a/src/test/ui/half-open-range-patterns/half-open-range-pats-hair-lower-empty.stderr b/src/test/ui/half-open-range-patterns/half-open-range-pats-thir-lower-empty.stderr index b536e1b5548..12ad8642961 100644 --- a/src/test/ui/half-open-range-patterns/half-open-range-pats-hair-lower-empty.stderr +++ b/src/test/ui/half-open-range-patterns/half-open-range-pats-thir-lower-empty.stderr @@ -1,155 +1,155 @@ error[E0579]: lower range bound must be less than upper - --> $DIR/half-open-range-pats-hair-lower-empty.rs:12:11 + --> $DIR/half-open-range-pats-thir-lower-empty.rs:12:11 | LL | m!(0, ..core::u8::MIN); | ^^^^^^^^^^^^^^^ error[E0579]: lower range bound must be less than upper - --> $DIR/half-open-range-pats-hair-lower-empty.rs:15:11 + --> $DIR/half-open-range-pats-thir-lower-empty.rs:15:11 | LL | m!(0, ..core::u16::MIN); | ^^^^^^^^^^^^^^^^ error[E0579]: lower range bound must be less than upper - --> $DIR/half-open-range-pats-hair-lower-empty.rs:18:11 + --> $DIR/half-open-range-pats-thir-lower-empty.rs:18:11 | LL | m!(0, ..core::u32::MIN); | ^^^^^^^^^^^^^^^^ error[E0579]: lower range bound must be less than upper - --> $DIR/half-open-range-pats-hair-lower-empty.rs:21:11 + --> $DIR/half-open-range-pats-thir-lower-empty.rs:21:11 | LL | m!(0, ..core::u64::MIN); | ^^^^^^^^^^^^^^^^ error[E0579]: lower range bound must be less than upper - --> $DIR/half-open-range-pats-hair-lower-empty.rs:24:11 + --> $DIR/half-open-range-pats-thir-lower-empty.rs:24:11 | LL | m!(0, ..core::u128::MIN); | ^^^^^^^^^^^^^^^^^ error[E0579]: lower range bound must be less than upper - --> $DIR/half-open-range-pats-hair-lower-empty.rs:28:11 + --> $DIR/half-open-range-pats-thir-lower-empty.rs:28:11 | LL | m!(0, ..core::i8::MIN); | ^^^^^^^^^^^^^^^ error[E0579]: lower range bound must be less than upper - --> $DIR/half-open-range-pats-hair-lower-empty.rs:31:11 + --> $DIR/half-open-range-pats-thir-lower-empty.rs:31:11 | LL | m!(0, ..core::i16::MIN); | ^^^^^^^^^^^^^^^^ error[E0579]: lower range bound must be less than upper - --> $DIR/half-open-range-pats-hair-lower-empty.rs:34:11 + --> $DIR/half-open-range-pats-thir-lower-empty.rs:34:11 | LL | m!(0, ..core::i32::MIN); | ^^^^^^^^^^^^^^^^ error[E0579]: lower range bound must be less than upper - --> $DIR/half-open-range-pats-hair-lower-empty.rs:37:11 + --> $DIR/half-open-range-pats-thir-lower-empty.rs:37:11 | LL | m!(0, ..core::i64::MIN); | ^^^^^^^^^^^^^^^^ error[E0579]: lower range bound must be less than upper - --> $DIR/half-open-range-pats-hair-lower-empty.rs:40:11 + --> $DIR/half-open-range-pats-thir-lower-empty.rs:40:11 | LL | m!(0, ..core::i128::MIN); | ^^^^^^^^^^^^^^^^^ error[E0579]: lower range bound must be less than upper - --> $DIR/half-open-range-pats-hair-lower-empty.rs:44:14 + --> $DIR/half-open-range-pats-thir-lower-empty.rs:44:14 | LL | m!(0f32, ..core::f32::NEG_INFINITY); | ^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0579]: lower range bound must be less than upper - --> $DIR/half-open-range-pats-hair-lower-empty.rs:47:14 + --> $DIR/half-open-range-pats-thir-lower-empty.rs:47:14 | LL | m!(0f64, ..core::f64::NEG_INFINITY); | ^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0579]: lower range bound must be less than upper - --> $DIR/half-open-range-pats-hair-lower-empty.rs:51:13 + --> $DIR/half-open-range-pats-thir-lower-empty.rs:51:13 | LL | m!('a', ..'\u{0}'); | ^^^^^^^^^ error[E0579]: lower range bound must be less than upper - --> $DIR/half-open-range-pats-hair-lower-empty.rs:12:11 + --> $DIR/half-open-range-pats-thir-lower-empty.rs:12:11 | LL | m!(0, ..core::u8::MIN); | ^^^^^^^^^^^^^^^ error[E0579]: lower range bound must be less than upper - --> $DIR/half-open-range-pats-hair-lower-empty.rs:15:11 + --> $DIR/half-open-range-pats-thir-lower-empty.rs:15:11 | LL | m!(0, ..core::u16::MIN); | ^^^^^^^^^^^^^^^^ error[E0579]: lower range bound must be less than upper - --> $DIR/half-open-range-pats-hair-lower-empty.rs:18:11 + --> $DIR/half-open-range-pats-thir-lower-empty.rs:18:11 | LL | m!(0, ..core::u32::MIN); | ^^^^^^^^^^^^^^^^ error[E0579]: lower range bound must be less than upper - --> $DIR/half-open-range-pats-hair-lower-empty.rs:21:11 + --> $DIR/half-open-range-pats-thir-lower-empty.rs:21:11 | LL | m!(0, ..core::u64::MIN); | ^^^^^^^^^^^^^^^^ error[E0579]: lower range bound must be less than upper - --> $DIR/half-open-range-pats-hair-lower-empty.rs:24:11 + --> $DIR/half-open-range-pats-thir-lower-empty.rs:24:11 | LL | m!(0, ..core::u128::MIN); | ^^^^^^^^^^^^^^^^^ error[E0579]: lower range bound must be less than upper - --> $DIR/half-open-range-pats-hair-lower-empty.rs:28:11 + --> $DIR/half-open-range-pats-thir-lower-empty.rs:28:11 | LL | m!(0, ..core::i8::MIN); | ^^^^^^^^^^^^^^^ error[E0579]: lower range bound must be less than upper - --> $DIR/half-open-range-pats-hair-lower-empty.rs:31:11 + --> $DIR/half-open-range-pats-thir-lower-empty.rs:31:11 | LL | m!(0, ..core::i16::MIN); | ^^^^^^^^^^^^^^^^ error[E0579]: lower range bound must be less than upper - --> $DIR/half-open-range-pats-hair-lower-empty.rs:34:11 + --> $DIR/half-open-range-pats-thir-lower-empty.rs:34:11 | LL | m!(0, ..core::i32::MIN); | ^^^^^^^^^^^^^^^^ error[E0579]: lower range bound must be less than upper - --> $DIR/half-open-range-pats-hair-lower-empty.rs:37:11 + --> $DIR/half-open-range-pats-thir-lower-empty.rs:37:11 | LL | m!(0, ..core::i64::MIN); | ^^^^^^^^^^^^^^^^ error[E0579]: lower range bound must be less than upper - --> $DIR/half-open-range-pats-hair-lower-empty.rs:40:11 + --> $DIR/half-open-range-pats-thir-lower-empty.rs:40:11 | LL | m!(0, ..core::i128::MIN); | ^^^^^^^^^^^^^^^^^ error[E0579]: lower range bound must be less than upper - --> $DIR/half-open-range-pats-hair-lower-empty.rs:44:14 + --> $DIR/half-open-range-pats-thir-lower-empty.rs:44:14 | LL | m!(0f32, ..core::f32::NEG_INFINITY); | ^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0579]: lower range bound must be less than upper - --> $DIR/half-open-range-pats-hair-lower-empty.rs:47:14 + --> $DIR/half-open-range-pats-thir-lower-empty.rs:47:14 | LL | m!(0f64, ..core::f64::NEG_INFINITY); | ^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0579]: lower range bound must be less than upper - --> $DIR/half-open-range-pats-hair-lower-empty.rs:51:13 + --> $DIR/half-open-range-pats-thir-lower-empty.rs:51:13 | LL | m!('a', ..'\u{0}'); | ^^^^^^^^^ diff --git a/src/test/ui/issues/issue-1460.rs b/src/test/ui/issues/issue-1460.rs index 143a0387e21..e663f7fd4c9 100644 --- a/src/test/ui/issues/issue-1460.rs +++ b/src/test/ui/issues/issue-1460.rs @@ -3,5 +3,5 @@ // pretty-expanded FIXME #23616 pub fn main() { - {|i: u32| if 1 == i { }}; + {|i: u32| if 1 == i { }}; //~ WARN unused closure that must be used } diff --git a/src/test/ui/issues/issue-1460.stderr b/src/test/ui/issues/issue-1460.stderr new file mode 100644 index 00000000000..26f95f5af3d --- /dev/null +++ b/src/test/ui/issues/issue-1460.stderr @@ -0,0 +1,11 @@ +warning: unused closure that must be used + --> $DIR/issue-1460.rs:6:5 + | +LL | {|i: u32| if 1 == i { }}; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(unused_must_use)]` on by default + = note: closures are lazy and do nothing unless called + +warning: 1 warning emitted + diff --git a/src/test/ui/issues/issue-16256.rs b/src/test/ui/issues/issue-16256.rs index e566eede8d2..eec23437bcb 100644 --- a/src/test/ui/issues/issue-16256.rs +++ b/src/test/ui/issues/issue-16256.rs @@ -3,5 +3,5 @@ fn main() { let mut buf = Vec::new(); - |c: u8| buf.push(c); + |c: u8| buf.push(c); //~ WARN unused closure that must be used } diff --git a/src/test/ui/issues/issue-16256.stderr b/src/test/ui/issues/issue-16256.stderr new file mode 100644 index 00000000000..9c7312461c4 --- /dev/null +++ b/src/test/ui/issues/issue-16256.stderr @@ -0,0 +1,11 @@ +warning: unused closure that must be used + --> $DIR/issue-16256.rs:6:5 + | +LL | |c: u8| buf.push(c); + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(unused_must_use)]` on by default + = note: closures are lazy and do nothing unless called + +warning: 1 warning emitted + diff --git a/src/test/ui/issues/issue-17337.rs b/src/test/ui/issues/issue-17337.rs index 65f2f8fc5ac..3fd81401e00 100644 --- a/src/test/ui/issues/issue-17337.rs +++ b/src/test/ui/issues/issue-17337.rs @@ -13,5 +13,5 @@ impl Foo { fn main() { Foo - .foo(); //~ ERROR use of deprecated item + .foo(); //~ ERROR use of deprecated } diff --git a/src/test/ui/issues/issue-17337.stderr b/src/test/ui/issues/issue-17337.stderr index 4a8116b1ffd..34c2eb05fff 100644 --- a/src/test/ui/issues/issue-17337.stderr +++ b/src/test/ui/issues/issue-17337.stderr @@ -1,4 +1,4 @@ -error: use of deprecated item 'Foo::foo': text +error: use of deprecated associated function `Foo::foo`: text --> $DIR/issue-17337.rs:16:6 | LL | .foo(); diff --git a/src/test/ui/issues/issue-37131.rs b/src/test/ui/issues/issue-37131.rs index aa3b6ea86bb..ac2d1d1ed8b 100644 --- a/src/test/ui/issues/issue-37131.rs +++ b/src/test/ui/issues/issue-37131.rs @@ -3,6 +3,7 @@ // compile-flags: --target=thumbv6m-none-eabi // ignore-arm +// needs-llvm-components: arm // error-pattern:target may not be installed fn main() { } diff --git a/src/test/ui/issues/issue-49851/compiler-builtins-error.rs b/src/test/ui/issues/issue-49851/compiler-builtins-error.rs index 9449376513f..ddb070ddf9f 100644 --- a/src/test/ui/issues/issue-49851/compiler-builtins-error.rs +++ b/src/test/ui/issues/issue-49851/compiler-builtins-error.rs @@ -1,6 +1,7 @@ //~ ERROR 1:1: 1:1: can't find crate for `core` [E0463] // compile-flags: --target thumbv7em-none-eabihf +// needs-llvm-components: arm #![deny(unsafe_code)] #![deny(warnings)] #![no_std] diff --git a/src/test/ui/issues/issue-50993.rs b/src/test/ui/issues/issue-50993.rs index d38eb826678..e6a9451a060 100644 --- a/src/test/ui/issues/issue-50993.rs +++ b/src/test/ui/issues/issue-50993.rs @@ -1,4 +1,5 @@ // compile-flags: --crate-type dylib --target thumbv7em-none-eabihf +// needs-llvm-components: arm // build-pass // error-pattern: dropping unsupported crate type `dylib` for target `thumbv7em-none-eabihf` diff --git a/src/test/ui/issues/issue-72574-1.rs b/src/test/ui/issues/issue-72574-1.rs index efbb0bfb150..1b80a21793a 100644 --- a/src/test/ui/issues/issue-72574-1.rs +++ b/src/test/ui/issues/issue-72574-1.rs @@ -6,3 +6,5 @@ fn main() { } } //~^^^^ ERROR `_x @` is not allowed in a tuple +//~| ERROR: `..` patterns are not allowed here +//~| ERROR: mismatched types diff --git a/src/test/ui/issues/issue-72574-1.stderr b/src/test/ui/issues/issue-72574-1.stderr index 329f7d008d4..92ebb45e88d 100644 --- a/src/test/ui/issues/issue-72574-1.stderr +++ b/src/test/ui/issues/issue-72574-1.stderr @@ -10,5 +10,25 @@ help: if you don't need to use the contents of _x, discard the tuple's remaining LL | (_a, ..) => {} | ^^ -error: aborting due to previous error +error: `..` patterns are not allowed here + --> $DIR/issue-72574-1.rs:4:19 + | +LL | (_a, _x @ ..) => {} + | ^^ + | + = note: only allowed in tuple, tuple struct, and slice patterns + +error[E0308]: mismatched types + --> $DIR/issue-72574-1.rs:4:9 + | +LL | match x { + | - this expression has type `({integer}, {integer}, {integer})` +LL | (_a, _x @ ..) => {} + | ^^^^^^^^^^^^^ expected a tuple with 3 elements, found one with 2 elements + | + = note: expected tuple `({integer}, {integer}, {integer})` + found tuple `(_, _)` + +error: aborting due to 3 previous errors +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/issues/issue-72574-2.rs b/src/test/ui/issues/issue-72574-2.rs index 0c8f6fcc508..0ad2db848b2 100644 --- a/src/test/ui/issues/issue-72574-2.rs +++ b/src/test/ui/issues/issue-72574-2.rs @@ -8,3 +8,5 @@ fn main() { } } //~^^^^ ERROR `_x @` is not allowed in a tuple struct +//~| ERROR: `..` patterns are not allowed here +//~| ERROR: this pattern has 2 fields, but the corresponding tuple struct has 3 fields diff --git a/src/test/ui/issues/issue-72574-2.stderr b/src/test/ui/issues/issue-72574-2.stderr index 6faa57bcca6..0a9c868af7a 100644 --- a/src/test/ui/issues/issue-72574-2.stderr +++ b/src/test/ui/issues/issue-72574-2.stderr @@ -10,5 +10,23 @@ help: if you don't need to use the contents of _x, discard the tuple's remaining LL | Binder(_a, ..) => {} | ^^ -error: aborting due to previous error +error: `..` patterns are not allowed here + --> $DIR/issue-72574-2.rs:6:25 + | +LL | Binder(_a, _x @ ..) => {} + | ^^ + | + = note: only allowed in tuple, tuple struct, and slice patterns + +error[E0023]: this pattern has 2 fields, but the corresponding tuple struct has 3 fields + --> $DIR/issue-72574-2.rs:6:9 + | +LL | struct Binder(i32, i32, i32); + | ----------------------------- tuple struct defined here +... +LL | Binder(_a, _x @ ..) => {} + | ^^^^^^^^^^^^^^^^^^^ expected 3 fields, found 2 + +error: aborting due to 3 previous errors +For more information about this error, try `rustc --explain E0023`. diff --git a/src/test/ui/issues/issue-74539.rs b/src/test/ui/issues/issue-74539.rs deleted file mode 100644 index 75632d11c1d..00000000000 --- a/src/test/ui/issues/issue-74539.rs +++ /dev/null @@ -1,12 +0,0 @@ -enum E { - A(u8, u8), -} - -fn main() { - let e = E::A(2, 3); - match e { - E::A(x @ ..) => { //~ ERROR `x @` is not allowed in a tuple - x //~ ERROR cannot find value `x` in this scope - } - }; -} diff --git a/src/test/ui/issues/issue-74539.stderr b/src/test/ui/issues/issue-74539.stderr deleted file mode 100644 index 94526dcd7cb..00000000000 --- a/src/test/ui/issues/issue-74539.stderr +++ /dev/null @@ -1,21 +0,0 @@ -error[E0425]: cannot find value `x` in this scope - --> $DIR/issue-74539.rs:9:13 - | -LL | x - | ^ help: a local variable with a similar name exists: `e` - -error: `x @` is not allowed in a tuple struct - --> $DIR/issue-74539.rs:8:14 - | -LL | E::A(x @ ..) => { - | ^^^^^^ this is only allowed in slice patterns - | - = help: remove this and bind each tuple field independently -help: if you don't need to use the contents of x, discard the tuple's remaining fields - | -LL | E::A(..) => { - | ^^ - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0425`. diff --git a/src/test/ui/issues/issue-74614.rs b/src/test/ui/issues/issue-74614.rs index f5e8deb29fb..8b0c00b1355 100644 --- a/src/test/ui/issues/issue-74614.rs +++ b/src/test/ui/issues/issue-74614.rs @@ -1,3 +1,4 @@ +// compile-flags:-Zpolymorphize=on // build-pass fn test<T>() { diff --git a/src/test/ui/lint/auxiliary/external_extern_fn.rs b/src/test/ui/lint/auxiliary/external_extern_fn.rs index b2caebc6fee..c2a8cadc6b5 100644 --- a/src/test/ui/lint/auxiliary/external_extern_fn.rs +++ b/src/test/ui/lint/auxiliary/external_extern_fn.rs @@ -1,3 +1,3 @@ -extern { +extern "C" { pub fn extern_fn(x: u8); } diff --git a/src/test/ui/lint/clashing-extern-fn.rs b/src/test/ui/lint/clashing-extern-fn.rs index 544614100ba..d6ac7ccccc7 100644 --- a/src/test/ui/lint/clashing-extern-fn.rs +++ b/src/test/ui/lint/clashing-extern-fn.rs @@ -3,52 +3,40 @@ #![crate_type = "lib"] #![warn(clashing_extern_declarations)] -extern crate external_extern_fn; - -extern "C" { - fn clash(x: u8); - fn no_clash(x: u8); -} - -fn redeclared_different_signature() { - extern "C" { - fn clash(x: u64); //~ WARN `clash` redeclared with a different signature +mod redeclared_different_signature { + mod a { + extern "C" { + fn clash(x: u8); + } } - - unsafe { - clash(123); - no_clash(123); + mod b { + extern "C" { + fn clash(x: u64); //~ WARN `clash` redeclared with a different signature + } } } -fn redeclared_same_signature() { - extern "C" { - fn no_clash(x: u8); +mod redeclared_same_signature { + mod a { + extern "C" { + fn no_clash(x: u8); + } } - unsafe { - no_clash(123); + mod b { + extern "C" { + fn no_clash(x: u8); + } } } -extern "C" { - fn extern_fn(x: u64); -} - -fn extern_clash() { +extern crate external_extern_fn; +mod extern_no_clash { + // Should not clash with external_extern_fn::extern_fn. extern "C" { - fn extern_fn(x: u32); //~ WARN `extern_fn` redeclared with a different signature - } - unsafe { - extern_fn(123); + fn extern_fn(x: u8); } } -fn extern_no_clash() { - unsafe { - external_extern_fn::extern_fn(123); - crate::extern_fn(123); - } -} extern "C" { fn some_other_new_name(x: i16); @@ -134,9 +122,9 @@ mod banana { weight: u32, length: u16, } // note: distinct type - extern "C" { // This should not trigger the lint because two::Banana is structurally equivalent to // one::Banana. + extern "C" { fn weigh_banana(count: *const Banana) -> u64; } } @@ -180,7 +168,120 @@ mod sameish_members { // always be the case, for every architecture and situation. This is also a really odd // thing to do anyway. extern "C" { - fn draw_point(p: Point); //~ WARN `draw_point` redeclared with a different + fn draw_point(p: Point); + //~^ WARN `draw_point` redeclared with a different signature + } + } +} + +mod same_sized_members_clash { + mod a { + #[repr(C)] + struct Point3 { + x: f32, + y: f32, + z: f32, + } + extern "C" { fn origin() -> Point3; } + } + mod b { + #[repr(C)] + struct Point3 { + x: i32, + y: i32, + z: i32, // NOTE: Incorrectly redeclared as i32 + } + extern "C" { fn origin() -> Point3; } + //~^ WARN `origin` redeclared with a different signature + } +} + +mod transparent { + #[repr(transparent)] + struct T(usize); + mod a { + use super::T; + extern "C" { + fn transparent() -> T; + fn transparent_incorrect() -> T; + } + } + + mod b { + extern "C" { + // Shouldn't warn here, because repr(transparent) guarantees that T's layout is the + // same as just the usize. + fn transparent() -> usize; + + // Should warn, because there's a signedness conversion here: + fn transparent_incorrect() -> isize; + //~^ WARN `transparent_incorrect` redeclared with a different signature + } + } +} + +mod missing_return_type { + mod a { + extern "C" { + fn missing_return_type() -> usize; + } + } + + mod b { + extern "C" { + // This should output a warning because we can't assume that the first declaration is + // the correct one -- if this one is the correct one, then calling the usize-returning + // version would allow reads into uninitialised memory. + fn missing_return_type(); + //~^ WARN `missing_return_type` redeclared with a different signature + } + } +} + +mod non_zero_and_non_null { + mod a { + extern "C" { + fn non_zero_usize() -> core::num::NonZeroUsize; + fn non_null_ptr() -> core::ptr::NonNull<usize>; + } + } + mod b { + extern "C" { + // If there's a clash in either of these cases you're either gaining an incorrect + // invariant that the value is non-zero, or you're missing out on that invariant. Both + // cases are warning for, from both a caller-convenience and optimisation perspective. + fn non_zero_usize() -> usize; + //~^ WARN `non_zero_usize` redeclared with a different signature + fn non_null_ptr() -> *const usize; + //~^ WARN `non_null_ptr` redeclared with a different signature + } + } +} + +mod null_optimised_enums { + mod a { + extern "C" { + fn option_non_zero_usize() -> usize; + fn option_non_zero_isize() -> isize; + fn option_non_null_ptr() -> *const usize; + + fn option_non_zero_usize_incorrect() -> usize; + fn option_non_null_ptr_incorrect() -> *const usize; + } + } + mod b { + extern "C" { + // This should be allowed, because these conversions are guaranteed to be FFI-safe (see + // #60300) + fn option_non_zero_usize() -> Option<core::num::NonZeroUsize>; + fn option_non_zero_isize() -> Option<core::num::NonZeroIsize>; + fn option_non_null_ptr() -> Option<core::ptr::NonNull<usize>>; + + // However, these should be incorrect (note isize instead of usize) + fn option_non_zero_usize_incorrect() -> isize; + //~^ WARN `option_non_zero_usize_incorrect` redeclared with a different signature + fn option_non_null_ptr_incorrect() -> *const isize; + //~^ WARN `option_non_null_ptr_incorrect` redeclared with a different signature } } } diff --git a/src/test/ui/lint/clashing-extern-fn.stderr b/src/test/ui/lint/clashing-extern-fn.stderr index 96e51ab5a3e..cca0c4c59eb 100644 --- a/src/test/ui/lint/clashing-extern-fn.stderr +++ b/src/test/ui/lint/clashing-extern-fn.stderr @@ -1,11 +1,11 @@ warning: `clash` redeclared with a different signature - --> $DIR/clashing-extern-fn.rs:15:9 + --> $DIR/clashing-extern-fn.rs:14:13 | -LL | fn clash(x: u8); - | ---------------- `clash` previously declared here +LL | fn clash(x: u8); + | ---------------- `clash` previously declared here ... -LL | fn clash(x: u64); - | ^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration +LL | fn clash(x: u64); + | ^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration | note: the lint level is defined here --> $DIR/clashing-extern-fn.rs:4:9 @@ -15,20 +15,8 @@ LL | #![warn(clashing_extern_declarations)] = note: expected `unsafe extern "C" fn(u8)` found `unsafe extern "C" fn(u64)` -warning: `extern_fn` redeclared with a different signature - --> $DIR/clashing-extern-fn.rs:39:9 - | -LL | fn extern_fn(x: u64); - | --------------------- `extern_fn` previously declared here -... -LL | fn extern_fn(x: u32); - | ^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration - | - = note: expected `unsafe extern "C" fn(u64)` - found `unsafe extern "C" fn(u32)` - warning: `extern_link_name` redeclared with a different signature - --> $DIR/clashing-extern-fn.rs:64:9 + --> $DIR/clashing-extern-fn.rs:52:9 | LL | / #[link_name = "extern_link_name"] LL | | fn some_new_name(x: i16); @@ -41,7 +29,7 @@ LL | fn extern_link_name(x: u32); found `unsafe extern "C" fn(u32)` warning: `some_other_extern_link_name` redeclares `some_other_new_name` with a different signature - --> $DIR/clashing-extern-fn.rs:67:9 + --> $DIR/clashing-extern-fn.rs:55:9 | LL | fn some_other_new_name(x: i16); | ------------------------------- `some_other_new_name` previously declared here @@ -55,7 +43,7 @@ LL | | fn some_other_extern_link_name(x: u32); found `unsafe extern "C" fn(u32)` warning: `other_both_names_different` redeclares `link_name_same` with a different signature - --> $DIR/clashing-extern-fn.rs:71:9 + --> $DIR/clashing-extern-fn.rs:59:9 | LL | / #[link_name = "link_name_same"] LL | | fn both_names_different(x: i16); @@ -70,7 +58,7 @@ LL | | fn other_both_names_different(x: u32); found `unsafe extern "C" fn(u32)` warning: `different_mod` redeclared with a different signature - --> $DIR/clashing-extern-fn.rs:84:9 + --> $DIR/clashing-extern-fn.rs:72:9 | LL | fn different_mod(x: u8); | ------------------------ `different_mod` previously declared here @@ -82,7 +70,7 @@ LL | fn different_mod(x: u64); found `unsafe extern "C" fn(u64)` warning: `variadic_decl` redeclared with a different signature - --> $DIR/clashing-extern-fn.rs:94:9 + --> $DIR/clashing-extern-fn.rs:82:9 | LL | fn variadic_decl(x: u8, ...); | ----------------------------- `variadic_decl` previously declared here @@ -94,7 +82,7 @@ LL | fn variadic_decl(x: u8); found `unsafe extern "C" fn(u8)` warning: `weigh_banana` redeclared with a different signature - --> $DIR/clashing-extern-fn.rs:154:13 + --> $DIR/clashing-extern-fn.rs:142:13 | LL | fn weigh_banana(count: *const Banana) -> u64; | --------------------------------------------- `weigh_banana` previously declared here @@ -106,7 +94,7 @@ LL | fn weigh_banana(count: *const Banana) -> u64; found `unsafe extern "C" fn(*const banana::three::Banana) -> u64` warning: `draw_point` redeclared with a different signature - --> $DIR/clashing-extern-fn.rs:183:13 + --> $DIR/clashing-extern-fn.rs:171:13 | LL | fn draw_point(p: Point); | ------------------------ `draw_point` previously declared here @@ -117,5 +105,89 @@ LL | fn draw_point(p: Point); = note: expected `unsafe extern "C" fn(sameish_members::a::Point)` found `unsafe extern "C" fn(sameish_members::b::Point)` -warning: 9 warnings emitted +warning: `origin` redeclared with a different signature + --> $DIR/clashing-extern-fn.rs:194:22 + | +LL | extern "C" { fn origin() -> Point3; } + | ---------------------- `origin` previously declared here +... +LL | extern "C" { fn origin() -> Point3; } + | ^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration + | + = note: expected `unsafe extern "C" fn() -> same_sized_members_clash::a::Point3` + found `unsafe extern "C" fn() -> same_sized_members_clash::b::Point3` + +warning: `transparent_incorrect` redeclared with a different signature + --> $DIR/clashing-extern-fn.rs:217:13 + | +LL | fn transparent_incorrect() -> T; + | -------------------------------- `transparent_incorrect` previously declared here +... +LL | fn transparent_incorrect() -> isize; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration + | + = note: expected `unsafe extern "C" fn() -> transparent::T` + found `unsafe extern "C" fn() -> isize` + +warning: `missing_return_type` redeclared with a different signature + --> $DIR/clashing-extern-fn.rs:235:13 + | +LL | fn missing_return_type() -> usize; + | ---------------------------------- `missing_return_type` previously declared here +... +LL | fn missing_return_type(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration + | + = note: expected `unsafe extern "C" fn() -> usize` + found `unsafe extern "C" fn()` + +warning: `non_zero_usize` redeclared with a different signature + --> $DIR/clashing-extern-fn.rs:253:13 + | +LL | fn non_zero_usize() -> core::num::NonZeroUsize; + | ----------------------------------------------- `non_zero_usize` previously declared here +... +LL | fn non_zero_usize() -> usize; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration + | + = note: expected `unsafe extern "C" fn() -> std::num::NonZeroUsize` + found `unsafe extern "C" fn() -> usize` + +warning: `non_null_ptr` redeclared with a different signature + --> $DIR/clashing-extern-fn.rs:255:13 + | +LL | fn non_null_ptr() -> core::ptr::NonNull<usize>; + | ----------------------------------------------- `non_null_ptr` previously declared here +... +LL | fn non_null_ptr() -> *const usize; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration + | + = note: expected `unsafe extern "C" fn() -> std::ptr::NonNull<usize>` + found `unsafe extern "C" fn() -> *const usize` + +warning: `option_non_zero_usize_incorrect` redeclared with a different signature + --> $DIR/clashing-extern-fn.rs:281:13 + | +LL | fn option_non_zero_usize_incorrect() -> usize; + | ---------------------------------------------- `option_non_zero_usize_incorrect` previously declared here +... +LL | fn option_non_zero_usize_incorrect() -> isize; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration + | + = note: expected `unsafe extern "C" fn() -> usize` + found `unsafe extern "C" fn() -> isize` + +warning: `option_non_null_ptr_incorrect` redeclared with a different signature + --> $DIR/clashing-extern-fn.rs:283:13 + | +LL | fn option_non_null_ptr_incorrect() -> *const usize; + | --------------------------------------------------- `option_non_null_ptr_incorrect` previously declared here +... +LL | fn option_non_null_ptr_incorrect() -> *const isize; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration + | + = note: expected `unsafe extern "C" fn() -> *const usize` + found `unsafe extern "C" fn() -> *const isize` + +warning: 15 warnings emitted diff --git a/src/test/ui/lint/issue-74883-unused-paren-baren-yield.rs b/src/test/ui/lint/issue-74883-unused-paren-baren-yield.rs new file mode 100644 index 00000000000..02182ec2993 --- /dev/null +++ b/src/test/ui/lint/issue-74883-unused-paren-baren-yield.rs @@ -0,0 +1,33 @@ +#![feature(generator_trait)] +#![feature(generators)] +#![deny(unused_braces, unused_parens)] + +use std::ops::Generator; +use std::pin::Pin; + +fn main() { + let mut x = |_| { + while let Some(_) = (yield) {} + while let Some(_) = {yield} {} + + // Only warn these cases + while let Some(_) = ({yield}) {} //~ ERROR: unnecessary parentheses + while let Some(_) = ((yield)) {} //~ ERROR: unnecessary parentheses + {{yield}}; //~ ERROR: unnecessary braces + {( yield )}; //~ ERROR: unnecessary parentheses + + // FIXME: Reduce duplicate warnings. + // Perhaps we should tweak checks in `BlockRetValue`? + while let Some(_) = {(yield)} {} + //~^ ERROR: unnecessary braces + //~| ERROR: unnecessary parentheses + while let Some(_) = {{yield}} {} + //~^ ERROR: unnecessary braces + //~| ERROR: unnecessary braces + + // FIXME: It'd be great if we could also warn them. + ((yield)); + ({ yield }); + }; + let _ = Pin::new(&mut x).resume(Some(5)); +} diff --git a/src/test/ui/lint/issue-74883-unused-paren-baren-yield.stderr b/src/test/ui/lint/issue-74883-unused-paren-baren-yield.stderr new file mode 100644 index 00000000000..267cc9e031a --- /dev/null +++ b/src/test/ui/lint/issue-74883-unused-paren-baren-yield.stderr @@ -0,0 +1,62 @@ +error: unnecessary parentheses around `let` scrutinee expression + --> $DIR/issue-74883-unused-paren-baren-yield.rs:14:29 + | +LL | while let Some(_) = ({yield}) {} + | ^^^^^^^^^ help: remove these parentheses + | +note: the lint level is defined here + --> $DIR/issue-74883-unused-paren-baren-yield.rs:3:24 + | +LL | #![deny(unused_braces, unused_parens)] + | ^^^^^^^^^^^^^ + +error: unnecessary parentheses around `let` scrutinee expression + --> $DIR/issue-74883-unused-paren-baren-yield.rs:15:29 + | +LL | while let Some(_) = ((yield)) {} + | ^^^^^^^^^ help: remove these parentheses + +error: unnecessary braces around block return value + --> $DIR/issue-74883-unused-paren-baren-yield.rs:16:10 + | +LL | {{yield}}; + | ^^^^^^^ help: remove these braces + | +note: the lint level is defined here + --> $DIR/issue-74883-unused-paren-baren-yield.rs:3:9 + | +LL | #![deny(unused_braces, unused_parens)] + | ^^^^^^^^^^^^^ + +error: unnecessary parentheses around block return value + --> $DIR/issue-74883-unused-paren-baren-yield.rs:17:10 + | +LL | {( yield )}; + | ^^^^^^^^^ help: remove these parentheses + +error: unnecessary braces around `let` scrutinee expression + --> $DIR/issue-74883-unused-paren-baren-yield.rs:21:29 + | +LL | while let Some(_) = {(yield)} {} + | ^^^^^^^^^ help: remove these braces + +error: unnecessary parentheses around block return value + --> $DIR/issue-74883-unused-paren-baren-yield.rs:21:30 + | +LL | while let Some(_) = {(yield)} {} + | ^^^^^^^ help: remove these parentheses + +error: unnecessary braces around `let` scrutinee expression + --> $DIR/issue-74883-unused-paren-baren-yield.rs:24:29 + | +LL | while let Some(_) = {{yield}} {} + | ^^^^^^^^^ help: remove these braces + +error: unnecessary braces around block return value + --> $DIR/issue-74883-unused-paren-baren-yield.rs:24:30 + | +LL | while let Some(_) = {{yield}} {} + | ^^^^^^^ help: remove these braces + +error: aborting due to 8 previous errors + diff --git a/src/test/ui/lint/lint-nonstandard-style-unicode-1.rs b/src/test/ui/lint/lint-nonstandard-style-unicode-1.rs index 4f90bd98c63..034499145b7 100644 --- a/src/test/ui/lint/lint-nonstandard-style-unicode-1.rs +++ b/src/test/ui/lint/lint-nonstandard-style-unicode-1.rs @@ -23,7 +23,7 @@ struct _ヒb; struct __χa; //~^ ERROR type `__χa` should have an upper camel case name -// Besides this, we cannot have two continous underscores in the middle. +// Besides this, we cannot have two continuous underscores in the middle. struct 对__否; //~^ ERROR type `对__否` should have an upper camel case name diff --git a/src/test/ui/lint/lint-nonstandard-style-unicode-2.rs b/src/test/ui/lint/lint-nonstandard-style-unicode-2.rs index 813e0ea5c57..0b52a5fde35 100644 --- a/src/test/ui/lint/lint-nonstandard-style-unicode-2.rs +++ b/src/test/ui/lint/lint-nonstandard-style-unicode-2.rs @@ -18,7 +18,7 @@ fn 编程() {} fn Ц() {} //~^ ERROR function `Ц` should have a snake case name -// besides this, you cannot use continous underscores in the middle +// besides this, you cannot use continuous underscores in the middle fn 分__隔() {} //~^ ERROR function `分__隔` should have a snake case name diff --git a/src/test/ui/lint/lint-output-format-2.rs b/src/test/ui/lint/lint-output-format-2.rs index 521472d99b1..985166e095d 100644 --- a/src/test/ui/lint/lint-output-format-2.rs +++ b/src/test/ui/lint/lint-output-format-2.rs @@ -5,11 +5,11 @@ extern crate lint_output_format; use lint_output_format::{foo, bar}; -//~^ WARNING use of deprecated item 'lint_output_format::foo': text +//~^ WARNING use of deprecated function `lint_output_format::foo`: text fn main() { let _x = foo(); - //~^ WARNING use of deprecated item 'lint_output_format::foo': text + //~^ WARNING use of deprecated function `lint_output_format::foo`: text let _y = bar(); } diff --git a/src/test/ui/lint/lint-output-format-2.stderr b/src/test/ui/lint/lint-output-format-2.stderr index a95fd69fb01..a36dbd61fdc 100644 --- a/src/test/ui/lint/lint-output-format-2.stderr +++ b/src/test/ui/lint/lint-output-format-2.stderr @@ -1,4 +1,4 @@ -warning: use of deprecated item 'lint_output_format::foo': text +warning: use of deprecated function `lint_output_format::foo`: text --> $DIR/lint-output-format-2.rs:7:26 | LL | use lint_output_format::{foo, bar}; @@ -6,7 +6,7 @@ LL | use lint_output_format::{foo, bar}; | = note: `#[warn(deprecated)]` on by default -warning: use of deprecated item 'lint_output_format::foo': text +warning: use of deprecated function `lint_output_format::foo`: text --> $DIR/lint-output-format-2.rs:12:14 | LL | let _x = foo(); diff --git a/src/test/ui/lint/lint-stability-deprecated.rs b/src/test/ui/lint/lint-stability-deprecated.rs index 4b407a29f64..a6fde11495c 100644 --- a/src/test/ui/lint/lint-stability-deprecated.rs +++ b/src/test/ui/lint/lint-stability-deprecated.rs @@ -22,41 +22,41 @@ mod cross_crate { type Foo = MethodTester; let foo = MethodTester; - deprecated(); //~ WARN use of deprecated item 'lint_stability::deprecated' - foo.method_deprecated(); //~ WARN use of deprecated item 'lint_stability::MethodTester::method_deprecated' - Foo::method_deprecated(&foo); //~ WARN use of deprecated item 'lint_stability::MethodTester::method_deprecated' - <Foo>::method_deprecated(&foo); //~ WARN use of deprecated item 'lint_stability::MethodTester::method_deprecated' - foo.trait_deprecated(); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated' - Trait::trait_deprecated(&foo); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated' - <Foo>::trait_deprecated(&foo); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated' - <Foo as Trait>::trait_deprecated(&foo); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated' - - deprecated_text(); //~ WARN use of deprecated item 'lint_stability::deprecated_text': text - foo.method_deprecated_text(); //~ WARN use of deprecated item 'lint_stability::MethodTester::method_deprecated_text': text - Foo::method_deprecated_text(&foo); //~ WARN use of deprecated item 'lint_stability::MethodTester::method_deprecated_text': text - <Foo>::method_deprecated_text(&foo); //~ WARN use of deprecated item 'lint_stability::MethodTester::method_deprecated_text': text - foo.trait_deprecated_text(); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated_text': text - Trait::trait_deprecated_text(&foo); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated_text': text - <Foo>::trait_deprecated_text(&foo); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated_text': text - <Foo as Trait>::trait_deprecated_text(&foo); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated_text': text - - deprecated_unstable(); //~ WARN use of deprecated item 'lint_stability::deprecated_unstable' - foo.method_deprecated_unstable(); //~ WARN use of deprecated item 'lint_stability::MethodTester::method_deprecated_unstable' - Foo::method_deprecated_unstable(&foo); //~ WARN use of deprecated item 'lint_stability::MethodTester::method_deprecated_unstable' - <Foo>::method_deprecated_unstable(&foo); //~ WARN use of deprecated item 'lint_stability::MethodTester::method_deprecated_unstable' - foo.trait_deprecated_unstable(); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable' - Trait::trait_deprecated_unstable(&foo); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable' - <Foo>::trait_deprecated_unstable(&foo); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable' - <Foo as Trait>::trait_deprecated_unstable(&foo); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable' - - deprecated_unstable_text(); //~ WARN use of deprecated item 'lint_stability::deprecated_unstable_text': text - foo.method_deprecated_unstable_text(); //~ WARN use of deprecated item 'lint_stability::MethodTester::method_deprecated_unstable_text': text - Foo::method_deprecated_unstable_text(&foo); //~ WARN use of deprecated item 'lint_stability::MethodTester::method_deprecated_unstable_text': text - <Foo>::method_deprecated_unstable_text(&foo); //~ WARN use of deprecated item 'lint_stability::MethodTester::method_deprecated_unstable_text': text - foo.trait_deprecated_unstable_text(); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable_text': text - Trait::trait_deprecated_unstable_text(&foo); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable_text': text - <Foo>::trait_deprecated_unstable_text(&foo); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable_text': text - <Foo as Trait>::trait_deprecated_unstable_text(&foo); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable_text': text + deprecated(); //~ WARN use of deprecated function `lint_stability::deprecated` + foo.method_deprecated(); //~ WARN use of deprecated associated function `lint_stability::MethodTester::method_deprecated` + Foo::method_deprecated(&foo); //~ WARN use of deprecated associated function `lint_stability::MethodTester::method_deprecated` + <Foo>::method_deprecated(&foo); //~ WARN use of deprecated associated function `lint_stability::MethodTester::method_deprecated` + foo.trait_deprecated(); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated` + Trait::trait_deprecated(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated` + <Foo>::trait_deprecated(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated` + <Foo as Trait>::trait_deprecated(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated` + + deprecated_text(); //~ WARN use of deprecated function `lint_stability::deprecated_text`: text + foo.method_deprecated_text(); //~ WARN use of deprecated associated function `lint_stability::MethodTester::method_deprecated_text`: text + Foo::method_deprecated_text(&foo); //~ WARN use of deprecated associated function `lint_stability::MethodTester::method_deprecated_text`: text + <Foo>::method_deprecated_text(&foo); //~ WARN use of deprecated associated function `lint_stability::MethodTester::method_deprecated_text`: text + foo.trait_deprecated_text(); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text + Trait::trait_deprecated_text(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text + <Foo>::trait_deprecated_text(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text + <Foo as Trait>::trait_deprecated_text(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text + + deprecated_unstable(); //~ WARN use of deprecated function `lint_stability::deprecated_unstable` + foo.method_deprecated_unstable(); //~ WARN use of deprecated associated function `lint_stability::MethodTester::method_deprecated_unstable` + Foo::method_deprecated_unstable(&foo); //~ WARN use of deprecated associated function `lint_stability::MethodTester::method_deprecated_unstable` + <Foo>::method_deprecated_unstable(&foo); //~ WARN use of deprecated associated function `lint_stability::MethodTester::method_deprecated_unstable` + foo.trait_deprecated_unstable(); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable` + Trait::trait_deprecated_unstable(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable` + <Foo>::trait_deprecated_unstable(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable` + <Foo as Trait>::trait_deprecated_unstable(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable` + + deprecated_unstable_text(); //~ WARN use of deprecated function `lint_stability::deprecated_unstable_text`: text + foo.method_deprecated_unstable_text(); //~ WARN use of deprecated associated function `lint_stability::MethodTester::method_deprecated_unstable_text`: text + Foo::method_deprecated_unstable_text(&foo); //~ WARN use of deprecated associated function `lint_stability::MethodTester::method_deprecated_unstable_text`: text + <Foo>::method_deprecated_unstable_text(&foo); //~ WARN use of deprecated associated function `lint_stability::MethodTester::method_deprecated_unstable_text`: text + foo.trait_deprecated_unstable_text(); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text + Trait::trait_deprecated_unstable_text(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text + <Foo>::trait_deprecated_unstable_text(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text + <Foo as Trait>::trait_deprecated_unstable_text(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text unstable(); foo.method_unstable(); @@ -96,38 +96,38 @@ mod cross_crate { struct S1<T: TraitWithAssociatedTypes>(T::TypeUnstable); struct S2<T: TraitWithAssociatedTypes>(T::TypeDeprecated); - //~^ WARN use of deprecated item 'lint_stability::TraitWithAssociatedTypes::TypeDeprecated': text - //~| WARN use of deprecated item 'lint_stability::TraitWithAssociatedTypes::TypeDeprecated': text + //~^ WARN use of deprecated associated type `lint_stability::TraitWithAssociatedTypes::TypeDeprecated`: text + //~| WARN use of deprecated associated type `lint_stability::TraitWithAssociatedTypes::TypeDeprecated`: text type A = dyn TraitWithAssociatedTypes< TypeUnstable = u8, TypeDeprecated = u16, - //~^ WARN use of deprecated item 'lint_stability::TraitWithAssociatedTypes::TypeDeprecated' - //~| WARN use of deprecated item 'lint_stability::TraitWithAssociatedTypes::TypeDeprecated' - //~| WARN use of deprecated item 'lint_stability::TraitWithAssociatedTypes::TypeDeprecated' + //~^ WARN use of deprecated associated type `lint_stability::TraitWithAssociatedTypes::TypeDeprecated` + //~| WARN use of deprecated associated type `lint_stability::TraitWithAssociatedTypes::TypeDeprecated` + //~| WARN use of deprecated associated type `lint_stability::TraitWithAssociatedTypes::TypeDeprecated` >; - let _ = DeprecatedStruct { //~ WARN use of deprecated item 'lint_stability::DeprecatedStruct' - i: 0 //~ WARN use of deprecated item 'lint_stability::DeprecatedStruct::i' + let _ = DeprecatedStruct { //~ WARN use of deprecated struct `lint_stability::DeprecatedStruct` + i: 0 //~ WARN use of deprecated field `lint_stability::DeprecatedStruct::i` }; let _ = DeprecatedUnstableStruct { - //~^ WARN use of deprecated item 'lint_stability::DeprecatedUnstableStruct' - i: 0 //~ WARN use of deprecated item 'lint_stability::DeprecatedUnstableStruct::i' + //~^ WARN use of deprecated struct `lint_stability::DeprecatedUnstableStruct` + i: 0 //~ WARN use of deprecated field `lint_stability::DeprecatedUnstableStruct::i` }; let _ = UnstableStruct { i: 0 }; let _ = StableStruct { i: 0 }; - let _ = DeprecatedUnitStruct; //~ WARN use of deprecated item 'lint_stability::DeprecatedUnitStruct' - let _ = DeprecatedUnstableUnitStruct; //~ WARN use of deprecated item 'lint_stability::DeprecatedUnstableUnitStruct' + let _ = DeprecatedUnitStruct; //~ WARN use of deprecated struct `lint_stability::DeprecatedUnitStruct` + let _ = DeprecatedUnstableUnitStruct; //~ WARN use of deprecated struct `lint_stability::DeprecatedUnstableUnitStruct` let _ = UnstableUnitStruct; let _ = StableUnitStruct; - let _ = Enum::DeprecatedVariant; //~ WARN use of deprecated item 'lint_stability::Enum::DeprecatedVariant' - let _ = Enum::DeprecatedUnstableVariant; //~ WARN use of deprecated item 'lint_stability::Enum::DeprecatedUnstableVariant' + let _ = Enum::DeprecatedVariant; //~ WARN use of deprecated variant `lint_stability::Enum::DeprecatedVariant` + let _ = Enum::DeprecatedUnstableVariant; //~ WARN use of deprecated variant `lint_stability::Enum::DeprecatedUnstableVariant` let _ = Enum::UnstableVariant; let _ = Enum::StableVariant; - let _ = DeprecatedTupleStruct (1); //~ WARN use of deprecated item 'lint_stability::DeprecatedTupleStruct' - let _ = DeprecatedUnstableTupleStruct (1); //~ WARN use of deprecated item 'lint_stability::DeprecatedUnstableTupleStruct' + let _ = DeprecatedTupleStruct (1); //~ WARN use of deprecated struct `lint_stability::DeprecatedTupleStruct` + let _ = DeprecatedUnstableTupleStruct (1); //~ WARN use of deprecated struct `lint_stability::DeprecatedUnstableTupleStruct` let _ = UnstableTupleStruct (1); let _ = StableTupleStruct (1); @@ -136,28 +136,28 @@ mod cross_crate { // Eventually, we will want to lint the contents of the // macro in the module *defining* it. Also, stability levels // on macros themselves are not yet linted. - macro_test_arg!(deprecated_text()); //~ WARN use of deprecated item 'lint_stability::deprecated_text': text - macro_test_arg!(deprecated_unstable_text()); //~ WARN use of deprecated item 'lint_stability::deprecated_unstable_text': text - macro_test_arg!(macro_test_arg!(deprecated_text())); //~ WARN use of deprecated item 'lint_stability::deprecated_text': text + macro_test_arg!(deprecated_text()); //~ WARN use of deprecated function `lint_stability::deprecated_text`: text + macro_test_arg!(deprecated_unstable_text()); //~ WARN use of deprecated function `lint_stability::deprecated_unstable_text`: text + macro_test_arg!(macro_test_arg!(deprecated_text())); //~ WARN use of deprecated function `lint_stability::deprecated_text`: text } fn test_method_param<Foo: Trait>(foo: Foo) { - foo.trait_deprecated(); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated' - Trait::trait_deprecated(&foo); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated' - <Foo>::trait_deprecated(&foo); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated' - <Foo as Trait>::trait_deprecated(&foo); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated' - foo.trait_deprecated_text(); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated_text': text - Trait::trait_deprecated_text(&foo); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated_text': text - <Foo>::trait_deprecated_text(&foo); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated_text': text - <Foo as Trait>::trait_deprecated_text(&foo); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated_text': text - foo.trait_deprecated_unstable(); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable' - Trait::trait_deprecated_unstable(&foo); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable' - <Foo>::trait_deprecated_unstable(&foo); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable' - <Foo as Trait>::trait_deprecated_unstable(&foo); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable' - foo.trait_deprecated_unstable_text(); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable_text': text - Trait::trait_deprecated_unstable_text(&foo); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable_text': text - <Foo>::trait_deprecated_unstable_text(&foo); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable_text': text - <Foo as Trait>::trait_deprecated_unstable_text(&foo); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable_text': text + foo.trait_deprecated(); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated` + Trait::trait_deprecated(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated` + <Foo>::trait_deprecated(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated` + <Foo as Trait>::trait_deprecated(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated` + foo.trait_deprecated_text(); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text + Trait::trait_deprecated_text(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text + <Foo>::trait_deprecated_text(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text + <Foo as Trait>::trait_deprecated_text(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text + foo.trait_deprecated_unstable(); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable` + Trait::trait_deprecated_unstable(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable` + <Foo>::trait_deprecated_unstable(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable` + <Foo as Trait>::trait_deprecated_unstable(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable` + foo.trait_deprecated_unstable_text(); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text + Trait::trait_deprecated_unstable_text(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text + <Foo>::trait_deprecated_unstable_text(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text + <Foo as Trait>::trait_deprecated_unstable_text(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text foo.trait_unstable(); Trait::trait_unstable(&foo); <Foo>::trait_unstable(&foo); @@ -173,10 +173,10 @@ mod cross_crate { } fn test_method_object(foo: &dyn Trait) { - foo.trait_deprecated(); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated' - foo.trait_deprecated_text(); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated_text': text - foo.trait_deprecated_unstable(); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable' - foo.trait_deprecated_unstable_text(); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable_text': text + foo.trait_deprecated(); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated` + foo.trait_deprecated_text(); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text + foo.trait_deprecated_unstable(); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable` + foo.trait_deprecated_unstable_text(); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text foo.trait_unstable(); foo.trait_unstable_text(); foo.trait_stable(); @@ -185,9 +185,9 @@ mod cross_crate { struct S; impl UnstableTrait for S { } - impl DeprecatedTrait for S {} //~ WARN use of deprecated item 'lint_stability::DeprecatedTrait': text + impl DeprecatedTrait for S {} //~ WARN use of deprecated trait `lint_stability::DeprecatedTrait`: text trait LocalTrait : UnstableTrait { } - trait LocalTrait2 : DeprecatedTrait { } //~ WARN use of deprecated item 'lint_stability::DeprecatedTrait': text + trait LocalTrait2 : DeprecatedTrait { } //~ WARN use of deprecated trait `lint_stability::DeprecatedTrait`: text impl Trait for S { fn trait_stable(&self) {} @@ -206,7 +206,7 @@ mod inheritance { stable_mod::unstable(); stable_mod::stable(); - unstable_mod::deprecated(); //~ WARN use of deprecated item 'inheritance::inherited_stability::unstable_mod::deprecated': text + unstable_mod::deprecated(); //~ WARN use of deprecated function `inheritance::inherited_stability::unstable_mod::deprecated`: text unstable_mod::unstable(); let _ = Unstable::UnstableVariant; @@ -328,23 +328,23 @@ mod this_crate { type Foo = MethodTester; let foo = MethodTester; - deprecated(); //~ WARN use of deprecated item 'this_crate::deprecated' - foo.method_deprecated(); //~ WARN use of deprecated item 'this_crate::MethodTester::method_deprecated' - Foo::method_deprecated(&foo); //~ WARN use of deprecated item 'this_crate::MethodTester::method_deprecated' - <Foo>::method_deprecated(&foo); //~ WARN use of deprecated item 'this_crate::MethodTester::method_deprecated' - foo.trait_deprecated(); //~ WARN use of deprecated item 'this_crate::Trait::trait_deprecated' - Trait::trait_deprecated(&foo); //~ WARN use of deprecated item 'this_crate::Trait::trait_deprecated' - <Foo>::trait_deprecated(&foo); //~ WARN use of deprecated item 'this_crate::Trait::trait_deprecated' - <Foo as Trait>::trait_deprecated(&foo); //~ WARN use of deprecated item 'this_crate::Trait::trait_deprecated' - - deprecated_text(); //~ WARN use of deprecated item 'this_crate::deprecated_text': text - foo.method_deprecated_text(); //~ WARN use of deprecated item 'this_crate::MethodTester::method_deprecated_text': text - Foo::method_deprecated_text(&foo); //~ WARN use of deprecated item 'this_crate::MethodTester::method_deprecated_text': text - <Foo>::method_deprecated_text(&foo); //~ WARN use of deprecated item 'this_crate::MethodTester::method_deprecated_text': text - foo.trait_deprecated_text(); //~ WARN use of deprecated item 'this_crate::Trait::trait_deprecated_text': text - Trait::trait_deprecated_text(&foo); //~ WARN use of deprecated item 'this_crate::Trait::trait_deprecated_text': text - <Foo>::trait_deprecated_text(&foo); //~ WARN use of deprecated item 'this_crate::Trait::trait_deprecated_text': text - <Foo as Trait>::trait_deprecated_text(&foo); //~ WARN use of deprecated item 'this_crate::Trait::trait_deprecated_text': text + deprecated(); //~ WARN use of deprecated function `this_crate::deprecated` + foo.method_deprecated(); //~ WARN use of deprecated associated function `this_crate::MethodTester::method_deprecated` + Foo::method_deprecated(&foo); //~ WARN use of deprecated associated function `this_crate::MethodTester::method_deprecated` + <Foo>::method_deprecated(&foo); //~ WARN use of deprecated associated function `this_crate::MethodTester::method_deprecated` + foo.trait_deprecated(); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated` + Trait::trait_deprecated(&foo); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated` + <Foo>::trait_deprecated(&foo); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated` + <Foo as Trait>::trait_deprecated(&foo); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated` + + deprecated_text(); //~ WARN use of deprecated function `this_crate::deprecated_text`: text + foo.method_deprecated_text(); //~ WARN use of deprecated associated function `this_crate::MethodTester::method_deprecated_text`: text + Foo::method_deprecated_text(&foo); //~ WARN use of deprecated associated function `this_crate::MethodTester::method_deprecated_text`: text + <Foo>::method_deprecated_text(&foo); //~ WARN use of deprecated associated function `this_crate::MethodTester::method_deprecated_text`: text + foo.trait_deprecated_text(); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text + Trait::trait_deprecated_text(&foo); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text + <Foo>::trait_deprecated_text(&foo); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text + <Foo as Trait>::trait_deprecated_text(&foo); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text unstable(); foo.method_unstable(); @@ -383,34 +383,34 @@ mod this_crate { <Foo as Trait>::trait_stable_text(&foo); let _ = DeprecatedStruct { - //~^ WARN use of deprecated item 'this_crate::DeprecatedStruct' - i: 0 //~ WARN use of deprecated item 'this_crate::DeprecatedStruct::i' + //~^ WARN use of deprecated struct `this_crate::DeprecatedStruct` + i: 0 //~ WARN use of deprecated field `this_crate::DeprecatedStruct::i` }; let _ = UnstableStruct { i: 0 }; let _ = StableStruct { i: 0 }; - let _ = DeprecatedUnitStruct; //~ WARN use of deprecated item 'this_crate::DeprecatedUnitStruct' + let _ = DeprecatedUnitStruct; //~ WARN use of deprecated unit struct `this_crate::DeprecatedUnitStruct` let _ = UnstableUnitStruct; let _ = StableUnitStruct; - let _ = Enum::DeprecatedVariant; //~ WARN use of deprecated item 'this_crate::Enum::DeprecatedVariant' + let _ = Enum::DeprecatedVariant; //~ WARN use of deprecated unit variant `this_crate::Enum::DeprecatedVariant` let _ = Enum::UnstableVariant; let _ = Enum::StableVariant; - let _ = DeprecatedTupleStruct (1); //~ WARN use of deprecated item 'this_crate::DeprecatedTupleStruct' + let _ = DeprecatedTupleStruct (1); //~ WARN use of deprecated tuple struct `this_crate::DeprecatedTupleStruct` let _ = UnstableTupleStruct (1); let _ = StableTupleStruct (1); } fn test_method_param<Foo: Trait>(foo: Foo) { - foo.trait_deprecated(); //~ WARN use of deprecated item 'this_crate::Trait::trait_deprecated' - Trait::trait_deprecated(&foo); //~ WARN use of deprecated item 'this_crate::Trait::trait_deprecated' - <Foo>::trait_deprecated(&foo); //~ WARN use of deprecated item 'this_crate::Trait::trait_deprecated' - <Foo as Trait>::trait_deprecated(&foo); //~ WARN use of deprecated item 'this_crate::Trait::trait_deprecated' - foo.trait_deprecated_text(); //~ WARN use of deprecated item 'this_crate::Trait::trait_deprecated_text': text - Trait::trait_deprecated_text(&foo); //~ WARN use of deprecated item 'this_crate::Trait::trait_deprecated_text': text - <Foo>::trait_deprecated_text(&foo); //~ WARN use of deprecated item 'this_crate::Trait::trait_deprecated_text': text - <Foo as Trait>::trait_deprecated_text(&foo); //~ WARN use of deprecated item 'this_crate::Trait::trait_deprecated_text': text + foo.trait_deprecated(); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated` + Trait::trait_deprecated(&foo); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated` + <Foo>::trait_deprecated(&foo); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated` + <Foo as Trait>::trait_deprecated(&foo); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated` + foo.trait_deprecated_text(); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text + Trait::trait_deprecated_text(&foo); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text + <Foo>::trait_deprecated_text(&foo); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text + <Foo as Trait>::trait_deprecated_text(&foo); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text foo.trait_unstable(); Trait::trait_unstable(&foo); <Foo>::trait_unstable(&foo); @@ -426,8 +426,8 @@ mod this_crate { } fn test_method_object(foo: &dyn Trait) { - foo.trait_deprecated(); //~ WARN use of deprecated item 'this_crate::Trait::trait_deprecated' - foo.trait_deprecated_text(); //~ WARN use of deprecated item 'this_crate::Trait::trait_deprecated_text': text + foo.trait_deprecated(); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated` + foo.trait_deprecated_text(); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text foo.trait_unstable(); foo.trait_unstable_text(); foo.trait_stable(); @@ -437,7 +437,7 @@ mod this_crate { #[rustc_deprecated(since = "1.0.0", reason = "text")] fn test_fn_body() { fn fn_in_body() {} - fn_in_body(); //~ WARN use of deprecated item 'this_crate::test_fn_body::fn_in_body': text + fn_in_body(); //~ WARN use of deprecated function `this_crate::test_fn_body::fn_in_body`: text } impl MethodTester { @@ -445,7 +445,7 @@ mod this_crate { #[rustc_deprecated(since = "1.0.0", reason = "text")] fn test_method_body(&self) { fn fn_in_body() {} - fn_in_body(); //~ WARN use of deprecated item 'this_crate::MethodTester::test_method_body::fn_in_body': text + fn_in_body(); //~ WARN use of deprecated function `this_crate::MethodTester::test_method_body::fn_in_body`: text } } @@ -457,9 +457,9 @@ mod this_crate { struct S; - impl DeprecatedTrait for S { } //~ WARN use of deprecated item 'this_crate::DeprecatedTrait' + impl DeprecatedTrait for S { } //~ WARN use of deprecated trait `this_crate::DeprecatedTrait` - trait LocalTrait : DeprecatedTrait { } //~ WARN use of deprecated item 'this_crate::DeprecatedTrait' + trait LocalTrait : DeprecatedTrait { } //~ WARN use of deprecated trait `this_crate::DeprecatedTrait` } fn main() {} diff --git a/src/test/ui/lint/lint-stability-deprecated.stderr b/src/test/ui/lint/lint-stability-deprecated.stderr index 801e04a7f4f..d8dd83b0d06 100644 --- a/src/test/ui/lint/lint-stability-deprecated.stderr +++ b/src/test/ui/lint/lint-stability-deprecated.stderr @@ -1,4 +1,4 @@ -warning: use of deprecated item 'lint_stability::deprecated': text +warning: use of deprecated function `lint_stability::deprecated`: text --> $DIR/lint-stability-deprecated.rs:25:9 | LL | deprecated(); @@ -10,643 +10,643 @@ note: the lint level is defined here LL | #![warn(deprecated)] | ^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::Trait::trait_deprecated': text +warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated`: text --> $DIR/lint-stability-deprecated.rs:30:9 | LL | Trait::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::Trait::trait_deprecated': text +warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated`: text --> $DIR/lint-stability-deprecated.rs:32:9 | LL | <Foo as Trait>::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::deprecated_text': text +warning: use of deprecated function `lint_stability::deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:34:9 | LL | deprecated_text(); | ^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_text': text +warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:39:9 | -LL | Trait::trait_deprecated_text(&foo); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... Trait::trait_deprecated_text(&foo); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_text': text +warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:41:9 | -LL | <Foo as Trait>::trait_deprecated_text(&foo); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... <Foo as Trait>::trait_deprecated_text(&foo); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::deprecated_unstable': text +warning: use of deprecated function `lint_stability::deprecated_unstable`: text --> $DIR/lint-stability-deprecated.rs:43:9 | LL | deprecated_unstable(); | ^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable': text +warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`: text --> $DIR/lint-stability-deprecated.rs:48:9 | -LL | Trait::trait_deprecated_unstable(&foo); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... Trait::trait_deprecated_unstable(&foo); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable': text +warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`: text --> $DIR/lint-stability-deprecated.rs:50:9 | -LL | <Foo as Trait>::trait_deprecated_unstable(&foo); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... <Foo as Trait>::trait_deprecated_unstable(&foo); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::deprecated_unstable_text': text +warning: use of deprecated function `lint_stability::deprecated_unstable_text`: text --> $DIR/lint-stability-deprecated.rs:52:9 | LL | deprecated_unstable_text(); | ^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable_text': text +warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text --> $DIR/lint-stability-deprecated.rs:57:9 | LL | ... Trait::trait_deprecated_unstable_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable_text': text +warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text --> $DIR/lint-stability-deprecated.rs:59:9 | LL | ... <Foo as Trait>::trait_deprecated_unstable_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::DeprecatedStruct': text +warning: use of deprecated struct `lint_stability::DeprecatedStruct`: text --> $DIR/lint-stability-deprecated.rs:109:17 | LL | let _ = DeprecatedStruct { | ^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::DeprecatedUnstableStruct': text +warning: use of deprecated struct `lint_stability::DeprecatedUnstableStruct`: text --> $DIR/lint-stability-deprecated.rs:112:17 | LL | let _ = DeprecatedUnstableStruct { | ^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::DeprecatedUnitStruct': text +warning: use of deprecated struct `lint_stability::DeprecatedUnitStruct`: text --> $DIR/lint-stability-deprecated.rs:119:17 | LL | let _ = DeprecatedUnitStruct; | ^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::DeprecatedUnstableUnitStruct': text +warning: use of deprecated struct `lint_stability::DeprecatedUnstableUnitStruct`: text --> $DIR/lint-stability-deprecated.rs:120:17 | LL | let _ = DeprecatedUnstableUnitStruct; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::Enum::DeprecatedVariant': text +warning: use of deprecated variant `lint_stability::Enum::DeprecatedVariant`: text --> $DIR/lint-stability-deprecated.rs:124:17 | LL | let _ = Enum::DeprecatedVariant; | ^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::Enum::DeprecatedUnstableVariant': text +warning: use of deprecated variant `lint_stability::Enum::DeprecatedUnstableVariant`: text --> $DIR/lint-stability-deprecated.rs:125:17 | LL | let _ = Enum::DeprecatedUnstableVariant; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::DeprecatedTupleStruct': text +warning: use of deprecated struct `lint_stability::DeprecatedTupleStruct`: text --> $DIR/lint-stability-deprecated.rs:129:17 | LL | let _ = DeprecatedTupleStruct (1); | ^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::DeprecatedUnstableTupleStruct': text +warning: use of deprecated struct `lint_stability::DeprecatedUnstableTupleStruct`: text --> $DIR/lint-stability-deprecated.rs:130:17 | LL | let _ = DeprecatedUnstableTupleStruct (1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::deprecated_text': text +warning: use of deprecated function `lint_stability::deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:139:25 | LL | macro_test_arg!(deprecated_text()); | ^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::deprecated_unstable_text': text +warning: use of deprecated function `lint_stability::deprecated_unstable_text`: text --> $DIR/lint-stability-deprecated.rs:140:25 | LL | macro_test_arg!(deprecated_unstable_text()); | ^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::deprecated_text': text +warning: use of deprecated function `lint_stability::deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:141:41 | LL | macro_test_arg!(macro_test_arg!(deprecated_text())); | ^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::Trait::trait_deprecated': text +warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated`: text --> $DIR/lint-stability-deprecated.rs:146:9 | LL | Trait::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::Trait::trait_deprecated': text +warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated`: text --> $DIR/lint-stability-deprecated.rs:148:9 | LL | <Foo as Trait>::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_text': text +warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:150:9 | -LL | Trait::trait_deprecated_text(&foo); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... Trait::trait_deprecated_text(&foo); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_text': text +warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:152:9 | -LL | <Foo as Trait>::trait_deprecated_text(&foo); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... <Foo as Trait>::trait_deprecated_text(&foo); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable': text +warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`: text --> $DIR/lint-stability-deprecated.rs:154:9 | -LL | Trait::trait_deprecated_unstable(&foo); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... Trait::trait_deprecated_unstable(&foo); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable': text +warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`: text --> $DIR/lint-stability-deprecated.rs:156:9 | -LL | <Foo as Trait>::trait_deprecated_unstable(&foo); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... <Foo as Trait>::trait_deprecated_unstable(&foo); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable_text': text +warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text --> $DIR/lint-stability-deprecated.rs:158:9 | LL | ... Trait::trait_deprecated_unstable_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable_text': text +warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text --> $DIR/lint-stability-deprecated.rs:160:9 | LL | ... <Foo as Trait>::trait_deprecated_unstable_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::DeprecatedTrait': text +warning: use of deprecated trait `lint_stability::DeprecatedTrait`: text --> $DIR/lint-stability-deprecated.rs:188:10 | LL | impl DeprecatedTrait for S {} | ^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::DeprecatedTrait': text +warning: use of deprecated trait `lint_stability::DeprecatedTrait`: text --> $DIR/lint-stability-deprecated.rs:190:25 | LL | trait LocalTrait2 : DeprecatedTrait { } | ^^^^^^^^^^^^^^^ -warning: use of deprecated item 'inheritance::inherited_stability::unstable_mod::deprecated': text +warning: use of deprecated function `inheritance::inherited_stability::unstable_mod::deprecated`: text --> $DIR/lint-stability-deprecated.rs:209:9 | LL | unstable_mod::deprecated(); | ^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'this_crate::deprecated': text +warning: use of deprecated function `this_crate::deprecated`: text --> $DIR/lint-stability-deprecated.rs:331:9 | LL | deprecated(); | ^^^^^^^^^^ -warning: use of deprecated item 'this_crate::Trait::trait_deprecated': text +warning: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text --> $DIR/lint-stability-deprecated.rs:336:9 | LL | Trait::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'this_crate::Trait::trait_deprecated': text +warning: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text --> $DIR/lint-stability-deprecated.rs:338:9 | LL | <Foo as Trait>::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'this_crate::deprecated_text': text +warning: use of deprecated function `this_crate::deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:340:9 | LL | deprecated_text(); | ^^^^^^^^^^^^^^^ -warning: use of deprecated item 'this_crate::Trait::trait_deprecated_text': text +warning: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:345:9 | LL | Trait::trait_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'this_crate::Trait::trait_deprecated_text': text +warning: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:347:9 | -LL | <Foo as Trait>::trait_deprecated_text(&foo); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... <Foo as Trait>::trait_deprecated_text(&foo); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'this_crate::DeprecatedStruct': text +warning: use of deprecated struct `this_crate::DeprecatedStruct`: text --> $DIR/lint-stability-deprecated.rs:385:17 | LL | let _ = DeprecatedStruct { | ^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'this_crate::DeprecatedUnitStruct': text +warning: use of deprecated unit struct `this_crate::DeprecatedUnitStruct`: text --> $DIR/lint-stability-deprecated.rs:392:17 | LL | let _ = DeprecatedUnitStruct; | ^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'this_crate::Enum::DeprecatedVariant': text +warning: use of deprecated unit variant `this_crate::Enum::DeprecatedVariant`: text --> $DIR/lint-stability-deprecated.rs:396:17 | LL | let _ = Enum::DeprecatedVariant; | ^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'this_crate::DeprecatedTupleStruct': text +warning: use of deprecated tuple struct `this_crate::DeprecatedTupleStruct`: text --> $DIR/lint-stability-deprecated.rs:400:17 | LL | let _ = DeprecatedTupleStruct (1); | ^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'this_crate::Trait::trait_deprecated': text +warning: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text --> $DIR/lint-stability-deprecated.rs:407:9 | LL | Trait::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'this_crate::Trait::trait_deprecated': text +warning: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text --> $DIR/lint-stability-deprecated.rs:409:9 | LL | <Foo as Trait>::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'this_crate::Trait::trait_deprecated_text': text +warning: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:411:9 | LL | Trait::trait_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'this_crate::Trait::trait_deprecated_text': text +warning: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:413:9 | -LL | <Foo as Trait>::trait_deprecated_text(&foo); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... <Foo as Trait>::trait_deprecated_text(&foo); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'this_crate::test_fn_body::fn_in_body': text +warning: use of deprecated function `this_crate::test_fn_body::fn_in_body`: text --> $DIR/lint-stability-deprecated.rs:440:9 | LL | fn_in_body(); | ^^^^^^^^^^ -warning: use of deprecated item 'this_crate::DeprecatedTrait': text +warning: use of deprecated trait `this_crate::DeprecatedTrait`: text --> $DIR/lint-stability-deprecated.rs:460:10 | LL | impl DeprecatedTrait for S { } | ^^^^^^^^^^^^^^^ -warning: use of deprecated item 'this_crate::DeprecatedTrait': text +warning: use of deprecated trait `this_crate::DeprecatedTrait`: text --> $DIR/lint-stability-deprecated.rs:462:24 | LL | trait LocalTrait : DeprecatedTrait { } | ^^^^^^^^^^^^^^^ -warning: use of deprecated item 'this_crate::MethodTester::test_method_body::fn_in_body': text +warning: use of deprecated function `this_crate::MethodTester::test_method_body::fn_in_body`: text --> $DIR/lint-stability-deprecated.rs:448:13 | LL | fn_in_body(); | ^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::TraitWithAssociatedTypes::TypeDeprecated': text +warning: use of deprecated associated type `lint_stability::TraitWithAssociatedTypes::TypeDeprecated`: text --> $DIR/lint-stability-deprecated.rs:98:48 | LL | struct S2<T: TraitWithAssociatedTypes>(T::TypeDeprecated); | ^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::TraitWithAssociatedTypes::TypeDeprecated': text +warning: use of deprecated associated type `lint_stability::TraitWithAssociatedTypes::TypeDeprecated`: text --> $DIR/lint-stability-deprecated.rs:103:13 | LL | TypeDeprecated = u16, | ^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::MethodTester::method_deprecated': text +warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated`: text --> $DIR/lint-stability-deprecated.rs:26:13 | LL | foo.method_deprecated(); | ^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::MethodTester::method_deprecated': text +warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated`: text --> $DIR/lint-stability-deprecated.rs:27:9 | LL | Foo::method_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::MethodTester::method_deprecated': text +warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated`: text --> $DIR/lint-stability-deprecated.rs:28:9 | LL | <Foo>::method_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::Trait::trait_deprecated': text +warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated`: text --> $DIR/lint-stability-deprecated.rs:29:13 | LL | foo.trait_deprecated(); | ^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::Trait::trait_deprecated': text +warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated`: text --> $DIR/lint-stability-deprecated.rs:31:9 | LL | <Foo>::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::MethodTester::method_deprecated_text': text +warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:35:13 | -LL | foo.method_deprecated_text(); - | ^^^^^^^^^^^^^^^^^^^^^^ +LL | ... foo.method_deprecated_text(); + | ^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::MethodTester::method_deprecated_text': text +warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:36:9 | -LL | Foo::method_deprecated_text(&foo); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... Foo::method_deprecated_text(&foo); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::MethodTester::method_deprecated_text': text +warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:37:9 | -LL | <Foo>::method_deprecated_text(&foo); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... <Foo>::method_deprecated_text(&foo); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_text': text +warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:38:13 | LL | foo.trait_deprecated_text(); | ^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_text': text +warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:40:9 | -LL | <Foo>::trait_deprecated_text(&foo); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... <Foo>::trait_deprecated_text(&foo); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::MethodTester::method_deprecated_unstable': text +warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated_unstable`: text --> $DIR/lint-stability-deprecated.rs:44:13 | -LL | foo.method_deprecated_unstable(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... foo.method_deprecated_unstable(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::MethodTester::method_deprecated_unstable': text +warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated_unstable`: text --> $DIR/lint-stability-deprecated.rs:45:9 | -LL | Foo::method_deprecated_unstable(&foo); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... Foo::method_deprecated_unstable(&foo); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::MethodTester::method_deprecated_unstable': text +warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated_unstable`: text --> $DIR/lint-stability-deprecated.rs:46:9 | -LL | <Foo>::method_deprecated_unstable(&foo); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... <Foo>::method_deprecated_unstable(&foo); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable': text +warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`: text --> $DIR/lint-stability-deprecated.rs:47:13 | LL | foo.trait_deprecated_unstable(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable': text +warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`: text --> $DIR/lint-stability-deprecated.rs:49:9 | -LL | <Foo>::trait_deprecated_unstable(&foo); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... <Foo>::trait_deprecated_unstable(&foo); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::MethodTester::method_deprecated_unstable_text': text +warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated_unstable_text`: text --> $DIR/lint-stability-deprecated.rs:53:13 | LL | ... foo.method_deprecated_unstable_text(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::MethodTester::method_deprecated_unstable_text': text +warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated_unstable_text`: text --> $DIR/lint-stability-deprecated.rs:54:9 | LL | ... Foo::method_deprecated_unstable_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::MethodTester::method_deprecated_unstable_text': text +warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated_unstable_text`: text --> $DIR/lint-stability-deprecated.rs:55:9 | LL | ... <Foo>::method_deprecated_unstable_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable_text': text +warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text --> $DIR/lint-stability-deprecated.rs:56:13 | -LL | foo.trait_deprecated_unstable_text(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... foo.trait_deprecated_unstable_text(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable_text': text +warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text --> $DIR/lint-stability-deprecated.rs:58:9 | LL | ... <Foo>::trait_deprecated_unstable_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::DeprecatedStruct::i': text +warning: use of deprecated field `lint_stability::DeprecatedStruct::i`: text --> $DIR/lint-stability-deprecated.rs:110:13 | LL | i: 0 | ^^^^ -warning: use of deprecated item 'lint_stability::DeprecatedUnstableStruct::i': text +warning: use of deprecated field `lint_stability::DeprecatedUnstableStruct::i`: text --> $DIR/lint-stability-deprecated.rs:114:13 | LL | i: 0 | ^^^^ -warning: use of deprecated item 'lint_stability::Trait::trait_deprecated': text +warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated`: text --> $DIR/lint-stability-deprecated.rs:145:13 | LL | foo.trait_deprecated(); | ^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::Trait::trait_deprecated': text +warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated`: text --> $DIR/lint-stability-deprecated.rs:147:9 | LL | <Foo>::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_text': text +warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:149:13 | LL | foo.trait_deprecated_text(); | ^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_text': text +warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:151:9 | -LL | <Foo>::trait_deprecated_text(&foo); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... <Foo>::trait_deprecated_text(&foo); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable': text +warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`: text --> $DIR/lint-stability-deprecated.rs:153:13 | LL | foo.trait_deprecated_unstable(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable': text +warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`: text --> $DIR/lint-stability-deprecated.rs:155:9 | -LL | <Foo>::trait_deprecated_unstable(&foo); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... <Foo>::trait_deprecated_unstable(&foo); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable_text': text +warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text --> $DIR/lint-stability-deprecated.rs:157:13 | -LL | foo.trait_deprecated_unstable_text(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... foo.trait_deprecated_unstable_text(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable_text': text +warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text --> $DIR/lint-stability-deprecated.rs:159:9 | LL | ... <Foo>::trait_deprecated_unstable_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::Trait::trait_deprecated': text +warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated`: text --> $DIR/lint-stability-deprecated.rs:176:13 | LL | foo.trait_deprecated(); | ^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_text': text +warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:177:13 | LL | foo.trait_deprecated_text(); | ^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable': text +warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`: text --> $DIR/lint-stability-deprecated.rs:178:13 | LL | foo.trait_deprecated_unstable(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable_text': text +warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text --> $DIR/lint-stability-deprecated.rs:179:13 | -LL | foo.trait_deprecated_unstable_text(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... foo.trait_deprecated_unstable_text(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'this_crate::MethodTester::method_deprecated': text +warning: use of deprecated associated function `this_crate::MethodTester::method_deprecated`: text --> $DIR/lint-stability-deprecated.rs:332:13 | LL | foo.method_deprecated(); | ^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'this_crate::MethodTester::method_deprecated': text +warning: use of deprecated associated function `this_crate::MethodTester::method_deprecated`: text --> $DIR/lint-stability-deprecated.rs:333:9 | LL | Foo::method_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'this_crate::MethodTester::method_deprecated': text +warning: use of deprecated associated function `this_crate::MethodTester::method_deprecated`: text --> $DIR/lint-stability-deprecated.rs:334:9 | LL | <Foo>::method_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'this_crate::Trait::trait_deprecated': text +warning: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text --> $DIR/lint-stability-deprecated.rs:335:13 | LL | foo.trait_deprecated(); | ^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'this_crate::Trait::trait_deprecated': text +warning: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text --> $DIR/lint-stability-deprecated.rs:337:9 | LL | <Foo>::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'this_crate::MethodTester::method_deprecated_text': text +warning: use of deprecated associated function `this_crate::MethodTester::method_deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:341:13 | -LL | foo.method_deprecated_text(); - | ^^^^^^^^^^^^^^^^^^^^^^ +LL | ... foo.method_deprecated_text(); + | ^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'this_crate::MethodTester::method_deprecated_text': text +warning: use of deprecated associated function `this_crate::MethodTester::method_deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:342:9 | -LL | Foo::method_deprecated_text(&foo); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... Foo::method_deprecated_text(&foo); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'this_crate::MethodTester::method_deprecated_text': text +warning: use of deprecated associated function `this_crate::MethodTester::method_deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:343:9 | -LL | <Foo>::method_deprecated_text(&foo); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... <Foo>::method_deprecated_text(&foo); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'this_crate::Trait::trait_deprecated_text': text +warning: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:344:13 | LL | foo.trait_deprecated_text(); | ^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'this_crate::Trait::trait_deprecated_text': text +warning: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:346:9 | LL | <Foo>::trait_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'this_crate::DeprecatedStruct::i': text +warning: use of deprecated field `this_crate::DeprecatedStruct::i`: text --> $DIR/lint-stability-deprecated.rs:387:13 | LL | i: 0 | ^^^^ -warning: use of deprecated item 'this_crate::Trait::trait_deprecated': text +warning: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text --> $DIR/lint-stability-deprecated.rs:406:13 | LL | foo.trait_deprecated(); | ^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'this_crate::Trait::trait_deprecated': text +warning: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text --> $DIR/lint-stability-deprecated.rs:408:9 | LL | <Foo>::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'this_crate::Trait::trait_deprecated_text': text +warning: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:410:13 | LL | foo.trait_deprecated_text(); | ^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'this_crate::Trait::trait_deprecated_text': text +warning: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:412:9 | LL | <Foo>::trait_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'this_crate::Trait::trait_deprecated': text +warning: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text --> $DIR/lint-stability-deprecated.rs:429:13 | LL | foo.trait_deprecated(); | ^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'this_crate::Trait::trait_deprecated_text': text +warning: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:430:13 | LL | foo.trait_deprecated_text(); | ^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::TraitWithAssociatedTypes::TypeDeprecated': text +warning: use of deprecated associated type `lint_stability::TraitWithAssociatedTypes::TypeDeprecated`: text --> $DIR/lint-stability-deprecated.rs:98:48 | LL | struct S2<T: TraitWithAssociatedTypes>(T::TypeDeprecated); | ^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::TraitWithAssociatedTypes::TypeDeprecated': text +warning: use of deprecated associated type `lint_stability::TraitWithAssociatedTypes::TypeDeprecated`: text --> $DIR/lint-stability-deprecated.rs:103:13 | LL | TypeDeprecated = u16, | ^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated item 'lint_stability::TraitWithAssociatedTypes::TypeDeprecated': text +warning: use of deprecated associated type `lint_stability::TraitWithAssociatedTypes::TypeDeprecated`: text --> $DIR/lint-stability-deprecated.rs:103:13 | LL | TypeDeprecated = u16, diff --git a/src/test/ui/lint/lint-stability-fields-deprecated.rs b/src/test/ui/lint/lint-stability-fields-deprecated.rs index 50e3970c7f0..14c6383806f 100644 --- a/src/test/ui/lint/lint-stability-fields-deprecated.rs +++ b/src/test/ui/lint/lint-stability-fields-deprecated.rs @@ -16,19 +16,19 @@ mod cross_crate { inherit: 1, override1: 2, override2: 3, - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field }; let _ = x.inherit; let _ = x.override1; let _ = x.override2; - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field let Stable { inherit: _, override1: _, override2: _ - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field } = x; // all fine let Stable { .. } = x; @@ -38,12 +38,12 @@ mod cross_crate { let _ = x.0; let _ = x.1; let _ = x.2; - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field let Stable2(_, _, _) - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field = x; // all fine let Stable2(..) = x; @@ -53,19 +53,19 @@ mod cross_crate { inherit: 1, override1: 2, override2: 3, - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field }; let _ = x.inherit; let _ = x.override1; let _ = x.override2; - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field let Unstable { inherit: _, override1: _, override2: _ - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field } = x; let Unstable @@ -78,13 +78,13 @@ mod cross_crate { let _ = x.0; let _ = x.1; let _ = x.2; - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field let Unstable2 (_, _, _) - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field = x; let Unstable2 // the patterns are all fine: @@ -92,58 +92,58 @@ mod cross_crate { let x = Deprecated { - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated struct inherit: 1, - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field override1: 2, - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field override2: 3, - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field }; let _ = x.inherit; - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field let _ = x.override1; - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field let _ = x.override2; - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field let Deprecated { - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated struct inherit: _, - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field override1: _, - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field override2: _ - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field } = x; let Deprecated - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated struct // the patterns are all fine: { .. } = x; let x = Deprecated2(1, 2, 3); - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated struct let _ = x.0; - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field let _ = x.1; - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field let _ = x.2; - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field let Deprecated2 - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated struct (_, - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field _, - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field _) - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field = x; let Deprecated2 - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated struct // the patterns are all fine: (..) = x; } @@ -203,19 +203,19 @@ mod this_crate { inherit: 1, override1: 2, override2: 3, - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field }; let _ = x.inherit; let _ = x.override1; let _ = x.override2; - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field let Stable { inherit: _, override1: _, override2: _ - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field } = x; // all fine let Stable { .. } = x; @@ -225,12 +225,12 @@ mod this_crate { let _ = x.0; let _ = x.1; let _ = x.2; - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field let Stable2(_, _, _) - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field = x; // all fine let Stable2(..) = x; @@ -240,19 +240,19 @@ mod this_crate { inherit: 1, override1: 2, override2: 3, - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field }; let _ = x.inherit; let _ = x.override1; let _ = x.override2; - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field let Unstable { inherit: _, override1: _, override2: _ - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field } = x; let Unstable @@ -265,13 +265,13 @@ mod this_crate { let _ = x.0; let _ = x.1; let _ = x.2; - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field let Unstable2 (_, _, _) - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field = x; let Unstable2 // the patterns are all fine: @@ -279,58 +279,58 @@ mod this_crate { let x = Deprecated { - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated struct inherit: 1, - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field override1: 2, - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field override2: 3, - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field }; let _ = x.inherit; - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field let _ = x.override1; - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field let _ = x.override2; - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field let Deprecated { - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated struct inherit: _, - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field override1: _, - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field override2: _ - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field } = x; let Deprecated - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated struct // the patterns are all fine: { .. } = x; let x = Deprecated2(1, 2, 3); - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated tuple struct let _ = x.0; - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field let _ = x.1; - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field let _ = x.2; - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field let Deprecated2 - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated tuple struct (_, - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field _, - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field _) - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated field = x; let Deprecated2 - //~^ ERROR use of deprecated item + //~^ ERROR use of deprecated tuple struct // the patterns are all fine: (..) = x; } diff --git a/src/test/ui/lint/lint-stability-fields-deprecated.stderr b/src/test/ui/lint/lint-stability-fields-deprecated.stderr index 5210fb690e9..ec786786023 100644 --- a/src/test/ui/lint/lint-stability-fields-deprecated.stderr +++ b/src/test/ui/lint/lint-stability-fields-deprecated.stderr @@ -1,4 +1,4 @@ -error: use of deprecated item 'cross_crate::lint_stability_fields::Deprecated': text +error: use of deprecated struct `cross_crate::lint_stability_fields::Deprecated`: text --> $DIR/lint-stability-fields-deprecated.rs:94:17 | LL | let x = Deprecated { @@ -10,367 +10,367 @@ note: the lint level is defined here LL | #![deny(deprecated)] | ^^^^^^^^^^ -error: use of deprecated item 'cross_crate::lint_stability_fields::Deprecated': text +error: use of deprecated struct `cross_crate::lint_stability_fields::Deprecated`: text --> $DIR/lint-stability-fields-deprecated.rs:111:13 | LL | let Deprecated { | ^^^^^^^^^^ -error: use of deprecated item 'cross_crate::lint_stability_fields::Deprecated': text +error: use of deprecated struct `cross_crate::lint_stability_fields::Deprecated`: text --> $DIR/lint-stability-fields-deprecated.rs:121:13 | LL | let Deprecated | ^^^^^^^^^^ -error: use of deprecated item 'cross_crate::lint_stability_fields::Deprecated2': text +error: use of deprecated struct `cross_crate::lint_stability_fields::Deprecated2`: text --> $DIR/lint-stability-fields-deprecated.rs:126:17 | LL | let x = Deprecated2(1, 2, 3); | ^^^^^^^^^^^ -error: use of deprecated item 'cross_crate::lint_stability_fields::Deprecated2': text +error: use of deprecated struct `cross_crate::lint_stability_fields::Deprecated2`: text --> $DIR/lint-stability-fields-deprecated.rs:136:13 | LL | let Deprecated2 | ^^^^^^^^^^^ -error: use of deprecated item 'cross_crate::lint_stability_fields::Deprecated2': text +error: use of deprecated struct `cross_crate::lint_stability_fields::Deprecated2`: text --> $DIR/lint-stability-fields-deprecated.rs:145:13 | LL | let Deprecated2 | ^^^^^^^^^^^ -error: use of deprecated item 'this_crate::Deprecated': text +error: use of deprecated struct `this_crate::Deprecated`: text --> $DIR/lint-stability-fields-deprecated.rs:281:17 | LL | let x = Deprecated { | ^^^^^^^^^^ -error: use of deprecated item 'this_crate::Deprecated': text +error: use of deprecated struct `this_crate::Deprecated`: text --> $DIR/lint-stability-fields-deprecated.rs:298:13 | LL | let Deprecated { | ^^^^^^^^^^ -error: use of deprecated item 'this_crate::Deprecated': text +error: use of deprecated struct `this_crate::Deprecated`: text --> $DIR/lint-stability-fields-deprecated.rs:308:13 | LL | let Deprecated | ^^^^^^^^^^ -error: use of deprecated item 'this_crate::Deprecated2': text +error: use of deprecated tuple struct `this_crate::Deprecated2`: text --> $DIR/lint-stability-fields-deprecated.rs:313:17 | LL | let x = Deprecated2(1, 2, 3); | ^^^^^^^^^^^ -error: use of deprecated item 'this_crate::Deprecated2': text +error: use of deprecated tuple struct `this_crate::Deprecated2`: text --> $DIR/lint-stability-fields-deprecated.rs:323:13 | LL | let Deprecated2 | ^^^^^^^^^^^ -error: use of deprecated item 'this_crate::Deprecated2': text +error: use of deprecated tuple struct `this_crate::Deprecated2`: text --> $DIR/lint-stability-fields-deprecated.rs:332:13 | LL | let Deprecated2 | ^^^^^^^^^^^ -error: use of deprecated item 'cross_crate::lint_stability_fields::Stable::override2': text +error: use of deprecated field `cross_crate::lint_stability_fields::Stable::override2`: text --> $DIR/lint-stability-fields-deprecated.rs:18:13 | LL | override2: 3, | ^^^^^^^^^^^^ -error: use of deprecated item 'cross_crate::lint_stability_fields::Stable::override2': text +error: use of deprecated field `cross_crate::lint_stability_fields::Stable::override2`: text --> $DIR/lint-stability-fields-deprecated.rs:24:17 | LL | let _ = x.override2; | ^^^^^^^^^^^ -error: use of deprecated item 'cross_crate::lint_stability_fields::Stable::override2': text +error: use of deprecated field `cross_crate::lint_stability_fields::Stable::override2`: text --> $DIR/lint-stability-fields-deprecated.rs:30:13 | LL | override2: _ | ^^^^^^^^^^^^ -error: use of deprecated item 'cross_crate::lint_stability_fields::Stable2::2': text +error: use of deprecated field `cross_crate::lint_stability_fields::Stable2::2`: text --> $DIR/lint-stability-fields-deprecated.rs:40:17 | LL | let _ = x.2; | ^^^ -error: use of deprecated item 'cross_crate::lint_stability_fields::Stable2::2': text +error: use of deprecated field `cross_crate::lint_stability_fields::Stable2::2`: text --> $DIR/lint-stability-fields-deprecated.rs:45:20 | LL | _) | ^ -error: use of deprecated item 'cross_crate::lint_stability_fields::Unstable::override2': text +error: use of deprecated field `cross_crate::lint_stability_fields::Unstable::override2`: text --> $DIR/lint-stability-fields-deprecated.rs:55:13 | LL | override2: 3, | ^^^^^^^^^^^^ -error: use of deprecated item 'cross_crate::lint_stability_fields::Unstable::override2': text +error: use of deprecated field `cross_crate::lint_stability_fields::Unstable::override2`: text --> $DIR/lint-stability-fields-deprecated.rs:61:17 | LL | let _ = x.override2; | ^^^^^^^^^^^ -error: use of deprecated item 'cross_crate::lint_stability_fields::Unstable::override2': text +error: use of deprecated field `cross_crate::lint_stability_fields::Unstable::override2`: text --> $DIR/lint-stability-fields-deprecated.rs:67:13 | LL | override2: _ | ^^^^^^^^^^^^ -error: use of deprecated item 'cross_crate::lint_stability_fields::Unstable2::2': text +error: use of deprecated field `cross_crate::lint_stability_fields::Unstable2::2`: text --> $DIR/lint-stability-fields-deprecated.rs:80:17 | LL | let _ = x.2; | ^^^ -error: use of deprecated item 'cross_crate::lint_stability_fields::Unstable2::2': text +error: use of deprecated field `cross_crate::lint_stability_fields::Unstable2::2`: text --> $DIR/lint-stability-fields-deprecated.rs:86:14 | LL | _) | ^ -error: use of deprecated item 'cross_crate::lint_stability_fields::Deprecated::inherit': text +error: use of deprecated field `cross_crate::lint_stability_fields::Deprecated::inherit`: text --> $DIR/lint-stability-fields-deprecated.rs:96:13 | LL | inherit: 1, | ^^^^^^^^^^ -error: use of deprecated item 'cross_crate::lint_stability_fields::Deprecated::override1': text +error: use of deprecated field `cross_crate::lint_stability_fields::Deprecated::override1`: text --> $DIR/lint-stability-fields-deprecated.rs:98:13 | LL | override1: 2, | ^^^^^^^^^^^^ -error: use of deprecated item 'cross_crate::lint_stability_fields::Deprecated::override2': text +error: use of deprecated field `cross_crate::lint_stability_fields::Deprecated::override2`: text --> $DIR/lint-stability-fields-deprecated.rs:100:13 | LL | override2: 3, | ^^^^^^^^^^^^ -error: use of deprecated item 'cross_crate::lint_stability_fields::Deprecated::inherit': text +error: use of deprecated field `cross_crate::lint_stability_fields::Deprecated::inherit`: text --> $DIR/lint-stability-fields-deprecated.rs:104:17 | LL | let _ = x.inherit; | ^^^^^^^^^ -error: use of deprecated item 'cross_crate::lint_stability_fields::Deprecated::override1': text +error: use of deprecated field `cross_crate::lint_stability_fields::Deprecated::override1`: text --> $DIR/lint-stability-fields-deprecated.rs:106:17 | LL | let _ = x.override1; | ^^^^^^^^^^^ -error: use of deprecated item 'cross_crate::lint_stability_fields::Deprecated::override2': text +error: use of deprecated field `cross_crate::lint_stability_fields::Deprecated::override2`: text --> $DIR/lint-stability-fields-deprecated.rs:108:17 | LL | let _ = x.override2; | ^^^^^^^^^^^ -error: use of deprecated item 'cross_crate::lint_stability_fields::Deprecated::inherit': text +error: use of deprecated field `cross_crate::lint_stability_fields::Deprecated::inherit`: text --> $DIR/lint-stability-fields-deprecated.rs:113:13 | LL | inherit: _, | ^^^^^^^^^^ -error: use of deprecated item 'cross_crate::lint_stability_fields::Deprecated::override1': text +error: use of deprecated field `cross_crate::lint_stability_fields::Deprecated::override1`: text --> $DIR/lint-stability-fields-deprecated.rs:115:13 | LL | override1: _, | ^^^^^^^^^^^^ -error: use of deprecated item 'cross_crate::lint_stability_fields::Deprecated::override2': text +error: use of deprecated field `cross_crate::lint_stability_fields::Deprecated::override2`: text --> $DIR/lint-stability-fields-deprecated.rs:117:13 | LL | override2: _ | ^^^^^^^^^^^^ -error: use of deprecated item 'cross_crate::lint_stability_fields::Deprecated2::0': text +error: use of deprecated field `cross_crate::lint_stability_fields::Deprecated2::0`: text --> $DIR/lint-stability-fields-deprecated.rs:129:17 | LL | let _ = x.0; | ^^^ -error: use of deprecated item 'cross_crate::lint_stability_fields::Deprecated2::1': text +error: use of deprecated field `cross_crate::lint_stability_fields::Deprecated2::1`: text --> $DIR/lint-stability-fields-deprecated.rs:131:17 | LL | let _ = x.1; | ^^^ -error: use of deprecated item 'cross_crate::lint_stability_fields::Deprecated2::2': text +error: use of deprecated field `cross_crate::lint_stability_fields::Deprecated2::2`: text --> $DIR/lint-stability-fields-deprecated.rs:133:17 | LL | let _ = x.2; | ^^^ -error: use of deprecated item 'cross_crate::lint_stability_fields::Deprecated2::0': text +error: use of deprecated field `cross_crate::lint_stability_fields::Deprecated2::0`: text --> $DIR/lint-stability-fields-deprecated.rs:138:14 | LL | (_, | ^ -error: use of deprecated item 'cross_crate::lint_stability_fields::Deprecated2::1': text +error: use of deprecated field `cross_crate::lint_stability_fields::Deprecated2::1`: text --> $DIR/lint-stability-fields-deprecated.rs:140:14 | LL | _, | ^ -error: use of deprecated item 'cross_crate::lint_stability_fields::Deprecated2::2': text +error: use of deprecated field `cross_crate::lint_stability_fields::Deprecated2::2`: text --> $DIR/lint-stability-fields-deprecated.rs:142:14 | LL | _) | ^ -error: use of deprecated item 'this_crate::Stable::override2': text +error: use of deprecated field `this_crate::Stable::override2`: text --> $DIR/lint-stability-fields-deprecated.rs:205:13 | LL | override2: 3, | ^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::Stable::override2': text +error: use of deprecated field `this_crate::Stable::override2`: text --> $DIR/lint-stability-fields-deprecated.rs:211:17 | LL | let _ = x.override2; | ^^^^^^^^^^^ -error: use of deprecated item 'this_crate::Stable::override2': text +error: use of deprecated field `this_crate::Stable::override2`: text --> $DIR/lint-stability-fields-deprecated.rs:217:13 | LL | override2: _ | ^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::Stable2::2': text +error: use of deprecated field `this_crate::Stable2::2`: text --> $DIR/lint-stability-fields-deprecated.rs:227:17 | LL | let _ = x.2; | ^^^ -error: use of deprecated item 'this_crate::Stable2::2': text +error: use of deprecated field `this_crate::Stable2::2`: text --> $DIR/lint-stability-fields-deprecated.rs:232:20 | LL | _) | ^ -error: use of deprecated item 'this_crate::Unstable::override2': text +error: use of deprecated field `this_crate::Unstable::override2`: text --> $DIR/lint-stability-fields-deprecated.rs:242:13 | LL | override2: 3, | ^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::Unstable::override2': text +error: use of deprecated field `this_crate::Unstable::override2`: text --> $DIR/lint-stability-fields-deprecated.rs:248:17 | LL | let _ = x.override2; | ^^^^^^^^^^^ -error: use of deprecated item 'this_crate::Unstable::override2': text +error: use of deprecated field `this_crate::Unstable::override2`: text --> $DIR/lint-stability-fields-deprecated.rs:254:13 | LL | override2: _ | ^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::Unstable2::2': text +error: use of deprecated field `this_crate::Unstable2::2`: text --> $DIR/lint-stability-fields-deprecated.rs:267:17 | LL | let _ = x.2; | ^^^ -error: use of deprecated item 'this_crate::Unstable2::2': text +error: use of deprecated field `this_crate::Unstable2::2`: text --> $DIR/lint-stability-fields-deprecated.rs:273:14 | LL | _) | ^ -error: use of deprecated item 'this_crate::Deprecated::inherit': text +error: use of deprecated field `this_crate::Deprecated::inherit`: text --> $DIR/lint-stability-fields-deprecated.rs:283:13 | LL | inherit: 1, | ^^^^^^^^^^ -error: use of deprecated item 'this_crate::Deprecated::override1': text +error: use of deprecated field `this_crate::Deprecated::override1`: text --> $DIR/lint-stability-fields-deprecated.rs:285:13 | LL | override1: 2, | ^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::Deprecated::override2': text +error: use of deprecated field `this_crate::Deprecated::override2`: text --> $DIR/lint-stability-fields-deprecated.rs:287:13 | LL | override2: 3, | ^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::Deprecated::inherit': text +error: use of deprecated field `this_crate::Deprecated::inherit`: text --> $DIR/lint-stability-fields-deprecated.rs:291:17 | LL | let _ = x.inherit; | ^^^^^^^^^ -error: use of deprecated item 'this_crate::Deprecated::override1': text +error: use of deprecated field `this_crate::Deprecated::override1`: text --> $DIR/lint-stability-fields-deprecated.rs:293:17 | LL | let _ = x.override1; | ^^^^^^^^^^^ -error: use of deprecated item 'this_crate::Deprecated::override2': text +error: use of deprecated field `this_crate::Deprecated::override2`: text --> $DIR/lint-stability-fields-deprecated.rs:295:17 | LL | let _ = x.override2; | ^^^^^^^^^^^ -error: use of deprecated item 'this_crate::Deprecated::inherit': text +error: use of deprecated field `this_crate::Deprecated::inherit`: text --> $DIR/lint-stability-fields-deprecated.rs:300:13 | LL | inherit: _, | ^^^^^^^^^^ -error: use of deprecated item 'this_crate::Deprecated::override1': text +error: use of deprecated field `this_crate::Deprecated::override1`: text --> $DIR/lint-stability-fields-deprecated.rs:302:13 | LL | override1: _, | ^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::Deprecated::override2': text +error: use of deprecated field `this_crate::Deprecated::override2`: text --> $DIR/lint-stability-fields-deprecated.rs:304:13 | LL | override2: _ | ^^^^^^^^^^^^ -error: use of deprecated item 'this_crate::Deprecated2::0': text +error: use of deprecated field `this_crate::Deprecated2::0`: text --> $DIR/lint-stability-fields-deprecated.rs:316:17 | LL | let _ = x.0; | ^^^ -error: use of deprecated item 'this_crate::Deprecated2::1': text +error: use of deprecated field `this_crate::Deprecated2::1`: text --> $DIR/lint-stability-fields-deprecated.rs:318:17 | LL | let _ = x.1; | ^^^ -error: use of deprecated item 'this_crate::Deprecated2::2': text +error: use of deprecated field `this_crate::Deprecated2::2`: text --> $DIR/lint-stability-fields-deprecated.rs:320:17 | LL | let _ = x.2; | ^^^ -error: use of deprecated item 'this_crate::Deprecated2::0': text +error: use of deprecated field `this_crate::Deprecated2::0`: text --> $DIR/lint-stability-fields-deprecated.rs:325:14 | LL | (_, | ^ -error: use of deprecated item 'this_crate::Deprecated2::1': text +error: use of deprecated field `this_crate::Deprecated2::1`: text --> $DIR/lint-stability-fields-deprecated.rs:327:14 | LL | _, | ^ -error: use of deprecated item 'this_crate::Deprecated2::2': text +error: use of deprecated field `this_crate::Deprecated2::2`: text --> $DIR/lint-stability-fields-deprecated.rs:329:14 | LL | _) diff --git a/src/test/ui/lint/lint-stability2.rs b/src/test/ui/lint/lint-stability2.rs index 9710d0826c7..9ae23dac61b 100644 --- a/src/test/ui/lint/lint-stability2.rs +++ b/src/test/ui/lint/lint-stability2.rs @@ -1,5 +1,5 @@ // aux-build:lint_stability.rs -// error-pattern: use of deprecated item +// error-pattern: use of deprecated function #![deny(deprecated)] diff --git a/src/test/ui/lint/lint-stability2.stderr b/src/test/ui/lint/lint-stability2.stderr index a14bf2ec8ca..036304d25f9 100644 --- a/src/test/ui/lint/lint-stability2.stderr +++ b/src/test/ui/lint/lint-stability2.stderr @@ -1,4 +1,4 @@ -error: use of deprecated item 'lint_stability::deprecated': text +error: use of deprecated function `lint_stability::deprecated`: text --> $DIR/lint-stability2.rs:12:5 | LL | macro_test!(); diff --git a/src/test/ui/lint/lint-stability3.rs b/src/test/ui/lint/lint-stability3.rs index 3d2cc6890b8..4452846ec0a 100644 --- a/src/test/ui/lint/lint-stability3.rs +++ b/src/test/ui/lint/lint-stability3.rs @@ -1,5 +1,5 @@ // aux-build:lint_stability.rs -// error-pattern: use of deprecated item +// error-pattern: use of deprecated function #![deny(deprecated)] #![allow(warnings)] diff --git a/src/test/ui/lint/lint-stability3.stderr b/src/test/ui/lint/lint-stability3.stderr index 858ac12612c..b89a7df4938 100644 --- a/src/test/ui/lint/lint-stability3.stderr +++ b/src/test/ui/lint/lint-stability3.stderr @@ -1,4 +1,4 @@ -error: use of deprecated item 'lint_stability::deprecated_text': text +error: use of deprecated function `lint_stability::deprecated_text`: text --> $DIR/lint-stability3.rs:13:5 | LL | macro_test_arg_nested!(deprecated_text); diff --git a/src/test/ui/liveness/liveness-upvars.rs b/src/test/ui/liveness/liveness-upvars.rs index b2837e74b8c..98ea4d71ccf 100644 --- a/src/test/ui/liveness/liveness-upvars.rs +++ b/src/test/ui/liveness/liveness-upvars.rs @@ -27,7 +27,7 @@ pub fn f() { let mut c = 0; // Captured by value, but variable is dead on entry. - move || { + let _ = move || { c = 1; //~ WARN value captured by `c` is never read println!("{}", c); }; @@ -37,7 +37,7 @@ pub fn f() { }; // Read and written to, but never actually used. - move || { + let _ = move || { c += 1; //~ WARN unused variable: `c` }; let _ = async move { @@ -45,13 +45,13 @@ pub fn f() { //~| WARN unused variable: `c` }; - move || { + let _ = move || { println!("{}", c); // Value is read by closure itself on later invocations. c += 1; }; let b = Box::new(42); - move || { + let _ = move || { println!("{}", c); // Never read because this is FnOnce closure. c += 1; //~ WARN value assigned to `c` is never read @@ -67,12 +67,12 @@ pub fn f() { pub fn nested() { let mut d = None; let mut e = None; - || { - || { + let _ = || { + let _ = || { d = Some("d1"); //~ WARN value assigned to `d` is never read d = Some("d2"); }; - move || { + let _ = move || { e = Some("e1"); //~ WARN value assigned to `e` is never read //~| WARN unused variable: `e` e = Some("e2"); //~ WARN value assigned to `e` is never read @@ -81,7 +81,7 @@ pub fn nested() { } pub fn g<T: Default>(mut v: T) { - |r| { + let _ = |r| { if r { v = T::default(); //~ WARN value assigned to `v` is never read } else { @@ -92,7 +92,7 @@ pub fn g<T: Default>(mut v: T) { pub fn h<T: Copy + Default + std::fmt::Debug>() { let mut z = T::default(); - move |b| { + let _ = move |b| { loop { if b { z = T::default(); //~ WARN value assigned to `z` is never read diff --git a/src/test/ui/macros/macro-deprecation.rs b/src/test/ui/macros/macro-deprecation.rs index 9636b48c2da..a7f327cf53b 100644 --- a/src/test/ui/macros/macro-deprecation.rs +++ b/src/test/ui/macros/macro-deprecation.rs @@ -8,6 +8,6 @@ macro_rules! local_deprecated{ () => () } fn main() { - local_deprecated!(); //~ WARN use of deprecated item 'local_deprecated': local deprecation note - deprecated_macro!(); //~ WARN use of deprecated item 'deprecated_macro': deprecation note + local_deprecated!(); //~ WARN use of deprecated macro `local_deprecated`: local deprecation note + deprecated_macro!(); //~ WARN use of deprecated macro `deprecated_macro`: deprecation note } diff --git a/src/test/ui/macros/macro-deprecation.stderr b/src/test/ui/macros/macro-deprecation.stderr index 0e8ecb58fe5..07849d7ce57 100644 --- a/src/test/ui/macros/macro-deprecation.stderr +++ b/src/test/ui/macros/macro-deprecation.stderr @@ -1,4 +1,4 @@ -warning: use of deprecated item 'local_deprecated': local deprecation note +warning: use of deprecated macro `local_deprecated`: local deprecation note --> $DIR/macro-deprecation.rs:11:5 | LL | local_deprecated!(); @@ -6,7 +6,7 @@ LL | local_deprecated!(); | = note: `#[warn(deprecated)]` on by default -warning: use of deprecated item 'deprecated_macro': deprecation note +warning: use of deprecated macro `deprecated_macro`: deprecation note --> $DIR/macro-deprecation.rs:12:5 | LL | deprecated_macro!(); diff --git a/src/test/ui/macros/macro-stability.rs b/src/test/ui/macros/macro-stability.rs index 755f55c28de..e2eff7c1c2d 100644 --- a/src/test/ui/macros/macro-stability.rs +++ b/src/test/ui/macros/macro-stability.rs @@ -22,7 +22,7 @@ fn main() { // unstable_macro_modern!(); // ERROR use of unstable library feature 'unstable_macros' deprecated_macro!(); - //~^ WARN use of deprecated item 'deprecated_macro': deprecation reason + //~^ WARN use of deprecated macro `deprecated_macro`: deprecation reason local_deprecated!(); - //~^ WARN use of deprecated item 'local_deprecated': local deprecation reason + //~^ WARN use of deprecated macro `local_deprecated`: local deprecation reason } diff --git a/src/test/ui/macros/macro-stability.stderr b/src/test/ui/macros/macro-stability.stderr index 9e127a3b855..34b62b4b1c3 100644 --- a/src/test/ui/macros/macro-stability.stderr +++ b/src/test/ui/macros/macro-stability.stderr @@ -22,7 +22,7 @@ LL | unstable_macro!(); | = help: add `#![feature(unstable_macros)]` to the crate attributes to enable -warning: use of deprecated item 'deprecated_macro': deprecation reason +warning: use of deprecated macro `deprecated_macro`: deprecation reason --> $DIR/macro-stability.rs:24:5 | LL | deprecated_macro!(); @@ -30,7 +30,7 @@ LL | deprecated_macro!(); | = note: `#[warn(deprecated)]` on by default -warning: use of deprecated item 'local_deprecated': local deprecation reason +warning: use of deprecated macro `local_deprecated`: local deprecation reason --> $DIR/macro-stability.rs:26:5 | LL | local_deprecated!(); diff --git a/src/test/ui/nll/capture-mut-ref.fixed b/src/test/ui/nll/capture-mut-ref.fixed index 639de2813a9..2dacb26b6eb 100644 --- a/src/test/ui/nll/capture-mut-ref.fixed +++ b/src/test/ui/nll/capture-mut-ref.fixed @@ -8,7 +8,7 @@ pub fn mutable_upvar() { let x = &mut 0; //~^ ERROR - move || { + let _ = move || { *x = 1; }; } diff --git a/src/test/ui/nll/capture-mut-ref.rs b/src/test/ui/nll/capture-mut-ref.rs index 89f49e1ea51..56e01f7b776 100644 --- a/src/test/ui/nll/capture-mut-ref.rs +++ b/src/test/ui/nll/capture-mut-ref.rs @@ -8,7 +8,7 @@ pub fn mutable_upvar() { let mut x = &mut 0; //~^ ERROR - move || { + let _ = move || { *x = 1; }; } diff --git a/src/test/ui/nll/issue-48623-generator.rs b/src/test/ui/nll/issue-48623-generator.rs index ba3eccff495..08d2584ee5e 100644 --- a/src/test/ui/nll/issue-48623-generator.rs +++ b/src/test/ui/nll/issue-48623-generator.rs @@ -12,7 +12,7 @@ impl Drop for WithDrop { fn reborrow_from_generator(r: &mut ()) { let d = WithDrop; - move || { d; yield; &mut *r }; + move || { d; yield; &mut *r }; //~ WARN unused generator that must be used } fn main() {} diff --git a/src/test/ui/nll/issue-48623-generator.stderr b/src/test/ui/nll/issue-48623-generator.stderr new file mode 100644 index 00000000000..70a83e46ff0 --- /dev/null +++ b/src/test/ui/nll/issue-48623-generator.stderr @@ -0,0 +1,11 @@ +warning: unused generator that must be used + --> $DIR/issue-48623-generator.rs:15:5 + | +LL | move || { d; yield; &mut *r }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(unused_must_use)]` on by default + = note: generators are lazy and do nothing unless resumed + +warning: 1 warning emitted + diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse-promotion.rs b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse-promotion.rs index 14797917193..993954b450e 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse-promotion.rs +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse-promotion.rs @@ -1,5 +1,5 @@ // Test that `by_move_binding @ pat_with_by_ref_bindings` is prevented even with promotion. -// Currently this logic exists in HAIR match checking as opposed to borrowck. +// Currently this logic exists in THIR match checking as opposed to borrowck. #![feature(bindings_after_at)] #![feature(move_ref_pattern)] diff --git a/src/test/ui/pattern/const-pat-ice.stderr b/src/test/ui/pattern/const-pat-ice.stderr index 6e87e5c6912..2aa0824f301 100644 --- a/src/test/ui/pattern/const-pat-ice.stderr +++ b/src/test/ui/pattern/const-pat-ice.stderr @@ -1,4 +1,4 @@ -thread 'rustc' panicked at 'assertion failed: rows.iter().all(|r| r.len() == v.len())', src/librustc_mir_build/hair/pattern/_match.rs:LL:CC +thread 'rustc' panicked at 'assertion failed: rows.iter().all(|r| r.len() == v.len())', src/librustc_mir_build/thir/pattern/_match.rs:LL:CC note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace error: internal compiler error: unexpected panic diff --git a/src/test/ui/pattern/issue-74539.rs b/src/test/ui/pattern/issue-74539.rs new file mode 100644 index 00000000000..0b25f87ec53 --- /dev/null +++ b/src/test/ui/pattern/issue-74539.rs @@ -0,0 +1,15 @@ +enum E { + A(u8, u8), +} + +fn main() { + let e = E::A(2, 3); + match e { + E::A(x @ ..) => { + //~^ ERROR: `x @` is not allowed in a tuple struct + //~| ERROR: `..` patterns are not allowed here + //~| ERROR: this pattern has 1 field, but the corresponding tuple variant has 2 fields + x + } + }; +} diff --git a/src/test/ui/pattern/issue-74539.stderr b/src/test/ui/pattern/issue-74539.stderr new file mode 100644 index 00000000000..cbc90b5397d --- /dev/null +++ b/src/test/ui/pattern/issue-74539.stderr @@ -0,0 +1,32 @@ +error: `x @` is not allowed in a tuple struct + --> $DIR/issue-74539.rs:8:14 + | +LL | E::A(x @ ..) => { + | ^^^^^^ this is only allowed in slice patterns + | + = help: remove this and bind each tuple field independently +help: if you don't need to use the contents of x, discard the tuple's remaining fields + | +LL | E::A(..) => { + | ^^ + +error: `..` patterns are not allowed here + --> $DIR/issue-74539.rs:8:18 + | +LL | E::A(x @ ..) => { + | ^^ + | + = note: only allowed in tuple, tuple struct, and slice patterns + +error[E0023]: this pattern has 1 field, but the corresponding tuple variant has 2 fields + --> $DIR/issue-74539.rs:8:9 + | +LL | A(u8, u8), + | --------- tuple variant defined here +... +LL | E::A(x @ ..) => { + | ^^^^^^^^^^^^ expected 2 fields, found 1 + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0023`. diff --git a/src/test/ui/pattern/issue-74702.rs b/src/test/ui/pattern/issue-74702.rs new file mode 100644 index 00000000000..0aeb3b217a2 --- /dev/null +++ b/src/test/ui/pattern/issue-74702.rs @@ -0,0 +1,7 @@ +fn main() { + let (foo @ ..,) = (0, 0); + //~^ ERROR: `foo @` is not allowed in a tuple + //~| ERROR: `..` patterns are not allowed here + //~| ERROR: mismatched types + dbg!(foo); +} diff --git a/src/test/ui/pattern/issue-74702.stderr b/src/test/ui/pattern/issue-74702.stderr new file mode 100644 index 00000000000..aca5c9aed96 --- /dev/null +++ b/src/test/ui/pattern/issue-74702.stderr @@ -0,0 +1,34 @@ +error: `foo @` is not allowed in a tuple + --> $DIR/issue-74702.rs:2:10 + | +LL | let (foo @ ..,) = (0, 0); + | ^^^^^^^^ this is only allowed in slice patterns + | + = help: remove this and bind each tuple field independently +help: if you don't need to use the contents of foo, discard the tuple's remaining fields + | +LL | let (..,) = (0, 0); + | ^^ + +error: `..` patterns are not allowed here + --> $DIR/issue-74702.rs:2:16 + | +LL | let (foo @ ..,) = (0, 0); + | ^^ + | + = note: only allowed in tuple, tuple struct, and slice patterns + +error[E0308]: mismatched types + --> $DIR/issue-74702.rs:2:9 + | +LL | let (foo @ ..,) = (0, 0); + | ^^^^^^^^^^^ ------ this expression has type `({integer}, {integer})` + | | + | expected a tuple with 2 elements, found one with 1 element + | + = note: expected tuple `({integer}, {integer})` + found tuple `(_,)` + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/pattern/issue-74954.rs b/src/test/ui/pattern/issue-74954.rs new file mode 100644 index 00000000000..269ec3c7abe --- /dev/null +++ b/src/test/ui/pattern/issue-74954.rs @@ -0,0 +1,7 @@ +// check-pass + +fn main() { + if let Some([b'@', filename @ ..]) = Some(b"@abc123") { + println!("filename {:?}", filename); + } +} diff --git a/src/test/ui/polymorphization/issue-74636.rs b/src/test/ui/polymorphization/issue-74636.rs new file mode 100644 index 00000000000..4c532f451e3 --- /dev/null +++ b/src/test/ui/polymorphization/issue-74636.rs @@ -0,0 +1,16 @@ +// compile-flags:-Zpolymorphize=on +// build-pass + +use std::any::TypeId; + +pub fn foo<T: 'static>(_: T) -> TypeId { + TypeId::of::<T>() +} + +fn outer<T: 'static>() { + foo(|| ()); +} + +fn main() { + outer::<u8>(); +} diff --git a/src/test/ui/proc-macro/attributes-on-definitions.rs b/src/test/ui/proc-macro/attributes-on-definitions.rs index 055781d2c60..c0733c8b416 100644 --- a/src/test/ui/proc-macro/attributes-on-definitions.rs +++ b/src/test/ui/proc-macro/attributes-on-definitions.rs @@ -6,7 +6,7 @@ extern crate attributes_on_definitions; attributes_on_definitions::with_attrs!(); -//~^ WARN use of deprecated item +//~^ WARN use of deprecated // No errors about the use of unstable and unsafe code inside the macro. fn main() {} diff --git a/src/test/ui/proc-macro/attributes-on-definitions.stderr b/src/test/ui/proc-macro/attributes-on-definitions.stderr index 3e6b8f6a435..c63dd00119a 100644 --- a/src/test/ui/proc-macro/attributes-on-definitions.stderr +++ b/src/test/ui/proc-macro/attributes-on-definitions.stderr @@ -1,4 +1,4 @@ -warning: use of deprecated item 'attributes_on_definitions::with_attrs': test +warning: use of deprecated macro `attributes_on_definitions::with_attrs`: test --> $DIR/attributes-on-definitions.rs:8:1 | LL | attributes_on_definitions::with_attrs!(); diff --git a/src/test/ui/proc-macro/crt-static.rs b/src/test/ui/proc-macro/crt-static.rs index 97f6265e308..4f11f81b00b 100644 --- a/src/test/ui/proc-macro/crt-static.rs +++ b/src/test/ui/proc-macro/crt-static.rs @@ -1,4 +1,4 @@ -// Test proc-macro crate can be built without addtional RUSTFLAGS +// Test proc-macro crate can be built without additional RUSTFLAGS // on musl target // override -Ctarget-feature=-crt-static from compiletest // compile-flags: -Ctarget-feature= diff --git a/src/test/ui/statics/static-promotion.rs b/src/test/ui/statics/static-promotion.rs new file mode 100644 index 00000000000..bd8910bdb3f --- /dev/null +++ b/src/test/ui/statics/static-promotion.rs @@ -0,0 +1,34 @@ +// check-pass + +// Use of global static variables in literal values should be allowed for +// promotion. +// This test is to demonstrate the issue raised in +// https://github.com/rust-lang/rust/issues/70584 + +// Literal values were previously promoted into local static values when +// other global static variables are used. + +struct A<T: 'static>(&'static T); +struct B<T: 'static + ?Sized> { + x: &'static T, +} +static STR: &'static [u8] = b"hi"; +static C: A<B<B<[u8]>>> = { + A(&B { + x: &B { x: STR }, + }) +}; + +pub struct Slice(&'static [i32]); + +static CONTENT: i32 = 42; +pub static CONTENT_MAP: Slice = Slice(&[CONTENT]); + +pub static FOO: (i32, i32) = (42, 43); +pub static CONTENT_MAP2: Slice = Slice(&[FOO.0]); + +fn main() { + assert_eq!(b"hi", C.0.x.x); + assert_eq!(&[42], CONTENT_MAP.0); + assert_eq!(&[42], CONTENT_MAP2.0); +} diff --git a/src/test/ui/suggestions/issue-61226.fixed b/src/test/ui/suggestions/issue-61226.fixed new file mode 100644 index 00000000000..6e9d74344bc --- /dev/null +++ b/src/test/ui/suggestions/issue-61226.fixed @@ -0,0 +1,6 @@ +// run-rustfix +struct X {} +fn main() { + let _ = vec![X {}]; //… + //~^ ERROR expected value, found struct `X` +} diff --git a/src/test/ui/suggestions/issue-61226.rs b/src/test/ui/suggestions/issue-61226.rs index e83b0b4d630..695fe73418a 100644 --- a/src/test/ui/suggestions/issue-61226.rs +++ b/src/test/ui/suggestions/issue-61226.rs @@ -1,5 +1,6 @@ +// run-rustfix struct X {} fn main() { - vec![X]; //… + let _ = vec![X]; //… //~^ ERROR expected value, found struct `X` } diff --git a/src/test/ui/suggestions/issue-61226.stderr b/src/test/ui/suggestions/issue-61226.stderr index 7f6f082d7a8..cda962a9045 100644 --- a/src/test/ui/suggestions/issue-61226.stderr +++ b/src/test/ui/suggestions/issue-61226.stderr @@ -1,11 +1,11 @@ error[E0423]: expected value, found struct `X` - --> $DIR/issue-61226.rs:3:10 + --> $DIR/issue-61226.rs:4:18 | LL | struct X {} | ----------- `X` defined here LL | fn main() { -LL | vec![X]; //… - | ^ help: use struct literal syntax instead: `X {}` +LL | let _ = vec![X]; //… + | ^ help: use struct literal syntax instead: `X {}` error: aborting due to previous error diff --git a/src/test/ui/suggestions/type-ascription-instead-of-method.fixed b/src/test/ui/suggestions/type-ascription-instead-of-method.fixed new file mode 100644 index 00000000000..56b740b0d5c --- /dev/null +++ b/src/test/ui/suggestions/type-ascription-instead-of-method.fixed @@ -0,0 +1,5 @@ +// run-rustfix +fn main() { + let _ = Box::new("foo".to_string()); + //~^ ERROR expected type, found +} diff --git a/src/test/ui/suggestions/type-ascription-instead-of-method.rs b/src/test/ui/suggestions/type-ascription-instead-of-method.rs index 361729d50c2..a603e09e7e8 100644 --- a/src/test/ui/suggestions/type-ascription-instead-of-method.rs +++ b/src/test/ui/suggestions/type-ascription-instead-of-method.rs @@ -1,4 +1,5 @@ +// run-rustfix fn main() { - Box:new("foo".to_string()) + let _ = Box:new("foo".to_string()); //~^ ERROR expected type, found } diff --git a/src/test/ui/suggestions/type-ascription-instead-of-method.stderr b/src/test/ui/suggestions/type-ascription-instead-of-method.stderr index c111b4a9bc7..83bc33f410a 100644 --- a/src/test/ui/suggestions/type-ascription-instead-of-method.stderr +++ b/src/test/ui/suggestions/type-ascription-instead-of-method.stderr @@ -1,10 +1,10 @@ error: expected type, found `"foo"` - --> $DIR/type-ascription-instead-of-method.rs:2:13 + --> $DIR/type-ascription-instead-of-method.rs:3:21 | -LL | Box:new("foo".to_string()) - | - ^^^^^ expected type - | | - | help: maybe write a path separator here: `::` +LL | let _ = Box:new("foo".to_string()); + | - ^^^^^ expected type + | | + | help: maybe write a path separator here: `::` | = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>` diff --git a/src/test/ui/suggestions/type-ascription-instead-of-path-2.fixed b/src/test/ui/suggestions/type-ascription-instead-of-path-2.fixed new file mode 100644 index 00000000000..787fcc1208e --- /dev/null +++ b/src/test/ui/suggestions/type-ascription-instead-of-path-2.fixed @@ -0,0 +1,6 @@ +// run-rustfix +fn main() -> Result<(), ()> { + let _ = vec![Ok(2)].into_iter().collect::<Result<Vec<_>,_>>()?; + //~^ ERROR expected `::`, found `(` + Ok(()) +} diff --git a/src/test/ui/suggestions/type-ascription-instead-of-path-2.rs b/src/test/ui/suggestions/type-ascription-instead-of-path-2.rs index 220fd1eebda..934016b3b81 100644 --- a/src/test/ui/suggestions/type-ascription-instead-of-path-2.rs +++ b/src/test/ui/suggestions/type-ascription-instead-of-path-2.rs @@ -1,5 +1,6 @@ +// run-rustfix fn main() -> Result<(), ()> { - vec![Ok(2)].into_iter().collect:<Result<Vec<_>,_>>()?; + let _ = vec![Ok(2)].into_iter().collect:<Result<Vec<_>,_>>()?; //~^ ERROR expected `::`, found `(` Ok(()) } diff --git a/src/test/ui/suggestions/type-ascription-instead-of-path-2.stderr b/src/test/ui/suggestions/type-ascription-instead-of-path-2.stderr index 1d1999d350f..970b220b737 100644 --- a/src/test/ui/suggestions/type-ascription-instead-of-path-2.stderr +++ b/src/test/ui/suggestions/type-ascription-instead-of-path-2.stderr @@ -1,10 +1,10 @@ error: expected `::`, found `(` - --> $DIR/type-ascription-instead-of-path-2.rs:2:55 + --> $DIR/type-ascription-instead-of-path-2.rs:3:63 | -LL | vec![Ok(2)].into_iter().collect:<Result<Vec<_>,_>>()?; - | - ^ expected `::` - | | - | help: maybe write a path separator here: `::` +LL | let _ = vec![Ok(2)].into_iter().collect:<Result<Vec<_>,_>>()?; + | - ^ expected `::` + | | + | help: maybe write a path separator here: `::` | = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>` diff --git a/src/test/ui/suggestions/type-ascription-instead-of-variant.fixed b/src/test/ui/suggestions/type-ascription-instead-of-variant.fixed new file mode 100644 index 00000000000..b3247e1287d --- /dev/null +++ b/src/test/ui/suggestions/type-ascription-instead-of-variant.fixed @@ -0,0 +1,5 @@ +// run-rustfix +fn main() { + let _ = Option::Some(""); + //~^ ERROR expected type, found +} diff --git a/src/test/ui/suggestions/type-ascription-instead-of-variant.rs b/src/test/ui/suggestions/type-ascription-instead-of-variant.rs index b90867fef6b..6fd2c19541c 100644 --- a/src/test/ui/suggestions/type-ascription-instead-of-variant.rs +++ b/src/test/ui/suggestions/type-ascription-instead-of-variant.rs @@ -1,3 +1,4 @@ +// run-rustfix fn main() { let _ = Option:Some(""); //~^ ERROR expected type, found diff --git a/src/test/ui/suggestions/type-ascription-instead-of-variant.stderr b/src/test/ui/suggestions/type-ascription-instead-of-variant.stderr index f38020dcc38..f59ba78d4d3 100644 --- a/src/test/ui/suggestions/type-ascription-instead-of-variant.stderr +++ b/src/test/ui/suggestions/type-ascription-instead-of-variant.stderr @@ -1,5 +1,5 @@ error: expected type, found `""` - --> $DIR/type-ascription-instead-of-variant.rs:2:25 + --> $DIR/type-ascription-instead-of-variant.rs:3:25 | LL | let _ = Option:Some(""); | - ^^ expected type diff --git a/src/test/ui/test-attrs/test-runner-hides-buried-main.rs b/src/test/ui/test-attrs/test-runner-hides-buried-main.rs index 917c09801e1..bf5482056d4 100644 --- a/src/test/ui/test-attrs/test-runner-hides-buried-main.rs +++ b/src/test/ui/test-attrs/test-runner-hides-buried-main.rs @@ -7,9 +7,9 @@ mod a { fn b() { - || { + (|| { #[main] fn c() { panic!(); } - }; + })(); } } diff --git a/src/test/ui/type/ascription/issue-47666.fixed b/src/test/ui/type/ascription/issue-47666.fixed new file mode 100644 index 00000000000..c4db747551e --- /dev/null +++ b/src/test/ui/type/ascription/issue-47666.fixed @@ -0,0 +1,4 @@ +// run-rustfix +fn main() { + let _ = Option::Some(vec![0, 1]); //~ ERROR expected type, found +} diff --git a/src/test/ui/type/ascription/issue-47666.rs b/src/test/ui/type/ascription/issue-47666.rs index 8035de4a48a..c67202e2157 100644 --- a/src/test/ui/type/ascription/issue-47666.rs +++ b/src/test/ui/type/ascription/issue-47666.rs @@ -1,7 +1,4 @@ +// run-rustfix fn main() { let _ = Option:Some(vec![0, 1]); //~ ERROR expected type, found - //~^ ERROR expected value, found enum `Option` - //~| ERROR expected type, found variant `Some` } - -// This case isn't currently being handled gracefully due to the macro invocation. diff --git a/src/test/ui/type/ascription/issue-47666.stderr b/src/test/ui/type/ascription/issue-47666.stderr index 72c7c144b53..ba393ff1a20 100644 --- a/src/test/ui/type/ascription/issue-47666.stderr +++ b/src/test/ui/type/ascription/issue-47666.stderr @@ -1,5 +1,5 @@ error: expected type, found reserved keyword `box` - --> $DIR/issue-47666.rs:2:25 + --> $DIR/issue-47666.rs:3:25 | LL | let _ = Option:Some(vec![0, 1]); | - ^^^^^^^^^^ @@ -12,35 +12,5 @@ LL | let _ = Option:Some(vec![0, 1]); = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>` = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0423]: expected value, found enum `Option` - --> $DIR/issue-47666.rs:2:13 - | -LL | let _ = Option:Some(vec![0, 1]); - | ^^^^^^ - | -help: try using one of the enum's variants - | -LL | let _ = std::option::Option::None:Some(vec![0, 1]); - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | let _ = std::option::Option::Some:Some(vec![0, 1]); - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - -error[E0573]: expected type, found variant `Some` - --> $DIR/issue-47666.rs:2:20 - | -LL | let _ = Option:Some(vec![0, 1]); - | ^^^^^^^^^^^^^^^^ not a type - | -help: try using the variant's enum - | -LL | let _ = Option:std::option::Option; - | ^^^^^^^^^^^^^^^^^^^ -help: maybe you meant to write a path separator here - | -LL | let _ = Option::Some(vec![0, 1]); - | ^^ - -error: aborting due to 3 previous errors +error: aborting due to previous error -Some errors have detailed explanations: E0423, E0573. -For more information about an error, try `rustc --explain E0423`. diff --git a/src/test/ui/type/ascription/issue-54516.fixed b/src/test/ui/type/ascription/issue-54516.fixed new file mode 100644 index 00000000000..181637b97bb --- /dev/null +++ b/src/test/ui/type/ascription/issue-54516.fixed @@ -0,0 +1,7 @@ +// run-rustfix +use std::collections::BTreeMap; + +fn main() { + println!("{}", std::mem::size_of::<BTreeMap<u32, u32>>()); + //~^ ERROR casts cannot be followed by a function call +} diff --git a/src/test/ui/type/ascription/issue-54516.rs b/src/test/ui/type/ascription/issue-54516.rs index 8d6fd2abb6d..f09ddd487d8 100644 --- a/src/test/ui/type/ascription/issue-54516.rs +++ b/src/test/ui/type/ascription/issue-54516.rs @@ -1,8 +1,7 @@ +// run-rustfix use std::collections::BTreeMap; fn main() { println!("{}", std::mem:size_of::<BTreeMap<u32, u32>>()); //~^ ERROR casts cannot be followed by a function call - //~| ERROR expected value, found module `std::mem` [E0423] - //~| ERROR cannot find type `size_of` in this scope [E0412] } diff --git a/src/test/ui/type/ascription/issue-54516.stderr b/src/test/ui/type/ascription/issue-54516.stderr index ec08cf209c2..2c7ff6bdc48 100644 --- a/src/test/ui/type/ascription/issue-54516.stderr +++ b/src/test/ui/type/ascription/issue-54516.stderr @@ -1,5 +1,5 @@ error: casts cannot be followed by a function call - --> $DIR/issue-54516.rs:4:20 + --> $DIR/issue-54516.rs:5:20 | LL | println!("{}", std::mem:size_of::<BTreeMap<u32, u32>>()); | ^^^^^^^^-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -8,23 +8,5 @@ LL | println!("{}", std::mem:size_of::<BTreeMap<u32, u32>>()); | = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>` -error[E0423]: expected value, found module `std::mem` - --> $DIR/issue-54516.rs:4:20 - | -LL | println!("{}", std::mem:size_of::<BTreeMap<u32, u32>>()); - | ^^^^^^^^- help: maybe you meant to write a path separator here: `::` - | | - | not a value - -error[E0412]: cannot find type `size_of` in this scope - --> $DIR/issue-54516.rs:4:29 - | -LL | println!("{}", std::mem:size_of::<BTreeMap<u32, u32>>()); - | -^^^^^^^ not found in this scope - | | - | help: maybe you meant to write a path separator here: `::` - -error: aborting due to 3 previous errors +error: aborting due to previous error -Some errors have detailed explanations: E0412, E0423. -For more information about an error, try `rustc --explain E0412`. diff --git a/src/test/ui/type/ascription/issue-60933.fixed b/src/test/ui/type/ascription/issue-60933.fixed new file mode 100644 index 00000000000..ac9f6a07031 --- /dev/null +++ b/src/test/ui/type/ascription/issue-60933.fixed @@ -0,0 +1,5 @@ +// run-rustfix +fn main() { + let _: usize = std::mem::size_of::<u32>(); + //~^ ERROR casts cannot be followed by a function call +} diff --git a/src/test/ui/type/ascription/issue-60933.rs b/src/test/ui/type/ascription/issue-60933.rs index bcf9f88cb41..cb093735efa 100644 --- a/src/test/ui/type/ascription/issue-60933.rs +++ b/src/test/ui/type/ascription/issue-60933.rs @@ -1,6 +1,5 @@ +// run-rustfix fn main() { - let u: usize = std::mem:size_of::<u32>(); + let _: usize = std::mem:size_of::<u32>(); //~^ ERROR casts cannot be followed by a function call - //~| ERROR expected value, found module `std::mem` [E0423] - //~| ERROR cannot find type `size_of` in this scope [E0412] } diff --git a/src/test/ui/type/ascription/issue-60933.stderr b/src/test/ui/type/ascription/issue-60933.stderr index 2006362e1bb..5c35de88e14 100644 --- a/src/test/ui/type/ascription/issue-60933.stderr +++ b/src/test/ui/type/ascription/issue-60933.stderr @@ -1,30 +1,12 @@ error: casts cannot be followed by a function call - --> $DIR/issue-60933.rs:2:20 + --> $DIR/issue-60933.rs:3:20 | -LL | let u: usize = std::mem:size_of::<u32>(); +LL | let _: usize = std::mem:size_of::<u32>(); | ^^^^^^^^-^^^^^^^^^^^^^^ | | | help: maybe write a path separator here: `::` | = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>` -error[E0423]: expected value, found module `std::mem` - --> $DIR/issue-60933.rs:2:20 - | -LL | let u: usize = std::mem:size_of::<u32>(); - | ^^^^^^^^- help: maybe you meant to write a path separator here: `::` - | | - | not a value - -error[E0412]: cannot find type `size_of` in this scope - --> $DIR/issue-60933.rs:2:29 - | -LL | let u: usize = std::mem:size_of::<u32>(); - | -^^^^^^^ not found in this scope - | | - | help: maybe you meant to write a path separator here: `::` - -error: aborting due to 3 previous errors +error: aborting due to previous error -Some errors have detailed explanations: E0412, E0423. -For more information about an error, try `rustc --explain E0412`. diff --git a/src/test/ui/type/type-ascription-with-fn-call.fixed b/src/test/ui/type/type-ascription-with-fn-call.fixed new file mode 100644 index 00000000000..6d96c4303c3 --- /dev/null +++ b/src/test/ui/type/type-ascription-with-fn-call.fixed @@ -0,0 +1,9 @@ +// run-rustfix +#![feature(type_ascription)] + +fn main() { + f() ; + f(); //~ ERROR expected type, found function +} + +fn f() {} diff --git a/src/test/ui/type/type-ascription-with-fn-call.rs b/src/test/ui/type/type-ascription-with-fn-call.rs index 2bd2efa4d38..ed4f7c9041c 100644 --- a/src/test/ui/type/type-ascription-with-fn-call.rs +++ b/src/test/ui/type/type-ascription-with-fn-call.rs @@ -1,3 +1,4 @@ +// run-rustfix #![feature(type_ascription)] fn main() { diff --git a/src/test/ui/type/type-ascription-with-fn-call.stderr b/src/test/ui/type/type-ascription-with-fn-call.stderr index eeaca5300f9..5f74724b59e 100644 --- a/src/test/ui/type/type-ascription-with-fn-call.stderr +++ b/src/test/ui/type/type-ascription-with-fn-call.stderr @@ -1,8 +1,8 @@ error[E0573]: expected type, found function `f` - --> $DIR/type-ascription-with-fn-call.rs:5:5 + --> $DIR/type-ascription-with-fn-call.rs:6:5 | LL | f() : - | - help: did you mean to use `;` here instead? + | - help: maybe you meant to write `;` here LL | f(); | ^^^ | | diff --git a/src/test/ui/unboxed-closures/unboxed-closures-move-mutable.rs b/src/test/ui/unboxed-closures/unboxed-closures-move-mutable.rs index e5b19db7822..470904fd391 100644 --- a/src/test/ui/unboxed-closures/unboxed-closures-move-mutable.rs +++ b/src/test/ui/unboxed-closures/unboxed-closures-move-mutable.rs @@ -2,6 +2,7 @@ // pretty-expanded FIXME #23616 #![deny(unused_mut)] +#![allow(unused_must_use)] // Test that mutating a mutable upvar in a capture-by-value unboxed // closure does not ice (issue #18238) and marks the upvar as used diff --git a/src/test/ui/unboxed-closures/unboxed-closures-move-mutable.stderr b/src/test/ui/unboxed-closures/unboxed-closures-move-mutable.stderr index 4dfd1bb3075..1254f8dbc5e 100644 --- a/src/test/ui/unboxed-closures/unboxed-closures-move-mutable.stderr +++ b/src/test/ui/unboxed-closures/unboxed-closures-move-mutable.stderr @@ -1,5 +1,5 @@ warning: unused variable: `x` - --> $DIR/unboxed-closures-move-mutable.rs:16:17 + --> $DIR/unboxed-closures-move-mutable.rs:17:17 | LL | move || x += 1; | ^ @@ -8,7 +8,7 @@ LL | move || x += 1; = help: did you mean to capture by reference instead? warning: unused variable: `x` - --> $DIR/unboxed-closures-move-mutable.rs:20:17 + --> $DIR/unboxed-closures-move-mutable.rs:21:17 | LL | move || x += 1; | ^ diff --git a/src/test/ui/unused/unused-closure.rs b/src/test/ui/unused/unused-closure.rs new file mode 100644 index 00000000000..637d8bb43a7 --- /dev/null +++ b/src/test/ui/unused/unused-closure.rs @@ -0,0 +1,40 @@ +// Test that closures and generators are "must use" types. +// edition:2018 + +#![feature(async_closure)] +#![feature(const_in_array_repeat_expressions)] +#![feature(generators)] +#![deny(unused_must_use)] + +fn unused() { + || { //~ ERROR unused closure that must be used + println!("Hello!"); + }; + + async {}; //~ ERROR unused implementer of `std::future::Future` that must be used + || async {}; //~ ERROR unused closure that must be used + async || {}; //~ ERROR unused closure that must be used + + + [Box::new([|| {}; 10]); 1]; //~ ERROR unused array of boxed arrays of closures that must be used + + [|| { //~ ERROR unused array of generators that must be used + yield 42u32; + }; 42]; + + vec![|| "a"].pop().unwrap(); //~ ERROR unused closure that must be used + + let b = false; + || true; //~ ERROR unused closure that must be used + println!("{}", b); +} + +fn ignored() { + let _ = || {}; + let _ = || yield 42; +} + +fn main() { + unused(); + ignored(); +} diff --git a/src/test/ui/unused/unused-closure.stderr b/src/test/ui/unused/unused-closure.stderr new file mode 100644 index 00000000000..9dc73fb7abe --- /dev/null +++ b/src/test/ui/unused/unused-closure.stderr @@ -0,0 +1,75 @@ +error: unused closure that must be used + --> $DIR/unused-closure.rs:10:5 + | +LL | / || { +LL | | println!("Hello!"); +LL | | }; + | |______^ + | +note: the lint level is defined here + --> $DIR/unused-closure.rs:7:9 + | +LL | #![deny(unused_must_use)] + | ^^^^^^^^^^^^^^^ + = note: closures are lazy and do nothing unless called + +error: unused implementer of `std::future::Future` that must be used + --> $DIR/unused-closure.rs:14:5 + | +LL | async {}; + | ^^^^^^^^^ + | + = note: futures do nothing unless you `.await` or poll them + +error: unused closure that must be used + --> $DIR/unused-closure.rs:15:5 + | +LL | || async {}; + | ^^^^^^^^^^^^ + | + = note: closures are lazy and do nothing unless called + +error: unused closure that must be used + --> $DIR/unused-closure.rs:16:5 + | +LL | async || {}; + | ^^^^^^^^^^^^ + | + = note: closures are lazy and do nothing unless called + +error: unused array of boxed arrays of closures that must be used + --> $DIR/unused-closure.rs:19:5 + | +LL | [Box::new([|| {}; 10]); 1]; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: closures are lazy and do nothing unless called + +error: unused array of generators that must be used + --> $DIR/unused-closure.rs:21:5 + | +LL | / [|| { +LL | | yield 42u32; +LL | | }; 42]; + | |___________^ + | + = note: generators are lazy and do nothing unless resumed + +error: unused closure that must be used + --> $DIR/unused-closure.rs:25:5 + | +LL | vec![|| "a"].pop().unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: closures are lazy and do nothing unless called + +error: unused closure that must be used + --> $DIR/unused-closure.rs:28:9 + | +LL | || true; + | ^^^^^^^^ + | + = note: closures are lazy and do nothing unless called + +error: aborting due to 8 previous errors + diff --git a/src/test/ui/unused/unused-mut-warning-captured-var.fixed b/src/test/ui/unused/unused-mut-warning-captured-var.fixed index b67b2a7259b..c21f18015c1 100644 --- a/src/test/ui/unused/unused-mut-warning-captured-var.fixed +++ b/src/test/ui/unused/unused-mut-warning-captured-var.fixed @@ -5,5 +5,5 @@ fn main() { let x = 1; //~^ ERROR: variable does not need to be mutable - move|| { println!("{}", x); }; + (move|| { println!("{}", x); })(); } diff --git a/src/test/ui/unused/unused-mut-warning-captured-var.rs b/src/test/ui/unused/unused-mut-warning-captured-var.rs index 8726c4f173f..3119d83a0eb 100644 --- a/src/test/ui/unused/unused-mut-warning-captured-var.rs +++ b/src/test/ui/unused/unused-mut-warning-captured-var.rs @@ -5,5 +5,5 @@ fn main() { let mut x = 1; //~^ ERROR: variable does not need to be mutable - move|| { println!("{}", x); }; + (move|| { println!("{}", x); })(); } diff --git a/src/test/ui/weird-exprs.rs b/src/test/ui/weird-exprs.rs index d812bbd011e..916cabbfb8c 100644 --- a/src/test/ui/weird-exprs.rs +++ b/src/test/ui/weird-exprs.rs @@ -5,7 +5,7 @@ #![allow(non_camel_case_types)] #![allow(dead_code)] #![allow(unreachable_code)] -#![allow(unused_braces, unused_parens)] +#![allow(unused_braces, unused_must_use, unused_parens)] #![recursion_limit = "256"] diff --git a/src/tools/cargo b/src/tools/cargo -Subproject aa6872140ab0fa10f641ab0b981d5330d419e92 +Subproject 2d5c2381e4e50484bf281fc1bfe19743aa9eb37 diff --git a/src/tools/clippy/clippy_lints/src/utils/mod.rs b/src/tools/clippy/clippy_lints/src/utils/mod.rs index 655b1133cf7..3f8e15d9029 100644 --- a/src/tools/clippy/clippy_lints/src/utils/mod.rs +++ b/src/tools/clippy/clippy_lints/src/utils/mod.rs @@ -883,7 +883,7 @@ pub fn is_ctor_or_promotable_const_function(cx: &LateContext<'_>, expr: &Expr<'_ } /// Returns `true` if a pattern is refutable. -// TODO: should be implemented using rustc/mir_build/hair machinery +// TODO: should be implemented using rustc/mir_build/thir machinery pub fn is_refutable(cx: &LateContext<'_>, pat: &Pat<'_>) -> bool { fn is_enum_variant(cx: &LateContext<'_>, qpath: &QPath<'_>, id: HirId) -> bool { matches!( diff --git a/src/tools/clippy/tests/ui/formatting.rs b/src/tools/clippy/tests/ui/formatting.rs index 078811b8d88..f54b3f2bfe2 100644 --- a/src/tools/clippy/tests/ui/formatting.rs +++ b/src/tools/clippy/tests/ui/formatting.rs @@ -149,7 +149,7 @@ fn main() { 1 + 2, 3 - 4, 5 ]; - // lint if it doesnt + // lint if it doesn't let _ = &[ -1 -4, diff --git a/src/tools/compiletest/Cargo.toml b/src/tools/compiletest/Cargo.toml index a26c3a4acab..bd4c5949800 100644 --- a/src/tools/compiletest/Cargo.toml +++ b/src/tools/compiletest/Cargo.toml @@ -8,13 +8,14 @@ edition = "2018" diff = "0.1.10" env_logger = { version = "0.7", default-features = false } getopts = "0.2" -log = "0.4" +log = { package = "tracing", version = "0.1" } regex = "1.0" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" rustfix = "0.5.0" lazy_static = "1.0" walkdir = "2" +glob = "0.3.0" [target.'cfg(unix)'.dependencies] libc = "0.2" diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index 2ab764eb920..047fbe9da14 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -1,3 +1,4 @@ +use std::collections::HashSet; use std::env; use std::fs::File; use std::io::prelude::*; @@ -186,6 +187,17 @@ impl EarlyProps { if config.system_llvm && line.starts_with("no-system-llvm") { return true; } + if let Some(needed_components) = + config.parse_name_value_directive(line, "needs-llvm-components") + { + let components: HashSet<_> = config.llvm_components.split_whitespace().collect(); + if !needed_components + .split_whitespace() + .all(|needed_component| components.contains(needed_component)) + { + return true; + } + } if let Some(actual_version) = config.llvm_version { if let Some(rest) = line.strip_prefix("min-llvm-version:").map(str::trim) { let min_version = extract_llvm_version(rest).unwrap(); diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 7fbe4f2b928..940e16720f6 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -28,6 +28,7 @@ use std::path::{Path, PathBuf}; use std::process::{Child, Command, ExitStatus, Output, Stdio}; use std::str; +use glob::glob; use lazy_static::lazy_static; use log::*; @@ -177,27 +178,30 @@ pub fn make_diff(expected: &str, actual: &str, context_size: usize) -> Vec<Misma results } -fn print_diff(expected: &str, actual: &str, context_size: usize) { +fn write_diff(expected: &str, actual: &str, context_size: usize) -> String { + use std::fmt::Write; + let mut output = String::new(); let diff_results = make_diff(expected, actual, context_size); for result in diff_results { let mut line_number = result.line_number; for line in result.lines { match line { DiffLine::Expected(e) => { - println!("-\t{}", e); + writeln!(output, "-\t{}", e).unwrap(); line_number += 1; } DiffLine::Context(c) => { - println!("{}\t{}", line_number, c); + writeln!(output, "{}\t{}", line_number, c).unwrap(); line_number += 1; } DiffLine::Resulting(r) => { - println!("+\t{}", r); + writeln!(output, "+\t{}", r).unwrap(); } } } - println!(); + writeln!(output, "").unwrap(); } + output } pub fn run(config: Config, testpaths: &TestPaths, revision: Option<&str>) { @@ -654,8 +658,12 @@ impl<'test> TestCx<'test> { ------------------------------------------\n\ {}\n\ ------------------------------------------\n\ - \n", - expected, actual + diff:\n\ + ------------------------------------------\n\ + {}\n", + expected, + actual, + write_diff(expected, actual, 3), )); } } @@ -3124,22 +3132,35 @@ impl<'test> TestCx<'test> { fn check_mir_dump(&self) { let test_file_contents = fs::read_to_string(&self.testpaths.file).unwrap(); - let mut test_dir = self.testpaths.file.with_extension(""); + let test_dir = self.testpaths.file.parent().unwrap(); + let test_crate = + self.testpaths.file.file_stem().unwrap().to_str().unwrap().replace("-", "_"); + let mut bit_width = String::new(); if test_file_contents.lines().any(|l| l == "// EMIT_MIR_FOR_EACH_BIT_WIDTH") { - test_dir.push(get_pointer_width(&self.config.target)) + bit_width = format!(".{}", get_pointer_width(&self.config.target)); } if self.config.bless { - let _ = std::fs::remove_dir_all(&test_dir); + for e in + glob(&format!("{}/{}.*.mir{}", test_dir.display(), test_crate, bit_width)).unwrap() + { + std::fs::remove_file(e.unwrap()).unwrap(); + } + for e in + glob(&format!("{}/{}.*.diff{}", test_dir.display(), test_crate, bit_width)).unwrap() + { + std::fs::remove_file(e.unwrap()).unwrap(); + } } + for l in test_file_contents.lines() { if l.starts_with("// EMIT_MIR ") { let test_name = l.trim_start_matches("// EMIT_MIR ").trim(); let mut test_names = test_name.split(' '); // sometimes we specify two files so that we get a diff between the two files let test_name = test_names.next().unwrap(); - let expected_file; + let mut expected_file; let from_file; let to_file; @@ -3147,7 +3168,7 @@ impl<'test> TestCx<'test> { let trimmed = test_name.trim_end_matches(".diff"); let test_against = format!("{}.after.mir", trimmed); from_file = format!("{}.before.mir", trimmed); - expected_file = test_name.to_string(); + expected_file = format!("{}{}", test_name, bit_width); assert!( test_names.next().is_none(), "two mir pass names specified for MIR diff" @@ -3159,12 +3180,13 @@ impl<'test> TestCx<'test> { test_names.next().is_none(), "three mir pass names specified for MIR diff" ); - expected_file = format!("{}.{}-{}.diff", test_name, first_pass, second_pass); + expected_file = + format!("{}{}.{}-{}.diff", test_name, bit_width, first_pass, second_pass); let second_file = format!("{}.{}.mir", test_name, second_pass); from_file = format!("{}.{}.mir", test_name, first_pass); to_file = Some(second_file); } else { - expected_file = test_name.to_string(); + expected_file = format!("{}{}", test_name, bit_width); from_file = test_name.to_string(); assert!( test_names.next().is_none(), @@ -3172,30 +3194,13 @@ impl<'test> TestCx<'test> { ); to_file = None; }; + if !expected_file.starts_with(&test_crate) { + expected_file = format!("{}.{}", test_crate, expected_file); + } let expected_file = test_dir.join(expected_file); let dumped_string = if let Some(after) = to_file { - let before = self.get_mir_dump_dir().join(from_file); - let after = self.get_mir_dump_dir().join(after); - debug!( - "comparing the contents of: {} with {}", - before.display(), - after.display() - ); - let before = fs::read_to_string(before).unwrap(); - let after = fs::read_to_string(after).unwrap(); - let before = self.normalize_output(&before, &[]); - let after = self.normalize_output(&after, &[]); - let mut dumped_string = String::new(); - for result in diff::lines(&before, &after) { - use std::fmt::Write; - match result { - diff::Result::Left(s) => writeln!(dumped_string, "- {}", s).unwrap(), - diff::Result::Right(s) => writeln!(dumped_string, "+ {}", s).unwrap(), - diff::Result::Both(s, _) => writeln!(dumped_string, " {}", s).unwrap(), - } - } - dumped_string + self.diff_mir_files(from_file.into(), after.into()) } else { let mut output_file = PathBuf::new(); output_file.push(self.get_mir_dump_dir()); @@ -3216,8 +3221,8 @@ impl<'test> TestCx<'test> { let dumped_string = fs::read_to_string(&output_file).unwrap(); self.normalize_output(&dumped_string, &[]) }; + if self.config.bless { - let _ = std::fs::create_dir_all(&test_dir); let _ = std::fs::remove_file(&expected_file); std::fs::write(expected_file, dumped_string.as_bytes()).unwrap(); } else { @@ -3229,7 +3234,7 @@ impl<'test> TestCx<'test> { } let expected_string = fs::read_to_string(&expected_file).unwrap(); if dumped_string != expected_string { - print_diff(&expected_string, &dumped_string, 3); + print!("{}", write_diff(&expected_string, &dumped_string, 3)); panic!( "Actual MIR output differs from expected MIR output {}", expected_file.display() @@ -3240,6 +3245,26 @@ impl<'test> TestCx<'test> { } } + fn diff_mir_files(&self, before: PathBuf, after: PathBuf) -> String { + let before = self.get_mir_dump_dir().join(before); + let after = self.get_mir_dump_dir().join(after); + debug!("comparing the contents of: {} with {}", before.display(), after.display()); + let before = fs::read_to_string(before).unwrap(); + let after = fs::read_to_string(after).unwrap(); + let before = self.normalize_output(&before, &[]); + let after = self.normalize_output(&after, &[]); + let mut dumped_string = String::new(); + for result in diff::lines(&before, &after) { + use std::fmt::Write; + match result { + diff::Result::Left(s) => writeln!(dumped_string, "- {}", s).unwrap(), + diff::Result::Right(s) => writeln!(dumped_string, "+ {}", s).unwrap(), + diff::Result::Both(s, _) => writeln!(dumped_string, " {}", s).unwrap(), + } + } + dumped_string + } + fn check_mir_test_timestamp(&self, test_name: &str, output_file: &Path) { let t = |file| fs::metadata(file).unwrap().modified().unwrap(); let source_file = &self.testpaths.file; @@ -3434,7 +3459,7 @@ impl<'test> TestCx<'test> { println!("normalized {}:\n{}\n", kind, actual); } else { println!("diff of {}:\n", kind); - print_diff(expected, actual, 3); + print!("{}", write_diff(expected, actual, 3)); } } diff --git a/src/tools/error_index_generator/main.rs b/src/tools/error_index_generator/main.rs index c4292d041d0..bd9f8fb0450 100644 --- a/src/tools/error_index_generator/main.rs +++ b/src/tools/error_index_generator/main.rs @@ -1,7 +1,7 @@ #![feature(rustc_private)] -extern crate env_logger; extern crate rustc_ast; +extern crate rustc_driver; extern crate rustc_span; use std::cell::RefCell; @@ -282,7 +282,7 @@ fn parse_args() -> (OutputFormat, PathBuf) { } fn main() { - env_logger::init(); + rustc_driver::init_env_logger("RUST_LOG"); let (format, dst) = parse_args(); let result = rustc_ast::with_default_session_globals(move || main_with_result(format, &dst)); if let Err(e) = result { diff --git a/src/tools/miri b/src/tools/miri -Subproject 515287f114b546a72d4a1fe8ffe1dbc20dedf13 +Subproject 55bdb3174653039f47362742f8dc941bfc086e8 diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index 56d2717c304..1f988f7d81b 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -17,6 +17,7 @@ const LICENSES: &[&str] = &[ "MIT", "Unlicense/MIT", "Unlicense OR MIT", + "0BSD OR MIT OR Apache-2.0", // adler license ]; /// These are exceptions to Rust's permissive licensing policy, and @@ -36,7 +37,6 @@ const EXCEPTIONS: &[(&str, &str)] = &[ ("ryu", "Apache-2.0 OR BSL-1.0"), // rls/cargo/... (because of serde) ("bytesize", "Apache-2.0"), // cargo ("im-rc", "MPL-2.0+"), // cargo - ("adler32", "BSD-3-Clause AND Zlib"), // cargo dep that isn't used ("constant_time_eq", "CC0-1.0"), // rustfmt ("sized-chunks", "MPL-2.0+"), // cargo via im-rc ("bitmaps", "MPL-2.0+"), // cargo via im-rc @@ -57,7 +57,8 @@ const RESTRICTED_DEPENDENCY_CRATES: &[&str] = &["rustc_middle", "rustc_codegen_l /// This list is here to provide a speed-bump to adding a new dependency to /// rustc. Please check with the compiler team before adding an entry. const PERMITTED_DEPENDENCIES: &[&str] = &[ - "adler32", + "addr2line", + "adler", "aho-corasick", "annotate-snippets", "ansi_term", @@ -65,7 +66,6 @@ const PERMITTED_DEPENDENCIES: &[&str] = &[ "atty", "autocfg", "backtrace", - "backtrace-sys", "bitflags", "block-buffer", "block-padding", @@ -98,6 +98,7 @@ const PERMITTED_DEPENDENCIES: &[&str] = &[ "generic-array", "getopts", "getrandom", + "gimli", "hashbrown", "hermit-abi", "humantime", @@ -119,6 +120,7 @@ const PERMITTED_DEPENDENCIES: &[&str] = &[ "miniz_oxide", "nodrop", "num_cpus", + "object", "once_cell", "opaque-debug", "parking_lot", @@ -136,7 +138,6 @@ const PERMITTED_DEPENDENCIES: &[&str] = &[ "rand_chacha", "rand_core", "rand_hc", - "rand_isaac", "rand_pcg", "rand_xorshift", "redox_syscall", @@ -164,6 +165,9 @@ const PERMITTED_DEPENDENCIES: &[&str] = &[ "termcolor", "termize", "thread_local", + "tracing", + "tracing-attributes", + "tracing-core", "typenum", "unicode-normalization", "unicode-script", @@ -178,7 +182,6 @@ const PERMITTED_DEPENDENCIES: &[&str] = &[ "winapi-i686-pc-windows-gnu", "winapi-util", "winapi-x86_64-pc-windows-gnu", - "wincolor", ]; /// Dependency checks. diff --git a/src/tools/tidy/src/lib.rs b/src/tools/tidy/src/lib.rs index 08b2fccd73f..19218cbd66a 100644 --- a/src/tools/tidy/src/lib.rs +++ b/src/tools/tidy/src/lib.rs @@ -51,6 +51,7 @@ pub mod unstable_book; fn filter_dirs(path: &Path) -> bool { let skip = [ "src/llvm-project", + "library/backtrace", "library/stdarch", "src/tools/cargo", "src/tools/clippy", diff --git a/src/tools/unstable-book-gen/src/main.rs b/src/tools/unstable-book-gen/src/main.rs index aa24881ac6b..11617911446 100644 --- a/src/tools/unstable-book-gen/src/main.rs +++ b/src/tools/unstable-book-gen/src/main.rs @@ -94,13 +94,15 @@ fn copy_recursive(from: &Path, to: &Path) { } fn main() { - let src_path_str = env::args_os().skip(1).next().expect("source path required"); - let dest_path_str = env::args_os().skip(2).next().expect("destination path required"); + let library_path_str = env::args_os().skip(1).next().expect("library path required"); + let src_path_str = env::args_os().skip(2).next().expect("source path required"); + let dest_path_str = env::args_os().skip(3).next().expect("destination path required"); + let library_path = Path::new(&library_path_str); let src_path = Path::new(&src_path_str); let dest_path = Path::new(&dest_path_str); let lang_features = collect_lang_features(src_path, &mut false); - let lib_features = collect_lib_features(src_path) + let lib_features = collect_lib_features(library_path) .into_iter() .filter(|&(ref name, _)| !lang_features.contains_key(name)) .collect(); |
