diff options
Diffstat (limited to 'src')
44 files changed, 487 insertions, 271 deletions
diff --git a/src/bootstrap/src/core/build_steps/check.rs b/src/bootstrap/src/core/build_steps/check.rs index f0acb7f7141..cfe090b22dc 100644 --- a/src/bootstrap/src/core/build_steps/check.rs +++ b/src/bootstrap/src/core/build_steps/check.rs @@ -370,132 +370,18 @@ impl Step for CodegenBackend { } } -/// Checks Rust analyzer that links to .rmetas from a checked rustc. -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct RustAnalyzer { - pub build_compiler: Compiler, - pub target: TargetSelection, -} - -impl Step for RustAnalyzer { - type Output = (); - const ONLY_HOSTS: bool = true; - const DEFAULT: bool = true; - - fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { - let builder = run.builder; - run.path("src/tools/rust-analyzer").default_condition( - builder - .config - .tools - .as_ref() - .is_none_or(|tools| tools.iter().any(|tool| tool == "rust-analyzer")), - ) - } - - fn make_run(run: RunConfig<'_>) { - let build_compiler = prepare_compiler_for_check(run.builder, run.target, Mode::ToolRustc); - run.builder.ensure(RustAnalyzer { build_compiler, target: run.target }); - } - - fn run(self, builder: &Builder<'_>) { - let build_compiler = self.build_compiler; - let target = self.target; - - let mut cargo = prepare_tool_cargo( - builder, - build_compiler, - Mode::ToolRustc, - target, - builder.kind, - "src/tools/rust-analyzer", - SourceType::InTree, - &["in-rust-tree".to_owned()], - ); - - cargo.allow_features(crate::core::build_steps::tool::RustAnalyzer::ALLOW_FEATURES); - - cargo.arg("--bins"); - cargo.arg("--tests"); - cargo.arg("--benches"); - - // Cargo's output path in a given stage, compiled by a particular - // compiler for the specified target. - let stamp = BuildStamp::new(&builder.cargo_out(build_compiler, Mode::ToolRustc, target)) - .with_prefix("rust-analyzer-check"); - - let _guard = builder.msg_check("rust-analyzer artifacts", target, None); - run_cargo(builder, cargo, builder.config.free_args.clone(), &stamp, vec![], true, false); - } - - fn metadata(&self) -> Option<StepMetadata> { - Some(StepMetadata::check("rust-analyzer", self.target).built_by(self.build_compiler)) - } -} - -/// Compiletest is implicitly "checked" when it gets built in order to run tests, -/// so this is mainly for people working on compiletest to run locally. -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct Compiletest { - pub target: TargetSelection, -} - -impl Step for Compiletest { - type Output = (); - const ONLY_HOSTS: bool = true; - const DEFAULT: bool = false; - - fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { - run.path("src/tools/compiletest") - } - - fn make_run(run: RunConfig<'_>) { - run.builder.ensure(Compiletest { target: run.target }); - } - - fn run(self, builder: &Builder<'_>) { - let mode = if builder.config.compiletest_use_stage0_libtest { - Mode::ToolBootstrap - } else { - Mode::ToolStd - }; - let build_compiler = prepare_compiler_for_check(builder, self.target, mode); - - let mut cargo = prepare_tool_cargo( - builder, - build_compiler, - mode, - self.target, - builder.kind, - "src/tools/compiletest", - SourceType::InTree, - &[], - ); - - cargo.allow_features(COMPILETEST_ALLOW_FEATURES); - - cargo.arg("--all-targets"); - - let stamp = BuildStamp::new(&builder.cargo_out(build_compiler, mode, self.target)) - .with_prefix("compiletest-check"); - - let _guard = builder.msg_check("compiletest artifacts", self.target, None); - run_cargo(builder, cargo, builder.config.free_args.clone(), &stamp, vec![], true, false); - } - - fn metadata(&self) -> Option<StepMetadata> { - Some(StepMetadata::check("compiletest", self.target)) - } -} - macro_rules! tool_check_step { ( $name:ident { // The part of this path after the final '/' is also used as a display name. path: $path:literal $(, alt_path: $alt_path:literal )* - , mode: $mode:path + // Closure that returns `Mode` based on the passed `&Builder<'_>` + , mode: $mode:expr + // Subset of nightly features that are allowed to be used when checking $(, allow_features: $allow_features:expr )? + // Features that should be enabled when checking + $(, enable_features: [$($enable_features:expr),*] )? $(, default: $default:literal )? $( , )? } @@ -518,10 +404,13 @@ macro_rules! tool_check_step { fn make_run(run: RunConfig<'_>) { let target = run.target; - let build_compiler = prepare_compiler_for_check(run.builder, target, $mode); + let builder = run.builder; + let mode = $mode(builder); + + let build_compiler = prepare_compiler_for_check(run.builder, target, mode); // It doesn't make sense to cross-check bootstrap tools - if $mode == Mode::ToolBootstrap && target != run.builder.host_target { + if mode == Mode::ToolBootstrap && target != run.builder.host_target { println!("WARNING: not checking bootstrap tool {} for target {target} as it is a bootstrap (host-only) tool", stringify!($path)); return; }; @@ -536,7 +425,9 @@ macro_rules! tool_check_step { $( _value = $allow_features; )? _value }; - run_tool_check_step(builder, build_compiler, target, $path, $mode, allow_features); + let extra_features: &[&str] = &[$($($enable_features),*)?]; + let mode = $mode(builder); + run_tool_check_step(builder, build_compiler, target, $path, mode, allow_features, extra_features); } fn metadata(&self) -> Option<StepMetadata> { @@ -554,9 +445,11 @@ fn run_tool_check_step( path: &str, mode: Mode, allow_features: &str, + extra_features: &[&str], ) { let display_name = path.rsplit('/').next().unwrap(); + let extra_features = extra_features.iter().map(|f| f.to_string()).collect::<Vec<String>>(); let mut cargo = prepare_tool_cargo( builder, build_compiler, @@ -569,12 +462,19 @@ fn run_tool_check_step( // steps should probably be marked non-default so that the default // checks aren't affected by toolstate being broken. SourceType::InTree, - &[], + &extra_features, ); cargo.allow_features(allow_features); - // FIXME: check bootstrap doesn't currently work with --all-targets - cargo.arg("--all-targets"); + // FIXME: check bootstrap doesn't currently work when multiple targets are checked + // FIXME: rust-analyzer does not work with --all-targets + if display_name == "rust-analyzer" { + cargo.arg("--bins"); + cargo.arg("--tests"); + cargo.arg("--benches"); + } else { + cargo.arg("--all-targets"); + } let stamp = BuildStamp::new(&builder.cargo_out(build_compiler, mode, target)) .with_prefix(&format!("{display_name}-check")); @@ -593,43 +493,66 @@ fn run_tool_check_step( tool_check_step!(Rustdoc { path: "src/tools/rustdoc", alt_path: "src/librustdoc", - mode: Mode::ToolRustc + mode: |_builder| Mode::ToolRustc }); // Clippy, miri and Rustfmt are hybrids. They are external tools, but use a git subtree instead // of a submodule. Since the SourceType only drives the deny-warnings // behavior, treat it as in-tree so that any new warnings in clippy will be // rejected. -tool_check_step!(Clippy { path: "src/tools/clippy", mode: Mode::ToolRustc }); -tool_check_step!(Miri { path: "src/tools/miri", mode: Mode::ToolRustc }); -tool_check_step!(CargoMiri { path: "src/tools/miri/cargo-miri", mode: Mode::ToolRustc }); -tool_check_step!(Rustfmt { path: "src/tools/rustfmt", mode: Mode::ToolRustc }); +tool_check_step!(Clippy { path: "src/tools/clippy", mode: |_builder| Mode::ToolRustc }); +tool_check_step!(Miri { path: "src/tools/miri", mode: |_builder| Mode::ToolRustc }); +tool_check_step!(CargoMiri { path: "src/tools/miri/cargo-miri", mode: |_builder| Mode::ToolRustc }); +tool_check_step!(Rustfmt { path: "src/tools/rustfmt", mode: |_builder| Mode::ToolRustc }); +tool_check_step!(RustAnalyzer { + path: "src/tools/rust-analyzer", + mode: |_builder| Mode::ToolRustc, + allow_features: tool::RustAnalyzer::ALLOW_FEATURES, + enable_features: ["in-rust-tree"], +}); tool_check_step!(MiroptTestTools { path: "src/tools/miropt-test-tools", - mode: Mode::ToolBootstrap + mode: |_builder| Mode::ToolBootstrap }); // We want to test the local std tool_check_step!(TestFloatParse { path: "src/tools/test-float-parse", - mode: Mode::ToolStd, + mode: |_builder| Mode::ToolStd, allow_features: tool::TestFloatParse::ALLOW_FEATURES }); tool_check_step!(FeaturesStatusDump { path: "src/tools/features-status-dump", - mode: Mode::ToolBootstrap + mode: |_builder| Mode::ToolBootstrap }); -tool_check_step!(Bootstrap { path: "src/bootstrap", mode: Mode::ToolBootstrap, default: false }); +tool_check_step!(Bootstrap { + path: "src/bootstrap", + mode: |_builder| Mode::ToolBootstrap, + default: false +}); // `run-make-support` will be built as part of suitable run-make compiletest test steps, but support // check to make it easier to work on. tool_check_step!(RunMakeSupport { path: "src/tools/run-make-support", - mode: Mode::ToolBootstrap, + mode: |_builder| Mode::ToolBootstrap, default: false }); tool_check_step!(CoverageDump { path: "src/tools/coverage-dump", - mode: Mode::ToolBootstrap, + mode: |_builder| Mode::ToolBootstrap, default: false }); + +// Compiletest is implicitly "checked" when it gets built in order to run tests, +// so this is mainly for people working on compiletest to run locally. +tool_check_step!(Compiletest { + path: "src/tools/compiletest", + mode: |builder: &Builder<'_>| if builder.config.compiletest_use_stage0_libtest { + Mode::ToolBootstrap + } else { + Mode::ToolStd + }, + allow_features: COMPILETEST_ALLOW_FEATURES, + default: false, +}); diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 7652ea1a488..8344b0e03b4 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -739,7 +739,6 @@ impl Step for CompiletestTest { #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct Clippy { - stage: u32, host: TargetSelection, } @@ -753,33 +752,23 @@ impl Step for Clippy { } fn make_run(run: RunConfig<'_>) { - // If stage is explicitly set or not lower than 2, keep it. Otherwise, make sure it's at least 2 - // as tests for this step don't work with a lower stage. - let stage = if run.builder.config.is_explicit_stage() || run.builder.top_stage >= 2 { - run.builder.top_stage - } else { - 2 - }; - - run.builder.ensure(Clippy { stage, host: run.target }); + run.builder.ensure(Clippy { host: run.target }); } /// Runs `cargo test` for clippy. fn run(self, builder: &Builder<'_>) { - let stage = self.stage; + let stage = builder.top_stage; let host = self.host; - let compiler = builder.compiler(stage, host); - - if stage < 2 { - eprintln!("WARNING: clippy tests on stage {stage} may not behave well."); - eprintln!("HELP: consider using stage 2"); - } + // We need to carefully distinguish the compiler that builds clippy, and the compiler + // that is linked into the clippy being tested. `target_compiler` is the latter, + // and it must also be used by clippy's test runner to build tests and their dependencies. + let target_compiler = builder.compiler(stage, host); - let tool_result = builder.ensure(tool::Clippy { compiler, target: self.host }); - let compiler = tool_result.build_compiler; + let tool_result = builder.ensure(tool::Clippy { compiler: target_compiler, target: host }); + let tool_compiler = tool_result.build_compiler; let mut cargo = tool::prepare_tool_cargo( builder, - compiler, + tool_compiler, Mode::ToolRustc, host, Kind::Test, @@ -788,11 +777,17 @@ impl Step for Clippy { &[], ); - cargo.env("RUSTC_TEST_SUITE", builder.rustc(compiler)); - cargo.env("RUSTC_LIB_PATH", builder.rustc_libdir(compiler)); - let host_libs = builder.stage_out(compiler, Mode::ToolRustc).join(builder.cargo_dir()); + cargo.env("RUSTC_TEST_SUITE", builder.rustc(tool_compiler)); + cargo.env("RUSTC_LIB_PATH", builder.rustc_libdir(tool_compiler)); + let host_libs = builder.stage_out(tool_compiler, Mode::ToolRustc).join(builder.cargo_dir()); cargo.env("HOST_LIBS", host_libs); + // Build the standard library that the tests can use. + builder.std(target_compiler, host); + cargo.env("TEST_SYSROOT", builder.sysroot(target_compiler)); + cargo.env("TEST_RUSTC", builder.rustc(target_compiler)); + cargo.env("TEST_RUSTC_LIB", builder.rustc_libdir(target_compiler)); + // Collect paths of tests to run 'partially_test: { let paths = &builder.config.paths[..]; @@ -813,7 +808,8 @@ impl Step for Clippy { cargo.add_rustc_lib_path(builder); let cargo = prepare_cargo_test(cargo, &[], &[], host, builder); - let _guard = builder.msg_sysroot_tool(Kind::Test, compiler.stage, "clippy", host, host); + let _guard = + builder.msg_sysroot_tool(Kind::Test, tool_compiler.stage, "clippy", host, host); // Clippy reports errors if it blessed the outputs if cargo.allow_failure().run(builder) { diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs index e60a115b19d..c025a8b15d0 100644 --- a/src/bootstrap/src/core/builder/tests.rs +++ b/src/bootstrap/src/core/builder/tests.rs @@ -1382,7 +1382,7 @@ mod snapshot { [check] rustc 1 <host> -> Miri 2 <target1> [check] rustc 1 <host> -> CargoMiri 2 <target1> [check] rustc 1 <host> -> Rustfmt 2 <target1> - [check] rustc 1 <host> -> rust-analyzer 2 <target1> + [check] rustc 1 <host> -> RustAnalyzer 2 <target1> [check] rustc 1 <host> -> TestFloatParse 2 <target1> [check] rustc 1 <host> -> std 1 <target1> "); @@ -1530,7 +1530,7 @@ mod snapshot { insta::assert_snapshot!( ctx.config("check") .path("compiletest") - .render_steps(), @"[check] compiletest <host>"); + .render_steps(), @"[check] rustc 0 <host> -> Compiletest 1 <host>"); } #[test] @@ -1544,7 +1544,7 @@ mod snapshot { [build] llvm <host> [build] rustc 0 <host> -> rustc 1 <host> [build] rustc 1 <host> -> std 1 <host> - [check] compiletest <host> + [check] rustc 1 <host> -> Compiletest 2 <host> "); } @@ -1569,7 +1569,7 @@ mod snapshot { .path("rust-analyzer") .render_steps(), @r" [check] rustc 0 <host> -> rustc 1 <host> - [check] rustc 0 <host> -> rust-analyzer 1 <host> + [check] rustc 0 <host> -> RustAnalyzer 1 <host> "); } diff --git a/src/doc/rustc-dev-guide/rust-version b/src/doc/rustc-dev-guide/rust-version index 3f10132b684..f6b7efe51a1 100644 --- a/src/doc/rustc-dev-guide/rust-version +++ b/src/doc/rustc-dev-guide/rust-version @@ -1 +1 @@ -fd2eb391d032181459773f3498c17b198513e0d0 +460259d14de0274b97b8801e08cb2fe5f16fdac5 diff --git a/src/doc/rustc-dev-guide/src/building/suggested.md b/src/doc/rustc-dev-guide/src/building/suggested.md index 7f626314f71..c046161e77f 100644 --- a/src/doc/rustc-dev-guide/src/building/suggested.md +++ b/src/doc/rustc-dev-guide/src/building/suggested.md @@ -162,7 +162,7 @@ create a `.vim/coc-settings.json`. The settings can be edited with [`src/etc/rust_analyzer_settings.json`]. Another way is without a plugin, and creating your own logic in your -configuration. The following code will work for any checkout of rust-lang/rust (newer than Febuary 2025): +configuration. The following code will work for any checkout of rust-lang/rust (newer than February 2025): ```lua local function expand_config_variables(option) diff --git a/src/doc/rustc-dev-guide/src/hir/ambig-unambig-ty-and-consts.md b/src/doc/rustc-dev-guide/src/hir/ambig-unambig-ty-and-consts.md index 709027883ae..d4f504ad2a9 100644 --- a/src/doc/rustc-dev-guide/src/hir/ambig-unambig-ty-and-consts.md +++ b/src/doc/rustc-dev-guide/src/hir/ambig-unambig-ty-and-consts.md @@ -38,7 +38,7 @@ Note that places 3 and 4 would never actually be possible to encounter as we alw This has a few failure modes: - People may write visitors which check for `GenericArg::Infer` but forget to check for `hir::TyKind/ConstArgKind::Infer`, only handling infers in ambig positions by accident. - People may write visitors which check for `hir::TyKind/ConstArgKind::Infer` but forget to check for `GenericArg::Infer`, only handling infers in unambig positions by accident. -- People may write visitors which check for `GenerArg::Type/Const(TyKind/ConstArgKind::Infer)` and `GenerigArg::Infer`, not realising that we never represent inferred types/consts in ambig positions as a `GenericArg::Type/Const`. +- People may write visitors which check for `GenericArg::Type/Const(TyKind/ConstArgKind::Infer)` and `GenericArg::Infer`, not realising that we never represent inferred types/consts in ambig positions as a `GenericArg::Type/Const`. - People may write visitors which check for *only* `TyKind::Infer` and not `ConstArgKind::Infer` forgetting that there are also inferred const arguments (and vice versa). To make writing HIR visitors less error prone when caring about inferred types/consts we have a relatively complex system: @@ -60,4 +60,4 @@ This has a number of benefits: [ambig_arg]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir/enum.AmbigArg.html [visit_ty]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/intravisit/trait.Visitor.html#method.visit_ty [visit_const_arg]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/intravisit/trait.Visitor.html#method.visit_const_arg -[visit_infer]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/intravisit/trait.Visitor.html#method.visit_infer \ No newline at end of file +[visit_infer]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/intravisit/trait.Visitor.html#method.visit_infer diff --git a/src/doc/rustc-dev-guide/src/rustdoc-internals/rustdoc-test-suite.md b/src/doc/rustc-dev-guide/src/rustdoc-internals/rustdoc-test-suite.md index 4f44cf1701c..3ec5ebd799e 100644 --- a/src/doc/rustc-dev-guide/src/rustdoc-internals/rustdoc-test-suite.md +++ b/src/doc/rustc-dev-guide/src/rustdoc-internals/rustdoc-test-suite.md @@ -20,7 +20,7 @@ Internally, [`compiletest`] invokes the supplementary checker script [`htmldocck Directives to HtmlDocCk are assertions that place constraints on the generated HTML. They look similar to those given to `compiletest` in that they take the form of `//@` comments -but ultimately, they are completey distinct and processed by different programs. +but ultimately, they are completely distinct and processed by different programs. [XPath] is used to query parts of the HTML document tree. diff --git a/src/doc/rustc-dev-guide/src/serialization.md b/src/doc/rustc-dev-guide/src/serialization.md index 47667061eda..8eb37bbe20b 100644 --- a/src/doc/rustc-dev-guide/src/serialization.md +++ b/src/doc/rustc-dev-guide/src/serialization.md @@ -75,7 +75,7 @@ impl<D: Decoder> Decodable<D> for MyStruct { rustc has a lot of [arena allocated types]. Deserializing these types isn't possible without access to the arena that they need to be allocated on. -The [`TyDecoder`] and [`TyEncoder`] traits are supertraits of [`Decoder`] and [`Encoder`] that allow access to a [`TyCtxt`]. +The [`TyDecoder`] and [`TyEncoder`] traits are subtraits of [`Decoder`] and [`Encoder`] that allow access to a [`TyCtxt`]. Types which contain `arena` allocated types can then bound the type parameter of their [`Encodable`] and [`Decodable`] implementations with these traits. diff --git a/src/doc/rustc-dev-guide/src/tests/compiletest.md b/src/doc/rustc-dev-guide/src/tests/compiletest.md index ded30234e70..aa99347b2bb 100644 --- a/src/doc/rustc-dev-guide/src/tests/compiletest.md +++ b/src/doc/rustc-dev-guide/src/tests/compiletest.md @@ -29,7 +29,7 @@ on if or how to run the test, what behavior to expect, and more. See [directives](directives.md) and the test suite documentation below for more details on these annotations. -See the [Adding new tests](adding.md) and [Best practies](best-practices.md) +See the [Adding new tests](adding.md) and [Best practices](best-practices.md) chapters for a tutorial on creating a new test and advice on writing a good test, and the [Running tests](running.md) chapter on how to run the test suite. diff --git a/src/doc/rustc-dev-guide/src/ty_module/instantiating_binders.md b/src/doc/rustc-dev-guide/src/ty_module/instantiating_binders.md index e3f091ca45f..0d1108c72e0 100644 --- a/src/doc/rustc-dev-guide/src/ty_module/instantiating_binders.md +++ b/src/doc/rustc-dev-guide/src/ty_module/instantiating_binders.md @@ -77,7 +77,7 @@ This end result is incorrect as we had two separate binders introducing their ow While in theory we could make this work it would be quite involved and more complex than the current setup, we would have to: - "rewrite" bound variables to have a higher `DebruijnIndex` whenever instantiating a `Binder`/`EarlyBinder` with a `Bound` ty/const/region -- When inferring an inference variable to a bound var, if that bound var is from a binder enterred after creating the infer var, we would have to lower the `DebruijnIndex` of the var. +- When inferring an inference variable to a bound var, if that bound var is from a binder entered after creating the infer var, we would have to lower the `DebruijnIndex` of the var. - Separately track what binder an inference variable was created inside of, also what the innermost binder it can name parameters from (currently we only have to track the latter) - When resolving inference variables rewrite any bound variables according to the current binder depth of the infcx - Maybe more (while writing this list items kept getting added so it seems naive to think this is exhaustive) diff --git a/src/doc/unstable-book/src/compiler-flags/offload.md b/src/doc/unstable-book/src/compiler-flags/offload.md new file mode 100644 index 00000000000..4266e8c11a2 --- /dev/null +++ b/src/doc/unstable-book/src/compiler-flags/offload.md @@ -0,0 +1,8 @@ +# `offload` + +The tracking issue for this feature is: [#131513](https://github.com/rust-lang/rust/issues/131513). + +------------------------ + +This feature will later allow you to run functions on GPUs. It is work in progress. +Set the `-Zoffload=Enable` compiler flag to experiment with it. diff --git a/src/tools/clippy/clippy_test_deps/Cargo.lock b/src/tools/clippy/clippy_test_deps/Cargo.lock index a591dae3a1a..5be404f24e6 100644 --- a/src/tools/clippy/clippy_test_deps/Cargo.lock +++ b/src/tools/clippy/clippy_test_deps/Cargo.lock @@ -72,6 +72,7 @@ dependencies = [ "futures", "if_chain", "itertools", + "libc", "parking_lot", "quote", "regex", diff --git a/src/tools/clippy/clippy_test_deps/Cargo.toml b/src/tools/clippy/clippy_test_deps/Cargo.toml index a23ffcaf2f9..fcedc5d4843 100644 --- a/src/tools/clippy/clippy_test_deps/Cargo.toml +++ b/src/tools/clippy/clippy_test_deps/Cargo.toml @@ -6,6 +6,7 @@ edition = "2021" # Add dependencies here to make them available in ui tests. [dependencies] +libc = "0.2" regex = "1.5.5" serde = { version = "1.0.145", features = ["derive"] } if_chain = "1.0" diff --git a/src/tools/clippy/tests/compile-test.rs b/src/tools/clippy/tests/compile-test.rs index 57d623b2cfc..83f91ccaa7b 100644 --- a/src/tools/clippy/tests/compile-test.rs +++ b/src/tools/clippy/tests/compile-test.rs @@ -151,7 +151,31 @@ impl TestContext { defaults.set_custom( "dependencies", DependencyBuilder { - program: CommandBuilder::cargo(), + program: { + let mut p = CommandBuilder::cargo(); + // If we run in bootstrap, we need to use the right compiler for building the + // tests -- not the compiler that built clippy, but the compiler that got linked + // into clippy. Just invoking TEST_RUSTC does not work because LD_LIBRARY_PATH + // is set in a way that makes it pick the wrong sysroot. Sadly due to + // <https://github.com/rust-lang/cargo/issues/4423> we cannot use RUSTFLAGS to + // set `--sysroot`, so we need to use bootstrap's rustc wrapper. That wrapper + // however has some staging logic that is hurting us here, so to work around + // that we set both the "real" and "staging" rustc to TEST_RUSTC, including the + // associated library paths. + if let Some(rustc) = option_env!("TEST_RUSTC") { + let libdir = option_env!("TEST_RUSTC_LIB").unwrap(); + let sysroot = option_env!("TEST_SYSROOT").unwrap(); + p.envs.push(("RUSTC_REAL".into(), Some(rustc.into()))); + p.envs.push(("RUSTC_REAL_LIBDIR".into(), Some(libdir.into()))); + p.envs.push(("RUSTC_SNAPSHOT".into(), Some(rustc.into()))); + p.envs.push(("RUSTC_SNAPSHOT_LIBDIR".into(), Some(libdir.into()))); + p.envs.push(( + "RUSTC_SYSROOT".into(), + Some(sysroot.into()), + )); + } + p + }, crate_manifest_path: Path::new("clippy_test_deps").join("Cargo.toml"), build_std: None, bless_lockfile: self.args.bless, @@ -192,6 +216,9 @@ impl TestContext { let dep = format!("-Ldependency={}", Path::new(host_libs).join("deps").display()); config.program.args.push(dep.into()); } + if let Some(sysroot) = option_env!("TEST_SYSROOT") { + config.program.args.push(format!("--sysroot={sysroot}").into()); + } config.program.program = profile_path.join(if cfg!(windows) { "clippy-driver.exe" diff --git a/src/tools/clippy/tests/ui/auxiliary/proc_macro_derive.rs b/src/tools/clippy/tests/ui/auxiliary/proc_macro_derive.rs index 5992d15935d..54650922871 100644 --- a/src/tools/clippy/tests/ui/auxiliary/proc_macro_derive.rs +++ b/src/tools/clippy/tests/ui/auxiliary/proc_macro_derive.rs @@ -16,7 +16,7 @@ pub fn derive(_: TokenStream) -> TokenStream { let output = quote! { // Should not trigger `useless_attribute` #[allow(dead_code)] - extern crate rustc_middle; + extern crate core; }; output } diff --git a/src/tools/clippy/tests/ui/cast_alignment.rs b/src/tools/clippy/tests/ui/cast_alignment.rs index 5773ffddb91..ef667f5598a 100644 --- a/src/tools/clippy/tests/ui/cast_alignment.rs +++ b/src/tools/clippy/tests/ui/cast_alignment.rs @@ -1,6 +1,5 @@ //! Test casts for alignment issues -#![feature(rustc_private)] #![feature(core_intrinsics)] #![warn(clippy::cast_ptr_alignment)] #![allow( @@ -10,8 +9,6 @@ clippy::borrow_as_ptr )] -extern crate libc; - fn main() { /* These should be warned against */ diff --git a/src/tools/clippy/tests/ui/cast_alignment.stderr b/src/tools/clippy/tests/ui/cast_alignment.stderr index 6d9a81f0ecf..ee4c3e9a77e 100644 --- a/src/tools/clippy/tests/ui/cast_alignment.stderr +++ b/src/tools/clippy/tests/ui/cast_alignment.stderr @@ -1,5 +1,5 @@ error: casting from `*const u8` to a more-strictly-aligned pointer (`*const u16`) (1 < 2 bytes) - --> tests/ui/cast_alignment.rs:19:5 + --> tests/ui/cast_alignment.rs:16:5 | LL | (&1u8 as *const u8) as *const u16; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -8,19 +8,19 @@ LL | (&1u8 as *const u8) as *const u16; = help: to override `-D warnings` add `#[allow(clippy::cast_ptr_alignment)]` error: casting from `*mut u8` to a more-strictly-aligned pointer (`*mut u16`) (1 < 2 bytes) - --> tests/ui/cast_alignment.rs:22:5 + --> tests/ui/cast_alignment.rs:19:5 | LL | (&mut 1u8 as *mut u8) as *mut u16; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: casting from `*const u8` to a more-strictly-aligned pointer (`*const u16`) (1 < 2 bytes) - --> tests/ui/cast_alignment.rs:26:5 + --> tests/ui/cast_alignment.rs:23:5 | LL | (&1u8 as *const u8).cast::<u16>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: casting from `*mut u8` to a more-strictly-aligned pointer (`*mut u16`) (1 < 2 bytes) - --> tests/ui/cast_alignment.rs:29:5 + --> tests/ui/cast_alignment.rs:26:5 | LL | (&mut 1u8 as *mut u8).cast::<u16>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/tools/clippy/tests/ui/iter_over_hash_type.rs b/src/tools/clippy/tests/ui/iter_over_hash_type.rs index 914cc9df0de..9a3e7033cd8 100644 --- a/src/tools/clippy/tests/ui/iter_over_hash_type.rs +++ b/src/tools/clippy/tests/ui/iter_over_hash_type.rs @@ -3,15 +3,18 @@ #![warn(clippy::iter_over_hash_type)] use std::collections::{HashMap, HashSet}; -extern crate rustc_data_structures; - extern crate proc_macros; +// Ensure it also works via type aliases (this isn't really the Fx hasher but that does not matter). +type FxBuildHasher = std::collections::hash_map::RandomState; +type FxHashMap<K, V> = HashMap<K, V, FxBuildHasher>; +type FxHashSet<K> = HashSet<K, FxBuildHasher>; + fn main() { let mut hash_set = HashSet::<i32>::new(); let mut hash_map = HashMap::<i32, i32>::new(); - let mut fx_hash_map = rustc_data_structures::fx::FxHashMap::<i32, i32>::default(); - let mut fx_hash_set = rustc_data_structures::fx::FxHashMap::<i32, i32>::default(); + let mut fx_hash_map = FxHashMap::<i32, i32>::default(); + let mut fx_hash_set = FxHashSet::<i32>::default(); let vec = Vec::<i32>::new(); // test hashset diff --git a/src/tools/clippy/tests/ui/iter_over_hash_type.stderr b/src/tools/clippy/tests/ui/iter_over_hash_type.stderr index 1bc6f4588d4..3356186547d 100644 --- a/src/tools/clippy/tests/ui/iter_over_hash_type.stderr +++ b/src/tools/clippy/tests/ui/iter_over_hash_type.stderr @@ -1,5 +1,5 @@ error: iteration over unordered hash-based type - --> tests/ui/iter_over_hash_type.rs:18:5 + --> tests/ui/iter_over_hash_type.rs:21:5 | LL | / for x in &hash_set { LL | | @@ -11,7 +11,7 @@ LL | | } = help: to override `-D warnings` add `#[allow(clippy::iter_over_hash_type)]` error: iteration over unordered hash-based type - --> tests/ui/iter_over_hash_type.rs:22:5 + --> tests/ui/iter_over_hash_type.rs:25:5 | LL | / for x in hash_set.iter() { LL | | @@ -20,7 +20,7 @@ LL | | } | |_____^ error: iteration over unordered hash-based type - --> tests/ui/iter_over_hash_type.rs:26:5 + --> tests/ui/iter_over_hash_type.rs:29:5 | LL | / for x in hash_set.clone() { LL | | @@ -29,7 +29,7 @@ LL | | } | |_____^ error: iteration over unordered hash-based type - --> tests/ui/iter_over_hash_type.rs:30:5 + --> tests/ui/iter_over_hash_type.rs:33:5 | LL | / for x in hash_set.drain() { LL | | @@ -38,7 +38,7 @@ LL | | } | |_____^ error: iteration over unordered hash-based type - --> tests/ui/iter_over_hash_type.rs:36:5 + --> tests/ui/iter_over_hash_type.rs:39:5 | LL | / for (x, y) in &hash_map { LL | | @@ -47,7 +47,7 @@ LL | | } | |_____^ error: iteration over unordered hash-based type - --> tests/ui/iter_over_hash_type.rs:40:5 + --> tests/ui/iter_over_hash_type.rs:43:5 | LL | / for x in hash_map.keys() { LL | | @@ -56,7 +56,7 @@ LL | | } | |_____^ error: iteration over unordered hash-based type - --> tests/ui/iter_over_hash_type.rs:44:5 + --> tests/ui/iter_over_hash_type.rs:47:5 | LL | / for x in hash_map.values() { LL | | @@ -65,7 +65,7 @@ LL | | } | |_____^ error: iteration over unordered hash-based type - --> tests/ui/iter_over_hash_type.rs:48:5 + --> tests/ui/iter_over_hash_type.rs:51:5 | LL | / for x in hash_map.values_mut() { LL | | @@ -74,7 +74,7 @@ LL | | } | |_____^ error: iteration over unordered hash-based type - --> tests/ui/iter_over_hash_type.rs:52:5 + --> tests/ui/iter_over_hash_type.rs:55:5 | LL | / for x in hash_map.iter() { LL | | @@ -83,7 +83,7 @@ LL | | } | |_____^ error: iteration over unordered hash-based type - --> tests/ui/iter_over_hash_type.rs:56:5 + --> tests/ui/iter_over_hash_type.rs:59:5 | LL | / for x in hash_map.clone() { LL | | @@ -92,7 +92,7 @@ LL | | } | |_____^ error: iteration over unordered hash-based type - --> tests/ui/iter_over_hash_type.rs:60:5 + --> tests/ui/iter_over_hash_type.rs:63:5 | LL | / for x in hash_map.drain() { LL | | @@ -101,7 +101,7 @@ LL | | } | |_____^ error: iteration over unordered hash-based type - --> tests/ui/iter_over_hash_type.rs:66:5 + --> tests/ui/iter_over_hash_type.rs:69:5 | LL | / for x in fx_hash_set { LL | | @@ -110,7 +110,7 @@ LL | | } | |_____^ error: iteration over unordered hash-based type - --> tests/ui/iter_over_hash_type.rs:70:5 + --> tests/ui/iter_over_hash_type.rs:73:5 | LL | / for x in fx_hash_map { LL | | diff --git a/src/tools/clippy/tests/ui/strlen_on_c_strings.fixed b/src/tools/clippy/tests/ui/strlen_on_c_strings.fixed index 31ed1cf03a2..17c1b541f77 100644 --- a/src/tools/clippy/tests/ui/strlen_on_c_strings.fixed +++ b/src/tools/clippy/tests/ui/strlen_on_c_strings.fixed @@ -1,7 +1,5 @@ #![warn(clippy::strlen_on_c_strings)] #![allow(dead_code, clippy::manual_c_str_literals)] -#![feature(rustc_private)] -extern crate libc; #[allow(unused)] use libc::strlen; diff --git a/src/tools/clippy/tests/ui/strlen_on_c_strings.rs b/src/tools/clippy/tests/ui/strlen_on_c_strings.rs index 0f3798c9fd8..c641422f5df 100644 --- a/src/tools/clippy/tests/ui/strlen_on_c_strings.rs +++ b/src/tools/clippy/tests/ui/strlen_on_c_strings.rs @@ -1,7 +1,5 @@ #![warn(clippy::strlen_on_c_strings)] #![allow(dead_code, clippy::manual_c_str_literals)] -#![feature(rustc_private)] -extern crate libc; #[allow(unused)] use libc::strlen; diff --git a/src/tools/clippy/tests/ui/strlen_on_c_strings.stderr b/src/tools/clippy/tests/ui/strlen_on_c_strings.stderr index b8619fa2df3..84a93b99ee3 100644 --- a/src/tools/clippy/tests/ui/strlen_on_c_strings.stderr +++ b/src/tools/clippy/tests/ui/strlen_on_c_strings.stderr @@ -1,5 +1,5 @@ error: using `libc::strlen` on a `CString` or `CStr` value - --> tests/ui/strlen_on_c_strings.rs:13:13 + --> tests/ui/strlen_on_c_strings.rs:11:13 | LL | let _ = unsafe { libc::strlen(cstring.as_ptr()) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `cstring.as_bytes().len()` @@ -8,37 +8,37 @@ LL | let _ = unsafe { libc::strlen(cstring.as_ptr()) }; = help: to override `-D warnings` add `#[allow(clippy::strlen_on_c_strings)]` error: using `libc::strlen` on a `CString` or `CStr` value - --> tests/ui/strlen_on_c_strings.rs:18:13 + --> tests/ui/strlen_on_c_strings.rs:16:13 | LL | let _ = unsafe { libc::strlen(cstr.as_ptr()) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `cstr.to_bytes().len()` error: using `libc::strlen` on a `CString` or `CStr` value - --> tests/ui/strlen_on_c_strings.rs:21:13 + --> tests/ui/strlen_on_c_strings.rs:19:13 | LL | let _ = unsafe { strlen(cstr.as_ptr()) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `cstr.to_bytes().len()` error: using `libc::strlen` on a `CString` or `CStr` value - --> tests/ui/strlen_on_c_strings.rs:25:22 + --> tests/ui/strlen_on_c_strings.rs:23:22 | LL | let _ = unsafe { strlen((*pcstr).as_ptr()) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(*pcstr).to_bytes().len()` error: using `libc::strlen` on a `CString` or `CStr` value - --> tests/ui/strlen_on_c_strings.rs:31:22 + --> tests/ui/strlen_on_c_strings.rs:29:22 | LL | let _ = unsafe { strlen(unsafe_identity(cstr).as_ptr()) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unsafe_identity(cstr).to_bytes().len()` error: using `libc::strlen` on a `CString` or `CStr` value - --> tests/ui/strlen_on_c_strings.rs:33:13 + --> tests/ui/strlen_on_c_strings.rs:31:13 | LL | let _ = unsafe { strlen(unsafe { unsafe_identity(cstr) }.as_ptr()) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unsafe { unsafe_identity(cstr) }.to_bytes().len()` error: using `libc::strlen` on a `CString` or `CStr` value - --> tests/ui/strlen_on_c_strings.rs:37:22 + --> tests/ui/strlen_on_c_strings.rs:35:22 | LL | let _ = unsafe { strlen(f(cstr).as_ptr()) }; | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `f(cstr).to_bytes().len()` diff --git a/src/tools/clippy/tests/ui/useless_attribute.fixed b/src/tools/clippy/tests/ui/useless_attribute.fixed index a96c8f46f55..930bc1eaecf 100644 --- a/src/tools/clippy/tests/ui/useless_attribute.fixed +++ b/src/tools/clippy/tests/ui/useless_attribute.fixed @@ -13,7 +13,7 @@ #[allow(unused_imports)] #[allow(unused_extern_crates)] #[macro_use] -extern crate rustc_middle; +extern crate regex as regex_crate; #[macro_use] extern crate proc_macro_derive; diff --git a/src/tools/clippy/tests/ui/useless_attribute.rs b/src/tools/clippy/tests/ui/useless_attribute.rs index b26410134bb..50fafd478e5 100644 --- a/src/tools/clippy/tests/ui/useless_attribute.rs +++ b/src/tools/clippy/tests/ui/useless_attribute.rs @@ -13,7 +13,7 @@ #[allow(unused_imports)] #[allow(unused_extern_crates)] #[macro_use] -extern crate rustc_middle; +extern crate regex as regex_crate; #[macro_use] extern crate proc_macro_derive; diff --git a/src/tools/enzyme b/src/tools/enzyme -Subproject b5098d515d5e1bd0f5470553bc0d18da9794ca8 +Subproject 2cccfba93c1650f26f1cf8be8aa875a7c1d23fb diff --git a/src/tools/miri/src/alloc_addresses/mod.rs b/src/tools/miri/src/alloc_addresses/mod.rs index 10339928ac2..334503d2994 100644 --- a/src/tools/miri/src/alloc_addresses/mod.rs +++ b/src/tools/miri/src/alloc_addresses/mod.rs @@ -116,14 +116,6 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { let this = self.eval_context_ref(); let info = this.get_alloc_info(alloc_id); - // Miri's address assignment leaks state across thread boundaries, which is incompatible - // with GenMC execution. So we instead let GenMC assign addresses to allocations. - if let Some(genmc_ctx) = this.machine.data_race.as_genmc_ref() { - let addr = genmc_ctx.handle_alloc(&this.machine, info.size, info.align, memory_kind)?; - return interp_ok(addr); - } - - let mut rng = this.machine.rng.borrow_mut(); // This is either called immediately after allocation (and then cached), or when // adjusting `tcx` pointers (which never get freed). So assert that we are looking // at a live allocation. This also ensures that we never re-assign an address to an @@ -131,6 +123,19 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { // information was removed. assert!(!matches!(info.kind, AllocKind::Dead)); + // TypeId allocations always have a "base address" of 0 (i.e., the relative offset is the + // hash fragment and therefore equal to the actual integer value). + if matches!(info.kind, AllocKind::TypeId) { + return interp_ok(0); + } + + // Miri's address assignment leaks state across thread boundaries, which is incompatible + // with GenMC execution. So we instead let GenMC assign addresses to allocations. + if let Some(genmc_ctx) = this.machine.data_race.as_genmc_ref() { + let addr = genmc_ctx.handle_alloc(&this.machine, info.size, info.align, memory_kind)?; + return interp_ok(addr); + } + // This allocation does not have a base address yet, pick or reuse one. if !this.machine.native_lib.is_empty() { // In native lib mode, we use the "real" address of the bytes for this allocation. @@ -157,7 +162,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { this.get_alloc_bytes_unchecked_raw(alloc_id)? } } - AllocKind::Function | AllocKind::Virtual => { + AllocKind::Function | AllocKind::VTable => { // Allocate some dummy memory to get a unique address for this function/vtable. let alloc_bytes = MiriAllocBytes::from_bytes( &[0u8; 1], @@ -169,12 +174,13 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { std::mem::forget(alloc_bytes); ptr } - AllocKind::Dead => unreachable!(), + AllocKind::TypeId | AllocKind::Dead => unreachable!(), }; // We don't have to expose this pointer yet, we do that in `prepare_for_native_call`. return interp_ok(base_ptr.addr().to_u64()); } // We are not in native lib mode, so we control the addresses ourselves. + let mut rng = this.machine.rng.borrow_mut(); if let Some((reuse_addr, clock)) = global_state.reuse.take_addr( &mut *rng, info.size, @@ -295,21 +301,25 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Store address in cache. global_state.base_addr.try_insert(alloc_id, base_addr).unwrap(); - // Also maintain the opposite mapping in `int_to_ptr_map`, ensuring we keep it sorted. - // We have a fast-path for the common case that this address is bigger than all previous ones. - let pos = if global_state - .int_to_ptr_map - .last() - .is_some_and(|(last_addr, _)| *last_addr < base_addr) - { - global_state.int_to_ptr_map.len() - } else { - global_state + // Also maintain the opposite mapping in `int_to_ptr_map`, ensuring we keep it + // sorted. We have a fast-path for the common case that this address is bigger than + // all previous ones. We skip this for allocations at address 0; those can't be + // real, they must be TypeId "fake allocations". + if base_addr != 0 { + let pos = if global_state .int_to_ptr_map - .binary_search_by_key(&base_addr, |(addr, _)| *addr) - .unwrap_err() - }; - global_state.int_to_ptr_map.insert(pos, (base_addr, alloc_id)); + .last() + .is_some_and(|(last_addr, _)| *last_addr < base_addr) + { + global_state.int_to_ptr_map.len() + } else { + global_state + .int_to_ptr_map + .binary_search_by_key(&base_addr, |(addr, _)| *addr) + .unwrap_err() + }; + global_state.int_to_ptr_map.insert(pos, (base_addr, alloc_id)); + } interp_ok(base_addr) } diff --git a/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs b/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs index e834fdffdd1..2977efaae04 100644 --- a/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs +++ b/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs @@ -650,7 +650,7 @@ trait EvalContextPrivExt<'tcx, 'ecx>: crate::MiriInterpCxExt<'tcx> { dcx.log_protector(); } }, - AllocKind::Function | AllocKind::Virtual | AllocKind::Dead => { + AllocKind::Function | AllocKind::VTable | AllocKind::TypeId | AllocKind::Dead => { // No stacked borrows on these allocations. } } @@ -1021,7 +1021,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { trace!("Stacked Borrows tag {tag:?} exposed in {alloc_id:?}"); alloc_extra.borrow_tracker_sb().borrow_mut().exposed_tags.insert(tag); } - AllocKind::Function | AllocKind::Virtual | AllocKind::Dead => { + AllocKind::Function | AllocKind::VTable | AllocKind::TypeId | AllocKind::Dead => { // No stacked borrows on these allocations. } } diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs index aa92f8a8c30..ad2a67160f4 100644 --- a/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs +++ b/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs @@ -673,7 +673,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { trace!("Tree Borrows tag {tag:?} exposed in {alloc_id:?}"); alloc_extra.borrow_tracker_tb().borrow_mut().expose_tag(tag); } - AllocKind::Function | AllocKind::Virtual | AllocKind::Dead => { + AllocKind::Function | AllocKind::VTable | AllocKind::TypeId | AllocKind::Dead => { // No tree borrows on these allocations. } } diff --git a/src/tools/miri/tests/pass/fn_align.rs b/src/tools/miri/tests/pass/fn_align.rs index 28f92995880..9752d033458 100644 --- a/src/tools/miri/tests/pass/fn_align.rs +++ b/src/tools/miri/tests/pass/fn_align.rs @@ -1,15 +1,19 @@ //@compile-flags: -Zmin-function-alignment=8 + +// FIXME(rust-lang/rust#82232, rust-lang/rust#143834): temporarily renamed to mitigate `#[align]` +// nameres ambiguity +#![feature(rustc_attrs)] #![feature(fn_align)] // When a function uses `align(N)`, the function address should be a multiple of `N`. -#[align(256)] +#[rustc_align(256)] fn foo() {} -#[align(16)] +#[rustc_align(16)] fn bar() {} -#[align(4)] +#[rustc_align(4)] fn baz() {} fn main() { diff --git a/src/tools/opt-dist/src/main.rs b/src/tools/opt-dist/src/main.rs index d0e6badede6..42170ff39d7 100644 --- a/src/tools/opt-dist/src/main.rs +++ b/src/tools/opt-dist/src/main.rs @@ -62,7 +62,7 @@ enum EnvironmentCmd { python: String, /// Directory where artifacts (like PGO profiles or rustc-perf) of this workflow - /// will be stored. + /// will be stored. Relative to `checkout_dir` #[arg(long, default_value = "opt-artifacts")] artifact_dir: Utf8PathBuf, @@ -150,7 +150,7 @@ fn create_environment(args: Args) -> anyhow::Result<(Environment, Vec<String>)> .python_binary(python) .checkout_dir(checkout_dir.clone()) .host_llvm_dir(llvm_dir) - .artifact_dir(artifact_dir) + .artifact_dir(checkout_dir.join(artifact_dir)) .build_dir(checkout_dir.join(build_dir)) .prebuilt_rustc_perf(rustc_perf_checkout_dir) .shared_llvm(llvm_shared) diff --git a/src/tools/rust-analyzer/Cargo.lock b/src/tools/rust-analyzer/Cargo.lock index e55cd80943d..c471234bbe3 100644 --- a/src/tools/rust-analyzer/Cargo.lock +++ b/src/tools/rust-analyzer/Cargo.lock @@ -1268,7 +1268,7 @@ dependencies = [ "expect-test", "intern", "parser", - "ra-ap-rustc_lexer", + "ra-ap-rustc_lexer 0.122.0", "rustc-hash 2.1.1", "smallvec", "span", @@ -1504,7 +1504,7 @@ dependencies = [ "drop_bomb", "edition", "expect-test", - "ra-ap-rustc_lexer", + "ra-ap-rustc_lexer 0.122.0", "rustc-literal-escaper", "stdx", "tracing", @@ -1614,7 +1614,7 @@ dependencies = [ "object", "paths", "proc-macro-test", - "ra-ap-rustc_lexer", + "ra-ap-rustc_lexer 0.122.0", "span", "syntax-bridge", "tt", @@ -1756,9 +1756,9 @@ dependencies = [ [[package]] name = "ra-ap-rustc_abi" -version = "0.121.0" +version = "0.122.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ee51482d1c9d3e538acda8cce723db8eea1a81540544bf362bf4c3d841b2329" +checksum = "fb01e1fec578003c85481c1cad4ff8cd8195b07c2dc85ae3f716108507ae15d5" dependencies = [ "bitflags 2.9.1", "ra-ap-rustc_hashes", @@ -1768,18 +1768,18 @@ dependencies = [ [[package]] name = "ra-ap-rustc_hashes" -version = "0.121.0" +version = "0.122.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19c8f1e0c28e24e1b4c55dc08058c6c9829df2204497d4034259f491d348c204" +checksum = "e0ec056e72a472ffef8761ce96ece6c626eb07368c09d0105b6df30d27d07673" dependencies = [ "rustc-stable-hash", ] [[package]] name = "ra-ap-rustc_index" -version = "0.121.0" +version = "0.122.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f33f429cec6b92fa2c7243883279fb29dd233fdc3e94099aff32aa91aa87f50" +checksum = "0fcdd1001db0295e59052e9f53aeda588bbe81e362534f4687d41bd44777b5a7" dependencies = [ "ra-ap-rustc_index_macros", "smallvec", @@ -1787,9 +1787,9 @@ dependencies = [ [[package]] name = "ra-ap-rustc_index_macros" -version = "0.121.0" +version = "0.122.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9b55910dbe1fe7ef34bdc1d1bcb41e99b377eb680ea58a1218d95d6b4152257" +checksum = "728d64dd98e25530b32e3f7c7c1e844e52722b269360daa1cdeba9dff9727a26" dependencies = [ "proc-macro2", "quote", @@ -1808,20 +1808,31 @@ dependencies = [ ] [[package]] +name = "ra-ap-rustc_lexer" +version = "0.122.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "415f0821f512608d825b3215489a6a6a2c18ed9f0045953d514e7ec23d4b90ab" +dependencies = [ + "memchr", + "unicode-properties", + "unicode-xid", +] + +[[package]] name = "ra-ap-rustc_parse_format" version = "0.121.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81057891bc2063ad9e353f29462fbc47a0f5072560af34428ae9313aaa5e9d97" dependencies = [ - "ra-ap-rustc_lexer", + "ra-ap-rustc_lexer 0.121.0", "rustc-literal-escaper", ] [[package]] name = "ra-ap-rustc_pattern_analysis" -version = "0.121.0" +version = "0.122.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe21a3542980d56d2435e96c2720773cac1c63fd4db666417e414729da192eb3" +checksum = "4657fcfdfe06e2a02ec8180d4e7c95aecf4811ba50367e363d1a2300b7623284" dependencies = [ "ra-ap-rustc_index", "rustc-hash 2.1.1", @@ -2581,7 +2592,7 @@ version = "0.0.0" dependencies = [ "arrayvec", "intern", - "ra-ap-rustc_lexer", + "ra-ap-rustc_lexer 0.122.0", "stdx", "text-size", ] diff --git a/src/tools/rust-analyzer/Cargo.toml b/src/tools/rust-analyzer/Cargo.toml index 41fa06a76a7..700c116ec18 100644 --- a/src/tools/rust-analyzer/Cargo.toml +++ b/src/tools/rust-analyzer/Cargo.toml @@ -89,11 +89,11 @@ vfs-notify = { path = "./crates/vfs-notify", version = "0.0.0" } vfs = { path = "./crates/vfs", version = "0.0.0" } edition = { path = "./crates/edition", version = "0.0.0" } -ra-ap-rustc_lexer = { version = "0.121", default-features = false } +ra-ap-rustc_lexer = { version = "0.122", default-features = false } ra-ap-rustc_parse_format = { version = "0.121", default-features = false } -ra-ap-rustc_index = { version = "0.121", default-features = false } -ra-ap-rustc_abi = { version = "0.121", default-features = false } -ra-ap-rustc_pattern_analysis = { version = "0.121", default-features = false } +ra-ap-rustc_index = { version = "0.122", default-features = false } +ra-ap-rustc_abi = { version = "0.122", default-features = false } +ra-ap-rustc_pattern_analysis = { version = "0.122", default-features = false } # local crates that aren't published to crates.io. These should not have versions. diff --git a/src/tools/rust-analyzer/crates/cfg/src/cfg_expr.rs b/src/tools/rust-analyzer/crates/cfg/src/cfg_expr.rs index 0ec082dfa7f..aed00aa9fc4 100644 --- a/src/tools/rust-analyzer/crates/cfg/src/cfg_expr.rs +++ b/src/tools/rust-analyzer/crates/cfg/src/cfg_expr.rs @@ -68,6 +68,11 @@ impl CfgExpr { next_cfg_expr(&mut tt.iter()).unwrap_or(CfgExpr::Invalid) } + #[cfg(feature = "tt")] + pub fn parse_from_iter<S: Copy>(tt: &mut tt::iter::TtIter<'_, S>) -> CfgExpr { + next_cfg_expr(tt).unwrap_or(CfgExpr::Invalid) + } + /// Fold the cfg by querying all basic `Atom` and `KeyValue` predicates. pub fn fold(&self, query: &dyn Fn(&CfgAtom) -> bool) -> Option<bool> { match self { @@ -96,7 +101,14 @@ fn next_cfg_expr<S: Copy>(it: &mut tt::iter::TtIter<'_, S>) -> Option<CfgExpr> { }; let ret = match it.peek() { - Some(TtElement::Leaf(tt::Leaf::Punct(punct))) if punct.char == '=' => { + Some(TtElement::Leaf(tt::Leaf::Punct(punct))) + // Don't consume on e.g. `=>`. + if punct.char == '=' + && (punct.spacing == tt::Spacing::Alone + || it.remaining().flat_tokens().get(1).is_none_or(|peek2| { + !matches!(peek2, tt::TokenTree::Leaf(tt::Leaf::Punct(_))) + })) => + { match it.remaining().flat_tokens().get(1) { Some(tt::TokenTree::Leaf(tt::Leaf::Literal(literal))) => { it.next(); diff --git a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/builtin_fn_macro.rs b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/builtin_fn_macro.rs index 1c3af47d522..eeaf865338b 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/builtin_fn_macro.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/builtin_fn_macro.rs @@ -550,3 +550,51 @@ fn main() { "\"hello\""; } "##]], ); } + +#[test] +fn cfg_select() { + check( + r#" +#[rustc_builtin_macro] +pub macro cfg_select($($tt:tt)*) {} + +cfg_select! { + false => { fn false_1() {} } + any(false, true) => { fn true_1() {} } +} + +cfg_select! { + false => { fn false_2() {} } + _ => { fn true_2() {} } +} + +cfg_select! { + false => { fn false_3() {} } +} + +cfg_select! { + false +} + +cfg_select! { + false => +} + + "#, + expect![[r#" +#[rustc_builtin_macro] +pub macro cfg_select($($tt:tt)*) {} + +fn true_1() {} + +fn true_2() {} + +/* error: none of the predicates in this `cfg_select` evaluated to true */ + +/* error: expected `=>` after cfg expression */ + +/* error: expected a token tree after `=>` */ + + "#]], + ); +} diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/builtin/fn_macro.rs b/src/tools/rust-analyzer/crates/hir-expand/src/builtin/fn_macro.rs index 60fbc660652..4a9af01091f 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/builtin/fn_macro.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/builtin/fn_macro.rs @@ -127,6 +127,7 @@ register_builtin! { (asm, Asm) => asm_expand, (global_asm, GlobalAsm) => global_asm_expand, (naked_asm, NakedAsm) => naked_asm_expand, + (cfg_select, CfgSelect) => cfg_select_expand, (cfg, Cfg) => cfg_expand, (core_panic, CorePanic) => panic_expand, (std_panic, StdPanic) => panic_expand, @@ -355,6 +356,71 @@ fn naked_asm_expand( ExpandResult::ok(expanded) } +fn cfg_select_expand( + db: &dyn ExpandDatabase, + id: MacroCallId, + tt: &tt::TopSubtree, + span: Span, +) -> ExpandResult<tt::TopSubtree> { + let loc = db.lookup_intern_macro_call(id); + let cfg_options = loc.krate.cfg_options(db); + + let mut iter = tt.iter(); + let mut expand_to = None; + while let Some(next) = iter.peek() { + let active = if let tt::TtElement::Leaf(tt::Leaf::Ident(ident)) = next + && ident.sym == sym::underscore + { + iter.next(); + true + } else { + cfg_options.check(&CfgExpr::parse_from_iter(&mut iter)) != Some(false) + }; + match iter.expect_glued_punct() { + Ok(it) if it.len() == 2 && it[0].char == '=' && it[1].char == '>' => {} + _ => { + let err_span = iter.peek().map(|it| it.first_span()).unwrap_or(span); + return ExpandResult::new( + tt::TopSubtree::empty(tt::DelimSpan::from_single(span)), + ExpandError::other(err_span, "expected `=>` after cfg expression"), + ); + } + } + let expand_to_if_active = match iter.next() { + Some(tt::TtElement::Subtree(_, tt)) => tt.remaining(), + _ => { + let err_span = iter.peek().map(|it| it.first_span()).unwrap_or(span); + return ExpandResult::new( + tt::TopSubtree::empty(tt::DelimSpan::from_single(span)), + ExpandError::other(err_span, "expected a token tree after `=>`"), + ); + } + }; + + if expand_to.is_none() && active { + expand_to = Some(expand_to_if_active); + } + } + match expand_to { + Some(expand_to) => { + let mut builder = tt::TopSubtreeBuilder::new(tt::Delimiter { + kind: tt::DelimiterKind::Invisible, + open: span, + close: span, + }); + builder.extend_with_tt(expand_to); + ExpandResult::ok(builder.build()) + } + None => ExpandResult::new( + tt::TopSubtree::empty(tt::DelimSpan::from_single(span)), + ExpandError::other( + span, + "none of the predicates in this `cfg_select` evaluated to true", + ), + ), + } +} + fn cfg_expand( db: &dyn ExpandDatabase, id: MacroCallId, diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_deref.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_deref.rs index c7b97dcd231..55a09c5d775 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_deref.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_deref.rs @@ -10,7 +10,7 @@ use syntax::{ use crate::{ AssistId, assist_context::{AssistContext, Assists, SourceChangeBuilder}, - utils::generate_trait_impl_text, + utils::generate_trait_impl_text_intransitive, }; // Assist: generate_deref @@ -150,7 +150,7 @@ fn generate_edit( ), }; let strukt_adt = ast::Adt::Struct(strukt); - let deref_impl = generate_trait_impl_text( + let deref_impl = generate_trait_impl_text_intransitive( &strukt_adt, &trait_path.display(db, edition).to_string(), &impl_code, @@ -228,6 +228,28 @@ impl core::ops::Deref for B { } #[test] + fn test_generate_record_deref_with_generic() { + check_assist( + generate_deref, + r#" +//- minicore: deref +struct A<T>($0T); +"#, + r#" +struct A<T>(T); + +impl<T> core::ops::Deref for A<T> { + type Target = T; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} +"#, + ); + } + + #[test] fn test_generate_record_deref_short_path() { check_assist( generate_deref, diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_mut_trait_impl.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_mut_trait_impl.rs index 4ddab2cfad0..dc26ec79a74 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_mut_trait_impl.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_mut_trait_impl.rs @@ -134,6 +134,9 @@ fn get_trait_mut(apply_trait: &hir::Trait, famous: FamousDefs<'_, '_>) -> Option if trait_ == famous.core_borrow_Borrow().as_ref() { return Some("BorrowMut"); } + if trait_ == famous.core_ops_Deref().as_ref() { + return Some("DerefMut"); + } None } @@ -142,6 +145,7 @@ fn process_method_name(name: ast::Name) -> Option<(ast::Name, &'static str)> { "index" => "index_mut", "as_ref" => "as_mut", "borrow" => "borrow_mut", + "deref" => "deref_mut", _ => return None, }; Some((name, new_name)) @@ -260,6 +264,39 @@ impl core::convert::AsRef<i32> for Foo { } "#, ); + + check_assist( + generate_mut_trait_impl, + r#" +//- minicore: deref +struct Foo(i32); + +impl core::ops::Deref$0 for Foo { + type Target = i32; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} +"#, + r#" +struct Foo(i32); + +$0impl core::ops::DerefMut for Foo { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} + +impl core::ops::Deref for Foo { + type Target = i32; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} +"#, + ); } #[test] diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs b/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs index 2c8cb6e4d91..fbce1d31eae 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs @@ -567,6 +567,7 @@ pub(crate) fn generate_impl_text(adt: &ast::Adt, code: &str) -> String { /// /// This is useful for traits like `PartialEq`, since `impl<T> PartialEq for U<T>` often requires `T: PartialEq`. // FIXME: migrate remaining uses to `generate_trait_impl` +#[allow(dead_code)] pub(crate) fn generate_trait_impl_text(adt: &ast::Adt, trait_text: &str, code: &str) -> String { generate_impl_text_inner(adt, Some(trait_text), true, code) } diff --git a/src/tools/rust-analyzer/crates/ide-db/src/search.rs b/src/tools/rust-analyzer/crates/ide-db/src/search.rs index 4efb83ba323..9cf0bcf9190 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/search.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/search.rs @@ -531,7 +531,7 @@ impl<'a> FindUsages<'a> { node.token_at_offset(offset) .find(|it| { // `name` is stripped of raw ident prefix. See the comment on name retrieval below. - it.text().trim_start_matches("r#") == name + it.text().trim_start_matches('\'').trim_start_matches("r#") == name }) .into_iter() .flat_map(move |token| { @@ -938,7 +938,12 @@ impl<'a> FindUsages<'a> { }) }; // We need to search without the `r#`, hence `as_str` access. - self.def.name(sema.db).or_else(self_kw_refs).map(|it| it.as_str().to_smolstr()) + // We strip `'` from lifetimes and labels as otherwise they may not match with raw-escaped ones, + // e.g. if we search `'foo` we won't find `'r#foo`. + self.def + .name(sema.db) + .or_else(self_kw_refs) + .map(|it| it.as_str().trim_start_matches('\'').to_smolstr()) } }; let name = match &name { diff --git a/src/tools/rust-analyzer/crates/ide/src/folding_ranges.rs b/src/tools/rust-analyzer/crates/ide/src/folding_ranges.rs index c081796d078..698fd147789 100755 --- a/src/tools/rust-analyzer/crates/ide/src/folding_ranges.rs +++ b/src/tools/rust-analyzer/crates/ide/src/folding_ranges.rs @@ -48,7 +48,6 @@ pub(crate) fn folding_ranges(file: &SourceFile) -> Vec<Fold> { let mut res = vec![]; let mut visited_comments = FxHashSet::default(); let mut visited_nodes = FxHashSet::default(); - let mut merged_fn_bodies = FxHashSet::default(); // regions can be nested, here is a LIFO buffer let mut region_starts: Vec<TextSize> = vec![]; @@ -73,7 +72,7 @@ pub(crate) fn folding_ranges(file: &SourceFile) -> Vec<Fold> { continue; } - if let Some(body) = fn_node.body() { + if fn_node.body().is_some() { res.push(Fold { range: TextRange::new( node.text_range().start(), @@ -81,7 +80,6 @@ pub(crate) fn folding_ranges(file: &SourceFile) -> Vec<Fold> { ), kind: FoldKind::Function, }); - merged_fn_bodies.insert(body.syntax().text_range()); continue; } } diff --git a/src/tools/rust-analyzer/crates/ide/src/references.rs b/src/tools/rust-analyzer/crates/ide/src/references.rs index fe874bc99b4..86b88a17c75 100644 --- a/src/tools/rust-analyzer/crates/ide/src/references.rs +++ b/src/tools/rust-analyzer/crates/ide/src/references.rs @@ -3088,4 +3088,42 @@ fn main() { "#]], ); } + + #[test] + fn raw_labels_and_lifetimes() { + check( + r#" +fn foo<'r#fn>(s: &'r#fn str) { + let _a: &'r#fn str = s; + let _b: &'r#fn str; + 'r#break$0: { + break 'r#break; + } +} + "#, + expect![[r#" + 'r#break Label FileId(0) 87..96 87..95 + + FileId(0) 113..121 + "#]], + ); + check( + r#" +fn foo<'r#fn$0>(s: &'r#fn str) { + let _a: &'r#fn str = s; + let _b: &'r#fn str; + 'r#break: { + break 'r#break; + } +} + "#, + expect![[r#" + 'r#fn LifetimeParam FileId(0) 7..12 + + FileId(0) 18..23 + FileId(0) 44..49 + FileId(0) 72..77 + "#]], + ); + } } diff --git a/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs b/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs index 1ccd20c25e9..4780743c4d9 100644 --- a/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs +++ b/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs @@ -156,6 +156,7 @@ define_symbols! { cfg_attr, cfg_eval, cfg, + cfg_select, char, clone, Clone, diff --git a/src/tools/rust-analyzer/crates/tt/src/iter.rs b/src/tools/rust-analyzer/crates/tt/src/iter.rs index 3246156f1cb..2e89d762a0e 100644 --- a/src/tools/rust-analyzer/crates/tt/src/iter.rs +++ b/src/tools/rust-analyzer/crates/tt/src/iter.rs @@ -217,6 +217,17 @@ pub enum TtElement<'a, S> { Subtree(&'a Subtree<S>, TtIter<'a, S>), } +impl<S: Copy + fmt::Debug> fmt::Debug for TtElement<'_, S> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::Leaf(leaf) => f.debug_tuple("Leaf").field(leaf).finish(), + Self::Subtree(subtree, inner) => { + f.debug_tuple("Subtree").field(subtree).field(inner).finish() + } + } + } +} + impl<S: Copy> TtElement<'_, S> { #[inline] pub fn first_span(&self) -> S { diff --git a/src/tools/rust-analyzer/rust-version b/src/tools/rust-analyzer/rust-version index 57ff326ce5a..c2b1c151b83 100644 --- a/src/tools/rust-analyzer/rust-version +++ b/src/tools/rust-analyzer/rust-version @@ -1 +1 @@ -a9fb6103b05c6ad6eee6bed4c0bb5a2e8e1024c6 +e05ab47e6c418fb2b9faa2eae9a7e70c65c98eaa |
