mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 23:04:33 +00:00
Auto merge of #114368 - Nilstrieb:rollup-pgvm9cf, r=Nilstrieb
Rollup of 5 pull requests Successful merges: - #114079 (Use `upvar_tys` in more places, make it return a list) - #114166 (Add regression test for resolving `--extern libc=test.rlib`) - #114321 (get auto traits for parallel rustc) - #114335 (fix and extend ptr_comparison test) - #114347 (x.py print more detailed format files and untracked files count) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
7637653b9f
@ -67,12 +67,6 @@ pub struct FormatArguments {
|
||||
names: FxHashMap<Symbol, usize>,
|
||||
}
|
||||
|
||||
// FIXME: Rustdoc has trouble proving Send/Sync for this. See #106930.
|
||||
#[cfg(parallel_compiler)]
|
||||
unsafe impl Sync for FormatArguments {}
|
||||
#[cfg(parallel_compiler)]
|
||||
unsafe impl Send for FormatArguments {}
|
||||
|
||||
impl FormatArguments {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
|
@ -886,6 +886,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
|
||||
.universal_regions()
|
||||
.defining_ty
|
||||
.upvar_tys()
|
||||
.iter()
|
||||
.position(|ty| self.any_param_predicate_mentions(&predicates, ty, region))
|
||||
{
|
||||
let (upvar_name, upvar_span) = self.regioncx.get_upvar_name_and_span_for_region(
|
||||
|
@ -43,7 +43,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||
fr: RegionVid,
|
||||
) -> Option<usize> {
|
||||
let upvar_index =
|
||||
self.universal_regions().defining_ty.upvar_tys().position(|upvar_ty| {
|
||||
self.universal_regions().defining_ty.upvar_tys().iter().position(|upvar_ty| {
|
||||
debug!("get_upvar_index_for_region: upvar_ty={upvar_ty:?}");
|
||||
tcx.any_free_region_meets(&upvar_ty, |r| {
|
||||
let r = r.as_var();
|
||||
@ -52,7 +52,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||
})
|
||||
})?;
|
||||
|
||||
let upvar_ty = self.universal_regions().defining_ty.upvar_tys().nth(upvar_index);
|
||||
let upvar_ty = self.universal_regions().defining_ty.upvar_tys().get(upvar_index);
|
||||
|
||||
debug!(
|
||||
"get_upvar_index_for_region: found {fr:?} in upvar {upvar_index} which has type {upvar_ty:?}",
|
||||
|
@ -791,25 +791,20 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
|
||||
(adt_def.variant(FIRST_VARIANT), args)
|
||||
}
|
||||
ty::Closure(_, args) => {
|
||||
return match args
|
||||
.as_closure()
|
||||
.tupled_upvars_ty()
|
||||
.tuple_fields()
|
||||
.get(field.index())
|
||||
{
|
||||
return match args.as_closure().upvar_tys().get(field.index()) {
|
||||
Some(&ty) => Ok(ty),
|
||||
None => Err(FieldAccessError::OutOfRange {
|
||||
field_count: args.as_closure().upvar_tys().count(),
|
||||
field_count: args.as_closure().upvar_tys().len(),
|
||||
}),
|
||||
};
|
||||
}
|
||||
ty::Generator(_, args, _) => {
|
||||
// Only prefix fields (upvars and current state) are
|
||||
// accessible without a variant index.
|
||||
return match args.as_generator().prefix_tys().nth(field.index()) {
|
||||
Some(ty) => Ok(ty),
|
||||
return match args.as_generator().prefix_tys().get(field.index()) {
|
||||
Some(ty) => Ok(*ty),
|
||||
None => Err(FieldAccessError::OutOfRange {
|
||||
field_count: args.as_generator().prefix_tys().count(),
|
||||
field_count: args.as_generator().prefix_tys().len(),
|
||||
}),
|
||||
};
|
||||
}
|
||||
@ -1772,10 +1767,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
AggregateKind::Closure(_, args) => {
|
||||
match args.as_closure().upvar_tys().nth(field_index.as_usize()) {
|
||||
Some(ty) => Ok(ty),
|
||||
match args.as_closure().upvar_tys().get(field_index.as_usize()) {
|
||||
Some(ty) => Ok(*ty),
|
||||
None => Err(FieldAccessError::OutOfRange {
|
||||
field_count: args.as_closure().upvar_tys().count(),
|
||||
field_count: args.as_closure().upvar_tys().len(),
|
||||
}),
|
||||
}
|
||||
}
|
||||
@ -1783,10 +1778,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
// It doesn't make sense to look at a field beyond the prefix;
|
||||
// these require a variant index, and are not initialized in
|
||||
// aggregate rvalues.
|
||||
match args.as_generator().prefix_tys().nth(field_index.as_usize()) {
|
||||
Some(ty) => Ok(ty),
|
||||
match args.as_generator().prefix_tys().get(field_index.as_usize()) {
|
||||
Some(ty) => Ok(*ty),
|
||||
None => Err(FieldAccessError::OutOfRange {
|
||||
field_count: args.as_generator().prefix_tys().count(),
|
||||
field_count: args.as_generator().prefix_tys().len(),
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
@ -12,7 +12,6 @@
|
||||
//! The code in this file doesn't *do anything* with those results; it
|
||||
//! just returns them for other code to use.
|
||||
|
||||
use either::Either;
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_errors::Diagnostic;
|
||||
use rustc_hir as hir;
|
||||
@ -115,14 +114,12 @@ impl<'tcx> DefiningTy<'tcx> {
|
||||
/// not a closure or generator, there are no upvars, and hence it
|
||||
/// will be an empty list. The order of types in this list will
|
||||
/// match up with the upvar order in the HIR, typesystem, and MIR.
|
||||
pub fn upvar_tys(self) -> impl Iterator<Item = Ty<'tcx>> + 'tcx {
|
||||
pub fn upvar_tys(self) -> &'tcx ty::List<Ty<'tcx>> {
|
||||
match self {
|
||||
DefiningTy::Closure(_, args) => Either::Left(args.as_closure().upvar_tys()),
|
||||
DefiningTy::Generator(_, args, _) => {
|
||||
Either::Right(Either::Left(args.as_generator().upvar_tys()))
|
||||
}
|
||||
DefiningTy::Closure(_, args) => args.as_closure().upvar_tys(),
|
||||
DefiningTy::Generator(_, args, _) => args.as_generator().upvar_tys(),
|
||||
DefiningTy::FnDef(..) | DefiningTy::Const(..) | DefiningTy::InlineConst(..) => {
|
||||
Either::Right(Either::Right(iter::empty()))
|
||||
ty::List::empty()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -990,14 +990,8 @@ fn build_upvar_field_di_nodes<'ll, 'tcx>(
|
||||
closure_or_generator_di_node: &'ll DIType,
|
||||
) -> SmallVec<&'ll DIType> {
|
||||
let (&def_id, up_var_tys) = match closure_or_generator_ty.kind() {
|
||||
ty::Generator(def_id, args, _) => {
|
||||
let upvar_tys: SmallVec<_> = args.as_generator().prefix_tys().collect();
|
||||
(def_id, upvar_tys)
|
||||
}
|
||||
ty::Closure(def_id, args) => {
|
||||
let upvar_tys: SmallVec<_> = args.as_closure().upvar_tys().collect();
|
||||
(def_id, upvar_tys)
|
||||
}
|
||||
ty::Generator(def_id, args, _) => (def_id, args.as_generator().prefix_tys()),
|
||||
ty::Closure(def_id, args) => (def_id, args.as_closure().upvar_tys()),
|
||||
_ => {
|
||||
bug!(
|
||||
"build_upvar_field_di_nodes() called with non-closure-or-generator-type: {:?}",
|
||||
@ -1007,9 +1001,7 @@ fn build_upvar_field_di_nodes<'ll, 'tcx>(
|
||||
};
|
||||
|
||||
debug_assert!(
|
||||
up_var_tys
|
||||
.iter()
|
||||
.all(|&t| t == cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), t))
|
||||
up_var_tys.iter().all(|t| t == cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), t))
|
||||
);
|
||||
|
||||
let capture_names = cx.tcx.closure_saved_names_of_captured_variables(def_id);
|
||||
|
@ -379,6 +379,7 @@ pub fn build_generator_variant_struct_type_di_node<'ll, 'tcx>(
|
||||
// Fields that are common to all states
|
||||
let common_fields: SmallVec<_> = generator_args
|
||||
.prefix_tys()
|
||||
.iter()
|
||||
.zip(common_upvar_names)
|
||||
.enumerate()
|
||||
.map(|(index, (upvar_ty, upvar_name))| {
|
||||
|
@ -630,7 +630,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
||||
}
|
||||
ty::Closure(_, args) => {
|
||||
let args = args.as_closure();
|
||||
let Some(f_ty) = args.upvar_tys().nth(f.as_usize()) else {
|
||||
let Some(&f_ty) = args.upvar_tys().get(f.as_usize()) else {
|
||||
fail_out_of_bounds(self, location);
|
||||
return;
|
||||
};
|
||||
@ -667,7 +667,8 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
||||
|
||||
f_ty.ty
|
||||
} else {
|
||||
let Some(f_ty) = args.as_generator().prefix_tys().nth(f.index()) else {
|
||||
let Some(&f_ty) = args.as_generator().prefix_tys().get(f.index())
|
||||
else {
|
||||
fail_out_of_bounds(self, location);
|
||||
return;
|
||||
};
|
||||
|
@ -448,7 +448,9 @@ where
|
||||
ty::Closure(_, ref args) => {
|
||||
// Skip lifetime parameters of the enclosing item(s)
|
||||
|
||||
args.as_closure().tupled_upvars_ty().visit_with(self);
|
||||
for upvar in args.as_closure().upvar_tys() {
|
||||
upvar.visit_with(self);
|
||||
}
|
||||
args.as_closure().sig_as_fn_ptr_ty().visit_with(self);
|
||||
}
|
||||
|
||||
@ -456,7 +458,9 @@ where
|
||||
// Skip lifetime parameters of the enclosing item(s)
|
||||
// Also skip the witness type, because that has no free regions.
|
||||
|
||||
args.as_generator().tupled_upvars_ty().visit_with(self);
|
||||
for upvar in args.as_generator().upvar_tys() {
|
||||
upvar.visit_with(self);
|
||||
}
|
||||
args.as_generator().return_ty().visit_with(self);
|
||||
args.as_generator().yield_ty().visit_with(self);
|
||||
args.as_generator().resume_ty().visit_with(self);
|
||||
|
@ -911,7 +911,7 @@ where
|
||||
if i == tag_field {
|
||||
return TyMaybeWithLayout::TyAndLayout(tag_layout(tag));
|
||||
}
|
||||
TyMaybeWithLayout::Ty(args.as_generator().prefix_tys().nth(i).unwrap())
|
||||
TyMaybeWithLayout::Ty(args.as_generator().prefix_tys()[i])
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -827,7 +827,7 @@ pub trait PrettyPrinter<'tcx>:
|
||||
if !args.as_generator().is_valid() {
|
||||
p!("unavailable");
|
||||
} else {
|
||||
self = self.comma_sep(args.as_generator().upvar_tys())?;
|
||||
self = self.comma_sep(args.as_generator().upvar_tys().iter())?;
|
||||
}
|
||||
p!(")");
|
||||
|
||||
@ -900,7 +900,7 @@ pub trait PrettyPrinter<'tcx>:
|
||||
print(args.as_closure().sig_as_fn_ptr_ty())
|
||||
);
|
||||
p!(" upvar_tys=(");
|
||||
self = self.comma_sep(args.as_closure().upvar_tys())?;
|
||||
self = self.comma_sep(args.as_closure().upvar_tys().iter())?;
|
||||
p!(")");
|
||||
}
|
||||
}
|
||||
|
@ -296,15 +296,13 @@ impl<'tcx> ClosureArgs<'tcx> {
|
||||
/// In case there was a type error in figuring out the types of the captured path, an
|
||||
/// empty iterator is returned.
|
||||
#[inline]
|
||||
pub fn upvar_tys(self) -> impl Iterator<Item = Ty<'tcx>> + 'tcx {
|
||||
pub fn upvar_tys(self) -> &'tcx List<Ty<'tcx>> {
|
||||
match self.tupled_upvars_ty().kind() {
|
||||
TyKind::Error(_) => None,
|
||||
TyKind::Tuple(..) => Some(self.tupled_upvars_ty().tuple_fields()),
|
||||
TyKind::Error(_) => ty::List::empty(),
|
||||
TyKind::Tuple(..) => self.tupled_upvars_ty().tuple_fields(),
|
||||
TyKind::Infer(_) => bug!("upvar_tys called before capture types are inferred"),
|
||||
ty => bug!("Unexpected representation of upvar types tuple {:?}", ty),
|
||||
}
|
||||
.into_iter()
|
||||
.flatten()
|
||||
}
|
||||
|
||||
/// Returns the tuple type representing the upvars for this closure.
|
||||
@ -436,15 +434,13 @@ impl<'tcx> GeneratorArgs<'tcx> {
|
||||
/// In case there was a type error in figuring out the types of the captured path, an
|
||||
/// empty iterator is returned.
|
||||
#[inline]
|
||||
pub fn upvar_tys(self) -> impl Iterator<Item = Ty<'tcx>> + 'tcx {
|
||||
pub fn upvar_tys(self) -> &'tcx List<Ty<'tcx>> {
|
||||
match self.tupled_upvars_ty().kind() {
|
||||
TyKind::Error(_) => None,
|
||||
TyKind::Tuple(..) => Some(self.tupled_upvars_ty().tuple_fields()),
|
||||
TyKind::Error(_) => ty::List::empty(),
|
||||
TyKind::Tuple(..) => self.tupled_upvars_ty().tuple_fields(),
|
||||
TyKind::Infer(_) => bug!("upvar_tys called before capture types are inferred"),
|
||||
ty => bug!("Unexpected representation of upvar types tuple {:?}", ty),
|
||||
}
|
||||
.into_iter()
|
||||
.flatten()
|
||||
}
|
||||
|
||||
/// Returns the tuple type representing the upvars for this generator.
|
||||
@ -576,7 +572,7 @@ impl<'tcx> GeneratorArgs<'tcx> {
|
||||
/// This is the types of the fields of a generator which are not stored in a
|
||||
/// variant.
|
||||
#[inline]
|
||||
pub fn prefix_tys(self) -> impl Iterator<Item = Ty<'tcx>> {
|
||||
pub fn prefix_tys(self) -> &'tcx List<Ty<'tcx>> {
|
||||
self.upvar_tys()
|
||||
}
|
||||
}
|
||||
@ -592,20 +588,18 @@ impl<'tcx> UpvarArgs<'tcx> {
|
||||
/// In case there was a type error in figuring out the types of the captured path, an
|
||||
/// empty iterator is returned.
|
||||
#[inline]
|
||||
pub fn upvar_tys(self) -> impl Iterator<Item = Ty<'tcx>> + 'tcx {
|
||||
pub fn upvar_tys(self) -> &'tcx List<Ty<'tcx>> {
|
||||
let tupled_tys = match self {
|
||||
UpvarArgs::Closure(args) => args.as_closure().tupled_upvars_ty(),
|
||||
UpvarArgs::Generator(args) => args.as_generator().tupled_upvars_ty(),
|
||||
};
|
||||
|
||||
match tupled_tys.kind() {
|
||||
TyKind::Error(_) => None,
|
||||
TyKind::Tuple(..) => Some(self.tupled_upvars_ty().tuple_fields()),
|
||||
TyKind::Error(_) => ty::List::empty(),
|
||||
TyKind::Tuple(..) => self.tupled_upvars_ty().tuple_fields(),
|
||||
TyKind::Infer(_) => bug!("upvar_tys called before capture types are inferred"),
|
||||
ty => bug!("Unexpected representation of upvar types tuple {:?}", ty),
|
||||
}
|
||||
.into_iter()
|
||||
.flatten()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -860,20 +860,14 @@ where
|
||||
fn open_drop(&mut self) -> BasicBlock {
|
||||
let ty = self.place_ty(self.place);
|
||||
match ty.kind() {
|
||||
ty::Closure(_, args) => {
|
||||
let tys: Vec<_> = args.as_closure().upvar_tys().collect();
|
||||
self.open_drop_for_tuple(&tys)
|
||||
}
|
||||
ty::Closure(_, args) => self.open_drop_for_tuple(&args.as_closure().upvar_tys()),
|
||||
// Note that `elaborate_drops` only drops the upvars of a generator,
|
||||
// and this is ok because `open_drop` here can only be reached
|
||||
// within that own generator's resume function.
|
||||
// This should only happen for the self argument on the resume function.
|
||||
// It effectively only contains upvars until the generator transformation runs.
|
||||
// See librustc_body/transform/generator.rs for more details.
|
||||
ty::Generator(_, args, _) => {
|
||||
let tys: Vec<_> = args.as_generator().upvar_tys().collect();
|
||||
self.open_drop_for_tuple(&tys)
|
||||
}
|
||||
ty::Generator(_, args, _) => self.open_drop_for_tuple(&args.as_generator().upvar_tys()),
|
||||
ty::Tuple(fields) => self.open_drop_for_tuple(fields),
|
||||
ty::Adt(def, args) => self.open_drop_for_adt(*def, args),
|
||||
ty::Dynamic(..) => self.complete_drop(self.succ, self.unwind),
|
||||
|
@ -856,7 +856,7 @@ fn sanitize_witness<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
witness: Ty<'tcx>,
|
||||
upvars: Vec<Ty<'tcx>>,
|
||||
upvars: &'tcx ty::List<Ty<'tcx>>,
|
||||
layout: &GeneratorLayout<'tcx>,
|
||||
) {
|
||||
let did = body.source.def_id();
|
||||
@ -1471,7 +1471,7 @@ impl<'tcx> MirPass<'tcx> for StateTransform {
|
||||
let args = args.as_generator();
|
||||
(
|
||||
args.discr_ty(tcx),
|
||||
args.upvar_tys().collect::<Vec<_>>(),
|
||||
args.upvar_tys(),
|
||||
args.witness(),
|
||||
movability == hir::Movability::Movable,
|
||||
)
|
||||
|
@ -291,9 +291,9 @@ pub fn dtorck_constraint_for_ty_inner<'tcx>(
|
||||
return Err(NoSolution);
|
||||
}
|
||||
|
||||
constraints.outlives.extend(
|
||||
args.as_generator().upvar_tys().map(|t| -> ty::GenericArg<'tcx> { t.into() }),
|
||||
);
|
||||
constraints
|
||||
.outlives
|
||||
.extend(args.as_generator().upvar_tys().iter().map(ty::GenericArg::from));
|
||||
constraints.outlives.push(args.as_generator().resume_ty().into());
|
||||
}
|
||||
|
||||
|
@ -2169,7 +2169,8 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
|
||||
let all = args
|
||||
.as_generator()
|
||||
.upvar_tys()
|
||||
.chain(iter::once(args.as_generator().witness()))
|
||||
.iter()
|
||||
.chain([args.as_generator().witness()])
|
||||
.collect::<Vec<_>>();
|
||||
Where(obligation.predicate.rebind(all))
|
||||
}
|
||||
@ -2210,7 +2211,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
|
||||
// Not yet resolved.
|
||||
Ambiguous
|
||||
} else {
|
||||
Where(obligation.predicate.rebind(args.as_closure().upvar_tys().collect()))
|
||||
Where(obligation.predicate.rebind(args.as_closure().upvar_tys().to_vec()))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -317,7 +317,9 @@ fn layout_of_uncached<'tcx>(
|
||||
ty::Closure(_, ref args) => {
|
||||
let tys = args.as_closure().upvar_tys();
|
||||
univariant(
|
||||
&tys.map(|ty| Ok(cx.layout_of(ty)?.layout)).try_collect::<IndexVec<_, _>>()?,
|
||||
&tys.iter()
|
||||
.map(|ty| Ok(cx.layout_of(ty)?.layout))
|
||||
.try_collect::<IndexVec<_, _>>()?,
|
||||
&ReprOptions::default(),
|
||||
StructKind::AlwaysSized,
|
||||
)?
|
||||
@ -729,7 +731,7 @@ fn generator_layout<'tcx>(
|
||||
// Build a prefix layout, including "promoting" all ineligible
|
||||
// locals as part of the prefix. We compute the layout of all of
|
||||
// these fields at once to get optimal packing.
|
||||
let tag_index = args.as_generator().prefix_tys().count();
|
||||
let tag_index = args.as_generator().prefix_tys().len();
|
||||
|
||||
// `info.variant_fields` already accounts for the reserved variants, so no need to add them.
|
||||
let max_discr = (info.variant_fields.len() - 1) as u128;
|
||||
@ -748,6 +750,7 @@ fn generator_layout<'tcx>(
|
||||
let prefix_layouts = args
|
||||
.as_generator()
|
||||
.prefix_tys()
|
||||
.iter()
|
||||
.map(|ty| Ok(cx.layout_of(ty)?.layout))
|
||||
.chain(iter::once(Ok(tag_layout)))
|
||||
.chain(promoted_layouts)
|
||||
@ -1062,6 +1065,7 @@ fn variant_info_for_generator<'tcx>(
|
||||
let upvar_fields: Vec<_> = args
|
||||
.as_generator()
|
||||
.upvar_tys()
|
||||
.iter()
|
||||
.zip(upvar_names)
|
||||
.enumerate()
|
||||
.map(|(field_idx, (_, name))| {
|
||||
|
@ -120,12 +120,16 @@ where
|
||||
_ if component.is_copy_modulo_regions(tcx, self.param_env) => (),
|
||||
|
||||
ty::Closure(_, args) => {
|
||||
queue_type(self, args.as_closure().tupled_upvars_ty());
|
||||
for upvar in args.as_closure().upvar_tys() {
|
||||
queue_type(self, upvar);
|
||||
}
|
||||
}
|
||||
|
||||
ty::Generator(def_id, args, _) => {
|
||||
let args = args.as_generator();
|
||||
queue_type(self, args.tupled_upvars_ty());
|
||||
for upvar in args.upvar_tys() {
|
||||
queue_type(self, upvar);
|
||||
}
|
||||
|
||||
let witness = args.witness();
|
||||
let interior_tys = match witness.kind() {
|
||||
|
@ -113,9 +113,9 @@ pub fn format(build: &Builder<'_>, check: bool, paths: &[PathBuf]) {
|
||||
}
|
||||
let rustfmt_config = t!(std::fs::read_to_string(&rustfmt_config));
|
||||
let rustfmt_config: RustfmtConfig = t!(toml::from_str(&rustfmt_config));
|
||||
let mut ignore_fmt = ignore::overrides::OverrideBuilder::new(&build.src);
|
||||
let mut fmt_override = ignore::overrides::OverrideBuilder::new(&build.src);
|
||||
for ignore in rustfmt_config.ignore {
|
||||
ignore_fmt.add(&format!("!{ignore}")).expect(&ignore);
|
||||
fmt_override.add(&format!("!{ignore}")).expect(&ignore);
|
||||
}
|
||||
let git_available = match Command::new("git")
|
||||
.arg("--version")
|
||||
@ -152,6 +152,7 @@ pub fn format(build: &Builder<'_>, check: bool, paths: &[PathBuf]) {
|
||||
.map(|entry| {
|
||||
entry.split(' ').nth(1).expect("every git status entry should list a path")
|
||||
});
|
||||
let mut untracked_count = 0;
|
||||
for untracked_path in untracked_paths {
|
||||
println!("skip untracked path {untracked_path} during rustfmt invocations");
|
||||
// The leading `/` makes it an exact match against the
|
||||
@ -159,7 +160,8 @@ pub fn format(build: &Builder<'_>, check: bool, paths: &[PathBuf]) {
|
||||
// have `foo.rs` in the repository root it will also match
|
||||
// against anything like `compiler/rustc_foo/src/foo.rs`,
|
||||
// preventing the latter from being formatted.
|
||||
ignore_fmt.add(&format!("!/{untracked_path}")).expect(&untracked_path);
|
||||
untracked_count += 1;
|
||||
fmt_override.add(&format!("!/{untracked_path}")).expect(&untracked_path);
|
||||
}
|
||||
// Only check modified files locally to speed up runtime.
|
||||
// We still check all files in CI to avoid bugs in `get_modified_rs_files` letting regressions slip through;
|
||||
@ -172,10 +174,25 @@ pub fn format(build: &Builder<'_>, check: bool, paths: &[PathBuf]) {
|
||||
println!("formatting modified file {file}");
|
||||
}
|
||||
} else {
|
||||
println!("formatting {} modified files", files.len());
|
||||
let pluralized = |count| if count > 1 { "files" } else { "file" };
|
||||
let untracked_msg = if untracked_count == 0 {
|
||||
"".to_string()
|
||||
} else {
|
||||
format!(
|
||||
", skipped {} untracked {}",
|
||||
untracked_count,
|
||||
pluralized(untracked_count),
|
||||
)
|
||||
};
|
||||
println!(
|
||||
"formatting {} modified {}{}",
|
||||
files.len(),
|
||||
pluralized(files.len()),
|
||||
untracked_msg
|
||||
);
|
||||
}
|
||||
for file in files {
|
||||
ignore_fmt.add(&format!("/{file}")).expect(&file);
|
||||
fmt_override.add(&format!("/{file}")).expect(&file);
|
||||
}
|
||||
}
|
||||
Ok(None) => {}
|
||||
@ -196,7 +213,7 @@ pub fn format(build: &Builder<'_>, check: bool, paths: &[PathBuf]) {
|
||||
println!("Could not find usable git. Skipping git-aware format checks");
|
||||
}
|
||||
|
||||
let ignore_fmt = ignore_fmt.build().unwrap();
|
||||
let fmt_override = fmt_override.build().unwrap();
|
||||
|
||||
let rustfmt_path = build.initial_rustfmt().unwrap_or_else(|| {
|
||||
eprintln!("./x.py fmt is not supported on this channel");
|
||||
@ -252,7 +269,7 @@ pub fn format(build: &Builder<'_>, check: bool, paths: &[PathBuf]) {
|
||||
None => WalkBuilder::new(src.clone()),
|
||||
}
|
||||
.types(matcher)
|
||||
.overrides(ignore_fmt)
|
||||
.overrides(fmt_override)
|
||||
.build_parallel();
|
||||
|
||||
// there is a lot of blocking involved in spawning a child process and reading files to format.
|
||||
|
@ -480,12 +480,6 @@ pub(crate) fn get_auto_trait_and_blanket_impls(
|
||||
cx: &mut DocContext<'_>,
|
||||
item_def_id: DefId,
|
||||
) -> impl Iterator<Item = Item> {
|
||||
// FIXME: To be removed once `parallel_compiler` bugs are fixed!
|
||||
// More information in <https://github.com/rust-lang/rust/pull/106930>.
|
||||
if cfg!(parallel_compiler) {
|
||||
return vec![].into_iter().chain(vec![].into_iter());
|
||||
}
|
||||
|
||||
let auto_impls = cx
|
||||
.sess()
|
||||
.prof
|
||||
|
@ -1,8 +1,5 @@
|
||||
// compile-flags: --crate-type=lib
|
||||
// normalize-stderr-32bit: "8 bytes" -> "$$TWO_WORDS bytes"
|
||||
// normalize-stderr-64bit: "16 bytes" -> "$$TWO_WORDS bytes"
|
||||
// normalize-stderr-32bit: "size 4" -> "size $$WORD"
|
||||
// normalize-stderr-64bit: "size 8" -> "size $$WORD"
|
||||
// check-pass
|
||||
|
||||
#![feature(
|
||||
core_intrinsics,
|
||||
@ -34,30 +31,13 @@ check!(ne, unsafe { (FOO as *const usize as *const u8).offset(3) }, 0);
|
||||
|
||||
// We want pointers to be equal to themselves, but aren't checking this yet because
|
||||
// there are some open questions (e.g. whether function pointers to the same function
|
||||
// compare equal, they don't necessarily at runtime).
|
||||
// The case tested here should work eventually, but does not work yet.
|
||||
// compare equal: they don't necessarily do at runtime).
|
||||
check!(!, FOO as *const _, FOO as *const _);
|
||||
|
||||
// aside from 0, these pointers might end up pretty much anywhere.
|
||||
check!(!, FOO as *const _, 1); // this one could be `ne` by taking into account alignment
|
||||
check!(!, FOO as *const _, 1024);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// If any of the below start compiling, make sure to add a `check` test for it.
|
||||
// These invocations exist as canaries so we don't forget to check that the
|
||||
// behaviour of `guaranteed_eq` and `guaranteed_ne` is still correct.
|
||||
// All of these try to obtain an out of bounds pointer in some manner. If we
|
||||
// can create out of bounds pointers, we can offset a pointer far enough that
|
||||
// at runtime it would be zero and at compile-time it would not be zero.
|
||||
|
||||
const _: *const usize = unsafe { (FOO as *const usize).offset(2) };
|
||||
|
||||
const _: *const u8 =
|
||||
unsafe { std::ptr::addr_of!((*(FOO as *const usize as *const [u8; 1000]))[999]) };
|
||||
//~^ ERROR evaluation of constant value failed
|
||||
//~| out-of-bounds
|
||||
|
||||
const _: usize = unsafe { std::mem::transmute::<*const usize, usize>(FOO) + 4 };
|
||||
//~^ ERROR evaluation of constant value failed
|
||||
//~| unable to turn pointer into raw bytes
|
||||
|
||||
const _: usize = unsafe { *std::mem::transmute::<&&usize, &usize>(&FOO) + 4 };
|
||||
//~^ ERROR evaluation of constant value failed
|
||||
//~| unable to turn pointer into raw bytes
|
||||
// When pointers go out-of-bounds, they *might* become null, so these comparions cannot work.
|
||||
check!(!, unsafe { (FOO as *const usize).wrapping_add(2) }, 0);
|
||||
check!(!, unsafe { (FOO as *const usize).wrapping_sub(1) }, 0);
|
||||
|
@ -1,40 +0,0 @@
|
||||
error[E0080]: evaluation of constant value failed
|
||||
--> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
||||
|
|
||||
= note: out-of-bounds pointer arithmetic: alloc3 has size $WORD, so pointer to $TWO_WORDS bytes starting at offset 0 is out-of-bounds
|
||||
|
|
||||
note: inside `ptr::const_ptr::<impl *const usize>::offset`
|
||||
--> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
||||
note: inside `_`
|
||||
--> $DIR/ptr_comparisons.rs:50:34
|
||||
|
|
||||
LL | const _: *const usize = unsafe { (FOO as *const usize).offset(2) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0080]: evaluation of constant value failed
|
||||
--> $DIR/ptr_comparisons.rs:53:33
|
||||
|
|
||||
LL | unsafe { std::ptr::addr_of!((*(FOO as *const usize as *const [u8; 1000]))[999]) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ dereferencing pointer failed: alloc3 has size $WORD, so pointer to 1000 bytes starting at offset 0 is out-of-bounds
|
||||
|
||||
error[E0080]: evaluation of constant value failed
|
||||
--> $DIR/ptr_comparisons.rs:57:27
|
||||
|
|
||||
LL | const _: usize = unsafe { std::mem::transmute::<*const usize, usize>(FOO) + 4 };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
|
||||
|
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
error[E0080]: evaluation of constant value failed
|
||||
--> $DIR/ptr_comparisons.rs:61:27
|
||||
|
|
||||
LL | const _: usize = unsafe { *std::mem::transmute::<&&usize, &usize>(&FOO) + 4 };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
|
||||
|
|
||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0080`.
|
14
tests/ui/imports/resolve-other-libc.rs
Normal file
14
tests/ui/imports/resolve-other-libc.rs
Normal file
@ -0,0 +1,14 @@
|
||||
// Regression test for https://github.com/rust-lang/rust/issues/26043
|
||||
|
||||
// compile-flags: --extern libc=test.rlib
|
||||
|
||||
// The error shall NOT be something similar to the following, because it
|
||||
// indicates that `libc` was wrongly resolved to `libc` shipped with the
|
||||
// compiler:
|
||||
//
|
||||
// error[E0658]: use of unstable library feature 'rustc_private': \
|
||||
// this crate is being loaded from the sysroot
|
||||
//
|
||||
extern crate libc; //~ ERROR: extern location for libc does not exist: test.rlib
|
||||
|
||||
fn main() {}
|
8
tests/ui/imports/resolve-other-libc.stderr
Normal file
8
tests/ui/imports/resolve-other-libc.stderr
Normal file
@ -0,0 +1,8 @@
|
||||
error: extern location for libc does not exist: test.rlib
|
||||
--> $DIR/resolve-other-libc.rs:12:1
|
||||
|
|
||||
LL | extern crate libc;
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
Loading…
Reference in New Issue
Block a user