Skip to content

Rollup of 5 pull requests #107456

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
9 changes: 9 additions & 0 deletions compiler/rustc_middle/src/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,15 @@ rustc_queries! {
separate_provide_extern
}

query unsizing_params_for_adt(key: DefId) -> rustc_index::bit_set::BitSet<u32>
{
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" }
Expand Down
35 changes: 16 additions & 19 deletions compiler/rustc_save_analysis/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -897,28 +897,25 @@ impl<'a> DumpHandler<'a> {

fn output_file(&self, ctx: &SaveContext<'_>) -> (BufWriter<File>, 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());

Expand Down
54 changes: 10 additions & 44 deletions compiler/rustc_trait_selection/src/traits/select/confirmation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -1064,51 +1063,18 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {

// `Struct<T>` -> `Struct<U>`
(&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<T>` and `TailField<U>` from `Struct<T>` and `Struct<U>`,
// normalizing in the process, since `type_of` returns something directly from
// astconv (which means it's un-normalized).
Expand Down
52 changes: 52 additions & 0 deletions compiler/rustc_ty_utils/src/ty.rs
Original file line number Diff line number Diff line change
@@ -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};
Expand Down Expand Up @@ -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<u32> {
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,
Expand All @@ -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
};
}
2 changes: 1 addition & 1 deletion library/alloc/src/rc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1092,7 +1092,7 @@ impl<T: ?Sized> Rc<T> {
/// # 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`.
Expand Down
2 changes: 1 addition & 1 deletion library/alloc/src/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1733,7 +1733,7 @@ impl<T: ?Sized> Arc<T> {
/// # 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`.
Expand Down
7 changes: 1 addition & 6 deletions library/std/src/os/fuchsia/raw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};

Expand Down
1 change: 0 additions & 1 deletion library/std/src/os/l4re/raw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
1 change: 0 additions & 1 deletion library/std/src/os/linux/raw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
48 changes: 31 additions & 17 deletions src/bootstrap/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -203,7 +203,6 @@ const EXTRA_CHECK_CFGS: &[(Option<Mode>, &'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),
Expand All @@ -214,18 +213,9 @@ const EXTRA_CHECK_CFGS: &[(Option<Mode>, &'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),
Expand All @@ -235,8 +225,12 @@ const EXTRA_CHECK_CFGS: &[(Option<Mode>, &'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.
Expand Down Expand Up @@ -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.
Expand Down
10 changes: 10 additions & 0 deletions src/tools/compiletest/src/runtest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) => {
Expand Down