diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 1f1f4fc95b59a..49ad887f26d66 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -183,6 +183,15 @@ rustc_queries! { separate_provide_extern } + query unsizing_params_for_adt(key: DefId) -> rustc_index::bit_set::BitSet + { + arena_cache + desc { |tcx| + "determining what parameters of `{}` can participate in unsizing", + tcx.def_path_str(key), + } + } + query analysis(key: ()) -> Result<(), ErrorGuaranteed> { eval_always desc { "running analysis passes on this crate" } diff --git a/compiler/rustc_save_analysis/src/lib.rs b/compiler/rustc_save_analysis/src/lib.rs index a9a92cc4f62ed..92fbfe24325d3 100644 --- a/compiler/rustc_save_analysis/src/lib.rs +++ b/compiler/rustc_save_analysis/src/lib.rs @@ -897,28 +897,25 @@ impl<'a> DumpHandler<'a> { fn output_file(&self, ctx: &SaveContext<'_>) -> (BufWriter, PathBuf) { let sess = &ctx.tcx.sess; - let file_name = match ctx.config.output_file { - Some(ref s) => PathBuf::from(s), + let mut root_path = match self.odir { + Some(val) => val.join("save-analysis"), None => { - let mut root_path = match self.odir { - Some(val) => val.join("save-analysis"), - None => PathBuf::from("save-analysis-temp"), - }; - - if let Err(e) = std::fs::create_dir_all(&root_path) { - error!("Could not create directory {}: {}", root_path.display(), e); - } - - let executable = sess.crate_types().iter().any(|ct| *ct == CrateType::Executable); - let mut out_name = if executable { String::new() } else { "lib".to_owned() }; - out_name.push_str(&self.cratename); - out_name.push_str(&sess.opts.cg.extra_filename); - out_name.push_str(".json"); - root_path.push(&out_name); - - root_path + PathBuf::from(ctx.config.output_file.as_ref().unwrap()).join("save-analysis-temp") } }; + if let Err(e) = std::fs::create_dir_all(&root_path) { + error!("Could not create directory {}: {}", root_path.display(), e); + } + let file_name = { + let executable = sess.crate_types().iter().any(|ct| *ct == CrateType::Executable); + let mut out_name = if executable { String::new() } else { "lib".to_owned() }; + out_name.push_str(&self.cratename); + out_name.push_str(&sess.opts.cg.extra_filename); + out_name.push_str(".json"); + root_path.push(&out_name); + + root_path + }; info!("Writing output to {}", file_name.display()); diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 9c84bfaad492b..89a8fdbac1cbc 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -8,12 +8,11 @@ //! https://rustc-dev-guide.rust-lang.org/traits/resolution.html#confirmation use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_hir::lang_items::LangItem; -use rustc_index::bit_set::GrowableBitSet; use rustc_infer::infer::InferOk; use rustc_infer::infer::LateBoundRegionConversionTime::HigherRankedType; use rustc_middle::ty::{ - self, Binder, GenericArg, GenericArgKind, GenericParamDefKind, InternalSubsts, SubstsRef, - ToPolyTraitRef, ToPredicate, TraitRef, Ty, TyCtxt, TypeVisitable, + self, Binder, GenericParamDefKind, InternalSubsts, SubstsRef, ToPolyTraitRef, ToPredicate, + TraitRef, Ty, TyCtxt, TypeVisitable, }; use rustc_session::config::TraitSolver; use rustc_span::def_id::DefId; @@ -1064,51 +1063,18 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // `Struct` -> `Struct` (&ty::Adt(def, substs_a), &ty::Adt(_, substs_b)) => { - let maybe_unsizing_param_idx = |arg: GenericArg<'tcx>| match arg.unpack() { - GenericArgKind::Type(ty) => match ty.kind() { - ty::Param(p) => Some(p.index), - _ => None, - }, - - // Lifetimes aren't allowed to change during unsizing. - GenericArgKind::Lifetime(_) => None, - - GenericArgKind::Const(ct) => match ct.kind() { - ty::ConstKind::Param(p) => Some(p.index), - _ => None, - }, - }; - - // FIXME(eddyb) cache this (including computing `unsizing_params`) - // by putting it in a query; it would only need the `DefId` as it - // looks at declared field types, not anything substituted. - - // The last field of the structure has to exist and contain type/const parameters. - let (tail_field, prefix_fields) = - def.non_enum_variant().fields.split_last().ok_or(Unimplemented)?; - let tail_field_ty = tcx.bound_type_of(tail_field.did); - - let mut unsizing_params = GrowableBitSet::new_empty(); - for arg in tail_field_ty.0.walk() { - if let Some(i) = maybe_unsizing_param_idx(arg) { - unsizing_params.insert(i); - } - } - - // Ensure none of the other fields mention the parameters used - // in unsizing. - for field in prefix_fields { - for arg in tcx.type_of(field.did).walk() { - if let Some(i) = maybe_unsizing_param_idx(arg) { - unsizing_params.remove(i); - } - } - } - + let unsizing_params = tcx.unsizing_params_for_adt(def.did()); if unsizing_params.is_empty() { return Err(Unimplemented); } + let tail_field = def + .non_enum_variant() + .fields + .last() + .expect("expected unsized ADT to have a tail field"); + let tail_field_ty = tcx.bound_type_of(tail_field.did); + // Extract `TailField` and `TailField` from `Struct` and `Struct`, // normalizing in the process, since `type_of` returns something directly from // astconv (which means it's un-normalized). diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index 89abffebdc684..b5005c1d8d804 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -1,5 +1,6 @@ use rustc_data_structures::fx::FxIndexSet; use rustc_hir as hir; +use rustc_index::bit_set::BitSet; use rustc_middle::ty::{self, Binder, Predicate, PredicateKind, ToPredicate, Ty, TyCtxt}; use rustc_session::config::TraitSolver; use rustc_span::def_id::{DefId, CRATE_DEF_ID}; @@ -406,6 +407,56 @@ fn asyncness(tcx: TyCtxt<'_>, def_id: DefId) -> hir::IsAsync { node.fn_sig().map_or(hir::IsAsync::NotAsync, |sig| sig.header.asyncness) } +fn unsizing_params_for_adt<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> BitSet { + let def = tcx.adt_def(def_id); + let num_params = tcx.generics_of(def_id).count(); + + let maybe_unsizing_param_idx = |arg: ty::GenericArg<'tcx>| match arg.unpack() { + ty::GenericArgKind::Type(ty) => match ty.kind() { + ty::Param(p) => Some(p.index), + _ => None, + }, + + // We can't unsize a lifetime + ty::GenericArgKind::Lifetime(_) => None, + + ty::GenericArgKind::Const(ct) => match ct.kind() { + ty::ConstKind::Param(p) => Some(p.index), + _ => None, + }, + }; + + // FIXME(eddyb) cache this (including computing `unsizing_params`) + // by putting it in a query; it would only need the `DefId` as it + // looks at declared field types, not anything substituted. + + // The last field of the structure has to exist and contain type/const parameters. + let Some((tail_field, prefix_fields)) = + def.non_enum_variant().fields.split_last() else + { + return BitSet::new_empty(num_params); + }; + + let mut unsizing_params = BitSet::new_empty(num_params); + for arg in tcx.bound_type_of(tail_field.did).subst_identity().walk() { + if let Some(i) = maybe_unsizing_param_idx(arg) { + unsizing_params.insert(i); + } + } + + // Ensure none of the other fields mention the parameters used + // in unsizing. + for field in prefix_fields { + for arg in tcx.bound_type_of(field.did).subst_identity().walk() { + if let Some(i) = maybe_unsizing_param_idx(arg) { + unsizing_params.remove(i); + } + } + } + + unsizing_params +} + pub fn provide(providers: &mut ty::query::Providers) { *providers = ty::query::Providers { asyncness, @@ -415,6 +466,7 @@ pub fn provide(providers: &mut ty::query::Providers) { instance_def_size_estimate, issue33140_self_ty, impl_defaultness, + unsizing_params_for_adt, ..*providers }; } diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index c9aa23fc4af1f..fd1e3e0f75b09 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -1092,7 +1092,7 @@ impl Rc { /// # Safety /// /// If any other `Rc` or [`Weak`] pointers to the same allocation exist, then - /// they must be must not be dereferenced or have active borrows for the duration + /// they must not be dereferenced or have active borrows for the duration /// of the returned borrow, and their inner type must be exactly the same as the /// inner type of this Rc (including lifetimes). This is trivially the case if no /// such pointers exist, for example immediately after `Rc::new`. diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index 9bc9182f7b53c..f20486ca9e4db 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -1733,7 +1733,7 @@ impl Arc { /// # Safety /// /// If any other `Arc` or [`Weak`] pointers to the same allocation exist, then - /// they must be must not be dereferenced or have active borrows for the duration + /// they must not be dereferenced or have active borrows for the duration /// of the returned borrow, and their inner type must be exactly the same as the /// inner type of this Rc (including lifetimes). This is trivially the case if no /// such pointers exist, for example immediately after `Arc::new`. diff --git a/library/std/src/os/fuchsia/raw.rs b/library/std/src/os/fuchsia/raw.rs index 060d6e86b6c2b..ea6b94f2f13c4 100644 --- a/library/std/src/os/fuchsia/raw.rs +++ b/library/std/src/os/fuchsia/raw.rs @@ -24,12 +24,7 @@ pub type pthread_t = c_ulong; #[stable(feature = "raw_ext", since = "1.1.0")] pub use self::arch::{blkcnt_t, blksize_t, ino_t, nlink_t, off_t, stat, time_t}; -#[cfg(any( - target_arch = "x86", - target_arch = "le32", - target_arch = "powerpc", - target_arch = "arm" -))] +#[cfg(any(target_arch = "x86", target_arch = "powerpc", target_arch = "arm"))] mod arch { use crate::os::raw::{c_long, c_short, c_uint}; diff --git a/library/std/src/os/l4re/raw.rs b/library/std/src/os/l4re/raw.rs index 699e8be33c8a8..b3f7439f8cdc0 100644 --- a/library/std/src/os/l4re/raw.rs +++ b/library/std/src/os/l4re/raw.rs @@ -26,7 +26,6 @@ pub use self::arch::{blkcnt_t, blksize_t, ino_t, nlink_t, off_t, stat, time_t}; #[cfg(any( target_arch = "x86", - target_arch = "le32", target_arch = "m68k", target_arch = "powerpc", target_arch = "sparc", diff --git a/library/std/src/os/linux/raw.rs b/library/std/src/os/linux/raw.rs index c73791d14529c..f46028c3a96c9 100644 --- a/library/std/src/os/linux/raw.rs +++ b/library/std/src/os/linux/raw.rs @@ -26,7 +26,6 @@ pub use self::arch::{blkcnt_t, blksize_t, ino_t, nlink_t, off_t, stat, time_t}; #[cfg(any( target_arch = "x86", - target_arch = "le32", target_arch = "m68k", target_arch = "powerpc", target_arch = "sparc", diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index 3b9dba4109d3e..267aa3278d8ff 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -110,7 +110,7 @@ use std::fs::{self, File}; use std::io; use std::io::ErrorKind; use std::path::{Path, PathBuf}; -use std::process::Command; +use std::process::{Command, Stdio}; use std::str; use build_helper::ci::CiEnv; @@ -203,7 +203,6 @@ const EXTRA_CHECK_CFGS: &[(Option, &'static str, Option<&[&'static str]>)] (None, "bootstrap", None), (Some(Mode::Rustc), "parallel_compiler", None), (Some(Mode::ToolRustc), "parallel_compiler", None), - (Some(Mode::ToolRustc), "emulate_second_only_system", None), (Some(Mode::Codegen), "parallel_compiler", None), (Some(Mode::Std), "stdarch_intel_sde", None), (Some(Mode::Std), "no_fp_fmt_parse", None), @@ -214,18 +213,9 @@ const EXTRA_CHECK_CFGS: &[(Option, &'static str, Option<&[&'static str]>)] (Some(Mode::Std), "backtrace_in_libstd", None), /* Extra values not defined in the built-in targets yet, but used in std */ (Some(Mode::Std), "target_env", Some(&["libnx"])), - (Some(Mode::Std), "target_os", Some(&["watchos"])), - ( - Some(Mode::Std), - "target_arch", - Some(&["asmjs", "spirv", "nvptx", "nvptx64", "le32", "xtensa"]), - ), + // (Some(Mode::Std), "target_os", Some(&[])), + (Some(Mode::Std), "target_arch", Some(&["asmjs", "spirv", "nvptx", "xtensa"])), /* Extra names used by dependencies */ - // FIXME: Used by rustfmt is their test but is invalid (neither cargo nor bootstrap ever set - // this config) should probably by removed or use a allow attribute. - (Some(Mode::ToolRustc), "release", None), - // FIXME: Used by stdarch in their test, should use a allow attribute instead. - (Some(Mode::Std), "dont_compile_me", None), // FIXME: Used by serde_json, but we should not be triggering on external dependencies. (Some(Mode::Rustc), "no_btreemap_remove_entry", None), (Some(Mode::ToolRustc), "no_btreemap_remove_entry", None), @@ -235,8 +225,12 @@ const EXTRA_CHECK_CFGS: &[(Option, &'static str, Option<&[&'static str]>)] // FIXME: Used by proc-macro2, but we should not be triggering on external dependencies. (Some(Mode::Rustc), "span_locations", None), (Some(Mode::ToolRustc), "span_locations", None), - // Can be passed in RUSTFLAGS to prevent direct syscalls in rustix. - (None, "rustix_use_libc", None), + // FIXME: Used by rustix, but we should not be triggering on external dependencies. + (Some(Mode::Rustc), "rustix_use_libc", None), + (Some(Mode::ToolRustc), "rustix_use_libc", None), + // FIXME: Used by filetime, but we should not be triggering on external dependencies. + (Some(Mode::Rustc), "emulate_second_only_system", None), + (Some(Mode::ToolRustc), "emulate_second_only_system", None), ]; /// A structure representing a Rust compiler. @@ -662,12 +656,32 @@ impl Build { // Try passing `--progress` to start, then run git again without if that fails. let update = |progress: bool| { - let mut git = Command::new("git"); + // Git is buggy and will try to fetch submodules from the tracking branch for *this* repository, + // even though that has no relation to the upstream for the submodule. + let current_branch = { + let output = self + .config + .git() + .args(["symbolic-ref", "--short", "HEAD"]) + .stderr(Stdio::inherit()) + .output(); + let output = t!(output); + if output.status.success() { + Some(String::from_utf8(output.stdout).unwrap().trim().to_owned()) + } else { + None + } + }; + + let mut git = self.config.git(); + if let Some(branch) = current_branch { + git.arg("-c").arg(format!("branch.{branch}.remote=origin")); + } git.args(&["submodule", "update", "--init", "--recursive", "--depth=1"]); if progress { git.arg("--progress"); } - git.arg(relative_path).current_dir(&self.config.src); + git.arg(relative_path); git }; // NOTE: doesn't use `try_run` because this shouldn't print an error if it fails. diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 51c9a27c83d51..514c818df315b 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -2011,6 +2011,16 @@ impl<'test> TestCx<'test> { match output_file { TargetLocation::ThisFile(path) => { + // The idea here is to use the env variable to pass the build_base directory to rustc_save_analysis to be used in cases where there is no output directory + env::set_var( + "RUST_SAVE_ANALYSIS_CONFIG", + format!( + "{{\"output_file\": \"{base}\",\"full_docs\": false,\ + \"pub_only\": true,\"reachable_only\": false,\ + \"distro_crate\": true,\"signatures\": false,\"borrow_data\": false}}", + base = self.config.build_base.display(), + ), + ); rustc.arg("-o").arg(path); } TargetLocation::ThisDirectory(path) => {