diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 3eae95d5b738d..2fac13b72019c 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -3494,7 +3494,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { continue; } trait_in_other_version_found = self - .detect_and_explain_multiple_crate_versions( + .detect_and_explain_multiple_crate_versions_of_trait_item( err, pick.item.def_id, rcvr.hir_id, @@ -3701,12 +3701,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // same crate. let rcvr_ty = self.node_ty_opt(ty.hir_id); - trait_in_other_version_found = self.detect_and_explain_multiple_crate_versions( - err, - assoc.def_id, - ty.hir_id, - rcvr_ty, - ); + trait_in_other_version_found = self + .detect_and_explain_multiple_crate_versions_of_trait_item( + err, + assoc.def_id, + ty.hir_id, + rcvr_ty, + ); } if !trait_in_other_version_found && self.suggest_valid_traits(err, item_name, valid_out_of_scope_traits, true) @@ -4098,7 +4099,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - fn detect_and_explain_multiple_crate_versions( + fn detect_and_explain_multiple_crate_versions_of_trait_item( &self, err: &mut Diag<'_>, item_def_id: DefId, @@ -4111,6 +4112,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return false; } let trait_def_id = self.tcx.parent(item_def_id); + if !self.tcx.is_trait(trait_def_id) { + return false; + } let krate = self.tcx.crate_name(trait_def_id.krate); let name = self.tcx.item_name(trait_def_id); let candidates: Vec<_> = traits diff --git a/library/core/src/iter/sources/generator.rs b/library/core/src/iter/sources/generator.rs index 155fa9368ad05..0846974d526a9 100644 --- a/library/core/src/iter/sources/generator.rs +++ b/library/core/src/iter/sources/generator.rs @@ -20,7 +20,7 @@ /// ``` #[unstable(feature = "iter_macro", issue = "none", reason = "generators are unstable")] #[allow_internal_unstable(coroutines, iter_from_coroutine)] -#[cfg_attr(not(bootstrap), rustc_builtin_macro)] +#[rustc_builtin_macro] pub macro iter($($t:tt)*) { /* compiler-builtin */ } diff --git a/library/std/tests/sync/mpmc.rs b/library/std/tests/sync/mpmc.rs index 78abcb3bcbe1d..594fc2180d83f 100644 --- a/library/std/tests/sync/mpmc.rs +++ b/library/std/tests/sync/mpmc.rs @@ -462,8 +462,8 @@ fn oneshot_single_thread_recv_timeout() { #[test] fn stress_recv_timeout_two_threads() { let (tx, rx) = channel(); - let stress = stress_factor() + 100; - let timeout = Duration::from_millis(100); + let stress = stress_factor() + 50; + let timeout = Duration::from_millis(5); thread::spawn(move || { for i in 0..stress { @@ -475,18 +475,23 @@ fn stress_recv_timeout_two_threads() { }); let mut recv_count = 0; + let mut got_timeout = false; loop { match rx.recv_timeout(timeout) { Ok(n) => { assert_eq!(n, 1usize); recv_count += 1; } - Err(RecvTimeoutError::Timeout) => continue, + Err(RecvTimeoutError::Timeout) => { + got_timeout = true; + continue; + } Err(RecvTimeoutError::Disconnected) => break, } } assert_eq!(recv_count, stress); + assert!(got_timeout); } #[test] diff --git a/library/std/tests/sync/mpsc.rs b/library/std/tests/sync/mpsc.rs index 1d8edfde44bed..9de4a71987b8e 100644 --- a/library/std/tests/sync/mpsc.rs +++ b/library/std/tests/sync/mpsc.rs @@ -425,8 +425,8 @@ fn oneshot_single_thread_recv_timeout() { #[test] fn stress_recv_timeout_two_threads() { let (tx, rx) = channel(); - let stress = stress_factor() + 100; - let timeout = Duration::from_millis(100); + let stress = stress_factor() + 50; + let timeout = Duration::from_millis(5); thread::spawn(move || { for i in 0..stress { @@ -438,18 +438,23 @@ fn stress_recv_timeout_two_threads() { }); let mut recv_count = 0; + let mut got_timeout = false; loop { match rx.recv_timeout(timeout) { Ok(n) => { assert_eq!(n, 1usize); recv_count += 1; } - Err(RecvTimeoutError::Timeout) => continue, + Err(RecvTimeoutError::Timeout) => { + got_timeout = true; + continue; + } Err(RecvTimeoutError::Disconnected) => break, } } assert_eq!(recv_count, stress); + assert!(got_timeout); } #[test] diff --git a/src/bootstrap/src/core/builder/cargo.rs b/src/bootstrap/src/core/builder/cargo.rs index 1e9af68a92df6..cf7f962d0263b 100644 --- a/src/bootstrap/src/core/builder/cargo.rs +++ b/src/bootstrap/src/core/builder/cargo.rs @@ -11,7 +11,7 @@ use crate::utils::build_stamp; use crate::utils::helpers::{self, LldThreads, check_cfg_arg, linker_args, linker_flags}; use crate::{ BootstrapCommand, CLang, Compiler, Config, DocTests, DryRun, EXTRA_CHECK_CFGS, GitRepo, Mode, - TargetSelection, command, prepare_behaviour_dump_dir, t, + RemapScheme, TargetSelection, command, prepare_behaviour_dump_dir, t, }; /// Represents flag values in `String` form with whitespace delimiter to pass it to the compiler @@ -636,6 +636,15 @@ impl Builder<'_> { for (restricted_mode, name, values) in EXTRA_CHECK_CFGS { if restricted_mode.is_none() || *restricted_mode == Some(mode) { rustflags.arg(&check_cfg_arg(name, *values)); + + if *name == "bootstrap" { + // Cargo doesn't pass RUSTFLAGS to proc_macros: + // https://github.com/rust-lang/cargo/issues/4423 + // Thus, if we are on stage 0, we explicitly set `--cfg=bootstrap`. + // We also declare that the flag is expected, which we need to do to not + // get warnings about it being unexpected. + hostflags.arg(check_cfg_arg(name, *values)); + } } } @@ -645,13 +654,6 @@ impl Builder<'_> { if stage == 0 { hostflags.arg("--cfg=bootstrap"); } - // Cargo doesn't pass RUSTFLAGS to proc_macros: - // https://github.com/rust-lang/cargo/issues/4423 - // Thus, if we are on stage 0, we explicitly set `--cfg=bootstrap`. - // We also declare that the flag is expected, which we need to do to not - // get warnings about it being unexpected. - hostflags.arg("-Zunstable-options"); - hostflags.arg("--check-cfg=cfg(bootstrap)"); // FIXME: It might be better to use the same value for both `RUSTFLAGS` and `RUSTDOCFLAGS`, // but this breaks CI. At the very least, stage0 `rustdoc` needs `--cfg bootstrap`. See @@ -920,13 +922,46 @@ impl Builder<'_> { hostflags.arg(format!("-Ctarget-feature={sign}crt-static")); } - if let Some(map_to) = self.build.debuginfo_map_to(GitRepo::Rustc) { - let map = format!("{}={}", self.build.src.display(), map_to); - cargo.env("RUSTC_DEBUGINFO_MAP", map); + // `rustc` needs to know the remapping scheme, in order to know how to reverse it (unremap) + // later. Two env vars are set and made available to the compiler + // + // - `CFG_VIRTUAL_RUST_SOURCE_BASE_DIR`: `rust-src` remap scheme (`NonCompiler`) + // - `CFG_VIRTUAL_RUSTC_DEV_SOURCE_BASE_DIR`: `rustc-dev` remap scheme (`Compiler`) + // + // Keep this scheme in sync with `rustc_metadata::rmeta::decoder`'s + // `try_to_translate_virtual_to_real`. + // + // `RUSTC_DEBUGINFO_MAP` is used to pass through to the underlying rustc + // `--remap-path-prefix`. + match mode { + Mode::Rustc | Mode::Codegen => { + if let Some(ref map_to) = + self.build.debuginfo_map_to(GitRepo::Rustc, RemapScheme::NonCompiler) + { + cargo.env("CFG_VIRTUAL_RUST_SOURCE_BASE_DIR", map_to); + } - // `rustc` needs to know the virtual `/rustc/$hash` we're mapping to, - // in order to opportunistically reverse it later. - cargo.env("CFG_VIRTUAL_RUST_SOURCE_BASE_DIR", map_to); + if let Some(ref map_to) = + self.build.debuginfo_map_to(GitRepo::Rustc, RemapScheme::Compiler) + { + // When building compiler sources, we want to apply the compiler remap scheme. + cargo.env( + "RUSTC_DEBUGINFO_MAP", + format!("{}={}", self.build.src.display(), map_to), + ); + cargo.env("CFG_VIRTUAL_RUSTC_DEV_SOURCE_BASE_DIR", map_to); + } + } + Mode::Std | Mode::ToolBootstrap | Mode::ToolRustc | Mode::ToolStd => { + if let Some(ref map_to) = + self.build.debuginfo_map_to(GitRepo::Rustc, RemapScheme::NonCompiler) + { + cargo.env( + "RUSTC_DEBUGINFO_MAP", + format!("{}={}", self.build.src.display(), map_to), + ); + } + } } if self.config.rust_remap_debuginfo { diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index 07772b8932d9d..7db57889009e9 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -81,7 +81,10 @@ const LLD_FILE_NAMES: &[&str] = &["ld.lld", "ld64.lld", "lld-link", "wasm-ld"]; /// (Mode restriction, config name, config values (if any)) #[expect(clippy::type_complexity)] // It's fine for hard-coded list and type is explained above. const EXTRA_CHECK_CFGS: &[(Option, &str, Option<&[&'static str]>)] = &[ - (None, "bootstrap", None), + (Some(Mode::Rustc), "bootstrap", None), + (Some(Mode::Codegen), "bootstrap", None), + (Some(Mode::ToolRustc), "bootstrap", None), + (Some(Mode::ToolStd), "bootstrap", None), (Some(Mode::Rustc), "llvm_enzyme", None), (Some(Mode::Codegen), "llvm_enzyme", None), (Some(Mode::ToolRustc), "llvm_enzyme", None), @@ -272,6 +275,16 @@ impl Mode { } } +/// When `rust.rust_remap_debuginfo` is requested, the compiler needs to know how to +/// opportunistically unremap compiler vs non-compiler sources. We use two schemes, +/// [`RemapScheme::Compiler`] and [`RemapScheme::NonCompiler`]. +pub enum RemapScheme { + /// The [`RemapScheme::Compiler`] scheme will remap to `/rustc-dev/{hash}`. + Compiler, + /// The [`RemapScheme::NonCompiler`] scheme will remap to `/rustc/{hash}`. + NonCompiler, +} + #[derive(Debug, Hash, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] pub enum CLang { C, @@ -1217,7 +1230,7 @@ Executed at: {executed_at}"#, }) } - fn debuginfo_map_to(&self, which: GitRepo) -> Option { + fn debuginfo_map_to(&self, which: GitRepo, remap_scheme: RemapScheme) -> Option { if !self.config.rust_remap_debuginfo { return None; } @@ -1225,7 +1238,24 @@ Executed at: {executed_at}"#, match which { GitRepo::Rustc => { let sha = self.rust_sha().unwrap_or(&self.version); - Some(format!("/rustc/{sha}")) + + match remap_scheme { + RemapScheme::Compiler => { + // For compiler sources, remap via `/rustc-dev/{sha}` to allow + // distinguishing between compiler sources vs library sources, since + // `rustc-dev` dist component places them under + // `$sysroot/lib/rustlib/rustc-src/rust` as opposed to `rust-src`'s + // `$sysroot/lib/rustlib/src/rust`. + // + // Keep this scheme in sync with `rustc_metadata::rmeta::decoder`'s + // `try_to_translate_virtual_to_real`. + Some(format!("/rustc-dev/{sha}")) + } + RemapScheme::NonCompiler => { + // For non-compiler sources, use `/rustc/{sha}` remapping scheme. + Some(format!("/rustc/{sha}")) + } + } } GitRepo::Llvm => Some(String::from("/rustc/llvm")), } @@ -1292,7 +1322,7 @@ Executed at: {executed_at}"#, base.push("-fno-omit-frame-pointer".into()); } - if let Some(map_to) = self.debuginfo_map_to(which) { + if let Some(map_to) = self.debuginfo_map_to(which, RemapScheme::NonCompiler) { let map = format!("{}={}", self.src.display(), map_to); let cc = self.cc(target); if cc.ends_with("clang") || cc.ends_with("gcc") { diff --git a/src/ci/docker/scripts/rfl-build.sh b/src/ci/docker/scripts/rfl-build.sh index fa18f67583ff6..c59928913989c 100755 --- a/src/ci/docker/scripts/rfl-build.sh +++ b/src/ci/docker/scripts/rfl-build.sh @@ -2,8 +2,7 @@ set -euo pipefail -# https://github.com/Rust-for-Linux/linux/issues/1163 -LINUX_VERSION=3ca02fc80cc4fdac63aaa6796642f1e07be591d6 +LINUX_VERSION=v6.16-rc1 # Build rustc, rustdoc, cargo, clippy-driver and rustfmt ../x.py build --stage 2 library rustdoc clippy rustfmt diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml index 3f8ea696ee2ed..43c77d1ddf7f5 100644 --- a/src/ci/github-actions/jobs.yml +++ b/src/ci/github-actions/jobs.yml @@ -129,6 +129,10 @@ pr: - name: mingw-check-tidy continue_on_error: true free_disk: false + env: + # This submodule is expensive to checkout, and it should not be needed for + # tidy. This speeds up the PR CI job by ~1 minute. + SKIP_SUBMODULES: src/gcc <<: *job-linux-4c - name: x86_64-gnu-llvm-19 env: diff --git a/src/ci/scripts/checkout-submodules.sh b/src/ci/scripts/checkout-submodules.sh index 5bb343241aea6..3b646587dc28d 100755 --- a/src/ci/scripts/checkout-submodules.sh +++ b/src/ci/scripts/checkout-submodules.sh @@ -55,7 +55,11 @@ for i in ${!modules[@]}; do bg_pids[${i}]=$! continue else + # Submodule paths contained in SKIP_SUBMODULES (comma-separated list) will not be + # checked out. + if [ -z "${SKIP_SUBMODULES:-}" ] || [[ ! ",$SKIP_SUBMODULES," = *",$module,"* ]]; then use_git="$use_git $module" + fi fi done retry sh -c "git submodule deinit -f $use_git && \ diff --git a/tests/crashes/135863.rs b/tests/crashes/135863.rs deleted file mode 100644 index a0ff5988a0db2..0000000000000 --- a/tests/crashes/135863.rs +++ /dev/null @@ -1,10 +0,0 @@ -//@ known-bug: #135863 -struct A; - -impl A { - fn len(self: &&B) {} -} - -fn main() { - A.len() -} diff --git a/tests/ui/suggestions/double-reference-ty-in-self-ty.rs b/tests/ui/suggestions/double-reference-ty-in-self-ty.rs new file mode 100644 index 0000000000000..4ac13f0f635d9 --- /dev/null +++ b/tests/ui/suggestions/double-reference-ty-in-self-ty.rs @@ -0,0 +1,12 @@ +// issue#135863 + +struct A; + +impl A { + fn len(self: &&A) {} +} + +fn main() { + A.len(); + //~^ ERROR: no method named `len` found for struct `A` in the current scope +} diff --git a/tests/ui/suggestions/double-reference-ty-in-self-ty.stderr b/tests/ui/suggestions/double-reference-ty-in-self-ty.stderr new file mode 100644 index 0000000000000..a718234241093 --- /dev/null +++ b/tests/ui/suggestions/double-reference-ty-in-self-ty.stderr @@ -0,0 +1,19 @@ +error[E0599]: no method named `len` found for struct `A` in the current scope + --> $DIR/double-reference-ty-in-self-ty.rs:10:7 + | +LL | struct A; + | -------- method `len` not found for this struct +... +LL | fn len(self: &&A) {} + | --- the method is available for `&A` here +... +LL | A.len(); + | ^^^ method not found in `A` + | + = help: items from traits can only be used if the trait is implemented and in scope + = note: the following trait defines an item `len`, perhaps you need to implement it: + candidate #1: `ExactSizeIterator` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0599`.