diff --git a/.mailmap b/.mailmap index 0f7bc5e38bd1..fc8e83d6493c 100644 --- a/.mailmap +++ b/.mailmap @@ -427,6 +427,7 @@ Marcell Pardavi Marco Ieni <11428655+MarcoIeni@users.noreply.github.com> Marcus Klaas de Vries Margaret Meyerhofer +Marijn Schouten Mark Mansi Mark Mansi Mark Rousskov diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index e21155002b0f..94c15094f525 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -3636,49 +3636,26 @@ pub struct Trait { pub items: ThinVec>, } -/// The location of a where clause on a `TyAlias` (`Span`) and whether there was -/// a `where` keyword (`bool`). This is split out from `WhereClause`, since there -/// are two locations for where clause on type aliases, but their predicates -/// are concatenated together. -/// -/// Take this example: -/// ```ignore (only-for-syntax-highlight) -/// trait Foo { -/// type Assoc<'a, 'b> where Self: 'a, Self: 'b; -/// } -/// impl Foo for () { -/// type Assoc<'a, 'b> where Self: 'a = () where Self: 'b; -/// // ^^^^^^^^^^^^^^ first where clause -/// // ^^^^^^^^^^^^^^ second where clause -/// } -/// ``` -/// -/// If there is no where clause, then this is `false` with `DUMMY_SP`. -#[derive(Copy, Clone, Encodable, Decodable, Debug, Default, Walkable)] -pub struct TyAliasWhereClause { - pub has_where_token: bool, - pub span: Span, -} - -/// The span information for the two where clauses on a `TyAlias`. -#[derive(Copy, Clone, Encodable, Decodable, Debug, Default, Walkable)] -pub struct TyAliasWhereClauses { - /// Before the equals sign. - pub before: TyAliasWhereClause, - /// After the equals sign. - pub after: TyAliasWhereClause, - /// The index in `TyAlias.generics.where_clause.predicates` that would split - /// into predicates from the where clause before the equals sign and the ones - /// from the where clause after the equals sign. - pub split: usize, -} - #[derive(Clone, Encodable, Decodable, Debug, Walkable)] pub struct TyAlias { pub defaultness: Defaultness, pub ident: Ident, pub generics: Generics, - pub where_clauses: TyAliasWhereClauses, + /// There are two locations for where clause on type aliases. This represents the second + /// where clause, before the semicolon. The first where clause is stored inside `generics`. + /// + /// Take this example: + /// ```ignore (only-for-syntax-highlight) + /// trait Foo { + /// type Assoc<'a, 'b> where Self: 'a, Self: 'b; + /// } + /// impl Foo for () { + /// type Assoc<'a, 'b> where Self: 'a = () where Self: 'b; + /// // ^^^^^^^^^^^^^^ before where clause + /// // ^^^^^^^^^^^^^^ after where clause + /// } + /// ``` + pub after_where_clause: WhereClause, #[visitable(extra = BoundKind::Bound)] pub bounds: GenericBounds, pub ty: Option>, diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index ebd5aa6e93d8..03e5a6edeece 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -471,8 +471,6 @@ macro_rules! common_visitor_and_walkers { TraitBoundModifiers, TraitObjectSyntax, TyAlias, - TyAliasWhereClause, - TyAliasWhereClauses, TyKind, TyPatKind, UnOp, diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index e4b23cba8aa1..8527108f7041 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -36,20 +36,18 @@ pub(super) struct ItemLowerer<'a, 'hir> { /// clause if it exists. fn add_ty_alias_where_clause( generics: &mut ast::Generics, - mut where_clauses: TyAliasWhereClauses, + after_where_clause: &ast::WhereClause, prefer_first: bool, ) { + generics.where_clause.predicates.extend_from_slice(&after_where_clause.predicates); + + let mut before = (generics.where_clause.has_where_token, generics.where_clause.span); + let mut after = (after_where_clause.has_where_token, after_where_clause.span); if !prefer_first { - (where_clauses.before, where_clauses.after) = (where_clauses.after, where_clauses.before); + (before, after) = (after, before); } - let where_clause = - if where_clauses.before.has_where_token || !where_clauses.after.has_where_token { - where_clauses.before - } else { - where_clauses.after - }; - generics.where_clause.has_where_token = where_clause.has_where_token; - generics.where_clause.span = where_clause.span; + (generics.where_clause.has_where_token, generics.where_clause.span) = + if before.0 || !after.0 { before } else { after }; } impl<'a, 'hir> ItemLowerer<'a, 'hir> { @@ -271,7 +269,7 @@ impl<'hir> LoweringContext<'_, 'hir> { self.lower_body(|this| (&[], this.expr(span, hir::ExprKind::InlineAsm(asm)))); hir::ItemKind::GlobalAsm { asm, fake_body } } - ItemKind::TyAlias(box TyAlias { ident, generics, where_clauses, ty, .. }) => { + ItemKind::TyAlias(box TyAlias { ident, generics, after_where_clause, ty, .. }) => { // We lower // // type Foo = impl Trait @@ -282,7 +280,7 @@ impl<'hir> LoweringContext<'_, 'hir> { // opaque type Foo1: Trait let ident = self.lower_ident(*ident); let mut generics = generics.clone(); - add_ty_alias_where_clause(&mut generics, *where_clauses, true); + add_ty_alias_where_clause(&mut generics, after_where_clause, true); let (generics, ty) = self.lower_generics( &generics, id, @@ -901,10 +899,15 @@ impl<'hir> LoweringContext<'_, 'hir> { ) } AssocItemKind::Type(box TyAlias { - ident, generics, where_clauses, bounds, ty, .. + ident, + generics, + after_where_clause, + bounds, + ty, + .. }) => { let mut generics = generics.clone(); - add_ty_alias_where_clause(&mut generics, *where_clauses, false); + add_ty_alias_where_clause(&mut generics, after_where_clause, false); let (generics, kind) = self.lower_generics( &generics, i.id, @@ -1070,9 +1073,11 @@ impl<'hir> LoweringContext<'_, 'hir> { (*ident, (generics, hir::ImplItemKind::Fn(sig, body_id))) } - AssocItemKind::Type(box TyAlias { ident, generics, where_clauses, ty, .. }) => { + AssocItemKind::Type(box TyAlias { + ident, generics, after_where_clause, ty, .. + }) => { let mut generics = generics.clone(); - add_ty_alias_where_clause(&mut generics, *where_clauses, false); + add_ty_alias_where_clause(&mut generics, after_where_clause, false); ( *ident, self.lower_generics( diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index f773b02058ef..93f8b74ad561 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -145,25 +145,24 @@ impl<'a> AstValidator<'a> { &mut self, ty_alias: &TyAlias, ) -> Result<(), errors::WhereClauseBeforeTypeAlias> { - if ty_alias.ty.is_none() || !ty_alias.where_clauses.before.has_where_token { + if ty_alias.ty.is_none() || !ty_alias.generics.where_clause.has_where_token { return Ok(()); } - let (before_predicates, after_predicates) = - ty_alias.generics.where_clause.predicates.split_at(ty_alias.where_clauses.split); - let span = ty_alias.where_clauses.before.span; + let span = ty_alias.generics.where_clause.span; - let sugg = if !before_predicates.is_empty() || !ty_alias.where_clauses.after.has_where_token + let sugg = if !ty_alias.generics.where_clause.predicates.is_empty() + || !ty_alias.after_where_clause.has_where_token { let mut state = State::new(); - if !ty_alias.where_clauses.after.has_where_token { + if !ty_alias.after_where_clause.has_where_token { state.space(); state.word_space("where"); } - let mut first = after_predicates.is_empty(); - for p in before_predicates { + let mut first = ty_alias.after_where_clause.predicates.is_empty(); + for p in &ty_alias.generics.where_clause.predicates { if !first { state.word_space(","); } @@ -174,7 +173,7 @@ impl<'a> AstValidator<'a> { errors::WhereClauseBeforeTypeAliasSugg::Move { left: span, snippet: state.s.eof(), - right: ty_alias.where_clauses.after.span.shrink_to_hi(), + right: ty_alias.after_where_clause.span.shrink_to_hi(), } } else { errors::WhereClauseBeforeTypeAliasSugg::Remove { span } @@ -566,11 +565,7 @@ impl<'a> AstValidator<'a> { self.dcx().emit_err(errors::BoundInContext { span, ctx }); } - fn check_foreign_ty_genericless( - &self, - generics: &Generics, - where_clauses: &TyAliasWhereClauses, - ) { + fn check_foreign_ty_genericless(&self, generics: &Generics, after_where_clause: &WhereClause) { let cannot_have = |span, descr, remove_descr| { self.dcx().emit_err(errors::ExternTypesCannotHave { span, @@ -584,14 +579,14 @@ impl<'a> AstValidator<'a> { cannot_have(generics.span, "generic parameters", "generic parameters"); } - let check_where_clause = |where_clause: TyAliasWhereClause| { + let check_where_clause = |where_clause: &WhereClause| { if where_clause.has_where_token { cannot_have(where_clause.span, "`where` clauses", "`where` clause"); } }; - check_where_clause(where_clauses.before); - check_where_clause(where_clauses.after); + check_where_clause(&generics.where_clause); + check_where_clause(&after_where_clause); } fn check_foreign_kind_bodyless(&self, ident: Ident, kind: &str, body_span: Option) { @@ -1261,7 +1256,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { visit::walk_item(self, item); } ItemKind::TyAlias( - ty_alias @ box TyAlias { defaultness, bounds, where_clauses, ty, .. }, + ty_alias @ box TyAlias { defaultness, bounds, after_where_clause, ty, .. }, ) => { self.check_defaultness(item.span, *defaultness); if ty.is_none() { @@ -1276,9 +1271,9 @@ impl<'a> Visitor<'a> for AstValidator<'a> { if let Err(err) = self.check_type_alias_where_clause_location(ty_alias) { self.dcx().emit_err(err); } - } else if where_clauses.after.has_where_token { + } else if after_where_clause.has_where_token { self.dcx().emit_err(errors::WhereClauseAfterTypeAlias { - span: where_clauses.after.span, + span: after_where_clause.span, help: self.sess.is_nightly_build(), }); } @@ -1308,7 +1303,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { defaultness, ident, generics, - where_clauses, + after_where_clause, bounds, ty, .. @@ -1316,7 +1311,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { self.check_defaultness(fi.span, *defaultness); self.check_foreign_kind_bodyless(*ident, "type", ty.as_ref().map(|b| b.span)); self.check_type_no_bounds(bounds, "`extern` blocks"); - self.check_foreign_ty_genericless(generics, where_clauses); + self.check_foreign_ty_genericless(generics, after_where_clause); self.check_foreign_item_ascii_only(*ident); } ForeignItemKind::Static(box StaticItem { ident, safety, expr, .. }) => { diff --git a/compiler/rustc_ast_pretty/src/pprust/state/item.rs b/compiler/rustc_ast_pretty/src/pprust/state/item.rs index ab402cbb8dc1..341266086340 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/item.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/item.rs @@ -59,14 +59,14 @@ impl<'a> State<'a> { defaultness, ident, generics, - where_clauses, + after_where_clause, bounds, ty, }) => { self.print_associated_type( *ident, generics, - *where_clauses, + after_where_clause, bounds, ty.as_deref(), vis, @@ -127,14 +127,12 @@ impl<'a> State<'a> { &mut self, ident: Ident, generics: &ast::Generics, - where_clauses: ast::TyAliasWhereClauses, + after_where_clause: &ast::WhereClause, bounds: &ast::GenericBounds, ty: Option<&ast::Ty>, vis: &ast::Visibility, defaultness: ast::Defaultness, ) { - let (before_predicates, after_predicates) = - generics.where_clause.predicates.split_at(where_clauses.split); let (cb, ib) = self.head(""); self.print_visibility(vis); self.print_defaultness(defaultness); @@ -145,13 +143,13 @@ impl<'a> State<'a> { self.word_nbsp(":"); self.print_type_bounds(bounds); } - self.print_where_clause_parts(where_clauses.before.has_where_token, before_predicates); + self.print_where_clause(&generics.where_clause); if let Some(ty) = ty { self.space(); self.word_space("="); self.print_type(ty); } - self.print_where_clause_parts(where_clauses.after.has_where_token, after_predicates); + self.print_where_clause(&after_where_clause); self.word(";"); self.end(ib); self.end(cb); @@ -283,14 +281,14 @@ impl<'a> State<'a> { defaultness, ident, generics, - where_clauses, + after_where_clause, bounds, ty, }) => { self.print_associated_type( *ident, generics, - *where_clauses, + after_where_clause, bounds, ty.as_deref(), &item.vis, @@ -585,14 +583,14 @@ impl<'a> State<'a> { defaultness, ident, generics, - where_clauses, + after_where_clause, bounds, ty, }) => { self.print_associated_type( *ident, generics, - *where_clauses, + after_where_clause, bounds, ty.as_deref(), vis, @@ -759,14 +757,7 @@ impl<'a> State<'a> { } fn print_where_clause(&mut self, where_clause: &ast::WhereClause) { - self.print_where_clause_parts(where_clause.has_where_token, &where_clause.predicates); - } - - fn print_where_clause_parts( - &mut self, - has_where_token: bool, - predicates: &[ast::WherePredicate], - ) { + let ast::WhereClause { has_where_token, ref predicates, span: _ } = *where_clause; if predicates.is_empty() && !has_where_token { return; } diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 984a154853a9..d1d0bff8fe06 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -1046,16 +1046,6 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { } } - &Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf, ty) => { - let trait_ref = - ty::TraitRef::new(tcx, tcx.require_lang_item(LangItem::Sized, span), [ty]); - - self.prove_trait_ref( - trait_ref, - location.to_locations(), - ConstraintCategory::SizedBound, - ); - } &Rvalue::NullaryOp(NullOp::ContractChecks, _) => {} &Rvalue::NullaryOp(NullOp::UbChecks, _) => {} diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs index 36ce1b720446..24a71ae94389 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs @@ -610,7 +610,7 @@ impl<'a> TraitDef<'a> { defaultness: ast::Defaultness::Final, ident, generics: Generics::default(), - where_clauses: ast::TyAliasWhereClauses::default(), + after_where_clause: ast::WhereClause::default(), bounds: Vec::new(), ty: Some(type_def.to_ty(cx, self.span, type_ident, generics)), })), diff --git a/compiler/rustc_codegen_cranelift/example/example.rs b/compiler/rustc_codegen_cranelift/example/example.rs index aeb38331edb0..769d262b9ebb 100644 --- a/compiler/rustc_codegen_cranelift/example/example.rs +++ b/compiler/rustc_codegen_cranelift/example/example.rs @@ -72,10 +72,6 @@ pub fn debug_tuple() -> DebugTuple { DebugTuple(()) } -pub fn size_of() -> usize { - intrinsics::size_of::() -} - pub fn use_size_of() -> usize { size_of::() } diff --git a/compiler/rustc_codegen_cranelift/example/mini_core.rs b/compiler/rustc_codegen_cranelift/example/mini_core.rs index 2f53bbf8b793..304d0d648561 100644 --- a/compiler/rustc_codegen_cranelift/example/mini_core.rs +++ b/compiler/rustc_codegen_cranelift/example/mini_core.rs @@ -6,6 +6,7 @@ extern_types, decl_macro, rustc_attrs, + rustc_private, transparent_unions, auto_traits, freeze_impls, @@ -594,7 +595,7 @@ impl, U: ?Sized> CoerceUnsized> for Box {} impl Box { pub fn new(val: T) -> Box { unsafe { - let size = intrinsics::size_of::(); + let size = size_of::(); let ptr = libc::malloc(size); intrinsics::copy(&val as *const T as *const u8, ptr, size); Box(Unique { pointer: NonNull(ptr as *const T), _marker: PhantomData }, Global) @@ -646,11 +647,11 @@ pub mod intrinsics { #[rustc_intrinsic] pub fn abort() -> !; #[rustc_intrinsic] - pub fn size_of() -> usize; + pub const fn size_of() -> usize; #[rustc_intrinsic] pub unsafe fn size_of_val(val: *const T) -> usize; #[rustc_intrinsic] - pub fn align_of() -> usize; + pub const fn align_of() -> usize; #[rustc_intrinsic] pub unsafe fn align_of_val(val: *const T) -> usize; #[rustc_intrinsic] @@ -715,6 +716,23 @@ impl Index for [T] { } } +pub const fn size_of() -> usize { + ::SIZE +} + +pub const fn align_of() -> usize { + ::ALIGN +} + +trait SizedTypeProperties: Sized { + #[lang = "mem_size_const"] + const SIZE: usize = intrinsics::size_of::(); + + #[lang = "mem_align_const"] + const ALIGN: usize = intrinsics::align_of::(); +} +impl SizedTypeProperties for T {} + extern "C" { type VaListImpl; } diff --git a/compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs b/compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs index 86602c6b2a3f..a9388814a7f5 100644 --- a/compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs +++ b/compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs @@ -109,10 +109,10 @@ fn start( puts(*argv as *const i8); } unsafe { - puts(*((argv as usize + intrinsics::size_of::<*const u8>()) as *const *const i8)); + puts(*((argv as usize + size_of::<*const u8>()) as *const *const i8)); } unsafe { - puts(*((argv as usize + 2 * intrinsics::size_of::<*const u8>()) as *const *const i8)); + puts(*((argv as usize + 2 * size_of::<*const u8>()) as *const *const i8)); } } @@ -213,8 +213,8 @@ fn main() { assert_eq!(intrinsics::size_of_val(a) as u8, 16); assert_eq!(intrinsics::size_of_val(&0u32) as u8, 4); - assert_eq!(intrinsics::align_of::() as u8, 2); - assert_eq!(intrinsics::align_of_val(&a) as u8, intrinsics::align_of::<&str>() as u8); + assert_eq!(align_of::() as u8, 2); + assert_eq!(intrinsics::align_of_val(&a) as u8, align_of::<&str>() as u8); let u8_needs_drop = const { intrinsics::needs_drop::() }; assert!(!u8_needs_drop); diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs index c97218797107..7d50548b4026 100644 --- a/compiler/rustc_codegen_cranelift/src/base.rs +++ b/compiler/rustc_codegen_cranelift/src/base.rs @@ -833,8 +833,6 @@ fn codegen_stmt<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, cur_block: Block, stmt: assert!(lval.layout().ty.is_sized(fx.tcx, fx.typing_env())); let layout = fx.layout_of(fx.monomorphize(ty)); let val = match null_op { - NullOp::SizeOf => layout.size.bytes(), - NullOp::AlignOf => layout.align.bytes(), NullOp::OffsetOf(fields) => fx .tcx .offset_of_subfield( diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index c12383f19312..14b3f3626efe 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -1325,6 +1325,8 @@ fn generic_simd_intrinsic<'ll, 'tcx>( }; } + let llvm_version = crate::llvm_util::get_version(); + /// Converts a vector mask, where each element has a bit width equal to the data elements it is used with, /// down to an i1 based mask that can be used by llvm intrinsics. /// @@ -1808,7 +1810,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>( ); // Alignment of T, must be a constant integer value: - let alignment = bx.const_i32(bx.align_of(in_elem).bytes() as i32); + let alignment = bx.align_of(in_elem).bytes(); // Truncate the mask vector to a vector of i1s: let mask = vector_mask_to_bitmask(bx, args[2].immediate(), mask_elem_bitwidth, in_len); @@ -1819,11 +1821,23 @@ fn generic_simd_intrinsic<'ll, 'tcx>( // Type of the vector of elements: let llvm_elem_vec_ty = llvm_vector_ty(bx, element_ty0, in_len); - return Ok(bx.call_intrinsic( - "llvm.masked.gather", - &[llvm_elem_vec_ty, llvm_pointer_vec_ty], - &[args[1].immediate(), alignment, mask, args[0].immediate()], - )); + let args: &[&'ll Value] = if llvm_version < (22, 0, 0) { + let alignment = bx.const_i32(alignment as i32); + &[args[1].immediate(), alignment, mask, args[0].immediate()] + } else { + &[args[1].immediate(), mask, args[0].immediate()] + }; + + let call = + bx.call_intrinsic("llvm.masked.gather", &[llvm_elem_vec_ty, llvm_pointer_vec_ty], args); + if llvm_version >= (22, 0, 0) { + crate::attributes::apply_to_callsite( + call, + crate::llvm::AttributePlace::Argument(0), + &[crate::llvm::CreateAlignmentAttr(bx.llcx, alignment)], + ) + } + return Ok(call); } if name == sym::simd_masked_load { @@ -1891,18 +1905,30 @@ fn generic_simd_intrinsic<'ll, 'tcx>( let mask = vector_mask_to_bitmask(bx, args[0].immediate(), m_elem_bitwidth, mask_len); // Alignment of T, must be a constant integer value: - let alignment = bx.const_i32(bx.align_of(values_elem).bytes() as i32); + let alignment = bx.align_of(values_elem).bytes(); let llvm_pointer = bx.type_ptr(); // Type of the vector of elements: let llvm_elem_vec_ty = llvm_vector_ty(bx, values_elem, values_len); - return Ok(bx.call_intrinsic( - "llvm.masked.load", - &[llvm_elem_vec_ty, llvm_pointer], - &[args[1].immediate(), alignment, mask, args[2].immediate()], - )); + let args: &[&'ll Value] = if llvm_version < (22, 0, 0) { + let alignment = bx.const_i32(alignment as i32); + + &[args[1].immediate(), alignment, mask, args[2].immediate()] + } else { + &[args[1].immediate(), mask, args[2].immediate()] + }; + + let call = bx.call_intrinsic("llvm.masked.load", &[llvm_elem_vec_ty, llvm_pointer], args); + if llvm_version >= (22, 0, 0) { + crate::attributes::apply_to_callsite( + call, + crate::llvm::AttributePlace::Argument(0), + &[crate::llvm::CreateAlignmentAttr(bx.llcx, alignment)], + ) + } + return Ok(call); } if name == sym::simd_masked_store { @@ -1964,18 +1990,29 @@ fn generic_simd_intrinsic<'ll, 'tcx>( let mask = vector_mask_to_bitmask(bx, args[0].immediate(), m_elem_bitwidth, mask_len); // Alignment of T, must be a constant integer value: - let alignment = bx.const_i32(bx.align_of(values_elem).bytes() as i32); + let alignment = bx.align_of(values_elem).bytes(); let llvm_pointer = bx.type_ptr(); // Type of the vector of elements: let llvm_elem_vec_ty = llvm_vector_ty(bx, values_elem, values_len); - return Ok(bx.call_intrinsic( - "llvm.masked.store", - &[llvm_elem_vec_ty, llvm_pointer], - &[args[2].immediate(), args[1].immediate(), alignment, mask], - )); + let args: &[&'ll Value] = if llvm_version < (22, 0, 0) { + let alignment = bx.const_i32(alignment as i32); + &[args[2].immediate(), args[1].immediate(), alignment, mask] + } else { + &[args[2].immediate(), args[1].immediate(), mask] + }; + + let call = bx.call_intrinsic("llvm.masked.store", &[llvm_elem_vec_ty, llvm_pointer], args); + if llvm_version >= (22, 0, 0) { + crate::attributes::apply_to_callsite( + call, + crate::llvm::AttributePlace::Argument(1), + &[crate::llvm::CreateAlignmentAttr(bx.llcx, alignment)], + ) + } + return Ok(call); } if name == sym::simd_scatter { @@ -2040,7 +2077,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>( ); // Alignment of T, must be a constant integer value: - let alignment = bx.const_i32(bx.align_of(in_elem).bytes() as i32); + let alignment = bx.align_of(in_elem).bytes(); // Truncate the mask vector to a vector of i1s: let mask = vector_mask_to_bitmask(bx, args[2].immediate(), mask_elem_bitwidth, in_len); @@ -2050,12 +2087,25 @@ fn generic_simd_intrinsic<'ll, 'tcx>( // Type of the vector of elements: let llvm_elem_vec_ty = llvm_vector_ty(bx, element_ty0, in_len); - - return Ok(bx.call_intrinsic( + let args: &[&'ll Value] = if llvm_version < (22, 0, 0) { + let alignment = bx.const_i32(alignment as i32); + &[args[0].immediate(), args[1].immediate(), alignment, mask] + } else { + &[args[0].immediate(), args[1].immediate(), mask] + }; + let call = bx.call_intrinsic( "llvm.masked.scatter", &[llvm_elem_vec_ty, llvm_pointer_vec_ty], - &[args[0].immediate(), args[1].immediate(), alignment, mask], - )); + args, + ); + if llvm_version >= (22, 0, 0) { + crate::attributes::apply_to_callsite( + call, + crate::llvm::AttributePlace::Argument(1), + &[crate::llvm::CreateAlignmentAttr(bx.llcx, alignment)], + ) + } + return Ok(call); } macro_rules! arith_red { diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index 0c626a9cd781..640f7211dc99 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -611,16 +611,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let ty = self.monomorphize(ty); let layout = bx.cx().layout_of(ty); let val = match null_op { - mir::NullOp::SizeOf => { - assert!(bx.cx().type_is_sized(ty)); - let val = layout.size.bytes(); - bx.cx().const_usize(val) - } - mir::NullOp::AlignOf => { - assert!(bx.cx().type_is_sized(ty)); - let val = layout.align.bytes(); - bx.cx().const_usize(val) - } mir::NullOp::OffsetOf(fields) => { let val = bx .tcx() diff --git a/compiler/rustc_const_eval/src/check_consts/check.rs b/compiler/rustc_const_eval/src/check_consts/check.rs index 2c6dd5bd01f9..ca173fe26c2f 100644 --- a/compiler/rustc_const_eval/src/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/check_consts/check.rs @@ -646,11 +646,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { Rvalue::Cast(_, _, _) => {} Rvalue::NullaryOp( - NullOp::SizeOf - | NullOp::AlignOf - | NullOp::OffsetOf(_) - | NullOp::UbChecks - | NullOp::ContractChecks, + NullOp::OffsetOf(_) | NullOp::UbChecks | NullOp::ContractChecks, _, ) => {} Rvalue::ShallowInitBox(_, _) => {} diff --git a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs index 4da2663319c3..bf5787c86bd5 100644 --- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs @@ -414,8 +414,6 @@ fn report_eval_error<'tcx>( let (error, backtrace) = error.into_parts(); backtrace.print_backtrace(); - let instance = with_no_trimmed_paths!(cid.instance.to_string()); - super::report( ecx, error, @@ -430,7 +428,7 @@ fn report_eval_error<'tcx>( diag.subdiagnostic(frame); } // Add after the frame rendering above, as it adds its own `instance` args. - diag.arg("instance", instance); + diag.arg("instance", with_no_trimmed_paths!(cid.instance.to_string())); diag.arg("num_frames", num_frames); }, ) diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index fc7f1166af99..f0f06d469c1e 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -156,6 +156,24 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { let b_ty = self.read_type_id(&args[1])?; self.write_scalar(Scalar::from_bool(a_ty == b_ty), dest)?; } + sym::size_of => { + let tp_ty = instance.args.type_at(0); + let layout = self.layout_of(tp_ty)?; + if !layout.is_sized() { + span_bug!(self.cur_span(), "unsized type for `size_of`"); + } + let val = layout.size.bytes(); + self.write_scalar(Scalar::from_target_usize(val, self), dest)?; + } + sym::align_of => { + let tp_ty = instance.args.type_at(0); + let layout = self.layout_of(tp_ty)?; + if !layout.is_sized() { + span_bug!(self.cur_span(), "unsized type for `align_of`"); + } + let val = layout.align.bytes(); + self.write_scalar(Scalar::from_target_usize(val, self), dest)?; + } sym::variant_count => { let tp_ty = instance.args.type_at(0); let ty = match tp_ty.kind() { diff --git a/compiler/rustc_const_eval/src/interpret/operator.rs b/compiler/rustc_const_eval/src/interpret/operator.rs index f0819423aa0f..58b90abf0129 100644 --- a/compiler/rustc_const_eval/src/interpret/operator.rs +++ b/compiler/rustc_const_eval/src/interpret/operator.rs @@ -517,20 +517,6 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { let usize_layout = || self.layout_of(self.tcx.types.usize).unwrap(); interp_ok(match null_op { - SizeOf => { - if !layout.is_sized() { - span_bug!(self.cur_span(), "unsized type for `NullaryOp::SizeOf`"); - } - let val = layout.size.bytes(); - ImmTy::from_uint(val, usize_layout()) - } - AlignOf => { - if !layout.is_sized() { - span_bug!(self.cur_span(), "unsized type for `NullaryOp::AlignOf`"); - } - let val = layout.align.bytes(); - ImmTy::from_uint(val, usize_layout()) - } OffsetOf(fields) => { let val = self.tcx.offset_of_subfield(self.typing_env, layout, fields.iter()).bytes(); diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index ae23ef1e2553..96a4ed3218fb 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -945,6 +945,11 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { None, "Span must not be empty and have no suggestion", ); + debug_assert_eq!( + parts.array_windows().find(|[a, b]| a.span.overlaps(b.span)), + None, + "suggestion must not have overlapping parts", + ); self.push_suggestion(CodeSuggestion { substitutions: vec![Substitution { parts }], diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index 2775e61902fb..9e32a85e361a 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -2350,6 +2350,7 @@ impl HumanEmitter { .sum(); let underline_start = (span_start_pos + start) as isize + offset; let underline_end = (span_start_pos + start + sub_len) as isize + offset; + assert!(underline_start >= 0 && underline_end >= 0); let padding: usize = max_line_num_len + 3; for p in underline_start..underline_end { if let DisplaySuggestion::Underline = show_code_change diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index c6685fa7a649..17cd466f96b8 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -400,17 +400,6 @@ impl CodeSuggestion { // Assumption: all spans are in the same file, and all spans // are disjoint. Sort in ascending order. substitution.parts.sort_by_key(|part| part.span.lo()); - // Verify the assumption that all spans are disjoint - assert_eq!( - substitution.parts.array_windows().find(|[a, b]| a.span.overlaps(b.span)), - None, - "all spans must be disjoint", - ); - - // Account for cases where we are suggesting the same code that's already - // there. This shouldn't happen often, but in some cases for multipart - // suggestions it's much easier to handle it here than in the origin. - substitution.parts.retain(|p| is_different(sm, &p.snippet, p.span)); // Find the bounding span. let lo = substitution.parts.iter().map(|part| part.span.lo()).min()?; @@ -505,12 +494,16 @@ impl CodeSuggestion { _ => 1, }) .sum(); - - line_highlight.push(SubstitutionHighlight { - start: (cur_lo.col.0 as isize + acc) as usize, - end: (cur_lo.col.0 as isize + acc + len) as usize, - }); - + if !is_different(sm, &part.snippet, part.span) { + // Account for cases where we are suggesting the same code that's already + // there. This shouldn't happen often, but in some cases for multipart + // suggestions it's much easier to handle it here than in the origin. + } else { + line_highlight.push(SubstitutionHighlight { + start: (cur_lo.col.0 as isize + acc) as usize, + end: (cur_lo.col.0 as isize + acc + len) as usize, + }); + } buf.push_str(&part.snippet); let cur_hi = sm.lookup_char_pos(part.span.hi()); // Account for the difference between the width of the current code and the diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs index 311cf8f995c8..9f7f4c758341 100644 --- a/compiler/rustc_hir/src/lang_items.rs +++ b/compiler/rustc_hir/src/lang_items.rs @@ -168,6 +168,8 @@ language_item_table! { MetaSized, sym::meta_sized, meta_sized_trait, Target::Trait, GenericRequirement::Exact(0); PointeeSized, sym::pointee_sized, pointee_sized_trait, Target::Trait, GenericRequirement::Exact(0); Unsize, sym::unsize, unsize_trait, Target::Trait, GenericRequirement::Minimum(1); + AlignOf, sym::mem_align_const, align_const, Target::AssocConst, GenericRequirement::Exact(0); + SizeOf, sym::mem_size_const, size_const, Target::AssocConst, GenericRequirement::Exact(0); /// Trait injected by `#[derive(PartialEq)]`, (i.e. "Partial EQ"). StructuralPeq, sym::structural_peq, structural_peq_trait, Target::Trait, GenericRequirement::None; Copy, sym::copy, copy_trait, Target::Trait, GenericRequirement::Exact(0); diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs index 60c2ef4d563e..17d8eeee68bf 100644 --- a/compiler/rustc_middle/src/mir/pretty.rs +++ b/compiler/rustc_middle/src/mir/pretty.rs @@ -1092,8 +1092,6 @@ impl<'tcx> Debug for Rvalue<'tcx> { NullaryOp(ref op, ref t) => { let t = with_no_trimmed_paths!(format!("{}", t)); match op { - NullOp::SizeOf => write!(fmt, "SizeOf({t})"), - NullOp::AlignOf => write!(fmt, "AlignOf({t})"), NullOp::OffsetOf(fields) => write!(fmt, "OffsetOf({t}, {fields:?})"), NullOp::UbChecks => write!(fmt, "UbChecks()"), NullOp::ContractChecks => write!(fmt, "ContractChecks()"), diff --git a/compiler/rustc_middle/src/mir/statement.rs b/compiler/rustc_middle/src/mir/statement.rs index 91a528678901..3cbb4b70b062 100644 --- a/compiler/rustc_middle/src/mir/statement.rs +++ b/compiler/rustc_middle/src/mir/statement.rs @@ -597,6 +597,18 @@ impl<'tcx> Operand<'tcx> { })) } + /// Convenience helper to make a constant that refers to the given `DefId` and args. Since this + /// is used to synthesize MIR, assumes `user_ty` is None. + pub fn unevaluated_constant( + tcx: TyCtxt<'tcx>, + def_id: DefId, + args: &[GenericArg<'tcx>], + span: Span, + ) -> Self { + let const_ = Const::from_unevaluated(tcx, def_id).instantiate(tcx, args); + Operand::Constant(Box::new(ConstOperand { span, user_ty: None, const_ })) + } + pub fn is_move(&self) -> bool { matches!(self, Operand::Move(..)) } @@ -782,9 +794,7 @@ impl<'tcx> Rvalue<'tcx> { op.ty(tcx, arg_ty) } Rvalue::Discriminant(ref place) => place.ty(local_decls, tcx).ty.discriminant_ty(tcx), - Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf | NullOp::OffsetOf(..), _) => { - tcx.types.usize - } + Rvalue::NullaryOp(NullOp::OffsetOf(..), _) => tcx.types.usize, Rvalue::NullaryOp(NullOp::ContractChecks, _) | Rvalue::NullaryOp(NullOp::UbChecks, _) => tcx.types.bool, Rvalue::Aggregate(ref ak, ref ops) => match **ak { @@ -853,7 +863,7 @@ impl BorrowKind { impl<'tcx> NullOp<'tcx> { pub fn ty(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> { match self { - NullOp::SizeOf | NullOp::AlignOf | NullOp::OffsetOf(_) => tcx.types.usize, + NullOp::OffsetOf(_) => tcx.types.usize, NullOp::UbChecks | NullOp::ContractChecks => tcx.types.bool, } } diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs index 38f03cf4e8a0..9d99239546ae 100644 --- a/compiler/rustc_middle/src/mir/syntax.rs +++ b/compiler/rustc_middle/src/mir/syntax.rs @@ -1563,10 +1563,6 @@ pub enum AggregateKind<'tcx> { #[derive(Copy, Clone, Debug, PartialEq, Eq, TyEncodable, TyDecodable, Hash, HashStable)] pub enum NullOp<'tcx> { - /// Returns the size of a value of that type - SizeOf, - /// Returns the minimum alignment of a type - AlignOf, /// Returns the offset of a field OffsetOf(&'tcx List<(VariantIdx, FieldIdx)>), /// Returns whether we should perform some UB-checking at runtime. diff --git a/compiler/rustc_middle/src/mir/terminator.rs b/compiler/rustc_middle/src/mir/terminator.rs index 62711ad92372..db8251c7d9dc 100644 --- a/compiler/rustc_middle/src/mir/terminator.rs +++ b/compiler/rustc_middle/src/mir/terminator.rs @@ -501,6 +501,8 @@ pub use helper::*; mod helper { use super::*; + // Note: the methods below use a `slice.chain(Option).chain(Option)` pattern so that all paths + // produce an iterator with the same concrete type. pub type Successors<'a> = impl DoubleEndedIterator + 'a; impl SwitchTargets { @@ -510,7 +512,7 @@ mod helper { #[define_opaque(Successors)] pub fn successors_for_value(&self, value: u128) -> Successors<'_> { let target = self.target_for_value(value); - (&[]).into_iter().copied().chain(Some(target).into_iter().chain(None)) + (&[]).into_iter().copied().chain(Some(target)).chain(None) } } @@ -522,10 +524,7 @@ mod helper { match *self { // 3-successors for async drop: target, unwind, dropline (parent coroutine drop) Drop { target: ref t, unwind: UnwindAction::Cleanup(u), drop: Some(d), .. } => { - slice::from_ref(t) - .into_iter() - .copied() - .chain(Some(u).into_iter().chain(Some(d))) + slice::from_ref(t).into_iter().copied().chain(Some(u)).chain(Some(d)) } // 2-successors Call { target: Some(ref t), unwind: UnwindAction::Cleanup(u), .. } @@ -534,7 +533,7 @@ mod helper { | Drop { target: ref t, unwind: _, drop: Some(u), .. } | Assert { target: ref t, unwind: UnwindAction::Cleanup(u), .. } | FalseUnwind { real_target: ref t, unwind: UnwindAction::Cleanup(u) } => { - slice::from_ref(t).into_iter().copied().chain(Some(u).into_iter().chain(None)) + slice::from_ref(t).into_iter().copied().chain(Some(u)).chain(None) } // single successor Goto { target: ref t } @@ -544,7 +543,7 @@ mod helper { | Drop { target: ref t, unwind: _, .. } | Assert { target: ref t, unwind: _, .. } | FalseUnwind { real_target: ref t, unwind: _ } => { - slice::from_ref(t).into_iter().copied().chain(None.into_iter().chain(None)) + slice::from_ref(t).into_iter().copied().chain(None).chain(None) } // No successors UnwindResume @@ -554,23 +553,24 @@ mod helper { | Unreachable | TailCall { .. } | Call { target: None, unwind: _, .. } => { - (&[]).into_iter().copied().chain(None.into_iter().chain(None)) + (&[]).into_iter().copied().chain(None).chain(None) } // Multiple successors InlineAsm { ref targets, unwind: UnwindAction::Cleanup(u), .. } => { - targets.iter().copied().chain(Some(u).into_iter().chain(None)) + targets.iter().copied().chain(Some(u)).chain(None) } InlineAsm { ref targets, unwind: _, .. } => { - targets.iter().copied().chain(None.into_iter().chain(None)) + targets.iter().copied().chain(None).chain(None) } SwitchInt { ref targets, .. } => { - targets.targets.iter().copied().chain(None.into_iter().chain(None)) + targets.targets.iter().copied().chain(None).chain(None) } // FalseEdge FalseEdge { ref real_target, imaginary_target } => slice::from_ref(real_target) .into_iter() .copied() - .chain(Some(imaginary_target).into_iter().chain(None)), + .chain(Some(imaginary_target)) + .chain(None), } } diff --git a/compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs index 3a5839f2d404..552f8c66784e 100644 --- a/compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs +++ b/compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs @@ -126,21 +126,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let tcx = this.tcx; let source_info = this.source_info(expr_span); - let size = this.temp(tcx.types.usize, expr_span); - this.cfg.push_assign( - block, - source_info, - size, - Rvalue::NullaryOp(NullOp::SizeOf, value_ty), - ); + let size = tcx.require_lang_item(LangItem::SizeOf, expr_span); + let size = Operand::unevaluated_constant(tcx, size, &[value_ty.into()], expr_span); - let align = this.temp(tcx.types.usize, expr_span); - this.cfg.push_assign( - block, - source_info, - align, - Rvalue::NullaryOp(NullOp::AlignOf, value_ty), - ); + let align = tcx.require_lang_item(LangItem::AlignOf, expr_span); + let align = + Operand::unevaluated_constant(tcx, align, &[value_ty.into()], expr_span); // malloc some memory of suitable size and align: let exchange_malloc = Operand::function_handle( @@ -157,8 +148,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { TerminatorKind::Call { func: exchange_malloc, args: [ - Spanned { node: Operand::Move(size), span: DUMMY_SP }, - Spanned { node: Operand::Move(align), span: DUMMY_SP }, + Spanned { node: size, span: DUMMY_SP }, + Spanned { node: align, span: DUMMY_SP }, ] .into(), destination: storage, diff --git a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs index b45f8a724c69..dd65f0699e97 100644 --- a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs +++ b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs @@ -452,11 +452,7 @@ impl<'a, 'tcx, F: Fn(Ty<'tcx>) -> bool> MoveDataBuilder<'a, 'tcx, F> { | Rvalue::RawPtr(..) | Rvalue::Discriminant(..) | Rvalue::NullaryOp( - NullOp::SizeOf - | NullOp::AlignOf - | NullOp::OffsetOf(..) - | NullOp::UbChecks - | NullOp::ContractChecks, + NullOp::OffsetOf(..) | NullOp::UbChecks | NullOp::ContractChecks, _, ) => {} } diff --git a/compiler/rustc_mir_transform/src/check_alignment.rs b/compiler/rustc_mir_transform/src/check_alignment.rs index 989787504b7b..e06883dd0fd1 100644 --- a/compiler/rustc_mir_transform/src/check_alignment.rs +++ b/compiler/rustc_mir_transform/src/check_alignment.rs @@ -1,4 +1,5 @@ use rustc_abi::Align; +use rustc_hir::LangItem; use rustc_index::IndexVec; use rustc_middle::mir::interpret::Scalar; use rustc_middle::mir::visit::PlaceContext; @@ -59,10 +60,9 @@ fn insert_alignment_check<'tcx>( stmts.push(Statement::new(source_info, StatementKind::Assign(Box::new((addr, rvalue))))); // Get the alignment of the pointee + let align_def_id = tcx.require_lang_item(LangItem::AlignOf, source_info.span); let alignment = - local_decls.push(LocalDecl::with_source_info(tcx.types.usize, source_info)).into(); - let rvalue = Rvalue::NullaryOp(NullOp::AlignOf, pointee_ty); - stmts.push(Statement::new(source_info, StatementKind::Assign(Box::new((alignment, rvalue))))); + Operand::unevaluated_constant(tcx, align_def_id, &[pointee_ty.into()], source_info.span); // Subtract 1 from the alignment to get the alignment mask let alignment_mask = @@ -76,7 +76,7 @@ fn insert_alignment_check<'tcx>( source_info, StatementKind::Assign(Box::new(( alignment_mask, - Rvalue::BinaryOp(BinOp::Sub, Box::new((Operand::Copy(alignment), one))), + Rvalue::BinaryOp(BinOp::Sub, Box::new((alignment.clone(), one))), ))), )); @@ -141,7 +141,7 @@ fn insert_alignment_check<'tcx>( PointerCheck { cond: Operand::Copy(is_ok), assert_kind: Box::new(AssertKind::MisalignedPointerDereference { - required: Operand::Copy(alignment), + required: alignment, found: Operand::Copy(addr), }), } diff --git a/compiler/rustc_mir_transform/src/check_null.rs b/compiler/rustc_mir_transform/src/check_null.rs index e365d36580ad..c73b4d7db243 100644 --- a/compiler/rustc_mir_transform/src/check_null.rs +++ b/compiler/rustc_mir_transform/src/check_null.rs @@ -1,3 +1,4 @@ +use rustc_hir::LangItem; use rustc_index::IndexVec; use rustc_middle::mir::visit::{MutatingUseContext, NonMutatingUseContext, PlaceContext}; use rustc_middle::mir::*; @@ -62,35 +63,23 @@ fn insert_null_check<'tcx>( Operand::Constant(Box::new(ConstOperand { span: source_info.span, user_ty: None, - const_: Const::Val(ConstValue::from_bool(true), tcx.types.bool), + const_: Const::from_bool(tcx, true), })) } // Other usages of null pointers only are UB if the pointee is not a ZST. _ => { - let rvalue = Rvalue::NullaryOp(NullOp::SizeOf, pointee_ty); - let sizeof_pointee = - local_decls.push(LocalDecl::with_source_info(tcx.types.usize, source_info)).into(); - stmts.push(Statement::new( - source_info, - StatementKind::Assign(Box::new((sizeof_pointee, rvalue))), - )); + let size_of = tcx.require_lang_item(LangItem::SizeOf, source_info.span); + let size_of = + Operand::unevaluated_constant(tcx, size_of, &[pointee_ty.into()], source_info.span); - // Check that the pointee is not a ZST. - let is_pointee_not_zst = + let pointee_should_be_checked = local_decls.push(LocalDecl::with_source_info(tcx.types.bool, source_info)).into(); + let rvalue = Rvalue::BinaryOp(BinOp::Ne, Box::new((size_of, zero.clone()))); stmts.push(Statement::new( source_info, - StatementKind::Assign(Box::new(( - is_pointee_not_zst, - Rvalue::BinaryOp( - BinOp::Ne, - Box::new((Operand::Copy(sizeof_pointee), zero.clone())), - ), - ))), + StatementKind::Assign(Box::new((pointee_should_be_checked, rvalue))), )); - - // Pointer needs to be checked only if pointee is not a ZST. - Operand::Copy(is_pointee_not_zst) + Operand::Copy(pointee_should_be_checked.into()) } }; diff --git a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs index fd5269d4ff8c..8bcda77f4bc3 100644 --- a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs +++ b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs @@ -466,8 +466,6 @@ impl<'a, 'tcx> ConstAnalysis<'a, 'tcx> { return ValueOrPlace::Value(FlatSet::Top); }; let val = match null_op { - NullOp::SizeOf if layout.is_sized() => layout.size.bytes(), - NullOp::AlignOf if layout.is_sized() => layout.align.bytes(), NullOp::OffsetOf(fields) => self .ecx .tcx diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs index 03073bb7cbdb..8eae80e235cc 100644 --- a/compiler/rustc_mir_transform/src/gvn.rs +++ b/compiler/rustc_mir_transform/src/gvn.rs @@ -670,14 +670,7 @@ impl<'body, 'a, 'tcx> VnState<'body, 'a, 'tcx> { } NullaryOp(null_op, arg_ty) => { let arg_layout = self.ecx.layout_of(arg_ty).ok()?; - if let NullOp::SizeOf | NullOp::AlignOf = null_op - && arg_layout.is_unsized() - { - return None; - } let val = match null_op { - NullOp::SizeOf => arg_layout.size.bytes(), - NullOp::AlignOf => arg_layout.align.bytes(), NullOp::OffsetOf(fields) => self .tcx .offset_of_subfield(self.typing_env(), arg_layout, fields.iter()) diff --git a/compiler/rustc_mir_transform/src/instsimplify.rs b/compiler/rustc_mir_transform/src/instsimplify.rs index c83bd25c6636..932744e4fa25 100644 --- a/compiler/rustc_mir_transform/src/instsimplify.rs +++ b/compiler/rustc_mir_transform/src/instsimplify.rs @@ -264,6 +264,7 @@ impl<'tcx> InstSimplifyContext<'_, 'tcx> { terminator: &mut Terminator<'tcx>, statements: &mut Vec>, ) { + let source_info = terminator.source_info; if let TerminatorKind::Call { func, args, destination, target: Some(destination_block), .. } = &terminator.kind @@ -272,12 +273,16 @@ impl<'tcx> InstSimplifyContext<'_, 'tcx> { && self.tcx.is_intrinsic(fn_def_id, sym::align_of_val) && let ty::Slice(elem_ty) = *generics.type_at(0).kind() { + let align_def_id = self.tcx.require_lang_item(LangItem::AlignOf, source_info.span); + let align_const = Operand::unevaluated_constant( + self.tcx, + align_def_id, + &[elem_ty.into()], + source_info.span, + ); statements.push(Statement::new( - terminator.source_info, - StatementKind::Assign(Box::new(( - *destination, - Rvalue::NullaryOp(NullOp::AlignOf, elem_ty), - ))), + source_info, + StatementKind::Assign(Box::new((*destination, Rvalue::Use(align_const)))), )); terminator.kind = TerminatorKind::Goto { target: *destination_block }; } diff --git a/compiler/rustc_mir_transform/src/known_panics_lint.rs b/compiler/rustc_mir_transform/src/known_panics_lint.rs index c67e875175fe..131e3943689b 100644 --- a/compiler/rustc_mir_transform/src/known_panics_lint.rs +++ b/compiler/rustc_mir_transform/src/known_panics_lint.rs @@ -608,8 +608,6 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { NullaryOp(ref null_op, ty) => { let op_layout = self.ecx.layout_of(ty).ok()?; let val = match null_op { - NullOp::SizeOf => op_layout.size.bytes(), - NullOp::AlignOf => op_layout.align.bytes(), NullOp::OffsetOf(fields) => self .tcx .offset_of_subfield(self.typing_env, op_layout, fields.iter()) diff --git a/compiler/rustc_mir_transform/src/lower_intrinsics.rs b/compiler/rustc_mir_transform/src/lower_intrinsics.rs index fc8092fd5832..ad7c52064a8e 100644 --- a/compiler/rustc_mir_transform/src/lower_intrinsics.rs +++ b/compiler/rustc_mir_transform/src/lower_intrinsics.rs @@ -139,23 +139,6 @@ impl<'tcx> crate::MirPass<'tcx> for LowerIntrinsics { )); terminator.kind = TerminatorKind::Goto { target }; } - sym::size_of | sym::align_of => { - let target = target.unwrap(); - let tp_ty = generic_args.type_at(0); - let null_op = match intrinsic.name { - sym::size_of => NullOp::SizeOf, - sym::align_of => NullOp::AlignOf, - _ => bug!("unexpected intrinsic"), - }; - block.statements.push(Statement::new( - terminator.source_info, - StatementKind::Assign(Box::new(( - *destination, - Rvalue::NullaryOp(null_op, tp_ty), - ))), - )); - terminator.kind = TerminatorKind::Goto { target }; - } sym::read_via_copy => { let Ok([arg]) = take_array(args) else { span_bug!(terminator.source_info.span, "Wrong number of arguments"); diff --git a/compiler/rustc_mir_transform/src/promote_consts.rs b/compiler/rustc_mir_transform/src/promote_consts.rs index c7dc18a4a134..9204c221515c 100644 --- a/compiler/rustc_mir_transform/src/promote_consts.rs +++ b/compiler/rustc_mir_transform/src/promote_consts.rs @@ -450,8 +450,6 @@ impl<'tcx> Validator<'_, 'tcx> { } Rvalue::NullaryOp(op, _) => match op { - NullOp::SizeOf => {} - NullOp::AlignOf => {} NullOp::OffsetOf(_) => {} NullOp::UbChecks => {} NullOp::ContractChecks => {} diff --git a/compiler/rustc_mir_transform/src/validate.rs b/compiler/rustc_mir_transform/src/validate.rs index bef81935bb8f..5a9018a62c57 100644 --- a/compiler/rustc_mir_transform/src/validate.rs +++ b/compiler/rustc_mir_transform/src/validate.rs @@ -1478,10 +1478,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { Rvalue::Repeat(_, _) | Rvalue::ThreadLocalRef(_) | Rvalue::RawPtr(_, _) - | Rvalue::NullaryOp( - NullOp::SizeOf | NullOp::AlignOf | NullOp::UbChecks | NullOp::ContractChecks, - _, - ) + | Rvalue::NullaryOp(NullOp::UbChecks | NullOp::ContractChecks, _) | Rvalue::Discriminant(_) => {} Rvalue::WrapUnsafeBinder(op, ty) => { diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 6f0e3b81cf2a..11eae9e2d903 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -1041,40 +1041,19 @@ impl<'a> Parser<'a> { // Parse optional colon and param bounds. let bounds = if self.eat(exp!(Colon)) { self.parse_generic_bounds()? } else { Vec::new() }; - let before_where_clause = self.parse_where_clause()?; + generics.where_clause = self.parse_where_clause()?; let ty = if self.eat(exp!(Eq)) { Some(self.parse_ty()?) } else { None }; let after_where_clause = self.parse_where_clause()?; - let where_clauses = TyAliasWhereClauses { - before: TyAliasWhereClause { - has_where_token: before_where_clause.has_where_token, - span: before_where_clause.span, - }, - after: TyAliasWhereClause { - has_where_token: after_where_clause.has_where_token, - span: after_where_clause.span, - }, - split: before_where_clause.predicates.len(), - }; - let mut predicates = before_where_clause.predicates; - predicates.extend(after_where_clause.predicates); - let where_clause = WhereClause { - has_where_token: before_where_clause.has_where_token - || after_where_clause.has_where_token, - predicates, - span: DUMMY_SP, - }; - generics.where_clause = where_clause; - self.expect_semi()?; Ok(ItemKind::TyAlias(Box::new(TyAlias { defaultness, ident, generics, - where_clauses, + after_where_clause, bounds, ty, }))) diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 85646b575bff..e87bac6114dd 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -75,6 +75,9 @@ pub trait DefIdVisitor<'tcx> { } fn tcx(&self) -> TyCtxt<'tcx>; + /// NOTE: Def-id visiting should be idempotent (or at least produce duplicated errors), + /// because `DefIdVisitorSkeleton` will use caching and sometimes avoid visiting duplicate + /// def-ids. All the current visitors follow this rule. fn visit_def_id(&mut self, def_id: DefId, kind: &str, descr: &dyn fmt::Display) -> Self::Result; @@ -82,7 +85,7 @@ pub trait DefIdVisitor<'tcx> { fn skeleton(&mut self) -> DefIdVisitorSkeleton<'_, 'tcx, Self> { DefIdVisitorSkeleton { def_id_visitor: self, - visited_opaque_tys: Default::default(), + visited_tys: Default::default(), dummy: Default::default(), } } @@ -102,7 +105,7 @@ pub trait DefIdVisitor<'tcx> { pub struct DefIdVisitorSkeleton<'v, 'tcx, V: ?Sized> { def_id_visitor: &'v mut V, - visited_opaque_tys: FxHashSet, + visited_tys: FxHashSet>, dummy: PhantomData>, } @@ -183,7 +186,8 @@ where let tcx = self.def_id_visitor.tcx(); // GenericArgs are not visited here because they are visited below // in `super_visit_with`. - match *ty.kind() { + let ty_kind = *ty.kind(); + match ty_kind { ty::Adt(ty::AdtDef(Interned(&ty::AdtDefData { did: def_id, .. }, _)), ..) | ty::Foreign(def_id) | ty::FnDef(def_id, ..) @@ -197,7 +201,7 @@ where // Default type visitor doesn't visit signatures of fn types. // Something like `fn() -> Priv {my_func}` is considered a private type even if // `my_func` is public, so we need to visit signatures. - if let ty::FnDef(..) = ty.kind() { + if let ty::FnDef(..) = ty_kind { // FIXME: this should probably use `args` from `FnDef` try_visit!(tcx.fn_sig(def_id).instantiate_identity().visit_with(self)); } @@ -220,6 +224,12 @@ where // free type aliases, but this isn't done yet. return V::Result::output(); } + if !self.visited_tys.insert(ty) { + // Avoid repeatedly visiting alias types (including projections). + // This helps with special cases like #145741, but doesn't introduce + // too much overhead in general case, unlike caching for other types. + return V::Result::output(); + } try_visit!(self.def_id_visitor.visit_def_id( data.def_id, @@ -259,7 +269,7 @@ where } ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) => { // Skip repeated `Opaque`s to avoid infinite recursion. - if self.visited_opaque_tys.insert(def_id) { + if self.visited_tys.insert(ty) { // The intent is to treat `impl Trait1 + Trait2` identically to // `dyn Trait1 + Trait2`. Therefore we ignore def-id of the opaque type itself // (it either has no visibility, or its visibility is insignificant, like @@ -929,7 +939,7 @@ impl<'tcx> NamePrivacyVisitor<'tcx> { // Checks that a field in a struct constructor (expression or pattern) is accessible. fn check_field( - &mut self, + &self, hir_id: hir::HirId, // ID of the field use use_ctxt: Span, // syntax context of the field name at the use site def: ty::AdtDef<'tcx>, // definition of the struct or enum @@ -947,7 +957,7 @@ impl<'tcx> NamePrivacyVisitor<'tcx> { // Checks that a field in a struct constructor (expression or pattern) is accessible. fn emit_unreachable_field_error( - &mut self, + &self, fields: Vec<(Symbol, Span, bool /* field is present */)>, def: ty::AdtDef<'tcx>, // definition of the struct or enum update_syntax: Option, @@ -1010,7 +1020,7 @@ impl<'tcx> NamePrivacyVisitor<'tcx> { } fn check_expanded_fields( - &mut self, + &self, adt: ty::AdtDef<'tcx>, variant: &'tcx ty::VariantDef, fields: &[hir::ExprField<'tcx>], @@ -1148,7 +1158,7 @@ impl<'tcx> TypePrivacyVisitor<'tcx> { result.is_break() } - fn check_def_id(&mut self, def_id: DefId, kind: &str, descr: &dyn fmt::Display) -> bool { + fn check_def_id(&self, def_id: DefId, kind: &str, descr: &dyn fmt::Display) -> bool { let is_error = !self.item_is_accessible(def_id); if is_error { self.tcx.dcx().emit_err(ItemIsPrivate { span: self.span, kind, descr: descr.into() }); @@ -1405,7 +1415,7 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> { self } - fn check_def_id(&mut self, def_id: DefId, kind: &str, descr: &dyn fmt::Display) -> bool { + fn check_def_id(&self, def_id: DefId, kind: &str, descr: &dyn fmt::Display) -> bool { if self.leaks_private_dep(def_id) { self.tcx.emit_node_span_lint( lint::builtin::EXPORTED_PRIVATE_DEPENDENCIES, diff --git a/compiler/rustc_public/src/mir/body.rs b/compiler/rustc_public/src/mir/body.rs index 615a5a48d15b..1a939cbe8dba 100644 --- a/compiler/rustc_public/src/mir/body.rs +++ b/compiler/rustc_public/src/mir/body.rs @@ -641,9 +641,7 @@ impl Rvalue { .discriminant_ty() .ok_or_else(|| error!("Expected a `RigidTy` but found: {place_ty:?}")) } - Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf | NullOp::OffsetOf(..), _) => { - Ok(Ty::usize_ty()) - } + Rvalue::NullaryOp(NullOp::OffsetOf(..), _) => Ok(Ty::usize_ty()), Rvalue::NullaryOp(NullOp::ContractChecks, _) | Rvalue::NullaryOp(NullOp::UbChecks, _) => Ok(Ty::bool_ty()), Rvalue::Aggregate(ak, ops) => match *ak { @@ -1024,10 +1022,6 @@ pub enum CastKind { #[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize)] pub enum NullOp { - /// Returns the size of a value of that type. - SizeOf, - /// Returns the minimum alignment of a type. - AlignOf, /// Returns the offset of a field. OffsetOf(Vec<(VariantIdx, FieldIdx)>), /// cfg!(ub_checks), but at codegen time diff --git a/compiler/rustc_public/src/unstable/convert/stable/mir.rs b/compiler/rustc_public/src/unstable/convert/stable/mir.rs index 392347ce345a..f850bc5f89b8 100644 --- a/compiler/rustc_public/src/unstable/convert/stable/mir.rs +++ b/compiler/rustc_public/src/unstable/convert/stable/mir.rs @@ -323,8 +323,6 @@ impl<'tcx> Stable<'tcx> for mir::NullOp<'tcx> { ) -> Self::T { use rustc_middle::mir::NullOp::*; match self { - SizeOf => crate::mir::NullOp::SizeOf, - AlignOf => crate::mir::NullOp::AlignOf, OffsetOf(indices) => crate::mir::NullOp::OffsetOf( indices.iter().map(|idx| idx.stable(tables, cx)).collect(), ), diff --git a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs index 021b206e1e2e..28481f3dcdb3 100644 --- a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs +++ b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs @@ -10,9 +10,8 @@ use rustc_hir as hir; use rustc_hir::LangItem; use rustc_middle::bug; use rustc_middle::ty::{ - self, AssocContainer, ExistentialPredicateStableCmpExt as _, Instance, InstanceKind, IntTy, - List, TraitRef, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt, - UintTy, + self, AssocContainer, ExistentialPredicateStableCmpExt as _, Instance, IntTy, List, TraitRef, + Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt, UintTy, }; use rustc_span::def_id::DefId; use rustc_span::{DUMMY_SP, sym}; @@ -459,6 +458,30 @@ pub(crate) fn transform_instance<'tcx>( instance } +fn default_or_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> Option { + match instance.def { + ty::InstanceKind::Item(def_id) | ty::InstanceKind::FnPtrShim(def_id, _) => { + tcx.opt_associated_item(def_id).map(|item| item.def_id) + } + _ => None, + } +} + +/// Determines if an instance represents a trait method implementation and returns the necessary +/// information for type erasure. +/// +/// This function handles two main cases: +/// +/// * **Implementation in an `impl` block**: When the instance represents a concrete implementation +/// of a trait method in an `impl` block, it extracts the trait reference, method ID, and trait +/// ID from the implementation. The method ID is obtained from the `trait_item_def_id` field of +/// the associated item, which points to the original trait method definition. +/// +/// * **Provided method in a `trait` block or synthetic `shim`**: When the instance represents a +/// default implementation provided in the trait definition itself or a synthetic shim, it uses +/// the instance's own `def_id` as the method ID and determines the trait ID from the associated +/// item. +/// fn implemented_method<'tcx>( tcx: TyCtxt<'tcx>, instance: Instance<'tcx>, @@ -476,10 +499,11 @@ fn implemented_method<'tcx>( trait_id = trait_ref.skip_binder().def_id; impl_id } else if let AssocContainer::Trait = assoc.container - && let InstanceKind::Item(def_id) = instance.def + && let Some(trait_method_def_id) = default_or_shim(tcx, instance) { + // Provided method in a `trait` block or a synthetic `shim` trait_method = assoc; - method_id = def_id; + method_id = trait_method_def_id; trait_id = tcx.parent(method_id); trait_ref = ty::EarlyBinder::bind(TraitRef::from_assoc(tcx, trait_id, instance.args)); trait_id diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 38340f9bd7ec..223d818a2949 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1387,11 +1387,13 @@ symbols! { maybe_uninit, maybe_uninit_uninit, maybe_uninit_zeroed, + mem_align_const, mem_align_of, mem_discriminant, mem_drop, mem_forget, mem_replace, + mem_size_const, mem_size_of, mem_size_of_val, mem_swap, diff --git a/library/alloc/src/borrow.rs b/library/alloc/src/borrow.rs index cb32896161e5..d2ab5412eeab 100644 --- a/library/alloc/src/borrow.rs +++ b/library/alloc/src/borrow.rs @@ -16,12 +16,13 @@ use crate::fmt; #[cfg(not(no_global_oom_handling))] use crate::string::String; +// FIXME(inference): const bounds removed due to inference regressions found by crater; +// see https://github.com/rust-lang/rust/issues/147964 +// #[rustc_const_unstable(feature = "const_convert", issue = "143773")] #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_convert", issue = "143773")] -impl<'a, B: ?Sized> const Borrow for Cow<'a, B> -where - B: ToOwned, - B::Owned: [const] Borrow, +impl<'a, B: ?Sized + ToOwned> Borrow for Cow<'a, B> +// where +// B::Owned: [const] Borrow, { fn borrow(&self) -> &B { &**self @@ -327,11 +328,13 @@ impl Cow<'_, B> { } } +// FIXME(inference): const bounds removed due to inference regressions found by crater; +// see https://github.com/rust-lang/rust/issues/147964 +// #[rustc_const_unstable(feature = "const_convert", issue = "143773")] #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_convert", issue = "143773")] -impl const Deref for Cow<'_, B> -where - B::Owned: [const] Borrow, +impl Deref for Cow<'_, B> +// where +// B::Owned: [const] Borrow, { type Target = B; @@ -441,11 +444,13 @@ where } } +// FIXME(inference): const bounds removed due to inference regressions found by crater; +// see https://github.com/rust-lang/rust/issues/147964 +// #[rustc_const_unstable(feature = "const_convert", issue = "143773")] #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_convert", issue = "143773")] -impl const AsRef for Cow<'_, T> -where - T::Owned: [const] Borrow, +impl AsRef for Cow<'_, T> +// where +// T::Owned: [const] Borrow, { fn as_ref(&self) -> &T { self diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index 87ad5b0ce30e..fd54a375f3ea 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -85,6 +85,7 @@ // // Library features: // tidy-alphabetical-start +#![cfg_attr(not(no_global_oom_handling), feature(string_replace_in_place))] #![feature(alloc_layout_extra)] #![feature(allocator_api)] #![feature(array_into_iter_constructors)] diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs index d5ea5dc1e79e..31743b0e35b2 100644 --- a/library/alloc/src/string.rs +++ b/library/alloc/src/string.rs @@ -2090,6 +2090,67 @@ impl String { unsafe { self.as_mut_vec() }.splice((start, end), replace_with.bytes()); } + /// Replaces the leftmost occurrence of a pattern with another string, in-place. + /// + /// This method can be preferred over [`string = string.replacen(..., 1);`][replacen], + /// as it can use the `String`'s existing capacity to prevent a reallocation if + /// sufficient space is available. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(string_replace_in_place)] + /// + /// let mut s = String::from("Test Results: ❌❌❌"); + /// + /// // Replace the leftmost ❌ with a ✅ + /// s.replace_first('❌', "✅"); + /// assert_eq!(s, "Test Results: ✅❌❌"); + /// ``` + /// + /// [replacen]: ../../std/primitive.str.html#method.replacen + #[cfg(not(no_global_oom_handling))] + #[unstable(feature = "string_replace_in_place", issue = "147949")] + pub fn replace_first(&mut self, from: P, to: &str) { + let range = match self.match_indices(from).next() { + Some((start, match_str)) => start..start + match_str.len(), + None => return, + }; + + self.replace_range(range, to); + } + + /// Replaces the rightmost occurrence of a pattern with another string, in-place. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(string_replace_in_place)] + /// + /// let mut s = String::from("Test Results: ❌❌❌"); + /// + /// // Replace the rightmost ❌ with a ✅ + /// s.replace_last('❌', "✅"); + /// assert_eq!(s, "Test Results: ❌❌✅"); + /// ``` + #[cfg(not(no_global_oom_handling))] + #[unstable(feature = "string_replace_in_place", issue = "147949")] + pub fn replace_last(&mut self, from: P, to: &str) + where + for<'a> P::Searcher<'a>: core::str::pattern::ReverseSearcher<'a>, + { + let range = match self.rmatch_indices(from).next() { + Some((start, match_str)) => start..start + match_str.len(), + None => return, + }; + + self.replace_range(range, to); + } + /// Converts this `String` into a [Box]<[str]>. /// /// Before doing the conversion, this method discards excess capacity like [`shrink_to_fit`]. diff --git a/library/alloctests/tests/lib.rs b/library/alloctests/tests/lib.rs index 49fb21ef5f3a..f94f92397bb1 100644 --- a/library/alloctests/tests/lib.rs +++ b/library/alloctests/tests/lib.rs @@ -36,6 +36,7 @@ #![feature(local_waker)] #![feature(str_as_str)] #![feature(strict_provenance_lints)] +#![feature(string_replace_in_place)] #![feature(vec_deque_pop_if)] #![feature(vec_deque_truncate_front)] #![feature(unique_rc_arc)] diff --git a/library/alloctests/tests/string.rs b/library/alloctests/tests/string.rs index d996c55f9466..ecc5b9dc82ed 100644 --- a/library/alloctests/tests/string.rs +++ b/library/alloctests/tests/string.rs @@ -719,6 +719,40 @@ fn test_replace_range_evil_end_bound() { assert_eq!(Ok(""), str::from_utf8(s.as_bytes())); } +#[test] +fn test_replace_first() { + let mut s = String::from("~ First ❌ Middle ❌ Last ❌ ~"); + s.replace_first("❌", "✅✅"); + assert_eq!(s, "~ First ✅✅ Middle ❌ Last ❌ ~"); + s.replace_first("🦀", "😳"); + assert_eq!(s, "~ First ✅✅ Middle ❌ Last ❌ ~"); + + let mut s = String::from("❌"); + s.replace_first('❌', "✅✅"); + assert_eq!(s, "✅✅"); + + let mut s = String::from(""); + s.replace_first('🌌', "❌"); + assert_eq!(s, ""); +} + +#[test] +fn test_replace_last() { + let mut s = String::from("~ First ❌ Middle ❌ Last ❌ ~"); + s.replace_last("❌", "✅✅"); + assert_eq!(s, "~ First ❌ Middle ❌ Last ✅✅ ~"); + s.replace_last("🦀", "😳"); + assert_eq!(s, "~ First ❌ Middle ❌ Last ✅✅ ~"); + + let mut s = String::from("❌"); + s.replace_last::('❌', "✅✅"); + assert_eq!(s, "✅✅"); + + let mut s = String::from(""); + s.replace_last::('🌌', "❌"); + assert_eq!(s, ""); +} + #[test] fn test_extend_ref() { let mut a = "foo".to_string(); diff --git a/library/core/src/mem/maybe_uninit.rs b/library/core/src/mem/maybe_uninit.rs index 8d666e9b130c..4ed914386eb8 100644 --- a/library/core/src/mem/maybe_uninit.rs +++ b/library/core/src/mem/maybe_uninit.rs @@ -253,6 +253,89 @@ use crate::{fmt, intrinsics, ptr, slice}; /// std::process::exit(*code); // UB! Accessing uninitialized memory. /// } /// ``` +/// +/// # Validity +/// +/// `MaybeUninit` has no validity requirements –- any sequence of [bytes] of +/// the appropriate length, initialized or uninitialized, are a valid +/// representation. +/// +/// Moving or copying a value of type `MaybeUninit` (i.e., performing a +/// "typed copy") will exactly preserve the contents, including the +/// [provenance], of all non-padding bytes of type `T` in the value's +/// representation. +/// +/// Therefore `MaybeUninit` can be used to perform a round trip of a value from +/// type `T` to type `MaybeUninit` then back to type `T`, while preserving +/// the original value, if two conditions are met. One, type `U` must have the +/// same size as type `T`. Two, for all byte offsets where type `U` has padding, +/// the corresponding bytes in the representation of the value must be +/// uninitialized. +/// +/// For example, due to the fact that the type `[u8; size_of::]` has no +/// padding, the following is sound for any type `T` and will return the +/// original value: +/// +/// ```rust,no_run +/// # use core::mem::{MaybeUninit, transmute}; +/// # struct T; +/// fn identity(t: T) -> T { +/// unsafe { +/// let u: MaybeUninit<[u8; size_of::()]> = transmute(t); +/// transmute(u) // OK. +/// } +/// } +/// ``` +/// +/// Note: Copying a value that contains references may implicitly reborrow them +/// causing the provenance of the returned value to differ from that of the +/// original. This applies equally to the trivial identity function: +/// +/// ```rust,no_run +/// fn trivial_identity(t: T) -> T { t } +/// ``` +/// +/// Note: Moving or copying a value whose representation has initialized bytes +/// at byte offsets where the type has padding may lose the value of those +/// bytes, so while the original value will be preserved, the original +/// *representation* of that value as bytes may not be. Again, this applies +/// equally to `trivial_identity`. +/// +/// Note: Performing this round trip when type `U` has padding at byte offsets +/// where the representation of the original value has initialized bytes may +/// produce undefined behavior or a different value. For example, the following +/// is unsound since `T` requires all bytes to be initialized: +/// +/// ```rust,no_run +/// # use core::mem::{MaybeUninit, transmute}; +/// #[repr(C)] struct T([u8; 4]); +/// #[repr(C)] struct U(u8, u16); +/// fn unsound_identity(t: T) -> T { +/// unsafe { +/// let u: MaybeUninit = transmute(t); +/// transmute(u) // UB. +/// } +/// } +/// ``` +/// +/// Conversely, the following is sound since `T` allows uninitialized bytes in +/// the representation of a value, but the round trip may alter the value: +/// +/// ```rust,no_run +/// # use core::mem::{MaybeUninit, transmute}; +/// #[repr(C)] struct T(MaybeUninit<[u8; 4]>); +/// #[repr(C)] struct U(u8, u16); +/// fn non_identity(t: T) -> T { +/// unsafe { +/// // May lose an initialized byte. +/// let u: MaybeUninit = transmute(t); +/// transmute(u) +/// } +/// } +/// ``` +/// +/// [bytes]: ../../reference/memory-model.html#bytes +/// [provenance]: crate::ptr#provenance #[stable(feature = "maybe_uninit", since = "1.36.0")] // Lang item so we can wrap other types in it. This is useful for coroutines. #[lang = "maybe_uninit"] diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs index a53726928477..619e8a263db4 100644 --- a/library/core/src/mem/mod.rs +++ b/library/core/src/mem/mod.rs @@ -333,7 +333,7 @@ pub fn forget_unsized(t: T) { #[rustc_const_stable(feature = "const_mem_size_of", since = "1.24.0")] #[rustc_diagnostic_item = "mem_size_of"] pub const fn size_of() -> usize { - intrinsics::size_of::() + ::SIZE } /// Returns the size of the pointed-to value in bytes. @@ -441,7 +441,7 @@ pub const unsafe fn size_of_val_raw(val: *const T) -> usize { #[stable(feature = "rust1", since = "1.0.0")] #[deprecated(note = "use `align_of` instead", since = "1.2.0", suggestion = "align_of")] pub fn min_align_of() -> usize { - intrinsics::align_of::() + ::ALIGN } /// Returns the [ABI]-required minimum alignment of the type of the value that `val` points to in @@ -488,7 +488,7 @@ pub fn min_align_of_val(val: &T) -> usize { #[rustc_const_stable(feature = "const_align_of", since = "1.24.0")] #[rustc_diagnostic_item = "mem_align_of"] pub const fn align_of() -> usize { - intrinsics::align_of::() + ::ALIGN } /// Returns the [ABI]-required minimum alignment of the type of the value that `val` points to in @@ -1236,6 +1236,16 @@ pub const fn variant_count() -> usize { #[doc(hidden)] #[unstable(feature = "sized_type_properties", issue = "none")] pub trait SizedTypeProperties: Sized { + #[doc(hidden)] + #[unstable(feature = "sized_type_properties", issue = "none")] + #[lang = "mem_size_const"] + const SIZE: usize = intrinsics::size_of::(); + + #[doc(hidden)] + #[unstable(feature = "sized_type_properties", issue = "none")] + #[lang = "mem_align_const"] + const ALIGN: usize = intrinsics::align_of::(); + /// `true` if this type requires no storage. /// `false` if its [size](size_of) is greater than zero. /// @@ -1263,7 +1273,7 @@ pub trait SizedTypeProperties: Sized { /// ``` #[doc(hidden)] #[unstable(feature = "sized_type_properties", issue = "none")] - const IS_ZST: bool = size_of::() == 0; + const IS_ZST: bool = Self::SIZE == 0; #[doc(hidden)] #[unstable(feature = "sized_type_properties", issue = "none")] @@ -1275,7 +1285,7 @@ pub trait SizedTypeProperties: Sized { /// which is never allowed for a single object. #[doc(hidden)] #[unstable(feature = "sized_type_properties", issue = "none")] - const MAX_SLICE_LEN: usize = match size_of::() { + const MAX_SLICE_LEN: usize = match Self::SIZE { 0 => usize::MAX, n => (isize::MAX as usize) / n, }; diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 60c8f53a0cc4..a8c50cec01e0 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -290,8 +290,6 @@ #![feature(ffi_const)] #![feature(formatting_options)] #![feature(funnel_shifts)] -#![feature(hash_map_internals)] -#![feature(hash_map_macro)] #![feature(if_let_guard)] #![feature(intra_doc_pointers)] #![feature(iter_advance_by)] diff --git a/library/std/src/macros.rs b/library/std/src/macros.rs index 254570ae9c83..25e2b7ea1370 100644 --- a/library/std/src/macros.rs +++ b/library/std/src/macros.rs @@ -379,77 +379,3 @@ macro_rules! dbg { ($($crate::dbg!($val)),+,) }; } - -#[doc(hidden)] -#[macro_export] -#[allow_internal_unstable(hash_map_internals)] -#[unstable(feature = "hash_map_internals", issue = "none")] -macro_rules! repetition_utils { - (@count $($tokens:tt),*) => {{ - [$($crate::repetition_utils!(@replace $tokens => ())),*].len() - }}; - - (@replace $x:tt => $y:tt) => { $y } -} - -/// Creates a [`HashMap`] containing the arguments. -/// -/// `hash_map!` allows specifying the entries that make -/// up the [`HashMap`] where the key and value are separated by a `=>`. -/// -/// The entries are separated by commas with a trailing comma being allowed. -/// -/// It is semantically equivalent to using repeated [`HashMap::insert`] -/// on a newly created hashmap. -/// -/// `hash_map!` will attempt to avoid repeated reallocations by -/// using [`HashMap::with_capacity`]. -/// -/// # Examples -/// -/// ```rust -/// #![feature(hash_map_macro)] -/// -/// let map = hash_map! { -/// "key" => "value", -/// "key1" => "value1" -/// }; -/// -/// assert_eq!(map.get("key"), Some(&"value")); -/// assert_eq!(map.get("key1"), Some(&"value1")); -/// assert!(map.get("brrrrrrooooommm").is_none()); -/// ``` -/// -/// And with a trailing comma -/// -///```rust -/// #![feature(hash_map_macro)] -/// -/// let map = hash_map! { -/// "key" => "value", // notice the , -/// }; -/// -/// assert_eq!(map.get("key"), Some(&"value")); -/// ``` -/// -/// The key and value are moved into the HashMap. -/// -/// [`HashMap`]: crate::collections::HashMap -/// [`HashMap::insert`]: crate::collections::HashMap::insert -/// [`HashMap::with_capacity`]: crate::collections::HashMap::with_capacity -#[macro_export] -#[allow_internal_unstable(hash_map_internals)] -#[unstable(feature = "hash_map_macro", issue = "144032")] -macro_rules! hash_map { - () => {{ - $crate::collections::HashMap::new() - }}; - - ( $( $key:expr => $value:expr ),* $(,)? ) => {{ - let mut map = $crate::collections::HashMap::with_capacity( - const { $crate::repetition_utils!(@count $($key),*) } - ); - $( map.insert($key, $value); )* - map - }} -} diff --git a/library/std/tests/ambiguous-hash_map.rs b/library/std/tests/ambiguous-hash_map.rs new file mode 100644 index 000000000000..bd5ae5a8957b --- /dev/null +++ b/library/std/tests/ambiguous-hash_map.rs @@ -0,0 +1,17 @@ +//! Make sure that a `std` macro `hash_map!` does not cause ambiguity +//! with a local glob import with the same name. +//! +//! See regression https://github.com/rust-lang/rust/issues/147971 + +mod module { + macro_rules! hash_map { + () => {}; + } + pub(crate) use hash_map; +} + +use module::*; + +fn main() { + hash_map! {} +} diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index adfc7481c73a..6bb8f2043f4b 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -5,7 +5,7 @@ use std::iter; use askama::Template; use rustc_abi::VariantIdx; use rustc_ast::join_path_syms; -use rustc_data_structures::fx::{FxHashMap, FxIndexSet}; +use rustc_data_structures::fx::{FxHashMap, FxIndexMap, FxIndexSet}; use rustc_hir as hir; use rustc_hir::def::CtorKind; use rustc_hir::def_id::DefId; @@ -307,8 +307,12 @@ fn item_module(cx: &Context<'_>, item: &clean::Item, items: &[clean::Item]) -> i fmt::from_fn(|w| { write!(w, "{}", document(cx, item, None, HeadingOffset::H2))?; - let mut not_stripped_items = - items.iter().filter(|i| !i.is_stripped()).enumerate().collect::>(); + let mut not_stripped_items: FxIndexMap> = + FxIndexMap::default(); + + for (index, item) in items.iter().filter(|i| !i.is_stripped()).enumerate() { + not_stripped_items.entry(item.type_()).or_default().push((index, item)); + } // the order of item types in the listing fn reorder(ty: ItemType) -> u8 { @@ -331,11 +335,6 @@ fn item_module(cx: &Context<'_>, item: &clean::Item, items: &[clean::Item]) -> i } fn cmp(i1: &clean::Item, i2: &clean::Item, tcx: TyCtxt<'_>) -> Ordering { - let rty1 = reorder(i1.type_()); - let rty2 = reorder(i2.type_()); - if rty1 != rty2 { - return rty1.cmp(&rty2); - } let is_stable1 = i1.stability(tcx).as_ref().map(|s| s.level.is_stable()).unwrap_or(true); let is_stable2 = @@ -357,7 +356,9 @@ fn item_module(cx: &Context<'_>, item: &clean::Item, items: &[clean::Item]) -> i match cx.shared.module_sorting { ModuleSorting::Alphabetical => { - not_stripped_items.sort_by(|(_, i1), (_, i2)| cmp(i1, i2, tcx)); + for items in not_stripped_items.values_mut() { + items.sort_by(|(_, i1), (_, i2)| cmp(i1, i2, tcx)); + } } ModuleSorting::DeclarationOrder => {} } @@ -380,155 +381,152 @@ fn item_module(cx: &Context<'_>, item: &clean::Item, items: &[clean::Item]) -> i // can be identical even if the elements are different (mostly in imports). // So in case this is an import, we keep everything by adding a "unique id" // (which is the position in the vector). - not_stripped_items.dedup_by_key(|(idx, i)| { - ( - i.item_id, - if i.name.is_some() { Some(full_path(cx, i)) } else { None }, - i.type_(), - if i.is_import() { *idx } else { 0 }, - ) - }); + for items in not_stripped_items.values_mut() { + items.dedup_by_key(|(idx, i)| { + ( + i.item_id, + if i.name.is_some() { Some(full_path(cx, i)) } else { None }, + i.type_(), + if i.is_import() { *idx } else { 0 }, + ) + }); + } debug!("{not_stripped_items:?}"); - let mut last_section = None; - for (_, myitem) in ¬_stripped_items { - let my_section = item_ty_to_section(myitem.type_()); - if Some(my_section) != last_section { - if last_section.is_some() { - w.write_str(ITEM_TABLE_CLOSE)?; - } - last_section = Some(my_section); - let section_id = my_section.id(); - let tag = - if section_id == "reexports" { REEXPORTS_TABLE_OPEN } else { ITEM_TABLE_OPEN }; - write!( - w, - "{}", - write_section_heading(my_section.name(), &cx.derive_id(section_id), None, tag) - )?; - } + let mut types = not_stripped_items.keys().copied().collect::>(); + types.sort_unstable_by(|a, b| reorder(*a).cmp(&reorder(*b))); - match myitem.kind { - clean::ExternCrateItem { ref src } => { - use crate::html::format::print_anchor; + for type_ in types { + let my_section = item_ty_to_section(type_); + let tag = if my_section == super::ItemSection::Reexports { + REEXPORTS_TABLE_OPEN + } else { + ITEM_TABLE_OPEN + }; + write!( + w, + "{}", + write_section_heading(my_section.name(), &cx.derive_id(my_section.id()), None, tag) + )?; - match *src { - Some(src) => { - write!( - w, - "
{}extern crate {} as {};", - visibility_print_with_space(myitem, cx), - print_anchor(myitem.item_id.expect_def_id(), src, cx), - EscapeBodyTextWithWbr(myitem.name.unwrap().as_str()) - )?; - } - None => { - write!( - w, - "
{}extern crate {};", - visibility_print_with_space(myitem, cx), - print_anchor( - myitem.item_id.expect_def_id(), - myitem.name.unwrap(), - cx - ) - )?; - } - } - w.write_str("
")?; - } + for (_, myitem) in ¬_stripped_items[&type_] { + match myitem.kind { + clean::ExternCrateItem { ref src } => { + use crate::html::format::print_anchor; - clean::ImportItem(ref import) => { - let stab_tags = import.source.did.map_or_else(String::new, |import_def_id| { - print_extra_info_tags(tcx, myitem, item, Some(import_def_id)).to_string() - }); - - let id = match import.kind { - clean::ImportKind::Simple(s) => { - format!(" id=\"{}\"", cx.derive_id(format!("reexport.{s}"))) - } - clean::ImportKind::Glob => String::new(), - }; - write!( - w, - "\ - " - )?; - render_attributes_in_code(w, myitem, "", cx); - write!( - w, - "{vis}{imp}{stab_tags}\ - ", - vis = visibility_print_with_space(myitem, cx), - imp = import.print(cx) - )?; - } - - _ => { - if myitem.name.is_none() { - continue; - } - - let unsafety_flag = match myitem.kind { - clean::FunctionItem(_) | clean::ForeignFunctionItem(..) - if myitem.fn_header(tcx).unwrap().safety - == hir::HeaderSafety::Normal(hir::Safety::Unsafe) => - { - "" - } - clean::ForeignStaticItem(_, hir::Safety::Unsafe) => { - "" - } - _ => "", - }; - - let visibility_and_hidden = match myitem.visibility(tcx) { - Some(ty::Visibility::Restricted(_)) => { - if myitem.is_doc_hidden() { - // Don't separate with a space when there are two of them - " 🔒👻 " - } else { - " 🔒 " + match *src { + Some(src) => { + write!( + w, + "
{}extern crate {} as {};", + visibility_print_with_space(myitem, cx), + print_anchor(myitem.item_id.expect_def_id(), src, cx), + EscapeBodyTextWithWbr(myitem.name.unwrap().as_str()) + )?; + } + None => { + write!( + w, + "
{}extern crate {};", + visibility_print_with_space(myitem, cx), + print_anchor( + myitem.item_id.expect_def_id(), + myitem.name.unwrap(), + cx + ) + )?; } } - _ if myitem.is_doc_hidden() => { - " 👻 " + } + clean::ImportItem(ref import) => { + let stab_tags = + import.source.did.map_or_else(String::new, |import_def_id| { + print_extra_info_tags(tcx, myitem, item, Some(import_def_id)) + .to_string() + }); + let id = match import.kind { + clean::ImportKind::Simple(s) => { + format!(" id=\"{}\"", cx.derive_id(format!("reexport.{s}"))) + } + clean::ImportKind::Glob => String::new(), + }; + write!( + w, + "\ + " + )?; + render_attributes_in_code(w, myitem, "", cx); + write!( + w, + "{vis}{imp}{stab_tags}\ +
", + vis = visibility_print_with_space(myitem, cx), + imp = import.print(cx) + )?; + } + _ => { + if myitem.name.is_none() { + continue; } - _ => "", - }; - let docs = - MarkdownSummaryLine(&myitem.doc_value(), &myitem.links(cx)).into_string(); - let (docs_before, docs_after) = - if docs.is_empty() { ("", "") } else { ("
", "
") }; - write!( - w, - "
\ - \ - {name}\ - \ - {visibility_and_hidden}\ - {unsafety_flag}\ - {stab_tags}\ -
\ - {docs_before}{docs}{docs_after}", - name = EscapeBodyTextWithWbr(myitem.name.unwrap().as_str()), - visibility_and_hidden = visibility_and_hidden, - stab_tags = print_extra_info_tags(tcx, myitem, item, None), - class = myitem.type_(), - unsafety_flag = unsafety_flag, - href = print_item_path(myitem.type_(), myitem.name.unwrap().as_str()), - title1 = myitem.type_(), - title2 = full_path(cx, myitem), - )?; + let unsafety_flag = match myitem.kind { + clean::FunctionItem(_) | clean::ForeignFunctionItem(..) + if myitem.fn_header(tcx).unwrap().safety + == hir::HeaderSafety::Normal(hir::Safety::Unsafe) => + { + "" + } + clean::ForeignStaticItem(_, hir::Safety::Unsafe) => { + "" + } + _ => "", + }; + let visibility_and_hidden = match myitem.visibility(tcx) { + Some(ty::Visibility::Restricted(_)) => { + if myitem.is_doc_hidden() { + // Don't separate with a space when there are two of them + " 🔒👻 " + } else { + " 🔒 " + } + } + _ if myitem.is_doc_hidden() => { + " 👻 " + } + _ => "", + }; + + let docs = MarkdownSummaryLine(&myitem.doc_value(), &myitem.links(cx)) + .into_string(); + let (docs_before, docs_after) = + if docs.is_empty() { ("", "") } else { ("
", "
") }; + write!( + w, + "
\ + \ + {name}\ + \ + {visibility_and_hidden}\ + {unsafety_flag}\ + {stab_tags}\ +
\ + {docs_before}{docs}{docs_after}", + name = EscapeBodyTextWithWbr(myitem.name.unwrap().as_str()), + visibility_and_hidden = visibility_and_hidden, + stab_tags = print_extra_info_tags(tcx, myitem, item, None), + class = type_, + unsafety_flag = unsafety_flag, + href = print_item_path(type_, myitem.name.unwrap().as_str()), + title1 = myitem.type_(), + title2 = full_path(cx, myitem), + )?; + } } } - } - - if last_section.is_some() { w.write_str(ITEM_TABLE_CLOSE)?; } + Ok(()) }) } diff --git a/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs b/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs index b01e160e2297..22b74ab16d61 100644 --- a/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs +++ b/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs @@ -562,7 +562,7 @@ pub fn eq_foreign_item_kind(l: &ForeignItemKind, r: &ForeignItemKind) -> bool { defaultness: ld, ident: li, generics: lg, - where_clauses: _, + after_where_clause: lw, bounds: lb, ty: lt, }), @@ -570,7 +570,7 @@ pub fn eq_foreign_item_kind(l: &ForeignItemKind, r: &ForeignItemKind) -> bool { defaultness: rd, ident: ri, generics: rg, - where_clauses: _, + after_where_clause: rw, bounds: rb, ty: rt, }), @@ -578,6 +578,7 @@ pub fn eq_foreign_item_kind(l: &ForeignItemKind, r: &ForeignItemKind) -> bool { eq_defaultness(*ld, *rd) && eq_id(*li, *ri) && eq_generics(lg, rg) + && over(&lw.predicates, &rw.predicates, eq_where_predicate) && over(lb, rb, eq_generic_bound) && both(lt.as_ref(), rt.as_ref(), |l, r| eq_ty(l, r)) }, @@ -645,7 +646,7 @@ pub fn eq_assoc_item_kind(l: &AssocItemKind, r: &AssocItemKind) -> bool { defaultness: ld, ident: li, generics: lg, - where_clauses: _, + after_where_clause: lw, bounds: lb, ty: lt, }), @@ -653,7 +654,7 @@ pub fn eq_assoc_item_kind(l: &AssocItemKind, r: &AssocItemKind) -> bool { defaultness: rd, ident: ri, generics: rg, - where_clauses: _, + after_where_clause: rw, bounds: rb, ty: rt, }), @@ -661,6 +662,7 @@ pub fn eq_assoc_item_kind(l: &AssocItemKind, r: &AssocItemKind) -> bool { eq_defaultness(*ld, *rd) && eq_id(*li, *ri) && eq_generics(lg, rg) + && over(&lw.predicates, &rw.predicates, eq_where_predicate) && over(lb, rb, eq_generic_bound) && both(lt.as_ref(), rt.as_ref(), |l, r| eq_ty(l, r)) }, diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs index 7722bebdbbe0..90ea2616890a 100644 --- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs +++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs @@ -194,10 +194,7 @@ fn check_rvalue<'tcx>( )) } }, - Rvalue::NullaryOp( - NullOp::SizeOf | NullOp::AlignOf | NullOp::OffsetOf(_) | NullOp::UbChecks | NullOp::ContractChecks, - _, - ) + Rvalue::NullaryOp(NullOp::OffsetOf(_) | NullOp::UbChecks | NullOp::ContractChecks, _) | Rvalue::ShallowInitBox(_, _) => Ok(()), Rvalue::UnaryOp(_, operand) => { let ty = operand.ty(body, cx.tcx); diff --git a/src/tools/clippy/tests/ui/bool_assert_comparison.stderr b/src/tools/clippy/tests/ui/bool_assert_comparison.stderr index 72aa6303a202..f823f08f31dc 100644 --- a/src/tools/clippy/tests/ui/bool_assert_comparison.stderr +++ b/src/tools/clippy/tests/ui/bool_assert_comparison.stderr @@ -272,8 +272,10 @@ LL | assert_eq!(a!(), true); | help: replace it with `assert!(..)` | -LL - assert_eq!(a!(), true); -LL + assert!(a!()); +LL | true +... +LL | +LL ~ assert!(a!()); | error: used `assert_eq!` with a literal bool @@ -284,8 +286,10 @@ LL | assert_eq!(true, b!()); | help: replace it with `assert!(..)` | -LL - assert_eq!(true, b!()); -LL + assert!(b!()); +LL | true +... +LL | +LL ~ assert!(b!()); | error: used `debug_assert_eq!` with a literal bool diff --git a/src/tools/miri/tests/fail/layout_cycle.stderr b/src/tools/miri/tests/fail/layout_cycle.stderr index c233f85063cc..dae693493122 100644 --- a/src/tools/miri/tests/fail/layout_cycle.stderr +++ b/src/tools/miri/tests/fail/layout_cycle.stderr @@ -2,29 +2,20 @@ error[E0391]: cycle detected when computing layout of `S>` | = note: ...which requires computing layout of ` as Tr>::I`... = note: ...which again requires computing layout of `S>`, completing the cycle - = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information - -error: post-monomorphization error: a cycle occurred during layout computation +note: cycle used when const-evaluating + checking `core::mem::SizedTypeProperties::SIZE` --> RUSTLIB/core/src/mem/mod.rs:LL:CC | -LL | intrinsics::size_of::() - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ post-monomorphization error occurred here - | - = note: BACKTRACE: - = note: inside `std::mem::size_of::>>` at RUSTLIB/core/src/mem/mod.rs:LL:CC -note: inside `foo::>` - --> tests/fail/layout_cycle.rs:LL:CC - | -LL | mem::size_of::>() - | ^^^^^^^^^^^^^^^^^^^^^^ -note: inside `main` - --> tests/fail/layout_cycle.rs:LL:CC - | -LL | println!("{}", foo::>()); - | ^^^^^^^^^^^^^^ +LL | const SIZE: usize = intrinsics::size_of::(); + | ^^^^^^^^^^^^^^^^^ + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information -note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace +error[E0080]: a cycle occurred during layout computation + --> RUSTLIB/core/src/mem/mod.rs:LL:CC + | +LL | const SIZE: usize = intrinsics::size_of::(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `> as std::mem::SizedTypeProperties>::SIZE` failed here error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0391`. +Some errors have detailed explanations: E0080, E0391. +For more information about an error, try `rustc --explain E0080`. diff --git a/src/tools/rustfmt/src/items.rs b/src/tools/rustfmt/src/items.rs index 75e468b35256..a2e89c10a480 100644 --- a/src/tools/rustfmt/src/items.rs +++ b/src/tools/rustfmt/src/items.rs @@ -836,8 +836,7 @@ pub(crate) fn format_impl( let where_span_end = context.snippet_provider.opt_span_before(missing_span, "{"); let where_clause_str = rewrite_where_clause( context, - &generics.where_clause.predicates, - generics.where_clause.span, + &generics.where_clause, context.config.brace_style(), Shape::legacy(where_budget, offset.block_only()), false, @@ -1224,8 +1223,7 @@ pub(crate) fn format_trait( let option = WhereClauseOption::snuggled(&generics_str); let where_clause_str = rewrite_where_clause( context, - &generics.where_clause.predicates, - generics.where_clause.span, + &generics.where_clause, context.config.brace_style(), Shape::legacy(where_budget, offset.block_only()), where_on_new_line, @@ -1350,8 +1348,7 @@ impl<'a> Rewrite for TraitAliasBounds<'a> { let where_str = rewrite_where_clause( context, - &self.generics.where_clause.predicates, - self.generics.where_clause.span, + &self.generics.where_clause, context.config.brace_style(), shape, false, @@ -1621,8 +1618,7 @@ fn format_tuple_struct( let option = WhereClauseOption::new(true, WhereClauseSpace::Newline); rewrite_where_clause( context, - &generics.where_clause.predicates, - generics.where_clause.span, + &generics.where_clause, context.config.brace_style(), Shape::legacy(where_budget, offset.block_only()), false, @@ -1691,7 +1687,7 @@ struct TyAliasRewriteInfo<'c, 'g>( &'c RewriteContext<'c>, Indent, &'g ast::Generics, - ast::TyAliasWhereClauses, + &'g ast::WhereClause, symbol::Ident, Span, ); @@ -1712,13 +1708,13 @@ pub(crate) fn rewrite_type_alias<'a>( ref generics, ref bounds, ref ty, - where_clauses, + ref after_where_clause, } = *ty_alias_kind; let ty_opt = ty.as_ref(); let rhs_hi = ty .as_ref() - .map_or(where_clauses.before.span.hi(), |ty| ty.span.hi()); - let rw_info = &TyAliasRewriteInfo(context, indent, generics, where_clauses, ident, span); + .map_or(generics.where_clause.span.hi(), |ty| ty.span.hi()); + let rw_info = &TyAliasRewriteInfo(context, indent, generics, after_where_clause, ident, span); let op_ty = opaque_ty(ty); // Type Aliases are formatted slightly differently depending on the context // in which they appear, whether they are opaque, and whether they are associated. @@ -1762,11 +1758,7 @@ fn rewrite_ty( vis: &ast::Visibility, ) -> RewriteResult { let mut result = String::with_capacity(128); - let TyAliasRewriteInfo(context, indent, generics, where_clauses, ident, span) = *rw_info; - let (before_where_predicates, after_where_predicates) = generics - .where_clause - .predicates - .split_at(where_clauses.split); + let TyAliasRewriteInfo(context, indent, generics, after_where_clause, ident, span) = *rw_info; result.push_str(&format!("{}type ", format_visibility(context, vis))); let ident_str = rewrite_ident(context, ident); @@ -1804,8 +1796,7 @@ fn rewrite_ty( } let before_where_clause_str = rewrite_where_clause( context, - before_where_predicates, - where_clauses.before.span, + &generics.where_clause, context.config.brace_style(), Shape::legacy(where_budget, indent), false, @@ -1820,9 +1811,9 @@ fn rewrite_ty( // If there are any where clauses, add a newline before the assignment. // If there is a before where clause, do not indent, but if there is // only an after where clause, additionally indent the type. - if !before_where_predicates.is_empty() { + if !generics.where_clause.predicates.is_empty() { result.push_str(&indent.to_string_with_newline(context.config)); - } else if !after_where_predicates.is_empty() { + } else if !after_where_clause.predicates.is_empty() { result.push_str( &indent .block_indent(context.config) @@ -1835,7 +1826,7 @@ fn rewrite_ty( let comment_span = context .snippet_provider .opt_span_before(span, "=") - .map(|op_lo| mk_sp(where_clauses.before.span.hi(), op_lo)); + .map(|op_lo| mk_sp(generics.where_clause.span.hi(), op_lo)); let lhs = match comment_span { Some(comment_span) @@ -1846,7 +1837,7 @@ fn rewrite_ty( .unknown_error()?, ) => { - let comment_shape = if !before_where_predicates.is_empty() { + let comment_shape = if !generics.where_clause.predicates.is_empty() { Shape::indented(indent, context.config) } else { let shape = Shape::indented(indent, context.config); @@ -1869,7 +1860,7 @@ fn rewrite_ty( // 1 = `;` unless there's a trailing where clause let shape = Shape::indented(indent, context.config); - let shape = if after_where_predicates.is_empty() { + let shape = if after_where_clause.predicates.is_empty() { Shape::indented(indent, context.config) .sub_width(1) .max_width_error(shape.width, span)? @@ -1881,12 +1872,11 @@ fn rewrite_ty( result }; - if !after_where_predicates.is_empty() { + if !after_where_clause.predicates.is_empty() { let option = WhereClauseOption::new(true, WhereClauseSpace::Newline); let after_where_clause_str = rewrite_where_clause( context, - after_where_predicates, - where_clauses.after.span, + &after_where_clause, context.config.brace_style(), Shape::indented(indent, context.config), false, @@ -2728,8 +2718,7 @@ fn rewrite_fn_base( } let where_clause_str = rewrite_where_clause( context, - &where_clause.predicates, - where_clause.span, + &where_clause, context.config.brace_style(), Shape::indented(indent, context.config), true, @@ -3158,8 +3147,7 @@ fn rewrite_bounds_on_where_clause( fn rewrite_where_clause( context: &RewriteContext<'_>, - predicates: &[ast::WherePredicate], - where_span: Span, + where_clause: &ast::WhereClause, brace_style: BraceStyle, shape: Shape, on_new_line: bool, @@ -3168,6 +3156,12 @@ fn rewrite_where_clause( span_end_before_where: BytePos, where_clause_option: WhereClauseOption, ) -> RewriteResult { + let ast::WhereClause { + ref predicates, + span: where_span, + has_where_token: _, + } = *where_clause; + if predicates.is_empty() { return Ok(String::new()); } @@ -3354,8 +3348,7 @@ fn format_generics( } let where_clause_str = rewrite_where_clause( context, - &generics.where_clause.predicates, - generics.where_clause.span, + &generics.where_clause, brace_style, Shape::legacy(budget, offset.block_only()), true, diff --git a/src/tools/tidy/src/alphabetical.rs b/src/tools/tidy/src/alphabetical.rs index f93d3b561130..3845e2269e9b 100644 --- a/src/tools/tidy/src/alphabetical.rs +++ b/src/tools/tidy/src/alphabetical.rs @@ -24,7 +24,7 @@ use std::fmt::Display; use std::iter::Peekable; use std::path::Path; -use crate::diagnostics::{CheckId, DiagCtx, RunningCheck}; +use crate::diagnostics::{CheckId, RunningCheck, TidyCtx}; use crate::walk::{filter_dirs, walk}; #[cfg(test)] @@ -130,8 +130,8 @@ fn check_lines<'a>( } } -pub fn check(path: &Path, diag_ctx: DiagCtx) { - let mut check = diag_ctx.start_check(CheckId::new("alphabetical").path(path)); +pub fn check(path: &Path, tidy_ctx: TidyCtx) { + let mut check = tidy_ctx.start_check(CheckId::new("alphabetical").path(path)); let skip = |path: &_, _is_dir| filter_dirs(path) || path.ends_with("tidy/src/alphabetical/tests.rs"); diff --git a/src/tools/tidy/src/alphabetical/tests.rs b/src/tools/tidy/src/alphabetical/tests.rs index b181ab8f744f..3e0dd798ab9d 100644 --- a/src/tools/tidy/src/alphabetical/tests.rs +++ b/src/tools/tidy/src/alphabetical/tests.rs @@ -1,12 +1,12 @@ use std::path::Path; use crate::alphabetical::check_lines; -use crate::diagnostics::DiagCtx; +use crate::diagnostics::{TidyCtx, TidyFlags}; #[track_caller] fn test(lines: &str, name: &str, expected_msg: &str, expected_bad: bool) { - let diag_ctx = DiagCtx::new(Path::new("/"), false); - let mut check = diag_ctx.start_check("alphabetical-test"); + let tidy_ctx = TidyCtx::new(Path::new("/"), false, TidyFlags::default()); + let mut check = tidy_ctx.start_check("alphabetical-test"); check_lines(&name, lines.lines().enumerate(), &mut check); assert_eq!(expected_bad, check.is_bad()); diff --git a/src/tools/tidy/src/bins.rs b/src/tools/tidy/src/bins.rs index 10b618699716..2dcbd8e9b38a 100644 --- a/src/tools/tidy/src/bins.rs +++ b/src/tools/tidy/src/bins.rs @@ -12,13 +12,13 @@ pub use os_impl::*; mod os_impl { use std::path::Path; - use crate::diagnostics::DiagCtx; + use crate::diagnostics::TidyCtx; pub fn check_filesystem_support(_sources: &[&Path], _output: &Path) -> bool { return false; } - pub fn check(_path: &Path, _diag_ctx: DiagCtx) {} + pub fn check(_path: &Path, _tidy_ctx: TidyCtx) {} } #[cfg(unix)] @@ -38,7 +38,7 @@ mod os_impl { use FilesystemSupport::*; - use crate::diagnostics::DiagCtx; + use crate::diagnostics::TidyCtx; fn is_executable(path: &Path) -> std::io::Result { Ok(path.metadata()?.mode() & 0o111 != 0) @@ -110,8 +110,8 @@ mod os_impl { } #[cfg(unix)] - pub fn check(path: &Path, diag_ctx: DiagCtx) { - let mut check = diag_ctx.start_check("bins"); + pub fn check(path: &Path, tidy_ctx: TidyCtx) { + let mut check = tidy_ctx.start_check("bins"); use std::ffi::OsStr; diff --git a/src/tools/tidy/src/debug_artifacts.rs b/src/tools/tidy/src/debug_artifacts.rs index 19effaede817..a1a0f37f7844 100644 --- a/src/tools/tidy/src/debug_artifacts.rs +++ b/src/tools/tidy/src/debug_artifacts.rs @@ -2,13 +2,13 @@ use std::path::Path; -use crate::diagnostics::{CheckId, DiagCtx}; +use crate::diagnostics::{CheckId, TidyCtx}; use crate::walk::{filter_dirs, filter_not_rust, walk}; const GRAPHVIZ_POSTFLOW_MSG: &str = "`borrowck_graphviz_postflow` attribute in test"; -pub fn check(test_dir: &Path, diag_ctx: DiagCtx) { - let mut check = diag_ctx.start_check(CheckId::new("debug_artifacts").path(test_dir)); +pub fn check(test_dir: &Path, tidy_ctx: TidyCtx) { + let mut check = tidy_ctx.start_check(CheckId::new("debug_artifacts").path(test_dir)); walk( test_dir, diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index 86845022c82b..6a1721df1642 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -9,7 +9,7 @@ use build_helper::ci::CiEnv; use cargo_metadata::semver::Version; use cargo_metadata::{Metadata, Package, PackageId}; -use crate::diagnostics::{DiagCtx, RunningCheck}; +use crate::diagnostics::{RunningCheck, TidyCtx}; #[path = "../../../bootstrap/src/utils/proc_macro_deps.rs"] mod proc_macro_deps; @@ -615,8 +615,9 @@ const PERMITTED_CRANELIFT_DEPENDENCIES: &[&str] = &[ /// /// `root` is path to the directory with the root `Cargo.toml` (for the workspace). `cargo` is path /// to the cargo executable. -pub fn check(root: &Path, cargo: &Path, bless: bool, diag_ctx: DiagCtx) { - let mut check = diag_ctx.start_check("deps"); +pub fn check(root: &Path, cargo: &Path, tidy_ctx: TidyCtx) { + let mut check = tidy_ctx.start_check("deps"); + let bless = tidy_ctx.is_bless_enabled(); let mut checked_runtime_licenses = false; diff --git a/src/tools/tidy/src/diagnostics.rs b/src/tools/tidy/src/diagnostics.rs index 6e95f97d0104..1e25f862522e 100644 --- a/src/tools/tidy/src/diagnostics.rs +++ b/src/tools/tidy/src/diagnostics.rs @@ -5,28 +5,59 @@ use std::sync::{Arc, Mutex}; use termcolor::{Color, WriteColor}; +#[derive(Clone, Default)] +///CLI flags used by tidy. +pub struct TidyFlags { + ///Applies style and formatting changes during a tidy run. + bless: bool, +} + +impl TidyFlags { + pub fn new(cfg_args: &[String]) -> Self { + let mut flags = Self::default(); + + for arg in cfg_args { + match arg.as_str() { + "--bless" => flags.bless = true, + _ => continue, + } + } + flags + } +} + /// Collects diagnostics from all tidy steps, and contains shared information /// that determines how should message and logs be presented. /// /// Since checks are executed in parallel, the context is internally synchronized, to avoid /// all checks to lock it explicitly. #[derive(Clone)] -pub struct DiagCtx(Arc>); +pub struct TidyCtx { + tidy_flags: TidyFlags, + diag_ctx: Arc>, +} -impl DiagCtx { - pub fn new(root_path: &Path, verbose: bool) -> Self { - Self(Arc::new(Mutex::new(DiagCtxInner { - running_checks: Default::default(), - finished_checks: Default::default(), - root_path: root_path.to_path_buf(), - verbose, - }))) +impl TidyCtx { + pub fn new(root_path: &Path, verbose: bool, tidy_flags: TidyFlags) -> Self { + Self { + diag_ctx: Arc::new(Mutex::new(DiagCtxInner { + running_checks: Default::default(), + finished_checks: Default::default(), + root_path: root_path.to_path_buf(), + verbose, + })), + tidy_flags, + } + } + + pub fn is_bless_enabled(&self) -> bool { + self.tidy_flags.bless } pub fn start_check>(&self, id: Id) -> RunningCheck { let mut id = id.into(); - let mut ctx = self.0.lock().unwrap(); + let mut ctx = self.diag_ctx.lock().unwrap(); // Shorten path for shorter diagnostics id.path = match id.path { @@ -38,14 +69,14 @@ impl DiagCtx { RunningCheck { id, bad: false, - ctx: self.0.clone(), + ctx: self.diag_ctx.clone(), #[cfg(test)] errors: vec![], } } pub fn into_failed_checks(self) -> Vec { - let ctx = Arc::into_inner(self.0).unwrap().into_inner().unwrap(); + let ctx = Arc::into_inner(self.diag_ctx).unwrap().into_inner().unwrap(); assert!(ctx.running_checks.is_empty(), "Some checks are still running"); ctx.finished_checks.into_iter().filter(|c| c.bad).collect() } @@ -151,7 +182,7 @@ impl RunningCheck { /// Useful if you want to run some functions from tidy without configuring /// diagnostics. pub fn new_noop() -> Self { - let ctx = DiagCtx::new(Path::new(""), false); + let ctx = TidyCtx::new(Path::new(""), false, TidyFlags::default()); ctx.start_check("noop") } diff --git a/src/tools/tidy/src/edition.rs b/src/tools/tidy/src/edition.rs index 448e0b0e0a8c..de21846ab188 100644 --- a/src/tools/tidy/src/edition.rs +++ b/src/tools/tidy/src/edition.rs @@ -2,11 +2,11 @@ use std::path::Path; -use crate::diagnostics::{CheckId, DiagCtx}; +use crate::diagnostics::{CheckId, TidyCtx}; use crate::walk::{filter_dirs, walk}; -pub fn check(path: &Path, diag_ctx: DiagCtx) { - let mut check = diag_ctx.start_check(CheckId::new("edition").path(path)); +pub fn check(path: &Path, tidy_ctx: TidyCtx) { + let mut check = tidy_ctx.start_check(CheckId::new("edition").path(path)); walk(path, |path, _is_dir| filter_dirs(path), &mut |entry, contents| { let file = entry.path(); let filename = file.file_name().unwrap(); diff --git a/src/tools/tidy/src/error_codes.rs b/src/tools/tidy/src/error_codes.rs index 83fbefa43d97..9150d36339c8 100644 --- a/src/tools/tidy/src/error_codes.rs +++ b/src/tools/tidy/src/error_codes.rs @@ -22,7 +22,7 @@ use std::path::Path; use regex::Regex; -use crate::diagnostics::{DiagCtx, RunningCheck}; +use crate::diagnostics::{RunningCheck, TidyCtx}; use crate::walk::{filter_dirs, walk, walk_many}; const ERROR_CODES_PATH: &str = "compiler/rustc_error_codes/src/lib.rs"; @@ -36,8 +36,8 @@ const IGNORE_DOCTEST_CHECK: &[&str] = &["E0464", "E0570", "E0601", "E0602", "E07 const IGNORE_UI_TEST_CHECK: &[&str] = &["E0461", "E0465", "E0514", "E0554", "E0640", "E0717", "E0729"]; -pub fn check(root_path: &Path, search_paths: &[&Path], ci_info: &crate::CiInfo, diag_ctx: DiagCtx) { - let mut check = diag_ctx.start_check("error_codes"); +pub fn check(root_path: &Path, search_paths: &[&Path], ci_info: &crate::CiInfo, tidy_ctx: TidyCtx) { + let mut check = tidy_ctx.start_check("error_codes"); // Check that no error code explanation was removed. check_removed_error_code_explanation(ci_info, &mut check); diff --git a/src/tools/tidy/src/extdeps.rs b/src/tools/tidy/src/extdeps.rs index f75de13b45ce..19c773d12f7f 100644 --- a/src/tools/tidy/src/extdeps.rs +++ b/src/tools/tidy/src/extdeps.rs @@ -4,7 +4,7 @@ use std::fs; use std::path::Path; use crate::deps::WorkspaceInfo; -use crate::diagnostics::DiagCtx; +use crate::diagnostics::TidyCtx; /// List of allowed sources for packages. const ALLOWED_SOURCES: &[&str] = &[ @@ -15,8 +15,8 @@ const ALLOWED_SOURCES: &[&str] = &[ /// Checks for external package sources. `root` is the path to the directory that contains the /// workspace `Cargo.toml`. -pub fn check(root: &Path, diag_ctx: DiagCtx) { - let mut check = diag_ctx.start_check("extdeps"); +pub fn check(root: &Path, tidy_ctx: TidyCtx) { + let mut check = tidy_ctx.start_check("extdeps"); for &WorkspaceInfo { path, submodules, .. } in crate::deps::WORKSPACES { if crate::deps::has_missing_submodule(root, submodules) { diff --git a/src/tools/tidy/src/extra_checks/mod.rs b/src/tools/tidy/src/extra_checks/mod.rs index 3a1c32e7b42e..a45af7fcf158 100644 --- a/src/tools/tidy/src/extra_checks/mod.rs +++ b/src/tools/tidy/src/extra_checks/mod.rs @@ -24,7 +24,7 @@ use std::str::FromStr; use std::{fmt, fs, io}; use crate::CiInfo; -use crate::diagnostics::DiagCtx; +use crate::diagnostics::TidyCtx; mod rustdoc_js; @@ -52,12 +52,11 @@ pub fn check( tools_path: &Path, npm: &Path, cargo: &Path, - bless: bool, extra_checks: Option<&str>, pos_args: &[String], - diag_ctx: DiagCtx, + tidy_ctx: TidyCtx, ) { - let mut check = diag_ctx.start_check("extra_checks"); + let mut check = tidy_ctx.start_check("extra_checks"); if let Err(e) = check_impl( root_path, @@ -67,9 +66,9 @@ pub fn check( tools_path, npm, cargo, - bless, extra_checks, pos_args, + &tidy_ctx, ) { check.error(e); } @@ -83,12 +82,13 @@ fn check_impl( tools_path: &Path, npm: &Path, cargo: &Path, - bless: bool, extra_checks: Option<&str>, pos_args: &[String], + tidy_ctx: &TidyCtx, ) -> Result<(), Error> { let show_diff = std::env::var("TIDY_PRINT_DIFF").is_ok_and(|v| v.eq_ignore_ascii_case("true") || v == "1"); + let bless = tidy_ctx.is_bless_enabled(); // Split comma-separated args up let mut lint_args = match extra_checks { diff --git a/src/tools/tidy/src/features.rs b/src/tools/tidy/src/features.rs index 0a0ba217c633..08061bd834e3 100644 --- a/src/tools/tidy/src/features.rs +++ b/src/tools/tidy/src/features.rs @@ -16,7 +16,7 @@ use std::num::NonZeroU32; use std::path::{Path, PathBuf}; use std::{fmt, fs}; -use crate::diagnostics::{DiagCtx, RunningCheck}; +use crate::diagnostics::{RunningCheck, TidyCtx}; use crate::walk::{filter_dirs, filter_not_rust, walk, walk_many}; #[cfg(test)] @@ -92,9 +92,9 @@ pub fn check( tests_path: &Path, compiler_path: &Path, lib_path: &Path, - diag_ctx: DiagCtx, + tidy_ctx: TidyCtx, ) -> CollectedFeatures { - let mut check = diag_ctx.start_check("features"); + let mut check = tidy_ctx.start_check("features"); let mut features = collect_lang_features(compiler_path, &mut check); assert!(!features.is_empty()); diff --git a/src/tools/tidy/src/filenames.rs b/src/tools/tidy/src/filenames.rs index 835cbefbf691..a355588fd99c 100644 --- a/src/tools/tidy/src/filenames.rs +++ b/src/tools/tidy/src/filenames.rs @@ -10,10 +10,10 @@ use std::path::Path; use std::process::Command; -use crate::diagnostics::DiagCtx; +use crate::diagnostics::TidyCtx; -pub fn check(root_path: &Path, diag_ctx: DiagCtx) { - let mut check = diag_ctx.start_check("filenames"); +pub fn check(root_path: &Path, tidy_ctx: TidyCtx) { + let mut check = tidy_ctx.start_check("filenames"); let stat_output = Command::new("git") .arg("-C") .arg(root_path) diff --git a/src/tools/tidy/src/fluent_alphabetical.rs b/src/tools/tidy/src/fluent_alphabetical.rs index 769f92d04f0a..7583241ea638 100644 --- a/src/tools/tidy/src/fluent_alphabetical.rs +++ b/src/tools/tidy/src/fluent_alphabetical.rs @@ -9,7 +9,7 @@ use fluent_syntax::ast::Entry; use fluent_syntax::parser; use regex::Regex; -use crate::diagnostics::{CheckId, DiagCtx, RunningCheck}; +use crate::diagnostics::{CheckId, RunningCheck, TidyCtx}; use crate::walk::{filter_dirs, walk}; fn message() -> &'static Regex { @@ -87,8 +87,9 @@ fn sort_messages( out } -pub fn check(path: &Path, bless: bool, diag_ctx: DiagCtx) { - let mut check = diag_ctx.start_check(CheckId::new("fluent_alphabetical").path(path)); +pub fn check(path: &Path, tidy_ctx: TidyCtx) { + let mut check = tidy_ctx.start_check(CheckId::new("fluent_alphabetical").path(path)); + let bless = tidy_ctx.is_bless_enabled(); let mut all_defined_msgs = HashMap::new(); walk( @@ -120,5 +121,5 @@ pub fn check(path: &Path, bless: bool, diag_ctx: DiagCtx) { assert!(!all_defined_msgs.is_empty()); - crate::fluent_used::check(path, all_defined_msgs, diag_ctx); + crate::fluent_used::check(path, all_defined_msgs, tidy_ctx); } diff --git a/src/tools/tidy/src/fluent_lowercase.rs b/src/tools/tidy/src/fluent_lowercase.rs index 1d80fda8f3b8..690b733a5b64 100644 --- a/src/tools/tidy/src/fluent_lowercase.rs +++ b/src/tools/tidy/src/fluent_lowercase.rs @@ -4,7 +4,7 @@ use std::path::Path; use fluent_syntax::ast::{Entry, Message, PatternElement}; -use crate::diagnostics::{CheckId, DiagCtx, RunningCheck}; +use crate::diagnostics::{CheckId, RunningCheck, TidyCtx}; use crate::walk::{filter_dirs, walk}; #[rustfmt::skip] @@ -53,8 +53,8 @@ fn check_lowercase(filename: &str, contents: &str, check: &mut RunningCheck) { } } -pub fn check(path: &Path, diag_ctx: DiagCtx) { - let mut check = diag_ctx.start_check(CheckId::new("fluent_lowercase").path(path)); +pub fn check(path: &Path, tidy_ctx: TidyCtx) { + let mut check = tidy_ctx.start_check(CheckId::new("fluent_lowercase").path(path)); walk( path, |path, is_dir| filter_dirs(path) || (!is_dir && filter_fluent(path)), diff --git a/src/tools/tidy/src/fluent_period.rs b/src/tools/tidy/src/fluent_period.rs index c7c760b8d54f..e7d59e2ce2a9 100644 --- a/src/tools/tidy/src/fluent_period.rs +++ b/src/tools/tidy/src/fluent_period.rs @@ -4,7 +4,7 @@ use std::path::Path; use fluent_syntax::ast::{Entry, PatternElement}; -use crate::diagnostics::{CheckId, DiagCtx, RunningCheck}; +use crate::diagnostics::{CheckId, RunningCheck, TidyCtx}; use crate::walk::{filter_dirs, walk}; fn filter_fluent(path: &Path) -> bool { @@ -75,8 +75,8 @@ fn find_line(haystack: &str, needle: &str) -> usize { 1 } -pub fn check(path: &Path, diag_ctx: DiagCtx) { - let mut check = diag_ctx.start_check(CheckId::new("fluent_period").path(path)); +pub fn check(path: &Path, tidy_ctx: TidyCtx) { + let mut check = tidy_ctx.start_check(CheckId::new("fluent_period").path(path)); walk( path, diff --git a/src/tools/tidy/src/fluent_used.rs b/src/tools/tidy/src/fluent_used.rs index 2047089631b3..75da1d7ea49d 100644 --- a/src/tools/tidy/src/fluent_used.rs +++ b/src/tools/tidy/src/fluent_used.rs @@ -3,7 +3,7 @@ use std::collections::HashMap; use std::path::Path; -use crate::diagnostics::{CheckId, DiagCtx}; +use crate::diagnostics::{CheckId, TidyCtx}; use crate::walk::{filter_dirs, walk}; fn filter_used_messages( @@ -28,8 +28,8 @@ fn filter_used_messages( } } -pub fn check(path: &Path, mut all_defined_msgs: HashMap, diag_ctx: DiagCtx) { - let mut check = diag_ctx.start_check(CheckId::new("fluent_used").path(path)); +pub fn check(path: &Path, mut all_defined_msgs: HashMap, tidy_ctx: TidyCtx) { + let mut check = tidy_ctx.start_check(CheckId::new("fluent_used").path(path)); let mut msgs_appear_only_once = HashMap::new(); walk(path, |path, _| filter_dirs(path), &mut |_, contents| { diff --git a/src/tools/tidy/src/gcc_submodule.rs b/src/tools/tidy/src/gcc_submodule.rs index 3a6e3247de60..46b816f5c9d0 100644 --- a/src/tools/tidy/src/gcc_submodule.rs +++ b/src/tools/tidy/src/gcc_submodule.rs @@ -4,10 +4,10 @@ use std::path::Path; use std::process::Command; -use crate::diagnostics::DiagCtx; +use crate::diagnostics::TidyCtx; -pub fn check(root_path: &Path, compiler_path: &Path, diag_ctx: DiagCtx) { - let mut check = diag_ctx.start_check("gcc_submodule"); +pub fn check(root_path: &Path, compiler_path: &Path, tidy_ctx: TidyCtx) { + let mut check = tidy_ctx.start_check("gcc_submodule"); let cg_gcc_version_path = compiler_path.join("rustc_codegen_gcc/libgccjit.version"); let cg_gcc_version = std::fs::read_to_string(&cg_gcc_version_path) diff --git a/src/tools/tidy/src/known_bug.rs b/src/tools/tidy/src/known_bug.rs index d3b75e0cf5b8..e6038341ba96 100644 --- a/src/tools/tidy/src/known_bug.rs +++ b/src/tools/tidy/src/known_bug.rs @@ -2,11 +2,11 @@ use std::path::Path; -use crate::diagnostics::{CheckId, DiagCtx}; +use crate::diagnostics::{CheckId, TidyCtx}; use crate::walk::*; -pub fn check(filepath: &Path, diag_ctx: DiagCtx) { - let mut check = diag_ctx.start_check(CheckId::new("known_bug").path(filepath)); +pub fn check(filepath: &Path, tidy_ctx: TidyCtx) { + let mut check = tidy_ctx.start_check(CheckId::new("known_bug").path(filepath)); walk(filepath, |path, _is_dir| filter_not_rust(path), &mut |entry, contents| { let file: &Path = entry.path(); diff --git a/src/tools/tidy/src/lib.rs b/src/tools/tidy/src/lib.rs index 0acbcd64f067..756f9790e04a 100644 --- a/src/tools/tidy/src/lib.rs +++ b/src/tools/tidy/src/lib.rs @@ -12,7 +12,7 @@ use build_helper::ci::CiEnv; use build_helper::git::{GitConfig, get_closest_upstream_commit}; use build_helper::stage0_parser::{Stage0Config, parse_stage0_file}; -use crate::diagnostics::{DiagCtx, RunningCheck}; +use crate::diagnostics::{RunningCheck, TidyCtx}; macro_rules! static_regex { ($re:literal) => {{ @@ -52,8 +52,8 @@ pub struct CiInfo { } impl CiInfo { - pub fn new(diag_ctx: DiagCtx) -> Self { - let mut check = diag_ctx.start_check("CI history"); + pub fn new(tidy_ctx: TidyCtx) -> Self { + let mut check = tidy_ctx.start_check("CI history"); let stage0 = parse_stage0_file(); let Stage0Config { nightly_branch, git_merge_commit_email, .. } = stage0.config; diff --git a/src/tools/tidy/src/main.rs b/src/tools/tidy/src/main.rs index 93bc16111992..94c24f11ed12 100644 --- a/src/tools/tidy/src/main.rs +++ b/src/tools/tidy/src/main.rs @@ -11,7 +11,7 @@ use std::str::FromStr; use std::thread::{self, ScopedJoinHandle, scope}; use std::{env, process}; -use tidy::diagnostics::{COLOR_ERROR, COLOR_SUCCESS, DiagCtx, output_message}; +use tidy::diagnostics::{COLOR_ERROR, COLOR_SUCCESS, TidyCtx, TidyFlags, output_message}; use tidy::*; fn main() { @@ -46,12 +46,12 @@ fn main() { None => (&args[..], [].as_slice()), }; let verbose = cfg_args.iter().any(|s| *s == "--verbose"); - let bless = cfg_args.iter().any(|s| *s == "--bless"); let extra_checks = cfg_args.iter().find(|s| s.starts_with("--extra-checks=")).map(String::as_str); - let diag_ctx = DiagCtx::new(&root_path, verbose); - let ci_info = CiInfo::new(diag_ctx.clone()); + let tidy_flags = TidyFlags::new(cfg_args); + let tidy_ctx = TidyCtx::new(&root_path, verbose, tidy_flags); + let ci_info = CiInfo::new(tidy_ctx.clone()); let drain_handles = |handles: &mut VecDeque>| { // poll all threads for completion before awaiting the oldest one @@ -86,9 +86,9 @@ fn main() { (@ $p:ident, name=$name:expr $(, $args:expr)* ) => { drain_handles(&mut handles); - let diag_ctx = diag_ctx.clone(); + let tidy_ctx = tidy_ctx.clone(); let handle = thread::Builder::new().name($name).spawn_scoped(s, || { - $p::check($($args, )* diag_ctx); + $p::check($($args, )* tidy_ctx); }).unwrap(); handles.push_back(handle); } @@ -97,15 +97,15 @@ fn main() { check!(target_specific_tests, &tests_path); // Checks that are done on the cargo workspace. - check!(deps, &root_path, &cargo, bless); + check!(deps, &root_path, &cargo); check!(extdeps, &root_path); // Checks over tests. check!(tests_placement, &root_path); check!(tests_revision_unpaired_stdout_stderr, &tests_path); check!(debug_artifacts, &tests_path); - check!(ui_tests, &root_path, bless); - check!(mir_opt_tests, &tests_path, bless); + check!(ui_tests, &root_path); + check!(mir_opt_tests, &tests_path); check!(rustdoc_gui_tests, &tests_path); check!(rustdoc_css_themes, &librustdoc_path); check!(rustdoc_templates, &librustdoc_path); @@ -115,7 +115,7 @@ fn main() { // Checks that only make sense for the compiler. check!(error_codes, &root_path, &[&compiler_path, &librustdoc_path], &ci_info); - check!(fluent_alphabetical, &compiler_path, bless); + check!(fluent_alphabetical, &compiler_path); check!(fluent_period, &compiler_path); check!(fluent_lowercase, &compiler_path); check!(target_policy, &root_path); @@ -156,7 +156,7 @@ fn main() { let collected = { drain_handles(&mut handles); - features::check(&src_path, &tests_path, &compiler_path, &library_path, diag_ctx.clone()) + features::check(&src_path, &tests_path, &compiler_path, &library_path, tidy_ctx.clone()) }; check!(unstable_book, &src_path, collected); @@ -169,13 +169,12 @@ fn main() { &tools_path, &npm, &cargo, - bless, extra_checks, pos_args ); }); - let failed_checks = diag_ctx.into_failed_checks(); + let failed_checks = tidy_ctx.into_failed_checks(); if !failed_checks.is_empty() { let mut failed: Vec = failed_checks.into_iter().map(|c| c.id().to_string()).collect(); diff --git a/src/tools/tidy/src/mir_opt_tests.rs b/src/tools/tidy/src/mir_opt_tests.rs index 0f9fab51d096..afc1dc2a1860 100644 --- a/src/tools/tidy/src/mir_opt_tests.rs +++ b/src/tools/tidy/src/mir_opt_tests.rs @@ -5,7 +5,7 @@ use std::path::{Path, PathBuf}; use miropt_test_tools::PanicStrategy; -use crate::diagnostics::{CheckId, DiagCtx, RunningCheck}; +use crate::diagnostics::{CheckId, RunningCheck, TidyCtx}; use crate::walk::walk_no_read; fn check_unused_files(path: &Path, bless: bool, check: &mut RunningCheck) { @@ -74,8 +74,9 @@ fn check_dash_files(path: &Path, bless: bool, check: &mut RunningCheck) { } } -pub fn check(path: &Path, bless: bool, diag_ctx: DiagCtx) { - let mut check = diag_ctx.start_check(CheckId::new("mir_opt_tests").path(path)); +pub fn check(path: &Path, tidy_ctx: TidyCtx) { + let mut check = tidy_ctx.start_check(CheckId::new("mir_opt_tests").path(path)); + let bless = tidy_ctx.is_bless_enabled(); check_unused_files(path, bless, &mut check); check_dash_files(path, bless, &mut check); diff --git a/src/tools/tidy/src/pal.rs b/src/tools/tidy/src/pal.rs index cefad7d9596a..dfca2cda9a0f 100644 --- a/src/tools/tidy/src/pal.rs +++ b/src/tools/tidy/src/pal.rs @@ -32,7 +32,7 @@ use std::path::Path; -use crate::diagnostics::{CheckId, DiagCtx, RunningCheck}; +use crate::diagnostics::{CheckId, RunningCheck, TidyCtx}; use crate::walk::{filter_dirs, walk}; // Paths that may contain platform-specific code. @@ -68,8 +68,8 @@ const EXCEPTION_PATHS: &[&str] = &[ "library/std/src/io/error.rs", // Repr unpacked needed for UEFI ]; -pub fn check(path: &Path, diag_ctx: DiagCtx) { - let mut check = diag_ctx.start_check(CheckId::new("pal").path(path)); +pub fn check(path: &Path, tidy_ctx: TidyCtx) { + let mut check = tidy_ctx.start_check(CheckId::new("pal").path(path)); // Sanity check that the complex parsing here works. let mut saw_target_arch = false; diff --git a/src/tools/tidy/src/rustdoc_css_themes.rs b/src/tools/tidy/src/rustdoc_css_themes.rs index 8d4af7a3bd56..f3aecc15cd9a 100644 --- a/src/tools/tidy/src/rustdoc_css_themes.rs +++ b/src/tools/tidy/src/rustdoc_css_themes.rs @@ -3,10 +3,10 @@ use std::path::Path; -use crate::diagnostics::{CheckId, DiagCtx, RunningCheck}; +use crate::diagnostics::{CheckId, RunningCheck, TidyCtx}; -pub fn check(librustdoc_path: &Path, diag_ctx: DiagCtx) { - let mut check = diag_ctx.start_check(CheckId::new("rustdoc_css_themes").path(librustdoc_path)); +pub fn check(librustdoc_path: &Path, tidy_ctx: TidyCtx) { + let mut check = tidy_ctx.start_check(CheckId::new("rustdoc_css_themes").path(librustdoc_path)); let rustdoc_css = "html/static/css/rustdoc.css"; let noscript_css = "html/static/css/noscript.css"; diff --git a/src/tools/tidy/src/rustdoc_gui_tests.rs b/src/tools/tidy/src/rustdoc_gui_tests.rs index 8ec300c42ce9..848250e18e74 100644 --- a/src/tools/tidy/src/rustdoc_gui_tests.rs +++ b/src/tools/tidy/src/rustdoc_gui_tests.rs @@ -2,10 +2,10 @@ use std::path::Path; -use crate::diagnostics::{CheckId, DiagCtx}; +use crate::diagnostics::{CheckId, TidyCtx}; -pub fn check(path: &Path, diag_ctx: DiagCtx) { - let mut check = diag_ctx.start_check(CheckId::new("rustdoc_gui_tests").path(path)); +pub fn check(path: &Path, tidy_ctx: TidyCtx) { + let mut check = tidy_ctx.start_check(CheckId::new("rustdoc_gui_tests").path(path)); crate::walk::walk( &path.join("rustdoc-gui"), diff --git a/src/tools/tidy/src/rustdoc_json.rs b/src/tools/tidy/src/rustdoc_json.rs index ade774616c71..b8fb04f2d4e1 100644 --- a/src/tools/tidy/src/rustdoc_json.rs +++ b/src/tools/tidy/src/rustdoc_json.rs @@ -4,12 +4,12 @@ use std::path::Path; use std::str::FromStr; -use crate::diagnostics::{CheckId, DiagCtx}; +use crate::diagnostics::{CheckId, TidyCtx}; const RUSTDOC_JSON_TYPES: &str = "src/rustdoc-json-types"; -pub fn check(src_path: &Path, ci_info: &crate::CiInfo, diag_ctx: DiagCtx) { - let mut check = diag_ctx.start_check(CheckId::new("rustdoc_json").path(src_path)); +pub fn check(src_path: &Path, ci_info: &crate::CiInfo, tidy_ctx: TidyCtx) { + let mut check = tidy_ctx.start_check(CheckId::new("rustdoc_json").path(src_path)); let Some(base_commit) = &ci_info.base_commit else { check.verbose_msg("No base commit, skipping rustdoc_json check"); diff --git a/src/tools/tidy/src/rustdoc_templates.rs b/src/tools/tidy/src/rustdoc_templates.rs index 4e5b9988d539..faeb95a92b76 100644 --- a/src/tools/tidy/src/rustdoc_templates.rs +++ b/src/tools/tidy/src/rustdoc_templates.rs @@ -6,14 +6,14 @@ use std::path::Path; use ignore::DirEntry; -use crate::diagnostics::{CheckId, DiagCtx}; +use crate::diagnostics::{CheckId, TidyCtx}; use crate::walk::walk; // Array containing `("beginning of tag", "end of tag")`. const TAGS: &[(&str, &str)] = &[("{#", "#}"), ("{%", "%}"), ("{{", "}}")]; -pub fn check(librustdoc_path: &Path, diag_ctx: DiagCtx) { - let mut check = diag_ctx.start_check(CheckId::new("rustdoc_templates").path(librustdoc_path)); +pub fn check(librustdoc_path: &Path, tidy_ctx: TidyCtx) { + let mut check = tidy_ctx.start_check(CheckId::new("rustdoc_templates").path(librustdoc_path)); walk( &librustdoc_path.join("html/templates"), diff --git a/src/tools/tidy/src/style.rs b/src/tools/tidy/src/style.rs index d17278edc849..7bb424d926c2 100644 --- a/src/tools/tidy/src/style.rs +++ b/src/tools/tidy/src/style.rs @@ -24,7 +24,7 @@ use std::sync::LazyLock; use regex::RegexSetBuilder; use rustc_hash::FxHashMap; -use crate::diagnostics::{CheckId, DiagCtx}; +use crate::diagnostics::{CheckId, TidyCtx}; use crate::walk::{filter_dirs, walk}; #[cfg(test)] @@ -339,8 +339,8 @@ fn is_unexplained_ignore(extension: &str, line: &str) -> bool { true } -pub fn check(path: &Path, diag_ctx: DiagCtx) { - let mut check = diag_ctx.start_check(CheckId::new("style").path(path)); +pub fn check(path: &Path, tidy_ctx: TidyCtx) { + let mut check = tidy_ctx.start_check(CheckId::new("style").path(path)); fn skip(path: &Path, is_dir: bool) -> bool { if path.file_name().is_some_and(|name| name.to_string_lossy().starts_with(".#")) { diff --git a/src/tools/tidy/src/target_policy.rs b/src/tools/tidy/src/target_policy.rs index cfcfcaf2435b..83fbe6a0d8da 100644 --- a/src/tools/tidy/src/target_policy.rs +++ b/src/tools/tidy/src/target_policy.rs @@ -5,7 +5,7 @@ use std::collections::HashSet; use std::path::Path; -use crate::diagnostics::DiagCtx; +use crate::diagnostics::TidyCtx; use crate::walk::{filter_not_rust, walk}; const TARGET_DEFINITIONS_PATH: &str = "compiler/rustc_target/src/spec/targets/"; @@ -24,8 +24,8 @@ const EXCEPTIONS: &[&str] = &[ "xtensa_esp32s3_espidf", ]; -pub fn check(root_path: &Path, diag_ctx: DiagCtx) { - let mut check = diag_ctx.start_check("target_policy"); +pub fn check(root_path: &Path, tidy_ctx: TidyCtx) { + let mut check = tidy_ctx.start_check("target_policy"); let mut targets_to_find = HashSet::new(); diff --git a/src/tools/tidy/src/target_specific_tests.rs b/src/tools/tidy/src/target_specific_tests.rs index c1db3874ad54..159d7278bb62 100644 --- a/src/tools/tidy/src/target_specific_tests.rs +++ b/src/tools/tidy/src/target_specific_tests.rs @@ -4,7 +4,7 @@ use std::collections::BTreeMap; use std::path::Path; -use crate::diagnostics::{CheckId, DiagCtx}; +use crate::diagnostics::{CheckId, TidyCtx}; use crate::iter_header::{HeaderLine, iter_header}; use crate::walk::filter_not_rust; @@ -17,8 +17,8 @@ struct RevisionInfo<'a> { llvm_components: Option>, } -pub fn check(tests_path: &Path, diag_ctx: DiagCtx) { - let mut check = diag_ctx.start_check(CheckId::new("target-specific-tests").path(tests_path)); +pub fn check(tests_path: &Path, tidy_ctx: TidyCtx) { + let mut check = tidy_ctx.start_check(CheckId::new("target-specific-tests").path(tests_path)); crate::walk::walk(tests_path, |path, _is_dir| filter_not_rust(path), &mut |entry, content| { if content.contains("// ignore-tidy-target-specific-tests") { diff --git a/src/tools/tidy/src/tests_placement.rs b/src/tools/tidy/src/tests_placement.rs index 8ba8cf552bd7..18b00608fdce 100644 --- a/src/tools/tidy/src/tests_placement.rs +++ b/src/tools/tidy/src/tests_placement.rs @@ -1,12 +1,12 @@ use std::path::Path; -use crate::diagnostics::DiagCtx; +use crate::diagnostics::TidyCtx; const FORBIDDEN_PATH: &str = "src/test"; const ALLOWED_PATH: &str = "tests"; -pub fn check(root_path: &Path, diag_ctx: DiagCtx) { - let mut check = diag_ctx.start_check("tests_placement"); +pub fn check(root_path: &Path, tidy_ctx: TidyCtx) { + let mut check = tidy_ctx.start_check("tests_placement"); if root_path.join(FORBIDDEN_PATH).exists() { check.error(format!( diff --git a/src/tools/tidy/src/tests_revision_unpaired_stdout_stderr.rs b/src/tools/tidy/src/tests_revision_unpaired_stdout_stderr.rs index 1738088a3a0c..4d9cb55138af 100644 --- a/src/tools/tidy/src/tests_revision_unpaired_stdout_stderr.rs +++ b/src/tools/tidy/src/tests_revision_unpaired_stdout_stderr.rs @@ -4,7 +4,7 @@ use std::collections::{BTreeMap, BTreeSet}; use std::ffi::OsStr; use std::path::Path; -use crate::diagnostics::{CheckId, DiagCtx}; +use crate::diagnostics::{CheckId, TidyCtx}; use crate::iter_header::*; use crate::walk::*; @@ -22,8 +22,8 @@ const IGNORES: &[&str] = &[ const EXTENSIONS: &[&str] = &["stdout", "stderr"]; const SPECIAL_TEST: &str = "tests/ui/command/need-crate-arg-ignore-tidy.x.rs"; -pub fn check(tests_path: &Path, diag_ctx: DiagCtx) { - let mut check = diag_ctx +pub fn check(tests_path: &Path, tidy_ctx: TidyCtx) { + let mut check = tidy_ctx .start_check(CheckId::new("tests_revision_unpaired_stdout_stderr").path(tests_path)); // Recurse over subdirectories under `tests/` diff --git a/src/tools/tidy/src/triagebot.rs b/src/tools/tidy/src/triagebot.rs index 41d61dcd1411..01401c94d730 100644 --- a/src/tools/tidy/src/triagebot.rs +++ b/src/tools/tidy/src/triagebot.rs @@ -4,10 +4,10 @@ use std::path::Path; use toml::Value; -use crate::diagnostics::DiagCtx; +use crate::diagnostics::TidyCtx; -pub fn check(path: &Path, diag_ctx: DiagCtx) { - let mut check = diag_ctx.start_check("triagebot"); +pub fn check(path: &Path, tidy_ctx: TidyCtx) { + let mut check = tidy_ctx.start_check("triagebot"); let triagebot_path = path.join("triagebot.toml"); // This check is mostly to catch broken path filters *within* `triagebot.toml`, and not enforce diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs index c74ecf3d43f4..45c2e76d1c1c 100644 --- a/src/tools/tidy/src/ui_tests.rs +++ b/src/tools/tidy/src/ui_tests.rs @@ -7,16 +7,17 @@ use std::fs; use std::io::Write; use std::path::{Path, PathBuf}; -use crate::diagnostics::{CheckId, DiagCtx, RunningCheck}; +use crate::diagnostics::{CheckId, RunningCheck, TidyCtx}; const ISSUES_TXT_HEADER: &str = r#"============================================================ ⚠️⚠️⚠️NOTHING SHOULD EVER BE ADDED TO THIS LIST⚠️⚠️⚠️ ============================================================ "#; -pub fn check(root_path: &Path, bless: bool, diag_ctx: DiagCtx) { +pub fn check(root_path: &Path, tidy_ctx: TidyCtx) { let path = &root_path.join("tests"); - let mut check = diag_ctx.start_check(CheckId::new("ui_tests").path(path)); + let mut check = tidy_ctx.start_check(CheckId::new("ui_tests").path(path)); + let bless = tidy_ctx.is_bless_enabled(); // the list of files in ui tests that are allowed to start with `issue-XXXX` // BTreeSet because we would like a stable ordering so --bless works diff --git a/src/tools/tidy/src/unit_tests.rs b/src/tools/tidy/src/unit_tests.rs index cab445ac63a1..74b6c4a3845a 100644 --- a/src/tools/tidy/src/unit_tests.rs +++ b/src/tools/tidy/src/unit_tests.rs @@ -11,11 +11,11 @@ use std::path::Path; -use crate::diagnostics::{CheckId, DiagCtx}; +use crate::diagnostics::{CheckId, TidyCtx}; use crate::walk::{filter_dirs, walk}; -pub fn check(root_path: &Path, stdlib: bool, diag_ctx: DiagCtx) { - let mut check = diag_ctx.start_check(CheckId::new("unit_tests").path(root_path)); +pub fn check(root_path: &Path, stdlib: bool, tidy_ctx: TidyCtx) { + let mut check = tidy_ctx.start_check(CheckId::new("unit_tests").path(root_path)); let skip = move |path: &Path, is_dir| { let file_name = path.file_name().unwrap_or_default(); diff --git a/src/tools/tidy/src/unknown_revision.rs b/src/tools/tidy/src/unknown_revision.rs index 776d45e25de0..43de6ee18b4d 100644 --- a/src/tools/tidy/src/unknown_revision.rs +++ b/src/tools/tidy/src/unknown_revision.rs @@ -12,12 +12,12 @@ use std::sync::OnceLock; use ignore::DirEntry; use regex::Regex; -use crate::diagnostics::{CheckId, DiagCtx, RunningCheck}; +use crate::diagnostics::{CheckId, RunningCheck, TidyCtx}; use crate::iter_header::{HeaderLine, iter_header}; use crate::walk::{filter_dirs, filter_not_rust, walk}; -pub fn check(tests_path: &Path, diag_ctx: DiagCtx) { - let mut check = diag_ctx.start_check(CheckId::new("unknown_revision").path(tests_path)); +pub fn check(tests_path: &Path, tidy_ctx: TidyCtx) { + let mut check = tidy_ctx.start_check(CheckId::new("unknown_revision").path(tests_path)); walk( tests_path, |path, is_dir| { diff --git a/src/tools/tidy/src/unstable_book.rs b/src/tools/tidy/src/unstable_book.rs index bab294abee02..cfaf56ae7b64 100644 --- a/src/tools/tidy/src/unstable_book.rs +++ b/src/tools/tidy/src/unstable_book.rs @@ -2,7 +2,7 @@ use std::collections::BTreeSet; use std::fs; use std::path::{Path, PathBuf}; -use crate::diagnostics::{DiagCtx, RunningCheck}; +use crate::diagnostics::{RunningCheck, TidyCtx}; use crate::features::{CollectedFeatures, Features, Status}; pub const PATH_STR: &str = "doc/unstable-book"; @@ -85,8 +85,8 @@ fn maybe_suggest_dashes(names: &BTreeSet, feature_name: &str, check: &mu } } -pub fn check(path: &Path, features: CollectedFeatures, diag_ctx: DiagCtx) { - let mut check = diag_ctx.start_check("unstable_book"); +pub fn check(path: &Path, features: CollectedFeatures, tidy_ctx: TidyCtx) { + let mut check = tidy_ctx.start_check("unstable_book"); let lang_features = features.lang; let lib_features = features diff --git a/src/tools/tidy/src/x_version.rs b/src/tools/tidy/src/x_version.rs index b3e322d9403f..28fd725cd3e2 100644 --- a/src/tools/tidy/src/x_version.rs +++ b/src/tools/tidy/src/x_version.rs @@ -3,10 +3,10 @@ use std::process::{Command, Stdio}; use semver::Version; -use crate::diagnostics::{CheckId, DiagCtx}; +use crate::diagnostics::{CheckId, TidyCtx}; -pub fn check(root: &Path, cargo: &Path, diag_ctx: DiagCtx) { - let mut check = diag_ctx.start_check(CheckId::new("x_version").path(root)); +pub fn check(root: &Path, cargo: &Path, tidy_ctx: TidyCtx) { + let mut check = tidy_ctx.start_check(CheckId::new("x_version").path(root)); let cargo_list = Command::new(cargo).args(["install", "--list"]).stdout(Stdio::piped()).spawn(); let child = match cargo_list { diff --git a/tests/codegen-llvm/emscripten-catch-unwind-js-eh.rs b/tests/codegen-llvm/emscripten-catch-unwind-js-eh.rs index f43869cf2189..dfe154c1c831 100644 --- a/tests/codegen-llvm/emscripten-catch-unwind-js-eh.rs +++ b/tests/codegen-llvm/emscripten-catch-unwind-js-eh.rs @@ -25,7 +25,7 @@ trait Copy {} impl Copy for *mut T {} #[rustc_intrinsic] -fn size_of() -> usize { +const fn size_of() -> usize { loop {} } @@ -40,7 +40,7 @@ unsafe fn catch_unwind( #[no_mangle] pub fn ptr_size() -> usize { // CHECK: ret [[PTR_SIZE:.*]] - size_of::<*mut u8>() + const { size_of::<*mut u8>() } } // CHECK-LABEL: @test_catch_unwind diff --git a/tests/codegen-llvm/emscripten-catch-unwind-wasm-eh.rs b/tests/codegen-llvm/emscripten-catch-unwind-wasm-eh.rs index b0750d52268a..88c95b088aaa 100644 --- a/tests/codegen-llvm/emscripten-catch-unwind-wasm-eh.rs +++ b/tests/codegen-llvm/emscripten-catch-unwind-wasm-eh.rs @@ -24,7 +24,7 @@ trait Copy {} impl Copy for *mut T {} #[rustc_intrinsic] -fn size_of() -> usize { +const fn size_of() -> usize { loop {} } #[rustc_intrinsic] @@ -38,7 +38,7 @@ unsafe fn catch_unwind( #[no_mangle] pub fn ptr_size() -> usize { // CHECK: ret [[PTR_SIZE:.*]] - size_of::<*mut u8>() + const { size_of::<*mut u8>() } } // CHECK-LABEL: @test_catch_unwind diff --git a/tests/codegen-llvm/simd-intrinsic/simd-intrinsic-generic-gather.rs b/tests/codegen-llvm/simd-intrinsic/simd-intrinsic-generic-gather.rs index 690bfb432f9b..d79a9cf96ada 100644 --- a/tests/codegen-llvm/simd-intrinsic/simd-intrinsic-generic-gather.rs +++ b/tests/codegen-llvm/simd-intrinsic/simd-intrinsic-generic-gather.rs @@ -1,6 +1,10 @@ // //@ compile-flags: -C no-prepopulate-passes +//@ revisions: LLVM21 LLVM22 +//@ [LLVM22] min-llvm-version: 22 +//@ [LLVM21] max-llvm-major-version: 21 +// ignore-tidy-linelength #![crate_type = "lib"] #![feature(repr_simd, core_intrinsics)] @@ -24,7 +28,8 @@ pub unsafe fn gather_f32x2( ) -> Vec2 { // CHECK: [[A:%[0-9]+]] = lshr <2 x i32> {{.*}}, {{|splat \(i32 31\)}} // CHECK: [[B:%[0-9]+]] = trunc <2 x i32> [[A]] to <2 x i1> - // CHECK: call <2 x float> @llvm.masked.gather.v2f32.v2p0(<2 x ptr> {{.*}}, i32 {{.*}}, <2 x i1> [[B]], <2 x float> {{.*}}) + // LLVM21: call <2 x float> @llvm.masked.gather.v2f32.v2p0(<2 x ptr> {{.*}}, i32 {{.*}}, <2 x i1> [[B]], <2 x float> {{.*}}) + // LLVM22: call <2 x float> @llvm.masked.gather.v2f32.v2p0(<2 x ptr> align {{.*}} {{.*}}, <2 x i1> [[B]], <2 x float> {{.*}}) simd_gather(values, pointers, mask) } @@ -37,7 +42,8 @@ pub unsafe fn gather_f32x2_unsigned( ) -> Vec2 { // CHECK: [[A:%[0-9]+]] = lshr <2 x i32> {{.*}}, {{|splat \(i32 31\)}} // CHECK: [[B:%[0-9]+]] = trunc <2 x i32> [[A]] to <2 x i1> - // CHECK: call <2 x float> @llvm.masked.gather.v2f32.v2p0(<2 x ptr> {{.*}}, i32 {{.*}}, <2 x i1> [[B]], <2 x float> {{.*}}) + // LLVM21: call <2 x float> @llvm.masked.gather.v2f32.v2p0(<2 x ptr> {{.*}}, i32 {{.*}}, <2 x i1> [[B]], <2 x float> {{.*}}) + // LLVM22: call <2 x float> @llvm.masked.gather.v2f32.v2p0(<2 x ptr> align {{.*}} {{.*}}, <2 x i1> [[B]], <2 x float> {{.*}}) simd_gather(values, pointers, mask) } @@ -50,6 +56,7 @@ pub unsafe fn gather_pf32x2( ) -> Vec2<*const f32> { // CHECK: [[A:%[0-9]+]] = lshr <2 x i32> {{.*}}, {{|splat \(i32 31\)}} // CHECK: [[B:%[0-9]+]] = trunc <2 x i32> [[A]] to <2 x i1> - // CHECK: call <2 x ptr> @llvm.masked.gather.v2p0.v2p0(<2 x ptr> {{.*}}, i32 {{.*}}, <2 x i1> [[B]], <2 x ptr> {{.*}}) + // LLVM21: call <2 x ptr> @llvm.masked.gather.v2p0.v2p0(<2 x ptr> {{.*}}, i32 {{.*}}, <2 x i1> [[B]], <2 x ptr> {{.*}}) + // LLVM22: call <2 x ptr> @llvm.masked.gather.v2p0.v2p0(<2 x ptr> align {{.*}} {{.*}}, <2 x i1> [[B]], <2 x ptr> {{.*}}) simd_gather(values, pointers, mask) } diff --git a/tests/codegen-llvm/simd-intrinsic/simd-intrinsic-generic-masked-load.rs b/tests/codegen-llvm/simd-intrinsic/simd-intrinsic-generic-masked-load.rs index fda315dc66ca..7df73cb9b4d7 100644 --- a/tests/codegen-llvm/simd-intrinsic/simd-intrinsic-generic-masked-load.rs +++ b/tests/codegen-llvm/simd-intrinsic/simd-intrinsic-generic-masked-load.rs @@ -1,4 +1,8 @@ //@ compile-flags: -C no-prepopulate-passes +//@ revisions: LLVM21 LLVM22 +//@ [LLVM22] min-llvm-version: 22 +//@ [LLVM21] max-llvm-major-version: 21 +// ignore-tidy-linelength #![crate_type = "lib"] #![feature(repr_simd, core_intrinsics)] @@ -18,7 +22,8 @@ pub type Vec4 = Simd; pub unsafe fn load_f32x2(mask: Vec2, pointer: *const f32, values: Vec2) -> Vec2 { // CHECK: [[A:%[0-9]+]] = lshr <2 x i32> {{.*}}, {{|splat \(i32 31\)}} // CHECK: [[B:%[0-9]+]] = trunc <2 x i32> [[A]] to <2 x i1> - // CHECK: call <2 x float> @llvm.masked.load.v2f32.p0(ptr {{.*}}, i32 4, <2 x i1> [[B]], <2 x float> {{.*}}) + // LLVM21: call <2 x float> @llvm.masked.load.v2f32.p0(ptr {{.*}}, i32 4, <2 x i1> [[B]], <2 x float> {{.*}}) + // LLVM22: call <2 x float> @llvm.masked.load.v2f32.p0(ptr align 4 {{.*}}, <2 x i1> [[B]], <2 x float> {{.*}}) simd_masked_load(mask, pointer, values) } @@ -31,7 +36,8 @@ pub unsafe fn load_f32x2_unsigned( ) -> Vec2 { // CHECK: [[A:%[0-9]+]] = lshr <2 x i32> {{.*}}, {{|splat \(i32 31\)}} // CHECK: [[B:%[0-9]+]] = trunc <2 x i32> [[A]] to <2 x i1> - // CHECK: call <2 x float> @llvm.masked.load.v2f32.p0(ptr {{.*}}, i32 4, <2 x i1> [[B]], <2 x float> {{.*}}) + // LLVM21: call <2 x float> @llvm.masked.load.v2f32.p0(ptr {{.*}}, i32 4, <2 x i1> [[B]], <2 x float> {{.*}}) + // LLVM22: call <2 x float> @llvm.masked.load.v2f32.p0(ptr align 4 {{.*}}, <2 x i1> [[B]], <2 x float> {{.*}}) simd_masked_load(mask, pointer, values) } @@ -44,6 +50,7 @@ pub unsafe fn load_pf32x4( ) -> Vec4<*const f32> { // CHECK: [[A:%[0-9]+]] = lshr <4 x i32> {{.*}}, {{|splat \(i32 31\)}} // CHECK: [[B:%[0-9]+]] = trunc <4 x i32> [[A]] to <4 x i1> - // CHECK: call <4 x ptr> @llvm.masked.load.v4p0.p0(ptr {{.*}}, i32 {{.*}}, <4 x i1> [[B]], <4 x ptr> {{.*}}) + // LLVM21: call <4 x ptr> @llvm.masked.load.v4p0.p0(ptr {{.*}}, i32 {{.*}}, <4 x i1> [[B]], <4 x ptr> {{.*}}) + // LLVM22: call <4 x ptr> @llvm.masked.load.v4p0.p0(ptr align {{.*}} {{.*}}, <4 x i1> [[B]], <4 x ptr> {{.*}}) simd_masked_load(mask, pointer, values) } diff --git a/tests/codegen-llvm/simd-intrinsic/simd-intrinsic-generic-masked-store.rs b/tests/codegen-llvm/simd-intrinsic/simd-intrinsic-generic-masked-store.rs index 6ca7388d464b..03119d89bacd 100644 --- a/tests/codegen-llvm/simd-intrinsic/simd-intrinsic-generic-masked-store.rs +++ b/tests/codegen-llvm/simd-intrinsic/simd-intrinsic-generic-masked-store.rs @@ -1,4 +1,8 @@ //@ compile-flags: -C no-prepopulate-passes +//@ revisions: LLVM21 LLVM22 +//@ [LLVM22] min-llvm-version: 22 +//@ [LLVM21] max-llvm-major-version: 21 +// ignore-tidy-linelength #![crate_type = "lib"] #![feature(repr_simd, core_intrinsics)] @@ -18,7 +22,8 @@ pub type Vec4 = Simd; pub unsafe fn store_f32x2(mask: Vec2, pointer: *mut f32, values: Vec2) { // CHECK: [[A:%[0-9]+]] = lshr <2 x i32> {{.*}}, {{|splat \(i32 31\)}} // CHECK: [[B:%[0-9]+]] = trunc <2 x i32> [[A]] to <2 x i1> - // CHECK: call void @llvm.masked.store.v2f32.p0(<2 x float> {{.*}}, ptr {{.*}}, i32 4, <2 x i1> [[B]]) + // LLVM21: call void @llvm.masked.store.v2f32.p0(<2 x float> {{.*}}, ptr {{.*}}, i32 4, <2 x i1> [[B]]) + // LLVM22: call void @llvm.masked.store.v2f32.p0(<2 x float> {{.*}}, ptr align 4 {{.*}}, <2 x i1> [[B]]) simd_masked_store(mask, pointer, values) } @@ -27,7 +32,8 @@ pub unsafe fn store_f32x2(mask: Vec2, pointer: *mut f32, values: Vec2) pub unsafe fn store_f32x2_unsigned(mask: Vec2, pointer: *mut f32, values: Vec2) { // CHECK: [[A:%[0-9]+]] = lshr <2 x i32> {{.*}}, {{|splat \(i32 31\)}} // CHECK: [[B:%[0-9]+]] = trunc <2 x i32> [[A]] to <2 x i1> - // CHECK: call void @llvm.masked.store.v2f32.p0(<2 x float> {{.*}}, ptr {{.*}}, i32 4, <2 x i1> [[B]]) + // LLVM21: call void @llvm.masked.store.v2f32.p0(<2 x float> {{.*}}, ptr {{.*}}, i32 4, <2 x i1> [[B]]) + // LLVM22: call void @llvm.masked.store.v2f32.p0(<2 x float> {{.*}}, ptr align 4 {{.*}}, <2 x i1> [[B]]) simd_masked_store(mask, pointer, values) } @@ -36,6 +42,7 @@ pub unsafe fn store_f32x2_unsigned(mask: Vec2, pointer: *mut f32, values: V pub unsafe fn store_pf32x4(mask: Vec4, pointer: *mut *const f32, values: Vec4<*const f32>) { // CHECK: [[A:%[0-9]+]] = lshr <4 x i32> {{.*}}, {{|splat \(i32 31\)}} // CHECK: [[B:%[0-9]+]] = trunc <4 x i32> [[A]] to <4 x i1> - // CHECK: call void @llvm.masked.store.v4p0.p0(<4 x ptr> {{.*}}, ptr {{.*}}, i32 {{.*}}, <4 x i1> [[B]]) + // LLVM21: call void @llvm.masked.store.v4p0.p0(<4 x ptr> {{.*}}, ptr {{.*}}, i32 {{.*}}, <4 x i1> [[B]]) + // LLVM22: call void @llvm.masked.store.v4p0.p0(<4 x ptr> {{.*}}, ptr align {{.*}} {{.*}}, <4 x i1> [[B]]) simd_masked_store(mask, pointer, values) } diff --git a/tests/codegen-llvm/simd-intrinsic/simd-intrinsic-generic-scatter.rs b/tests/codegen-llvm/simd-intrinsic/simd-intrinsic-generic-scatter.rs index 743652966e16..533fa429ae70 100644 --- a/tests/codegen-llvm/simd-intrinsic/simd-intrinsic-generic-scatter.rs +++ b/tests/codegen-llvm/simd-intrinsic/simd-intrinsic-generic-scatter.rs @@ -1,6 +1,10 @@ // //@ compile-flags: -C no-prepopulate-passes +//@ revisions: LLVM21 LLVM22 +//@ [LLVM22] min-llvm-version: 22 +//@ [LLVM21] max-llvm-major-version: 21 +// ignore-tidy-linelength #![crate_type = "lib"] #![feature(repr_simd, core_intrinsics)] @@ -20,7 +24,8 @@ pub type Vec4 = Simd; pub unsafe fn scatter_f32x2(pointers: Vec2<*mut f32>, mask: Vec2, values: Vec2) { // CHECK: [[A:%[0-9]+]] = lshr <2 x i32> {{.*}}, {{|splat \(i32 31\)}} // CHECK: [[B:%[0-9]+]] = trunc <2 x i32> [[A]] to <2 x i1> - // CHECK: call void @llvm.masked.scatter.v2f32.v2p0(<2 x float> {{.*}}, <2 x ptr> {{.*}}, i32 {{.*}}, <2 x i1> [[B]] + // LLVM21: call void @llvm.masked.scatter.v2f32.v2p0(<2 x float> {{.*}}, <2 x ptr> {{.*}}, i32 {{.*}}, <2 x i1> [[B]] + // LLVM22: call void @llvm.masked.scatter.v2f32.v2p0(<2 x float> {{.*}}, <2 x ptr> align {{.*}} {{.*}}, <2 x i1> [[B]] simd_scatter(values, pointers, mask) } @@ -29,7 +34,8 @@ pub unsafe fn scatter_f32x2(pointers: Vec2<*mut f32>, mask: Vec2, values: V pub unsafe fn scatter_f32x2_unsigned(pointers: Vec2<*mut f32>, mask: Vec2, values: Vec2) { // CHECK: [[A:%[0-9]+]] = lshr <2 x i32> {{.*}}, {{|splat \(i32 31\)}} // CHECK: [[B:%[0-9]+]] = trunc <2 x i32> [[A]] to <2 x i1> - // CHECK: call void @llvm.masked.scatter.v2f32.v2p0(<2 x float> {{.*}}, <2 x ptr> {{.*}}, i32 {{.*}}, <2 x i1> [[B]] + // LLVM21: call void @llvm.masked.scatter.v2f32.v2p0(<2 x float> {{.*}}, <2 x ptr> {{.*}}, i32 {{.*}}, <2 x i1> [[B]] + // LLVM22: call void @llvm.masked.scatter.v2f32.v2p0(<2 x float> {{.*}}, <2 x ptr> align {{.*}} {{.*}}, <2 x i1> [[B]] simd_scatter(values, pointers, mask) } @@ -42,6 +48,7 @@ pub unsafe fn scatter_pf32x2( ) { // CHECK: [[A:%[0-9]+]] = lshr <2 x i32> {{.*}}, {{|splat \(i32 31\)}} // CHECK: [[B:%[0-9]+]] = trunc <2 x i32> [[A]] to <2 x i1> - // CHECK: call void @llvm.masked.scatter.v2p0.v2p0(<2 x ptr> {{.*}}, <2 x ptr> {{.*}}, i32 {{.*}}, <2 x i1> [[B]] + // LLVM21: call void @llvm.masked.scatter.v2p0.v2p0(<2 x ptr> {{.*}}, <2 x ptr> {{.*}}, i32 {{.*}}, <2 x i1> [[B]] + // LLVM22: call void @llvm.masked.scatter.v2p0.v2p0(<2 x ptr> {{.*}}, <2 x ptr> align {{.*}} {{.*}}, <2 x i1> [[B]] simd_scatter(values, pointers, mask) } diff --git a/tests/crashes/114663.rs b/tests/crashes/114663.rs deleted file mode 100644 index 406371f12e46..000000000000 --- a/tests/crashes/114663.rs +++ /dev/null @@ -1,17 +0,0 @@ -//@ known-bug: #114663 -//@ edition:2021 - -#![feature(generic_const_exprs)] - -use core::fmt::Debug; - -struct Inline -where - [u8; ::core::mem::size_of::() + 1]:, -{ - _phantom: PhantomData, -} - -fn main() { - let dst = Inline::::new(0); // BANG! -} diff --git a/tests/crashes/146261.rs b/tests/crashes/146261.rs new file mode 100644 index 000000000000..f901497a769c --- /dev/null +++ b/tests/crashes/146261.rs @@ -0,0 +1,13 @@ +// This is part of series of regression tests for some diagnostics ICEs encountered in the wild with +// suggestions having overlapping parts under https://github.com/rust-lang/rust/pull/146121. + +//@ needs-rustc-debug-assertions +//@ known-bug: #146261 + +enum U { + B(), +} + +fn main() { + A(U::C) +} diff --git a/tests/crashes/146706.rs b/tests/crashes/146706.rs new file mode 100644 index 000000000000..358ce3e8600a --- /dev/null +++ b/tests/crashes/146706.rs @@ -0,0 +1,15 @@ +// This is part of series of regression tests for some diagnostics ICEs encountered in the wild with +// suggestions having overlapping parts under https://github.com/rust-lang/rust/pull/146121. + +//@ needs-rustc-debug-assertions +//@ known-bug: #146706 + +type Alias<'a, T> = Foo; + +enum Foo { + Bar { t: T }, +} + +fn main() { + Alias::Bar:: { t: 0 }; +} diff --git a/tests/crashes/147973.rs b/tests/crashes/147973.rs new file mode 100644 index 000000000000..7271c54846f1 --- /dev/null +++ b/tests/crashes/147973.rs @@ -0,0 +1,14 @@ +// This is part of series of regression tests for some diagnostics ICEs encountered in the wild with +// suggestions having overlapping parts under https://github.com/rust-lang/rust/pull/146121. +// This is one MCVE from the beta crater run regressions from issue 147973. + +//@ needs-rustc-debug-assertions +//@ known-bug: #147973 + +//@ aux-build: overlapping_spans_helper.rs +extern crate overlapping_spans_helper; + +fn main() { + let _name = Some(1); + overlapping_spans_helper::do_loop!(_name); +} diff --git a/tests/crashes/auxiliary/overlapping_spans_helper.rs b/tests/crashes/auxiliary/overlapping_spans_helper.rs new file mode 100644 index 000000000000..e449fcd36c37 --- /dev/null +++ b/tests/crashes/auxiliary/overlapping_spans_helper.rs @@ -0,0 +1,15 @@ +// Auxiliary lib for the issue 147973 regression test with ICEs due to overlapping spans. + +#[macro_export] +macro_rules! identity { + ($x:ident) => { + $x + }; +} + +#[macro_export] +macro_rules! do_loop { + ($x:ident) => { + for $crate::identity!($x) in $x {} + }; +} diff --git a/tests/mir-opt/box_expr.main.ElaborateDrops.diff b/tests/mir-opt/box_expr.main.ElaborateDrops.diff index 827dc6ac7aef..4fa77cf82d81 100644 --- a/tests/mir-opt/box_expr.main.ElaborateDrops.diff +++ b/tests/mir-opt/box_expr.main.ElaborateDrops.diff @@ -4,49 +4,45 @@ fn main() -> () { let mut _0: (); let _1: std::boxed::Box; - let mut _2: usize; - let mut _3: usize; - let mut _4: *mut u8; + let mut _2: *mut u8; + let mut _3: std::boxed::Box; + let _4: (); let mut _5: std::boxed::Box; - let _6: (); - let mut _7: std::boxed::Box; -+ let mut _8: &mut std::boxed::Box; -+ let mut _9: (); -+ let mut _10: *const S; ++ let mut _6: &mut std::boxed::Box; ++ let mut _7: (); ++ let mut _8: *const S; scope 1 { debug x => _1; } bb0: { StorageLive(_1); - _2 = SizeOf(S); - _3 = AlignOf(S); - _4 = alloc::alloc::exchange_malloc(move _2, move _3) -> [return: bb1, unwind continue]; + _2 = alloc::alloc::exchange_malloc(const ::SIZE, const ::ALIGN) -> [return: bb1, unwind continue]; } bb1: { - StorageLive(_5); - _5 = ShallowInitBox(move _4, S); - (*_5) = S::new() -> [return: bb2, unwind: bb8]; + StorageLive(_3); + _3 = ShallowInitBox(move _2, S); + (*_3) = S::new() -> [return: bb2, unwind: bb8]; } bb2: { - _1 = move _5; -- drop(_5) -> [return: bb3, unwind continue]; + _1 = move _3; +- drop(_3) -> [return: bb3, unwind continue]; + goto -> bb3; } bb3: { - StorageDead(_5); - StorageLive(_6); - StorageLive(_7); - _7 = move _1; - _6 = std::mem::drop::>(move _7) -> [return: bb4, unwind: bb6]; + StorageDead(_3); + StorageLive(_4); + StorageLive(_5); + _5 = move _1; + _4 = std::mem::drop::>(move _5) -> [return: bb4, unwind: bb6]; } bb4: { - StorageDead(_7); - StorageDead(_6); + StorageDead(_5); + StorageDead(_4); _0 = const (); - drop(_1) -> [return: bb5, unwind continue]; + goto -> bb5; @@ -58,7 +54,7 @@ } bb6 (cleanup): { -- drop(_7) -> [return: bb7, unwind terminate(cleanup)]; +- drop(_5) -> [return: bb7, unwind terminate(cleanup)]; + goto -> bb7; } @@ -68,7 +64,7 @@ } bb8 (cleanup): { -- drop(_5) -> [return: bb9, unwind terminate(cleanup)]; +- drop(_3) -> [return: bb9, unwind terminate(cleanup)]; + goto -> bb12; } @@ -77,8 +73,8 @@ + } + + bb10 (cleanup): { -+ _8 = &mut _5; -+ _9 = as Drop>::drop(move _8) -> [return: bb9, unwind terminate(cleanup)]; ++ _6 = &mut _3; ++ _7 = as Drop>::drop(move _6) -> [return: bb9, unwind terminate(cleanup)]; + } + + bb11 (cleanup): { @@ -86,7 +82,7 @@ + } + + bb12 (cleanup): { -+ _10 = copy ((_5.0: std::ptr::Unique).0: std::ptr::NonNull) as *const S (Transmute); ++ _8 = copy ((_3.0: std::ptr::Unique).0: std::ptr::NonNull) as *const S (Transmute); + goto -> bb11; } } diff --git a/tests/mir-opt/building/uniform_array_move_out.move_out_by_subslice.built.after.mir b/tests/mir-opt/building/uniform_array_move_out.move_out_by_subslice.built.after.mir index 6d3b2cf29103..839bdeca86a8 100644 --- a/tests/mir-opt/building/uniform_array_move_out.move_out_by_subslice.built.after.mir +++ b/tests/mir-opt/building/uniform_array_move_out.move_out_by_subslice.built.after.mir @@ -4,63 +4,55 @@ fn move_out_by_subslice() -> () { let mut _0: (); let _1: [std::boxed::Box; 2]; let mut _2: std::boxed::Box; - let mut _3: usize; - let mut _4: usize; - let mut _5: *mut u8; - let mut _6: std::boxed::Box; + let mut _3: *mut u8; + let mut _4: std::boxed::Box; + let mut _5: std::boxed::Box; + let mut _6: *mut u8; let mut _7: std::boxed::Box; - let mut _8: usize; - let mut _9: usize; - let mut _10: *mut u8; - let mut _11: std::boxed::Box; scope 1 { debug a => _1; - let _12: [std::boxed::Box; 2]; + let _8: [std::boxed::Box; 2]; scope 2 { - debug _y => _12; + debug _y => _8; } } bb0: { StorageLive(_1); StorageLive(_2); - _3 = SizeOf(i32); - _4 = AlignOf(i32); - _5 = alloc::alloc::exchange_malloc(move _3, move _4) -> [return: bb1, unwind: bb13]; + _3 = alloc::alloc::exchange_malloc(const ::SIZE, const ::ALIGN) -> [return: bb1, unwind: bb13]; } bb1: { - StorageLive(_6); - _6 = ShallowInitBox(move _5, i32); - (*_6) = const 1_i32; - _2 = move _6; - drop(_6) -> [return: bb2, unwind: bb12]; + StorageLive(_4); + _4 = ShallowInitBox(move _3, i32); + (*_4) = const 1_i32; + _2 = move _4; + drop(_4) -> [return: bb2, unwind: bb12]; } bb2: { - StorageDead(_6); - StorageLive(_7); - _8 = SizeOf(i32); - _9 = AlignOf(i32); - _10 = alloc::alloc::exchange_malloc(move _8, move _9) -> [return: bb3, unwind: bb12]; + StorageDead(_4); + StorageLive(_5); + _6 = alloc::alloc::exchange_malloc(const ::SIZE, const ::ALIGN) -> [return: bb3, unwind: bb12]; } bb3: { - StorageLive(_11); - _11 = ShallowInitBox(move _10, i32); - (*_11) = const 2_i32; - _7 = move _11; - drop(_11) -> [return: bb4, unwind: bb11]; + StorageLive(_7); + _7 = ShallowInitBox(move _6, i32); + (*_7) = const 2_i32; + _5 = move _7; + drop(_7) -> [return: bb4, unwind: bb11]; } bb4: { - StorageDead(_11); - _1 = [move _2, move _7]; - drop(_7) -> [return: bb5, unwind: bb12]; + StorageDead(_7); + _1 = [move _2, move _5]; + drop(_5) -> [return: bb5, unwind: bb12]; } bb5: { - StorageDead(_7); + StorageDead(_5); drop(_2) -> [return: bb6, unwind: bb13]; } @@ -68,10 +60,10 @@ fn move_out_by_subslice() -> () { StorageDead(_2); FakeRead(ForLet(None), _1); PlaceMention(_1); - StorageLive(_12); - _12 = move _1[0..2]; + StorageLive(_8); + _8 = move _1[0..2]; _0 = const (); - drop(_12) -> [return: bb8, unwind: bb10]; + drop(_8) -> [return: bb8, unwind: bb10]; } bb7: { @@ -80,7 +72,7 @@ fn move_out_by_subslice() -> () { } bb8: { - StorageDead(_12); + StorageDead(_8); drop(_1) -> [return: bb9, unwind: bb13]; } @@ -94,7 +86,7 @@ fn move_out_by_subslice() -> () { } bb11 (cleanup): { - drop(_7) -> [return: bb12, unwind terminate(cleanup)]; + drop(_5) -> [return: bb12, unwind terminate(cleanup)]; } bb12 (cleanup): { diff --git a/tests/mir-opt/building/uniform_array_move_out.move_out_from_end.built.after.mir b/tests/mir-opt/building/uniform_array_move_out.move_out_from_end.built.after.mir index 003b90a912d2..7fda69c7500a 100644 --- a/tests/mir-opt/building/uniform_array_move_out.move_out_from_end.built.after.mir +++ b/tests/mir-opt/building/uniform_array_move_out.move_out_from_end.built.after.mir @@ -4,63 +4,55 @@ fn move_out_from_end() -> () { let mut _0: (); let _1: [std::boxed::Box; 2]; let mut _2: std::boxed::Box; - let mut _3: usize; - let mut _4: usize; - let mut _5: *mut u8; - let mut _6: std::boxed::Box; + let mut _3: *mut u8; + let mut _4: std::boxed::Box; + let mut _5: std::boxed::Box; + let mut _6: *mut u8; let mut _7: std::boxed::Box; - let mut _8: usize; - let mut _9: usize; - let mut _10: *mut u8; - let mut _11: std::boxed::Box; scope 1 { debug a => _1; - let _12: std::boxed::Box; + let _8: std::boxed::Box; scope 2 { - debug _y => _12; + debug _y => _8; } } bb0: { StorageLive(_1); StorageLive(_2); - _3 = SizeOf(i32); - _4 = AlignOf(i32); - _5 = alloc::alloc::exchange_malloc(move _3, move _4) -> [return: bb1, unwind: bb13]; + _3 = alloc::alloc::exchange_malloc(const ::SIZE, const ::ALIGN) -> [return: bb1, unwind: bb13]; } bb1: { - StorageLive(_6); - _6 = ShallowInitBox(move _5, i32); - (*_6) = const 1_i32; - _2 = move _6; - drop(_6) -> [return: bb2, unwind: bb12]; + StorageLive(_4); + _4 = ShallowInitBox(move _3, i32); + (*_4) = const 1_i32; + _2 = move _4; + drop(_4) -> [return: bb2, unwind: bb12]; } bb2: { - StorageDead(_6); - StorageLive(_7); - _8 = SizeOf(i32); - _9 = AlignOf(i32); - _10 = alloc::alloc::exchange_malloc(move _8, move _9) -> [return: bb3, unwind: bb12]; + StorageDead(_4); + StorageLive(_5); + _6 = alloc::alloc::exchange_malloc(const ::SIZE, const ::ALIGN) -> [return: bb3, unwind: bb12]; } bb3: { - StorageLive(_11); - _11 = ShallowInitBox(move _10, i32); - (*_11) = const 2_i32; - _7 = move _11; - drop(_11) -> [return: bb4, unwind: bb11]; + StorageLive(_7); + _7 = ShallowInitBox(move _6, i32); + (*_7) = const 2_i32; + _5 = move _7; + drop(_7) -> [return: bb4, unwind: bb11]; } bb4: { - StorageDead(_11); - _1 = [move _2, move _7]; - drop(_7) -> [return: bb5, unwind: bb12]; + StorageDead(_7); + _1 = [move _2, move _5]; + drop(_5) -> [return: bb5, unwind: bb12]; } bb5: { - StorageDead(_7); + StorageDead(_5); drop(_2) -> [return: bb6, unwind: bb13]; } @@ -68,10 +60,10 @@ fn move_out_from_end() -> () { StorageDead(_2); FakeRead(ForLet(None), _1); PlaceMention(_1); - StorageLive(_12); - _12 = move _1[1 of 2]; + StorageLive(_8); + _8 = move _1[1 of 2]; _0 = const (); - drop(_12) -> [return: bb8, unwind: bb10]; + drop(_8) -> [return: bb8, unwind: bb10]; } bb7: { @@ -80,7 +72,7 @@ fn move_out_from_end() -> () { } bb8: { - StorageDead(_12); + StorageDead(_8); drop(_1) -> [return: bb9, unwind: bb13]; } @@ -94,7 +86,7 @@ fn move_out_from_end() -> () { } bb11 (cleanup): { - drop(_7) -> [return: bb12, unwind terminate(cleanup)]; + drop(_5) -> [return: bb12, unwind terminate(cleanup)]; } bb12 (cleanup): { diff --git a/tests/mir-opt/const_prop/boxes.main.GVN.panic-abort.diff b/tests/mir-opt/const_prop/boxes.main.GVN.panic-abort.diff index 16bae67cc989..95eaf18b4703 100644 --- a/tests/mir-opt/const_prop/boxes.main.GVN.panic-abort.diff +++ b/tests/mir-opt/const_prop/boxes.main.GVN.panic-abort.diff @@ -6,15 +6,13 @@ let _1: i32; let mut _2: i32; let mut _3: std::boxed::Box; - let mut _4: usize; - let mut _5: usize; - let mut _6: *mut u8; - let mut _7: std::boxed::Box; - let mut _8: *const i32; - let mut _9: std::ptr::NonNull; - let mut _10: std::ptr::Unique; - let mut _11: *const i32; - let mut _12: *const i32; + let mut _4: *mut u8; + let mut _5: std::boxed::Box; + let mut _6: *const i32; + let mut _7: std::ptr::NonNull; + let mut _8: std::ptr::Unique; + let mut _9: *const i32; + let mut _10: *const i32; scope 1 { debug x => _1; } @@ -24,31 +22,26 @@ - StorageLive(_2); + nop; StorageLive(_3); -- _4 = SizeOf(i32); -- _5 = AlignOf(i32); -- _6 = alloc::alloc::exchange_malloc(move _4, move _5) -> [return: bb1, unwind unreachable]; -+ _4 = const 4_usize; -+ _5 = const 4_usize; -+ _6 = alloc::alloc::exchange_malloc(const 4_usize, const 4_usize) -> [return: bb1, unwind unreachable]; + _4 = alloc::alloc::exchange_malloc(const ::SIZE, const ::ALIGN) -> [return: bb1, unwind unreachable]; } bb1: { - StorageLive(_7); -- _8 = move _6 as *const i32 (Transmute); -- _9 = NonNull:: { pointer: move _8 }; -- _10 = Unique:: { pointer: move _9, _marker: const PhantomData:: }; -+ _8 = copy _6 as *const i32 (PtrToPtr); -+ _9 = NonNull:: { pointer: copy _8 }; -+ _10 = Unique:: { pointer: copy _9, _marker: const PhantomData:: }; - _7 = Box::(move _10, const std::alloc::Global); -- _11 = copy ((_7.0: std::ptr::Unique).0: std::ptr::NonNull) as *const i32 (Transmute); -- (*_11) = const 42_i32; -+ _11 = copy _8; -+ (*_8) = const 42_i32; - _3 = move _7; - StorageDead(_7); - _12 = copy ((_3.0: std::ptr::Unique).0: std::ptr::NonNull) as *const i32 (Transmute); - _2 = copy (*_12); + StorageLive(_5); +- _6 = move _4 as *const i32 (Transmute); +- _7 = NonNull:: { pointer: move _6 }; +- _8 = Unique:: { pointer: move _7, _marker: const PhantomData:: }; ++ _6 = copy _4 as *const i32 (PtrToPtr); ++ _7 = NonNull:: { pointer: copy _6 }; ++ _8 = Unique:: { pointer: copy _7, _marker: const PhantomData:: }; + _5 = Box::(move _8, const std::alloc::Global); +- _9 = copy ((_5.0: std::ptr::Unique).0: std::ptr::NonNull) as *const i32 (Transmute); +- (*_9) = const 42_i32; ++ _9 = copy _6; ++ (*_6) = const 42_i32; + _3 = move _5; + StorageDead(_5); + _10 = copy ((_3.0: std::ptr::Unique).0: std::ptr::NonNull) as *const i32 (Transmute); + _2 = copy (*_10); - _1 = Add(move _2, const 0_i32); - StorageDead(_2); + _1 = copy _2; diff --git a/tests/mir-opt/const_prop/boxes.main.GVN.panic-unwind.diff b/tests/mir-opt/const_prop/boxes.main.GVN.panic-unwind.diff index 3fbf7a57a76f..6d8d3a0dcfe2 100644 --- a/tests/mir-opt/const_prop/boxes.main.GVN.panic-unwind.diff +++ b/tests/mir-opt/const_prop/boxes.main.GVN.panic-unwind.diff @@ -6,15 +6,13 @@ let _1: i32; let mut _2: i32; let mut _3: std::boxed::Box; - let mut _4: usize; - let mut _5: usize; - let mut _6: *mut u8; - let mut _7: std::boxed::Box; - let mut _8: *const i32; - let mut _9: std::ptr::NonNull; - let mut _10: std::ptr::Unique; - let mut _11: *const i32; - let mut _12: *const i32; + let mut _4: *mut u8; + let mut _5: std::boxed::Box; + let mut _6: *const i32; + let mut _7: std::ptr::NonNull; + let mut _8: std::ptr::Unique; + let mut _9: *const i32; + let mut _10: *const i32; scope 1 { debug x => _1; } @@ -24,31 +22,26 @@ - StorageLive(_2); + nop; StorageLive(_3); -- _4 = SizeOf(i32); -- _5 = AlignOf(i32); -- _6 = alloc::alloc::exchange_malloc(move _4, move _5) -> [return: bb1, unwind continue]; -+ _4 = const 4_usize; -+ _5 = const 4_usize; -+ _6 = alloc::alloc::exchange_malloc(const 4_usize, const 4_usize) -> [return: bb1, unwind continue]; + _4 = alloc::alloc::exchange_malloc(const ::SIZE, const ::ALIGN) -> [return: bb1, unwind continue]; } bb1: { - StorageLive(_7); -- _8 = move _6 as *const i32 (Transmute); -- _9 = NonNull:: { pointer: move _8 }; -- _10 = Unique:: { pointer: move _9, _marker: const PhantomData:: }; -+ _8 = copy _6 as *const i32 (PtrToPtr); -+ _9 = NonNull:: { pointer: copy _8 }; -+ _10 = Unique:: { pointer: copy _9, _marker: const PhantomData:: }; - _7 = Box::(move _10, const std::alloc::Global); -- _11 = copy ((_7.0: std::ptr::Unique).0: std::ptr::NonNull) as *const i32 (Transmute); -- (*_11) = const 42_i32; -+ _11 = copy _8; -+ (*_8) = const 42_i32; - _3 = move _7; - StorageDead(_7); - _12 = copy ((_3.0: std::ptr::Unique).0: std::ptr::NonNull) as *const i32 (Transmute); - _2 = copy (*_12); + StorageLive(_5); +- _6 = move _4 as *const i32 (Transmute); +- _7 = NonNull:: { pointer: move _6 }; +- _8 = Unique:: { pointer: move _7, _marker: const PhantomData:: }; ++ _6 = copy _4 as *const i32 (PtrToPtr); ++ _7 = NonNull:: { pointer: copy _6 }; ++ _8 = Unique:: { pointer: copy _7, _marker: const PhantomData:: }; + _5 = Box::(move _8, const std::alloc::Global); +- _9 = copy ((_5.0: std::ptr::Unique).0: std::ptr::NonNull) as *const i32 (Transmute); +- (*_9) = const 42_i32; ++ _9 = copy _6; ++ (*_6) = const 42_i32; + _3 = move _5; + StorageDead(_5); + _10 = copy ((_3.0: std::ptr::Unique).0: std::ptr::NonNull) as *const i32 (Transmute); + _2 = copy (*_10); - _1 = Add(move _2, const 0_i32); - StorageDead(_2); + _1 = copy _2; diff --git a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-abort.diff b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-abort.diff index f47e54438549..38beb81e1ead 100644 --- a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-abort.diff +++ b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-abort.diff @@ -11,6 +11,8 @@ let mut _9: *const [()]; let mut _10: std::boxed::Box<()>; let mut _11: *const (); + let mut _16: usize; + let mut _17: usize; let mut _27: usize; scope 1 { debug vp_ctx => _1; @@ -35,12 +37,10 @@ } } scope 5 (inlined Box::<()>::new) { - let mut _12: usize; - let mut _13: usize; - let mut _14: *mut u8; - let mut _15: *const (); - let mut _16: std::ptr::NonNull<()>; - let mut _17: std::ptr::Unique<()>; + let mut _12: *mut u8; + let mut _13: *const (); + let mut _14: std::ptr::NonNull<()>; + let mut _15: std::ptr::Unique<()>; scope 6 (inlined alloc::alloc::exchange_malloc) { let _18: std::alloc::Layout; let mut _19: std::result::Result, std::alloc::AllocError>; @@ -85,11 +85,11 @@ StorageLive(_14); StorageLive(_15); StorageLive(_16); +- _16 = const <() as std::mem::SizedTypeProperties>::SIZE; ++ _16 = const 0_usize; StorageLive(_17); -- _12 = SizeOf(()); -- _13 = AlignOf(()); -+ _12 = const 0_usize; -+ _13 = const 1_usize; +- _17 = const <() as std::mem::SizedTypeProperties>::ALIGN; ++ _17 = const 1_usize; StorageLive(_18); StorageLive(_20); StorageLive(_21); @@ -120,7 +120,7 @@ - StorageLive(_26); + nop; _26 = copy _21 as *mut [u8] (Transmute); - _14 = copy _26 as *mut u8 (PtrToPtr); + _12 = copy _26 as *mut u8 (PtrToPtr); - StorageDead(_26); + nop; StorageDead(_19); @@ -129,15 +129,15 @@ StorageDead(_21); StorageDead(_20); StorageDead(_18); -- _15 = copy _14 as *const () (PtrToPtr); -+ _15 = copy _26 as *const () (PtrToPtr); - _16 = NonNull::<()> { pointer: copy _15 }; - _17 = Unique::<()> { pointer: copy _16, _marker: const PhantomData::<()> }; - _3 = Box::<()>(move _17, const std::alloc::Global); -- (*_15) = move _4; -+ (*_15) = const (); StorageDead(_17); StorageDead(_16); +- _13 = copy _12 as *const () (PtrToPtr); ++ _13 = copy _26 as *const () (PtrToPtr); + _14 = NonNull::<()> { pointer: copy _13 }; + _15 = Unique::<()> { pointer: copy _14, _marker: const PhantomData::<()> }; + _3 = Box::<()>(move _15, const std::alloc::Global); +- (*_13) = move _4; ++ (*_13) = const (); StorageDead(_15); StorageDead(_14); StorageDead(_13); @@ -183,15 +183,15 @@ } bb5: { -- _24 = Layout::from_size_align_unchecked::precondition_check(copy _12, copy _13) -> [return: bb6, unwind unreachable]; +- _24 = Layout::from_size_align_unchecked::precondition_check(copy _16, copy _17) -> [return: bb6, unwind unreachable]; + _24 = Layout::from_size_align_unchecked::precondition_check(const 0_usize, const 1_usize) -> [return: bb6, unwind unreachable]; } bb6: { StorageDead(_23); StorageLive(_25); -- _25 = copy _13 as std::ptr::Alignment (Transmute); -- _18 = Layout { size: copy _12, align: move _25 }; +- _25 = copy _17 as std::ptr::Alignment (Transmute); +- _18 = Layout { size: copy _16, align: move _25 }; + _25 = const std::ptr::Alignment(std::ptr::alignment::AlignmentEnum::_Align1Shl0); + _18 = const Layout {{ size: 0_usize, align: std::ptr::Alignment(std::ptr::alignment::AlignmentEnum::_Align1Shl0) }}; StorageDead(_25); diff --git a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-abort.diff b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-abort.diff index fe88ff7a53e7..047579cdb509 100644 --- a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-abort.diff +++ b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-abort.diff @@ -11,6 +11,8 @@ let mut _9: *const [()]; let mut _10: std::boxed::Box<()>; let mut _11: *const (); + let mut _16: usize; + let mut _17: usize; let mut _27: usize; scope 1 { debug vp_ctx => _1; @@ -35,12 +37,10 @@ } } scope 5 (inlined Box::<()>::new) { - let mut _12: usize; - let mut _13: usize; - let mut _14: *mut u8; - let mut _15: *const (); - let mut _16: std::ptr::NonNull<()>; - let mut _17: std::ptr::Unique<()>; + let mut _12: *mut u8; + let mut _13: *const (); + let mut _14: std::ptr::NonNull<()>; + let mut _15: std::ptr::Unique<()>; scope 6 (inlined alloc::alloc::exchange_malloc) { let _18: std::alloc::Layout; let mut _19: std::result::Result, std::alloc::AllocError>; @@ -85,11 +85,11 @@ StorageLive(_14); StorageLive(_15); StorageLive(_16); +- _16 = const <() as std::mem::SizedTypeProperties>::SIZE; ++ _16 = const 0_usize; StorageLive(_17); -- _12 = SizeOf(()); -- _13 = AlignOf(()); -+ _12 = const 0_usize; -+ _13 = const 1_usize; +- _17 = const <() as std::mem::SizedTypeProperties>::ALIGN; ++ _17 = const 1_usize; StorageLive(_18); StorageLive(_20); StorageLive(_21); @@ -120,7 +120,7 @@ - StorageLive(_26); + nop; _26 = copy _21 as *mut [u8] (Transmute); - _14 = copy _26 as *mut u8 (PtrToPtr); + _12 = copy _26 as *mut u8 (PtrToPtr); - StorageDead(_26); + nop; StorageDead(_19); @@ -129,15 +129,15 @@ StorageDead(_21); StorageDead(_20); StorageDead(_18); -- _15 = copy _14 as *const () (PtrToPtr); -+ _15 = copy _26 as *const () (PtrToPtr); - _16 = NonNull::<()> { pointer: copy _15 }; - _17 = Unique::<()> { pointer: copy _16, _marker: const PhantomData::<()> }; - _3 = Box::<()>(move _17, const std::alloc::Global); -- (*_15) = move _4; -+ (*_15) = const (); StorageDead(_17); StorageDead(_16); +- _13 = copy _12 as *const () (PtrToPtr); ++ _13 = copy _26 as *const () (PtrToPtr); + _14 = NonNull::<()> { pointer: copy _13 }; + _15 = Unique::<()> { pointer: copy _14, _marker: const PhantomData::<()> }; + _3 = Box::<()>(move _15, const std::alloc::Global); +- (*_13) = move _4; ++ (*_13) = const (); StorageDead(_15); StorageDead(_14); StorageDead(_13); @@ -183,15 +183,15 @@ } bb5: { -- _24 = Layout::from_size_align_unchecked::precondition_check(copy _12, copy _13) -> [return: bb6, unwind unreachable]; +- _24 = Layout::from_size_align_unchecked::precondition_check(copy _16, copy _17) -> [return: bb6, unwind unreachable]; + _24 = Layout::from_size_align_unchecked::precondition_check(const 0_usize, const 1_usize) -> [return: bb6, unwind unreachable]; } bb6: { StorageDead(_23); StorageLive(_25); -- _25 = copy _13 as std::ptr::Alignment (Transmute); -- _18 = Layout { size: copy _12, align: move _25 }; +- _25 = copy _17 as std::ptr::Alignment (Transmute); +- _18 = Layout { size: copy _16, align: move _25 }; + _25 = const std::ptr::Alignment(std::ptr::alignment::AlignmentEnum::_Align1Shl0); + _18 = const Layout {{ size: 0_usize, align: std::ptr::Alignment(std::ptr::alignment::AlignmentEnum::_Align1Shl0) }}; StorageDead(_25); diff --git a/tests/mir-opt/instsimplify/align_of_slice.of_val_slice.InstSimplify-after-simplifycfg.diff b/tests/mir-opt/instsimplify/align_of_slice.of_val_slice.InstSimplify-after-simplifycfg.diff index 042e19bf2aa1..bbcc9012a25d 100644 --- a/tests/mir-opt/instsimplify/align_of_slice.of_val_slice.InstSimplify-after-simplifycfg.diff +++ b/tests/mir-opt/instsimplify/align_of_slice.of_val_slice.InstSimplify-after-simplifycfg.diff @@ -10,7 +10,7 @@ StorageLive(_2); _2 = &raw const (*_1); - _0 = std::intrinsics::align_of_val::<[T]>(move _2) -> [return: bb1, unwind unreachable]; -+ _0 = AlignOf(T); ++ _0 = const ::ALIGN; + goto -> bb1; } diff --git a/tests/mir-opt/instsimplify/align_of_slice.rs b/tests/mir-opt/instsimplify/align_of_slice.rs index 0af05cb6b0b0..99a68e444fe5 100644 --- a/tests/mir-opt/instsimplify/align_of_slice.rs +++ b/tests/mir-opt/instsimplify/align_of_slice.rs @@ -7,6 +7,6 @@ // EMIT_MIR align_of_slice.of_val_slice.InstSimplify-after-simplifycfg.diff pub fn of_val_slice(slice: &[T]) -> usize { // CHECK-LABEL: fn of_val_slice(_1: &[T]) - // CHECK: _0 = AlignOf(T); + // CHECK: _0 = const ::ALIGN; unsafe { core::intrinsics::align_of_val(slice) } } diff --git a/tests/mir-opt/issue_62289.test.ElaborateDrops.before.panic-abort.mir b/tests/mir-opt/issue_62289.test.ElaborateDrops.before.panic-abort.mir index 736a8bbca49c..c46549c5742f 100644 --- a/tests/mir-opt/issue_62289.test.ElaborateDrops.before.panic-abort.mir +++ b/tests/mir-opt/issue_62289.test.ElaborateDrops.before.panic-abort.mir @@ -3,49 +3,45 @@ fn test() -> Option> { let mut _0: std::option::Option>; let mut _1: std::boxed::Box; - let mut _2: usize; - let mut _3: usize; - let mut _4: *mut u8; - let mut _5: std::boxed::Box; - let mut _6: std::ops::ControlFlow, u32>; - let mut _7: std::option::Option; - let mut _8: isize; - let _9: std::option::Option; - let mut _10: !; - let mut _11: std::option::Option; - let _12: u32; + let mut _2: *mut u8; + let mut _3: std::boxed::Box; + let mut _4: std::ops::ControlFlow, u32>; + let mut _5: std::option::Option; + let mut _6: isize; + let _7: std::option::Option; + let mut _8: !; + let mut _9: std::option::Option; + let _10: u32; scope 1 { - debug residual => _9; + debug residual => _7; scope 2 { } } scope 3 { - debug val => _12; + debug val => _10; scope 4 { } } bb0: { StorageLive(_1); - _2 = SizeOf(u32); - _3 = AlignOf(u32); - _4 = alloc::alloc::exchange_malloc(move _2, move _3) -> [return: bb1, unwind: bb13]; + _2 = alloc::alloc::exchange_malloc(const ::SIZE, const ::ALIGN) -> [return: bb1, unwind: bb13]; } bb1: { + StorageLive(_3); + _3 = ShallowInitBox(move _2, u32); + StorageLive(_4); StorageLive(_5); - _5 = ShallowInitBox(move _4, u32); - StorageLive(_6); - StorageLive(_7); - _7 = Option::::None; - _6 = as Try>::branch(move _7) -> [return: bb2, unwind: bb12]; + _5 = Option::::None; + _4 = as Try>::branch(move _5) -> [return: bb2, unwind: bb12]; } bb2: { - StorageDead(_7); - PlaceMention(_6); - _8 = discriminant(_6); - switchInt(move _8) -> [0: bb4, 1: bb5, otherwise: bb3]; + StorageDead(_5); + PlaceMention(_4); + _6 = discriminant(_4); + switchInt(move _6) -> [0: bb4, 1: bb5, otherwise: bb3]; } bb3: { @@ -53,44 +49,44 @@ fn test() -> Option> { } bb4: { - StorageLive(_12); - _12 = copy ((_6 as Continue).0: u32); - (*_5) = copy _12; - StorageDead(_12); - _1 = move _5; - drop(_5) -> [return: bb7, unwind: bb11]; + StorageLive(_10); + _10 = copy ((_4 as Continue).0: u32); + (*_3) = copy _10; + StorageDead(_10); + _1 = move _3; + drop(_3) -> [return: bb7, unwind: bb11]; } bb5: { + StorageLive(_7); + _7 = copy ((_4 as Break).0: std::option::Option); StorageLive(_9); - _9 = copy ((_6 as Break).0: std::option::Option); - StorageLive(_11); - _11 = copy _9; - _0 = > as FromResidual>>::from_residual(move _11) -> [return: bb6, unwind: bb12]; + _9 = copy _7; + _0 = > as FromResidual>>::from_residual(move _9) -> [return: bb6, unwind: bb12]; } bb6: { - StorageDead(_11); StorageDead(_9); - drop(_5) -> [return: bb9, unwind: bb13]; + StorageDead(_7); + drop(_3) -> [return: bb9, unwind: bb13]; } bb7: { - StorageDead(_5); + StorageDead(_3); _0 = Option::>::Some(move _1); drop(_1) -> [return: bb8, unwind: bb13]; } bb8: { StorageDead(_1); - StorageDead(_6); + StorageDead(_4); goto -> bb10; } bb9: { - StorageDead(_5); + StorageDead(_3); StorageDead(_1); - StorageDead(_6); + StorageDead(_4); goto -> bb10; } @@ -103,7 +99,7 @@ fn test() -> Option> { } bb12 (cleanup): { - drop(_5) -> [return: bb13, unwind terminate(cleanup)]; + drop(_3) -> [return: bb13, unwind terminate(cleanup)]; } bb13 (cleanup): { diff --git a/tests/mir-opt/issue_62289.test.ElaborateDrops.before.panic-unwind.mir b/tests/mir-opt/issue_62289.test.ElaborateDrops.before.panic-unwind.mir index 1acb1ae20b69..9f26debdbb6d 100644 --- a/tests/mir-opt/issue_62289.test.ElaborateDrops.before.panic-unwind.mir +++ b/tests/mir-opt/issue_62289.test.ElaborateDrops.before.panic-unwind.mir @@ -3,49 +3,45 @@ fn test() -> Option> { let mut _0: std::option::Option>; let mut _1: std::boxed::Box; - let mut _2: usize; - let mut _3: usize; - let mut _4: *mut u8; - let mut _5: std::boxed::Box; - let mut _6: std::ops::ControlFlow, u32>; - let mut _7: std::option::Option; - let mut _8: isize; - let _9: std::option::Option; - let mut _10: !; - let mut _11: std::option::Option; - let _12: u32; + let mut _2: *mut u8; + let mut _3: std::boxed::Box; + let mut _4: std::ops::ControlFlow, u32>; + let mut _5: std::option::Option; + let mut _6: isize; + let _7: std::option::Option; + let mut _8: !; + let mut _9: std::option::Option; + let _10: u32; scope 1 { - debug residual => _9; + debug residual => _7; scope 2 { } } scope 3 { - debug val => _12; + debug val => _10; scope 4 { } } bb0: { StorageLive(_1); - _2 = SizeOf(u32); - _3 = AlignOf(u32); - _4 = alloc::alloc::exchange_malloc(move _2, move _3) -> [return: bb1, unwind continue]; + _2 = alloc::alloc::exchange_malloc(const ::SIZE, const ::ALIGN) -> [return: bb1, unwind continue]; } bb1: { + StorageLive(_3); + _3 = ShallowInitBox(move _2, u32); + StorageLive(_4); StorageLive(_5); - _5 = ShallowInitBox(move _4, u32); - StorageLive(_6); - StorageLive(_7); - _7 = Option::::None; - _6 = as Try>::branch(move _7) -> [return: bb2, unwind: bb12]; + _5 = Option::::None; + _4 = as Try>::branch(move _5) -> [return: bb2, unwind: bb12]; } bb2: { - StorageDead(_7); - PlaceMention(_6); - _8 = discriminant(_6); - switchInt(move _8) -> [0: bb4, 1: bb5, otherwise: bb3]; + StorageDead(_5); + PlaceMention(_4); + _6 = discriminant(_4); + switchInt(move _6) -> [0: bb4, 1: bb5, otherwise: bb3]; } bb3: { @@ -53,44 +49,44 @@ fn test() -> Option> { } bb4: { - StorageLive(_12); - _12 = copy ((_6 as Continue).0: u32); - (*_5) = copy _12; - StorageDead(_12); - _1 = move _5; - drop(_5) -> [return: bb7, unwind: bb11]; + StorageLive(_10); + _10 = copy ((_4 as Continue).0: u32); + (*_3) = copy _10; + StorageDead(_10); + _1 = move _3; + drop(_3) -> [return: bb7, unwind: bb11]; } bb5: { + StorageLive(_7); + _7 = copy ((_4 as Break).0: std::option::Option); StorageLive(_9); - _9 = copy ((_6 as Break).0: std::option::Option); - StorageLive(_11); - _11 = copy _9; - _0 = > as FromResidual>>::from_residual(move _11) -> [return: bb6, unwind: bb12]; + _9 = copy _7; + _0 = > as FromResidual>>::from_residual(move _9) -> [return: bb6, unwind: bb12]; } bb6: { - StorageDead(_11); StorageDead(_9); - drop(_5) -> [return: bb9, unwind continue]; + StorageDead(_7); + drop(_3) -> [return: bb9, unwind continue]; } bb7: { - StorageDead(_5); + StorageDead(_3); _0 = Option::>::Some(move _1); drop(_1) -> [return: bb8, unwind continue]; } bb8: { StorageDead(_1); - StorageDead(_6); + StorageDead(_4); goto -> bb10; } bb9: { - StorageDead(_5); + StorageDead(_3); StorageDead(_1); - StorageDead(_6); + StorageDead(_4); goto -> bb10; } @@ -103,7 +99,7 @@ fn test() -> Option> { } bb12 (cleanup): { - drop(_5) -> [return: bb13, unwind terminate(cleanup)]; + drop(_3) -> [return: bb13, unwind terminate(cleanup)]; } bb13 (cleanup): { diff --git a/tests/mir-opt/lower_intrinsics.align_of.LowerIntrinsics.panic-abort.diff b/tests/mir-opt/lower_intrinsics.align_of.LowerIntrinsics.panic-abort.diff deleted file mode 100644 index e61a3e8d7383..000000000000 --- a/tests/mir-opt/lower_intrinsics.align_of.LowerIntrinsics.panic-abort.diff +++ /dev/null @@ -1,17 +0,0 @@ -- // MIR for `align_of` before LowerIntrinsics -+ // MIR for `align_of` after LowerIntrinsics - - fn align_of() -> usize { - let mut _0: usize; - - bb0: { -- _0 = std::intrinsics::align_of::() -> [return: bb1, unwind unreachable]; -+ _0 = AlignOf(T); -+ goto -> bb1; - } - - bb1: { - return; - } - } - diff --git a/tests/mir-opt/lower_intrinsics.align_of.LowerIntrinsics.panic-unwind.diff b/tests/mir-opt/lower_intrinsics.align_of.LowerIntrinsics.panic-unwind.diff deleted file mode 100644 index e61a3e8d7383..000000000000 --- a/tests/mir-opt/lower_intrinsics.align_of.LowerIntrinsics.panic-unwind.diff +++ /dev/null @@ -1,17 +0,0 @@ -- // MIR for `align_of` before LowerIntrinsics -+ // MIR for `align_of` after LowerIntrinsics - - fn align_of() -> usize { - let mut _0: usize; - - bb0: { -- _0 = std::intrinsics::align_of::() -> [return: bb1, unwind unreachable]; -+ _0 = AlignOf(T); -+ goto -> bb1; - } - - bb1: { - return; - } - } - diff --git a/tests/mir-opt/lower_intrinsics.non_const.LowerIntrinsics.panic-abort.diff b/tests/mir-opt/lower_intrinsics.non_const.LowerIntrinsics.panic-abort.diff index 5aa986984768..42b8ab3da66c 100644 --- a/tests/mir-opt/lower_intrinsics.non_const.LowerIntrinsics.panic-abort.diff +++ b/tests/mir-opt/lower_intrinsics.non_const.LowerIntrinsics.panic-abort.diff @@ -3,26 +3,21 @@ fn non_const() -> usize { let mut _0: usize; - let _1: fn() -> usize {std::intrinsics::size_of::}; - let mut _2: fn() -> usize {std::intrinsics::size_of::}; + let _1: unsafe fn() -> ! {std::intrinsics::unreachable}; + let mut _2: !; + let mut _3: unsafe fn() -> ! {std::intrinsics::unreachable}; scope 1 { - debug size_of_t => _1; + debug unreachable => _1; } bb0: { StorageLive(_1); - _1 = std::intrinsics::size_of::; + _1 = std::intrinsics::unreachable; StorageLive(_2); - _2 = copy _1; -- _0 = move _2() -> [return: bb1, unwind unreachable]; -+ _0 = SizeOf(T); -+ goto -> bb1; - } - - bb1: { - StorageDead(_2); - StorageDead(_1); - return; + StorageLive(_3); + _3 = copy _1; +- _2 = move _3() -> unwind unreachable; ++ unreachable; } } diff --git a/tests/mir-opt/lower_intrinsics.non_const.LowerIntrinsics.panic-unwind.diff b/tests/mir-opt/lower_intrinsics.non_const.LowerIntrinsics.panic-unwind.diff index 5aa986984768..42b8ab3da66c 100644 --- a/tests/mir-opt/lower_intrinsics.non_const.LowerIntrinsics.panic-unwind.diff +++ b/tests/mir-opt/lower_intrinsics.non_const.LowerIntrinsics.panic-unwind.diff @@ -3,26 +3,21 @@ fn non_const() -> usize { let mut _0: usize; - let _1: fn() -> usize {std::intrinsics::size_of::}; - let mut _2: fn() -> usize {std::intrinsics::size_of::}; + let _1: unsafe fn() -> ! {std::intrinsics::unreachable}; + let mut _2: !; + let mut _3: unsafe fn() -> ! {std::intrinsics::unreachable}; scope 1 { - debug size_of_t => _1; + debug unreachable => _1; } bb0: { StorageLive(_1); - _1 = std::intrinsics::size_of::; + _1 = std::intrinsics::unreachable; StorageLive(_2); - _2 = copy _1; -- _0 = move _2() -> [return: bb1, unwind unreachable]; -+ _0 = SizeOf(T); -+ goto -> bb1; - } - - bb1: { - StorageDead(_2); - StorageDead(_1); - return; + StorageLive(_3); + _3 = copy _1; +- _2 = move _3() -> unwind unreachable; ++ unreachable; } } diff --git a/tests/mir-opt/lower_intrinsics.rs b/tests/mir-opt/lower_intrinsics.rs index 7729e502ad6b..6b8c2a790202 100644 --- a/tests/mir-opt/lower_intrinsics.rs +++ b/tests/mir-opt/lower_intrinsics.rs @@ -40,20 +40,6 @@ pub unsafe fn unchecked(a: i32, b: i32, c: u32) { let _l = core::intrinsics::unchecked_shr(a, c); } -// EMIT_MIR lower_intrinsics.size_of.LowerIntrinsics.diff -pub fn size_of() -> usize { - // CHECK-LABEL: fn size_of( - // CHECK: {{_.*}} = SizeOf(T); - core::intrinsics::size_of::() -} - -// EMIT_MIR lower_intrinsics.align_of.LowerIntrinsics.diff -pub fn align_of() -> usize { - // CHECK-LABEL: fn align_of( - // CHECK: {{_.*}} = AlignOf(T); - core::intrinsics::align_of::() -} - // EMIT_MIR lower_intrinsics.forget.LowerIntrinsics.diff pub fn forget(t: T) { // CHECK-LABEL: fn forget( @@ -73,11 +59,13 @@ pub fn unreachable() -> ! { // EMIT_MIR lower_intrinsics.non_const.LowerIntrinsics.diff pub fn non_const() -> usize { // CHECK-LABEL: fn non_const( - // CHECK: SizeOf(T); + // CHECK: _1 = std::intrinsics::unreachable; + // CHECK: unreachable; + // CHECK-NEXT: } // Check that lowering works with non-const operand as a func. - let size_of_t = core::intrinsics::size_of::; - size_of_t() + let unreachable = core::intrinsics::unreachable; + unsafe { unreachable() } } // EMIT_MIR lower_intrinsics.transmute_inhabited.LowerIntrinsics.diff diff --git a/tests/mir-opt/lower_intrinsics.size_of.LowerIntrinsics.panic-abort.diff b/tests/mir-opt/lower_intrinsics.size_of.LowerIntrinsics.panic-abort.diff deleted file mode 100644 index a547bdf3737b..000000000000 --- a/tests/mir-opt/lower_intrinsics.size_of.LowerIntrinsics.panic-abort.diff +++ /dev/null @@ -1,17 +0,0 @@ -- // MIR for `size_of` before LowerIntrinsics -+ // MIR for `size_of` after LowerIntrinsics - - fn size_of() -> usize { - let mut _0: usize; - - bb0: { -- _0 = std::intrinsics::size_of::() -> [return: bb1, unwind unreachable]; -+ _0 = SizeOf(T); -+ goto -> bb1; - } - - bb1: { - return; - } - } - diff --git a/tests/mir-opt/lower_intrinsics.size_of.LowerIntrinsics.panic-unwind.diff b/tests/mir-opt/lower_intrinsics.size_of.LowerIntrinsics.panic-unwind.diff deleted file mode 100644 index a547bdf3737b..000000000000 --- a/tests/mir-opt/lower_intrinsics.size_of.LowerIntrinsics.panic-unwind.diff +++ /dev/null @@ -1,17 +0,0 @@ -- // MIR for `size_of` before LowerIntrinsics -+ // MIR for `size_of` after LowerIntrinsics - - fn size_of() -> usize { - let mut _0: usize; - - bb0: { -- _0 = std::intrinsics::size_of::() -> [return: bb1, unwind unreachable]; -+ _0 = SizeOf(T); -+ goto -> bb1; - } - - bb1: { - return; - } - } - diff --git a/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.32bit.panic-abort.mir b/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.32bit.panic-abort.mir index ba6ce0ee5286..791d6b71a6f7 100644 --- a/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.32bit.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.32bit.panic-abort.mir @@ -73,7 +73,7 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () { } bb1: { - _6 = AlignOf(T); + _6 = const ::ALIGN; StorageLive(_7); _7 = copy _6 as std::ptr::Alignment (Transmute); _8 = move (_7.0: std::ptr::alignment::AlignmentEnum); diff --git a/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.32bit.panic-unwind.mir b/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.32bit.panic-unwind.mir index ba6ce0ee5286..791d6b71a6f7 100644 --- a/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.32bit.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.32bit.panic-unwind.mir @@ -73,7 +73,7 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () { } bb1: { - _6 = AlignOf(T); + _6 = const ::ALIGN; StorageLive(_7); _7 = copy _6 as std::ptr::Alignment (Transmute); _8 = move (_7.0: std::ptr::alignment::AlignmentEnum); diff --git a/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.64bit.panic-abort.mir b/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.64bit.panic-abort.mir index ba6ce0ee5286..791d6b71a6f7 100644 --- a/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.64bit.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.64bit.panic-abort.mir @@ -73,7 +73,7 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () { } bb1: { - _6 = AlignOf(T); + _6 = const ::ALIGN; StorageLive(_7); _7 = copy _6 as std::ptr::Alignment (Transmute); _8 = move (_7.0: std::ptr::alignment::AlignmentEnum); diff --git a/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.64bit.panic-unwind.mir b/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.64bit.panic-unwind.mir index ba6ce0ee5286..791d6b71a6f7 100644 --- a/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.64bit.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.64bit.panic-unwind.mir @@ -73,7 +73,7 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () { } bb1: { - _6 = AlignOf(T); + _6 = const ::ALIGN; StorageLive(_7); _7 = copy _6 as std::ptr::Alignment (Transmute); _8 = move (_7.0: std::ptr::alignment::AlignmentEnum); diff --git a/tests/mir-opt/pre-codegen/drop_boxed_slice.rs b/tests/mir-opt/pre-codegen/drop_boxed_slice.rs index 9ceba9444b8d..83b10f8bd688 100644 --- a/tests/mir-opt/pre-codegen/drop_boxed_slice.rs +++ b/tests/mir-opt/pre-codegen/drop_boxed_slice.rs @@ -9,7 +9,7 @@ pub unsafe fn generic_in_place(ptr: *mut Box<[T]>) { // CHECK-LABEL: fn generic_in_place(_1: *mut Box<[T]>) // CHECK: (inlined as Drop>::drop) // CHECK: [[SIZE:_.+]] = std::intrinsics::size_of_val::<[T]> - // CHECK: [[ALIGN:_.+]] = AlignOf(T); + // CHECK: [[ALIGN:_.+]] = const ::ALIGN; // CHECK: [[B:_.+]] = copy [[ALIGN]] as std::ptr::Alignment (Transmute); // CHECK: [[C:_.+]] = move ([[B]].0: std::ptr::alignment::AlignmentEnum); // CHECK: [[D:_.+]] = discriminant([[C]]); diff --git a/tests/mir-opt/pre-codegen/loops.vec_move.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/loops.vec_move.PreCodegen.after.mir index 66eb1bcfaa66..4260ec3eaedf 100644 --- a/tests/mir-opt/pre-codegen/loops.vec_move.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/loops.vec_move.PreCodegen.after.mir @@ -3,17 +3,17 @@ fn vec_move(_1: Vec) -> () { debug v => _1; let mut _0: (); + let mut _21: std::vec::IntoIter; let mut _22: std::vec::IntoIter; - let mut _23: std::vec::IntoIter; - let mut _24: &mut std::vec::IntoIter; - let mut _25: std::option::Option; - let mut _26: isize; - let _28: (); + let mut _23: &mut std::vec::IntoIter; + let mut _24: std::option::Option; + let mut _25: isize; + let _27: (); scope 1 { - debug iter => _23; - let _27: impl Sized; + debug iter => _22; + let _26: impl Sized; scope 2 { - debug x => _27; + debug x => _26; } } scope 3 (inlined as IntoIterator>::into_iter) { @@ -24,16 +24,16 @@ fn vec_move(_1: Vec) -> () { let mut _10: *mut impl Sized; let mut _11: *const impl Sized; let mut _12: usize; - let _29: &std::vec::Vec; - let mut _30: &std::mem::ManuallyDrop>; - let mut _31: &alloc::raw_vec::RawVec; - let mut _32: &std::mem::ManuallyDrop>; - let _33: &std::vec::Vec; - let mut _34: &std::mem::ManuallyDrop>; - let _35: &std::vec::Vec; - let mut _36: &std::mem::ManuallyDrop>; - let mut _37: &alloc::raw_vec::RawVec; - let mut _38: &std::mem::ManuallyDrop>; + let _28: &std::vec::Vec; + let mut _29: &std::mem::ManuallyDrop>; + let mut _30: &alloc::raw_vec::RawVec; + let mut _31: &std::mem::ManuallyDrop>; + let _32: &std::vec::Vec; + let mut _33: &std::mem::ManuallyDrop>; + let _34: &std::vec::Vec; + let mut _35: &std::mem::ManuallyDrop>; + let mut _36: &alloc::raw_vec::RawVec; + let mut _37: &std::mem::ManuallyDrop>; scope 4 { debug me => _2; scope 5 { @@ -46,34 +46,33 @@ fn vec_move(_1: Vec) -> () { debug begin => _7; scope 8 { debug end => _11; - let _20: usize; + let _19: usize; scope 9 { - debug cap => _20; + debug cap => _19; } scope 39 (inlined > as Deref>::deref) { - debug self => _38; + debug self => _37; } scope 40 (inlined alloc::raw_vec::RawVec::::capacity) { - debug self => _37; - let mut _19: usize; - let mut _39: &alloc::raw_vec::RawVecInner; + debug self => _36; + let mut _38: &alloc::raw_vec::RawVecInner; scope 41 (inlined std::mem::size_of::) { } scope 42 (inlined alloc::raw_vec::RawVecInner::capacity) { - debug self => _39; - debug elem_size => _19; - let mut _21: core::num::niche_types::UsizeNoHighBit; + debug self => _38; + debug elem_size => const ::SIZE; + let mut _20: core::num::niche_types::UsizeNoHighBit; scope 43 (inlined core::num::niche_types::UsizeNoHighBit::as_inner) { - debug self => _21; + debug self => _20; } } } } scope 25 (inlined > as Deref>::deref) { - debug self => _34; + debug self => _33; } scope 26 (inlined Vec::::len) { - debug self => _33; + debug self => _32; let mut _13: bool; scope 27 { } @@ -108,10 +107,10 @@ fn vec_move(_1: Vec) -> () { } } scope 35 (inlined > as Deref>::deref) { - debug self => _36; + debug self => _35; } scope 36 (inlined Vec::::len) { - debug self => _35; + debug self => _34; let mut _9: bool; scope 37 { } @@ -126,10 +125,10 @@ fn vec_move(_1: Vec) -> () { } } scope 17 (inlined > as Deref>::deref) { - debug self => _32; + debug self => _31; } scope 18 (inlined alloc::raw_vec::RawVec::::non_null) { - debug self => _31; + debug self => _30; scope 19 (inlined alloc::raw_vec::RawVecInner::non_null::) { let mut _4: std::ptr::NonNull; scope 20 (inlined Unique::::cast::) { @@ -145,10 +144,10 @@ fn vec_move(_1: Vec) -> () { } } scope 11 (inlined > as Deref>::deref) { - debug self => _30; + debug self => _29; } scope 12 (inlined Vec::::allocator) { - debug self => _29; + debug self => _28; scope 13 (inlined alloc::raw_vec::RawVec::::allocator) { scope 14 (inlined alloc::raw_vec::RawVecInner::allocator) { } @@ -167,23 +166,23 @@ fn vec_move(_1: Vec) -> () { } bb0: { - StorageLive(_22); + StorageLive(_21); StorageLive(_6); StorageLive(_7); StorageLive(_11); - StorageLive(_20); + StorageLive(_19); StorageLive(_5); StorageLive(_4); StorageLive(_17); StorageLive(_2); _2 = ManuallyDrop::> { value: copy _1 }; StorageLive(_3); - // DBG: _30 = &_2; - // DBG: _29 = &(_2.0: std::vec::Vec); + // DBG: _29 = &_2; + // DBG: _28 = &(_2.0: std::vec::Vec); _3 = &raw const ((((_2.0: std::vec::Vec).0: alloc::raw_vec::RawVec).0: alloc::raw_vec::RawVecInner).2: std::alloc::Global); StorageDead(_3); - // DBG: _32 = &_2; - // DBG: _31 = &((_2.0: std::vec::Vec).0: alloc::raw_vec::RawVec); + // DBG: _31 = &_2; + // DBG: _30 = &((_2.0: std::vec::Vec).0: alloc::raw_vec::RawVec); _4 = copy (((((_2.0: std::vec::Vec).0: alloc::raw_vec::RawVec).0: alloc::raw_vec::RawVecInner).0: std::ptr::Unique).0: std::ptr::NonNull); _5 = copy _4 as *const impl Sized (Transmute); _6 = NonNull:: { pointer: copy _5 }; @@ -194,8 +193,8 @@ fn vec_move(_1: Vec) -> () { bb1: { StorageLive(_10); StorageLive(_8); - // DBG: _36 = &_2; - // DBG: _35 = &(_2.0: std::vec::Vec); + // DBG: _35 = &_2; + // DBG: _34 = &(_2.0: std::vec::Vec); _8 = copy ((_2.0: std::vec::Vec).1: usize); StorageLive(_9); _9 = Le(copy _8, const ::MAX_SLICE_LEN); @@ -210,8 +209,8 @@ fn vec_move(_1: Vec) -> () { bb2: { StorageLive(_12); - // DBG: _34 = &_2; - // DBG: _33 = &(_2.0: std::vec::Vec); + // DBG: _33 = &_2; + // DBG: _32 = &(_2.0: std::vec::Vec); _12 = copy ((_2.0: std::vec::Vec).1: usize); StorageLive(_13); _13 = Le(copy _12, const ::MAX_SLICE_LEN); @@ -239,72 +238,69 @@ fn vec_move(_1: Vec) -> () { } bb4: { - // DBG: _38 = &_2; - // DBG: _37 = &((_2.0: std::vec::Vec).0: alloc::raw_vec::RawVec); - // DBG: _39 = &(((_2.0: std::vec::Vec).0: alloc::raw_vec::RawVec).0: alloc::raw_vec::RawVecInner); - StorageLive(_19); - _19 = SizeOf(impl Sized); - switchInt(move _19) -> [0: bb5, otherwise: bb6]; + // DBG: _37 = &_2; + // DBG: _36 = &((_2.0: std::vec::Vec).0: alloc::raw_vec::RawVec); + // DBG: _38 = &(((_2.0: std::vec::Vec).0: alloc::raw_vec::RawVec).0: alloc::raw_vec::RawVecInner); + switchInt(const ::SIZE) -> [0: bb5, otherwise: bb6]; } bb5: { - _20 = const usize::MAX; + _19 = const usize::MAX; goto -> bb7; } bb6: { - StorageLive(_21); - _21 = copy ((((_2.0: std::vec::Vec).0: alloc::raw_vec::RawVec).0: alloc::raw_vec::RawVecInner).1: core::num::niche_types::UsizeNoHighBit); - _20 = copy _21 as usize (Transmute); - StorageDead(_21); + StorageLive(_20); + _20 = copy ((((_2.0: std::vec::Vec).0: alloc::raw_vec::RawVec).0: alloc::raw_vec::RawVecInner).1: core::num::niche_types::UsizeNoHighBit); + _19 = copy _20 as usize (Transmute); + StorageDead(_20); goto -> bb7; } bb7: { - StorageDead(_19); - _22 = std::vec::IntoIter:: { buf: copy _6, phantom: const ZeroSized: PhantomData, cap: move _20, alloc: const ManuallyDrop:: {{ value: std::alloc::Global }}, ptr: copy _6, end: copy _11 }; + _21 = std::vec::IntoIter:: { buf: copy _6, phantom: const ZeroSized: PhantomData, cap: move _19, alloc: const ManuallyDrop:: {{ value: std::alloc::Global }}, ptr: copy _6, end: copy _11 }; StorageDead(_2); StorageDead(_17); StorageDead(_4); StorageDead(_5); - StorageDead(_20); + StorageDead(_19); StorageDead(_11); StorageDead(_7); StorageDead(_6); - StorageLive(_23); - _23 = move _22; + StorageLive(_22); + _22 = move _21; goto -> bb8; } bb8: { - StorageLive(_25); - _24 = &mut _23; - _25 = as Iterator>::next(move _24) -> [return: bb9, unwind: bb15]; + StorageLive(_24); + _23 = &mut _22; + _24 = as Iterator>::next(move _23) -> [return: bb9, unwind: bb15]; } bb9: { - _26 = discriminant(_25); - switchInt(move _26) -> [0: bb10, 1: bb12, otherwise: bb14]; + _25 = discriminant(_24); + switchInt(move _25) -> [0: bb10, 1: bb12, otherwise: bb14]; } bb10: { - StorageDead(_25); - drop(_23) -> [return: bb11, unwind continue]; + StorageDead(_24); + drop(_22) -> [return: bb11, unwind continue]; } bb11: { - StorageDead(_23); StorageDead(_22); + StorageDead(_21); return; } bb12: { - _27 = move ((_25 as Some).0: impl Sized); - _28 = opaque::(move _27) -> [return: bb13, unwind: bb15]; + _26 = move ((_24 as Some).0: impl Sized); + _27 = opaque::(move _26) -> [return: bb13, unwind: bb15]; } bb13: { - StorageDead(_25); + StorageDead(_24); goto -> bb8; } @@ -313,7 +309,7 @@ fn vec_move(_1: Vec) -> () { } bb15 (cleanup): { - drop(_23) -> [return: bb16, unwind terminate(cleanup)]; + drop(_22) -> [return: bb16, unwind terminate(cleanup)]; } bb16 (cleanup): { diff --git a/tests/ui-fulldeps/rustc_public/check_def_ty.rs b/tests/ui-fulldeps/rustc_public/check_def_ty.rs index 176a9d79ef11..4a45bb6daa5f 100644 --- a/tests/ui-fulldeps/rustc_public/check_def_ty.rs +++ b/tests/ui-fulldeps/rustc_public/check_def_ty.rs @@ -90,15 +90,13 @@ fn generate_input(path: &str) -> std::io::Result<()> { write!( file, r#" - // We would like to check intrinsic definition. - #![feature(core_intrinsics)] static STATIC_STR: &str = "foo"; const CONST_U32: u32 = 0u32; fn main() {{ let _c = core::char::from_u32(99); let _v = Vec::::new(); - let _i = std::intrinsics::size_of::(); + let _i = std::mem::size_of::(); }} extern "C" {{ diff --git a/tests/ui/const-generics/generic_const_exprs/issue-80742.rs b/tests/ui/const-generics/generic_const_exprs/issue-80742.rs index ac4d9fc0f4f4..0d392902be87 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-80742.rs +++ b/tests/ui/const-generics/generic_const_exprs/issue-80742.rs @@ -1,12 +1,4 @@ //@ check-fail -//@ known-bug: #97477 -//@ failure-status: 101 -//@ normalize-stderr: "note: .*\n\n" -> "" -//@ normalize-stderr: "thread 'rustc'.*panicked.*\n" -> "" -//@ normalize-stderr: "(error: internal compiler error: [^:]+):\d+:\d+: " -> "$1:LL:CC: " -//@ rustc-env:RUST_BACKTRACE=0 - -// This test used to cause an ICE in rustc_mir::interpret::step::eval_rvalue_into_place #![allow(incomplete_features)] #![feature(generic_const_exprs)] @@ -34,4 +26,6 @@ where fn main() { let dst = Inline::::new(0); + //~^ ERROR the size for values of type `dyn Debug` cannot be known at compilation time + //~| ERROR the function or associated item `new` exists for struct `Inline` } diff --git a/tests/ui/const-generics/generic_const_exprs/issue-80742.stderr b/tests/ui/const-generics/generic_const_exprs/issue-80742.stderr index 07fd231cb7ae..ac1bfc8d7a1b 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-80742.stderr +++ b/tests/ui/const-generics/generic_const_exprs/issue-80742.stderr @@ -1,11 +1,42 @@ -error: internal compiler error: compiler/rustc_const_eval/src/interpret/operator.rs:LL:CC: unsized type for `NullaryOp::SizeOf` - --> $SRC_DIR/core/src/mem/mod.rs:LL:COL +error[E0277]: the size for values of type `dyn Debug` cannot be known at compilation time + --> $DIR/issue-80742.rs:28:15 + | +LL | let dst = Inline::::new(0); + | ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `dyn Debug` +note: required by an implicit `Sized` bound in `Inline` + --> $DIR/issue-80742.rs:10:15 + | +LL | struct Inline + | ^ required by the implicit `Sized` requirement on this type parameter in `Inline` +help: consider relaxing the implicit `Sized` restriction + | +LL | struct Inline + | ++++++++ +error[E0599]: the function or associated item `new` exists for struct `Inline`, but its trait bounds were not satisfied + --> $DIR/issue-80742.rs:28:36 + | +LL | struct Inline + | ---------------- function or associated item `new` not found for this struct +... +LL | let dst = Inline::::new(0); + | ^^^ function or associated item cannot be called on `Inline` due to unsatisfied trait bounds + | +note: trait bound `dyn Debug: Sized` was not satisfied + --> $DIR/issue-80742.rs:18:6 + | +LL | impl Inline + | ^ --------- + | | + | unsatisfied trait bound introduced here +help: consider relaxing the type parameter's implicit `Sized` bound + | +LL | impl Inline + | ++++++++ -Box -query stack during panic: -#0 [eval_to_allocation_raw] const-evaluating + checking `Inline::{constant#0}` -#1 [eval_to_valtree] evaluating type-level constant -... and 2 other queries... use `env RUST_BACKTRACE=1` to see the full query stack -error: aborting due to 1 previous error +error: aborting due to 2 previous errors +Some errors have detailed explanations: E0277, E0599. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/crashes/119729.rs b/tests/ui/const-generics/generic_const_exprs/size_of-dyn-trait-2.rs similarity index 52% rename from tests/crashes/119729.rs rename to tests/ui/const-generics/generic_const_exprs/size_of-dyn-trait-2.rs index ed07c58e89fd..ee5d65cf4b2b 100644 --- a/tests/crashes/119729.rs +++ b/tests/ui/const-generics/generic_const_exprs/size_of-dyn-trait-2.rs @@ -1,5 +1,7 @@ -//@ known-bug: #119729 +//! Regression test for #119729 + #![feature(generic_const_exprs)] +#![allow(incomplete_features)] trait Size {} @@ -10,3 +12,7 @@ struct A + ?Sized> { } fn foo(x: A) {} +//~^ ERROR mismatched types +//~| ERROR the size for values of type `(dyn Send + 'static)` cannot be known at compilation time + +fn main() {} diff --git a/tests/ui/const-generics/generic_const_exprs/size_of-dyn-trait-2.stderr b/tests/ui/const-generics/generic_const_exprs/size_of-dyn-trait-2.stderr new file mode 100644 index 000000000000..71fea4df163d --- /dev/null +++ b/tests/ui/const-generics/generic_const_exprs/size_of-dyn-trait-2.stderr @@ -0,0 +1,38 @@ +error[E0308]: mismatched types + --> $DIR/size_of-dyn-trait-2.rs:14:11 + | +LL | fn foo(x: A) {} + | ^^^^^^^^^^^ expected `8`, found `{ std::mem::size_of::() }` + | + = note: expected constant `8` + found constant `{ std::mem::size_of::() }` +note: required by a bound in `A` + --> $DIR/size_of-dyn-trait-2.rs:10:13 + | +LL | struct A + ?Sized> { + | ^^^^^^^ required by this bound in `A` + +error[E0277]: the size for values of type `(dyn Send + 'static)` cannot be known at compilation time + --> $DIR/size_of-dyn-trait-2.rs:14:11 + | +LL | fn foo(x: A) {} + | ^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `(dyn Send + 'static)` +note: required for `(dyn Send + 'static)` to implement `Size<8>` + --> $DIR/size_of-dyn-trait-2.rs:8:16 + | +LL | impl Size<{ std::mem::size_of::() }> for T {} + | ----- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^ + | | + | unsatisfied trait bound introduced here +note: required by a bound in `A` + --> $DIR/size_of-dyn-trait-2.rs:10:13 + | +LL | struct A + ?Sized> { + | ^^^^^^^ required by this bound in `A` + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0277, E0308. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/const-generics/generic_const_exprs/size_of-dyn-trait-3.rs b/tests/ui/const-generics/generic_const_exprs/size_of-dyn-trait-3.rs new file mode 100644 index 000000000000..afb086a41305 --- /dev/null +++ b/tests/ui/const-generics/generic_const_exprs/size_of-dyn-trait-3.rs @@ -0,0 +1,21 @@ +//! Regression test for #114663 +//@ edition:2021 + +#![feature(generic_const_exprs)] +#![allow(incomplete_features)] + +use core::fmt::Debug; +use core::marker::PhantomData; + +struct Inline +where + [u8; ::core::mem::size_of::() + 1]:, +{ + _phantom: PhantomData, +} + +fn main() { + let dst = Inline::::new(0); + //~^ ERROR the size for values of type `dyn Debug` cannot be known at compilation time + //~| ERROR no function or associated item named `new` found for struct `Inline` +} diff --git a/tests/ui/const-generics/generic_const_exprs/size_of-dyn-trait-3.stderr b/tests/ui/const-generics/generic_const_exprs/size_of-dyn-trait-3.stderr new file mode 100644 index 000000000000..bcc253ed9670 --- /dev/null +++ b/tests/ui/const-generics/generic_const_exprs/size_of-dyn-trait-3.stderr @@ -0,0 +1,30 @@ +error[E0277]: the size for values of type `dyn Debug` cannot be known at compilation time + --> $DIR/size_of-dyn-trait-3.rs:18:15 + | +LL | let dst = Inline::::new(0); + | ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `dyn Debug` +note: required by an implicit `Sized` bound in `Inline` + --> $DIR/size_of-dyn-trait-3.rs:10:15 + | +LL | struct Inline + | ^ required by the implicit `Sized` requirement on this type parameter in `Inline` +help: consider relaxing the implicit `Sized` restriction + | +LL | struct Inline + | ++++++++ + +error[E0599]: no function or associated item named `new` found for struct `Inline` in the current scope + --> $DIR/size_of-dyn-trait-3.rs:18:36 + | +LL | struct Inline + | ---------------- function or associated item `new` not found for this struct +... +LL | let dst = Inline::::new(0); + | ^^^ function or associated item not found in `Inline` + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0277, E0599. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/crashes/136175.rs b/tests/ui/const-generics/generic_const_exprs/size_of-dyn-trait.rs similarity index 57% rename from tests/crashes/136175.rs rename to tests/ui/const-generics/generic_const_exprs/size_of-dyn-trait.rs index 0b5f2fdaa922..34b4734f4772 100644 --- a/tests/crashes/136175.rs +++ b/tests/ui/const-generics/generic_const_exprs/size_of-dyn-trait.rs @@ -1,4 +1,5 @@ -//@ known-bug: #136175 +//! Regression test for #136175 + #![feature(generic_const_exprs)] #![allow(incomplete_features)] @@ -10,4 +11,5 @@ where fn main() { let x: A; + //~^ ERROR the size for values of type `dyn Trait` cannot be known at compilation time } diff --git a/tests/ui/const-generics/generic_const_exprs/size_of-dyn-trait.stderr b/tests/ui/const-generics/generic_const_exprs/size_of-dyn-trait.stderr new file mode 100644 index 000000000000..4669a2f1ce7d --- /dev/null +++ b/tests/ui/const-generics/generic_const_exprs/size_of-dyn-trait.stderr @@ -0,0 +1,23 @@ +error[E0277]: the size for values of type `dyn Trait` cannot be known at compilation time + --> $DIR/size_of-dyn-trait.rs:13:12 + | +LL | let x: A; + | ^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `dyn Trait` +note: required by an implicit `Sized` bound in `A` + --> $DIR/size_of-dyn-trait.rs:8:10 + | +LL | struct A(T) + | ^ required by the implicit `Sized` requirement on this type parameter in `A` +help: you could relax the implicit `Sized` bound on `T` if it were used through indirection like `&T` or `Box` + --> $DIR/size_of-dyn-trait.rs:8:10 + | +LL | struct A(T) + | ^ - ...if indirection were used here: `Box` + | | + | this could be changed to `T: ?Sized`... + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/consts/const-size_of-cycle.stderr b/tests/ui/consts/const-size_of-cycle.stderr index b127f83d8853..01aa5e726b45 100644 --- a/tests/ui/consts/const-size_of-cycle.stderr +++ b/tests/ui/consts/const-size_of-cycle.stderr @@ -5,10 +5,11 @@ LL | bytes: [u8; std::mem::size_of::()] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: ...which requires const-evaluating + checking `Foo::bytes::{constant#0}`... - --> $DIR/const-size_of-cycle.rs:2:17 - | -LL | bytes: [u8; std::mem::size_of::()] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + --> $SRC_DIR/core/src/mem/mod.rs:LL:COL +note: ...which requires simplifying constant for the type system `core::mem::SizedTypeProperties::SIZE`... + --> $SRC_DIR/core/src/mem/mod.rs:LL:COL +note: ...which requires const-evaluating + checking `core::mem::SizedTypeProperties::SIZE`... + --> $SRC_DIR/core/src/mem/mod.rs:LL:COL = note: ...which requires computing layout of `Foo`... = note: ...which requires computing layout of `[u8; std::mem::size_of::()]`... note: ...which requires normalizing `[u8; std::mem::size_of::()]`... diff --git a/tests/ui/debuginfo/debuginfo-type-name-layout-ice-94961-1.rs b/tests/ui/debuginfo/debuginfo-type-name-layout-ice-94961-1.rs index 7f85cbf227ae..771656a2c462 100644 --- a/tests/ui/debuginfo/debuginfo-type-name-layout-ice-94961-1.rs +++ b/tests/ui/debuginfo/debuginfo-type-name-layout-ice-94961-1.rs @@ -1,4 +1,4 @@ -//~ ERROR values of the type `[u8; usize::MAX]` are too big for the target architecture +//~? ERROR values of the type `[u8; usize::MAX]` are too big for the target architecture // Make sure the compiler does not ICE when trying to generate the debuginfo name of a type that // causes a layout error. See https://github.com/rust-lang/rust/issues/94961. diff --git a/tests/ui/debuginfo/debuginfo-type-name-layout-ice-94961-1.stderr b/tests/ui/debuginfo/debuginfo-type-name-layout-ice-94961-1.stderr index a3772e509ed6..73e157824267 100644 --- a/tests/ui/debuginfo/debuginfo-type-name-layout-ice-94961-1.stderr +++ b/tests/ui/debuginfo/debuginfo-type-name-layout-ice-94961-1.stderr @@ -1,4 +1,14 @@ -error: values of the type `[u8; usize::MAX]` are too big for the target architecture +error[E0080]: values of the type `[u8; usize::MAX]` are too big for the target architecture + --> $SRC_DIR/core/src/mem/mod.rs:LL:COL + | + = note: evaluation of ` as std::mem::SizedTypeProperties>::SIZE` failed here + +note: the above error was encountered while instantiating `fn std::mem::size_of::>` + --> $DIR/debuginfo-type-name-layout-ice-94961-1.rs:13:5 + | +LL | std::mem::size_of::>() + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 1 previous error +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/debuginfo/debuginfo-type-name-layout-ice-94961-2.stderr b/tests/ui/debuginfo/debuginfo-type-name-layout-ice-94961-2.stderr index a3772e509ed6..4ce1e2e407e9 100644 --- a/tests/ui/debuginfo/debuginfo-type-name-layout-ice-94961-2.stderr +++ b/tests/ui/debuginfo/debuginfo-type-name-layout-ice-94961-2.stderr @@ -1,4 +1,14 @@ -error: values of the type `[u8; usize::MAX]` are too big for the target architecture +error[E0080]: values of the type `[u8; usize::MAX]` are too big for the target architecture + --> $SRC_DIR/core/src/mem/mod.rs:LL:COL + | + = note: evaluation of ` as std::mem::SizedTypeProperties>::SIZE` failed here + +note: the above error was encountered while instantiating `fn std::mem::size_of::>` + --> $DIR/debuginfo-type-name-layout-ice-94961-2.rs:16:5 + | +LL | std::mem::size_of::>() + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 1 previous error +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/frontmatter/space-in-infostring.rs b/tests/ui/frontmatter/space-in-infostring.rs new file mode 100644 index 000000000000..a8448af11344 --- /dev/null +++ b/tests/ui/frontmatter/space-in-infostring.rs @@ -0,0 +1,9 @@ +--- cargo clippy +//~^ ERROR: invalid infostring for frontmatter +--- + +// infostrings cannot have spaces + +#![feature(frontmatter)] + +fn main() {} diff --git a/tests/ui/frontmatter/space-in-infostring.stderr b/tests/ui/frontmatter/space-in-infostring.stderr new file mode 100644 index 000000000000..b876ddae782e --- /dev/null +++ b/tests/ui/frontmatter/space-in-infostring.stderr @@ -0,0 +1,10 @@ +error: invalid infostring for frontmatter + --> $DIR/space-in-infostring.rs:1:4 + | +LL | --- cargo clippy + | ^^^^^^^^^^^^^ + | + = note: frontmatter infostrings must be a single identifier immediately following the opening + +error: aborting due to 1 previous error + diff --git a/tests/ui/generics/issue-32498.rs b/tests/ui/generics/issue-32498.rs index b7685ac73360..871914f0b36e 100644 --- a/tests/ui/generics/issue-32498.rs +++ b/tests/ui/generics/issue-32498.rs @@ -1,5 +1,6 @@ //@ run-pass #![allow(dead_code)] +#![recursion_limit = "256"] // Making sure that no overflow occurs. diff --git a/tests/ui/intrinsics/intrinsic-alignment.rs b/tests/ui/intrinsics/intrinsic-alignment.rs index 904da71c306b..5fee6b0b3978 100644 --- a/tests/ui/intrinsics/intrinsic-alignment.rs +++ b/tests/ui/intrinsics/intrinsic-alignment.rs @@ -2,8 +2,6 @@ #![feature(core_intrinsics, rustc_attrs)] -use std::intrinsics as rusti; - #[cfg(any( target_os = "aix", target_os = "android", @@ -23,12 +21,12 @@ use std::intrinsics as rusti; mod m { #[cfg(target_arch = "x86")] pub fn main() { - assert_eq!(crate::rusti::align_of::(), 4); + assert_eq!(std::mem::align_of::(), 4); } #[cfg(not(target_arch = "x86"))] pub fn main() { - assert_eq!(crate::rusti::align_of::(), 8); + assert_eq!(std::mem::align_of::(), 8); } } @@ -36,21 +34,21 @@ mod m { mod m { #[cfg(target_arch = "x86_64")] pub fn main() { - assert_eq!(crate::rusti::align_of::(), 8); + assert_eq!(std::mem::align_of::(), 8); } } #[cfg(target_os = "windows")] mod m { pub fn main() { - assert_eq!(crate::rusti::align_of::(), 8); + assert_eq!(std::mem::align_of::(), 8); } } #[cfg(target_family = "wasm")] mod m { pub fn main() { - assert_eq!(crate::rusti::align_of::(), 8); + assert_eq!(std::mem::align_of::(), 8); } } diff --git a/tests/ui/layout/invalid-unsized-in-always-sized-tail.rs b/tests/ui/layout/invalid-unsized-in-always-sized-tail.rs index 8da2bb385ef2..31d70c1dd9ec 100644 --- a/tests/ui/layout/invalid-unsized-in-always-sized-tail.rs +++ b/tests/ui/layout/invalid-unsized-in-always-sized-tail.rs @@ -13,6 +13,6 @@ struct P2 { } static CHECK: () = assert!(align_of::() == 1); -//~^ ERROR the type `MySlice<[bool]>` has an unknown layout +//~? ERROR the type `MySlice<[bool]>` has an unknown layout fn main() {} diff --git a/tests/ui/layout/invalid-unsized-in-always-sized-tail.stderr b/tests/ui/layout/invalid-unsized-in-always-sized-tail.stderr index 5f6a6099ba23..b08e37dbd747 100644 --- a/tests/ui/layout/invalid-unsized-in-always-sized-tail.stderr +++ b/tests/ui/layout/invalid-unsized-in-always-sized-tail.stderr @@ -19,13 +19,9 @@ LL | struct MySlice(T); | this could be changed to `T: ?Sized`... error[E0080]: the type `MySlice<[bool]>` has an unknown layout - --> $DIR/invalid-unsized-in-always-sized-tail.rs:15:28 - | -LL | static CHECK: () = assert!(align_of::() == 1); - | ^^^^^^^^^^^^^^^^ evaluation of `CHECK` failed inside this call - | -note: inside `std::mem::align_of::` --> $SRC_DIR/core/src/mem/mod.rs:LL:COL + | + = note: evaluation of `::ALIGN` failed here error: aborting due to 2 previous errors diff --git a/tests/ui/layout/layout-cycle.rs b/tests/ui/layout/layout-cycle.rs index 3c930def43b2..b38bd52c6ade 100644 --- a/tests/ui/layout/layout-cycle.rs +++ b/tests/ui/layout/layout-cycle.rs @@ -1,6 +1,6 @@ //@ build-fail -//~^ ERROR: a cycle occurred during layout computation -//~| ERROR: cycle detected when computing layout of +//~^ ERROR: cycle detected when computing layout of +//~? ERROR: a cycle occurred during layout computation // Issue #111176 -- ensure that we do not emit ICE on layout cycles diff --git a/tests/ui/layout/layout-cycle.stderr b/tests/ui/layout/layout-cycle.stderr index a3cdb7edcc23..e05ff614567c 100644 --- a/tests/ui/layout/layout-cycle.stderr +++ b/tests/ui/layout/layout-cycle.stderr @@ -2,10 +2,22 @@ error[E0391]: cycle detected when computing layout of `S>` | = note: ...which requires computing layout of ` as Tr>::I`... = note: ...which again requires computing layout of `S>`, completing the cycle +note: cycle used when const-evaluating + checking `core::mem::SizedTypeProperties::SIZE` + --> $SRC_DIR/core/src/mem/mod.rs:LL:COL = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information -error: failed to get layout for S>: a cycle occurred during layout computation +error[E0080]: a cycle occurred during layout computation + --> $SRC_DIR/core/src/mem/mod.rs:LL:COL + | + = note: evaluation of `> as std::mem::SizedTypeProperties>::SIZE` failed here + +note: the above error was encountered while instantiating `fn std::mem::size_of::>>` + --> $DIR/layout-cycle.rs:26:5 + | +LL | mem::size_of::>() + | ^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0391`. +Some errors have detailed explanations: E0080, E0391. +For more information about an error, try `rustc --explain E0080`. diff --git a/tests/ui/limits/issue-17913.32bit.stderr b/tests/ui/limits/issue-17913.32bit.stderr new file mode 100644 index 000000000000..1311822d0d0c --- /dev/null +++ b/tests/ui/limits/issue-17913.32bit.stderr @@ -0,0 +1,19 @@ +error[E0080]: values of the type `[&usize; usize::MAX]` are too big for the target architecture + --> $SRC_DIR/core/src/mem/mod.rs:LL:COL + | + = note: evaluation of `<[&usize; usize::MAX] as std::mem::SizedTypeProperties>::SIZE` failed here + +error[E0080]: values of the type `[&usize; usize::MAX]` are too big for the target architecture + --> $SRC_DIR/core/src/mem/mod.rs:LL:COL + | + = note: evaluation of `<[&usize; usize::MAX] as std::mem::SizedTypeProperties>::ALIGN` failed here + +note: the above error was encountered while instantiating `fn Box::<[&usize; usize::MAX]>::new` + --> $DIR/issue-17913.rs:16:21 + | +LL | let a: Box<_> = Box::new([&n; SIZE]); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/limits/issue-17913.64bit.stderr b/tests/ui/limits/issue-17913.64bit.stderr new file mode 100644 index 000000000000..b0481ee99378 --- /dev/null +++ b/tests/ui/limits/issue-17913.64bit.stderr @@ -0,0 +1,19 @@ +error[E0080]: values of the type `[&usize; usize::MAX]` are too big for the target architecture + --> $SRC_DIR/core/src/mem/mod.rs:LL:COL + | + = note: evaluation of `<[&usize; usize::MAX] as std::mem::SizedTypeProperties>::SIZE` failed here + +error[E0080]: values of the type `[&usize; usize::MAX]` are too big for the target architecture + --> $SRC_DIR/core/src/mem/mod.rs:LL:COL + | + = note: evaluation of `<[&usize; usize::MAX] as std::mem::SizedTypeProperties>::ALIGN` failed here + +note: the above error was encountered while instantiating `fn Box::<[&usize; usize::MAX]>::new` + --> $DIR/issue-17913.rs:9:21 + | +LL | let a: Box<_> = Box::new([&n; SIZE]); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/limits/issue-17913.rs b/tests/ui/limits/issue-17913.rs index 85deab4bc4c7..d804b64ab330 100644 --- a/tests/ui/limits/issue-17913.rs +++ b/tests/ui/limits/issue-17913.rs @@ -1,5 +1,7 @@ //@ build-fail +//@ stderr-per-bitwidth //@ normalize-stderr: "\[&usize; \d+\]" -> "[&usize; usize::MAX]" +//@ normalize-stderr: "\[&n; 0x[0-9A-F]+_usize\]" -> "[&n; SIZE]" #[cfg(target_pointer_width = "64")] fn main() { @@ -16,3 +18,4 @@ fn main() { } //~? ERROR are too big for the target architecture +//~? ERROR are too big for the target architecture diff --git a/tests/ui/limits/issue-17913.stderr b/tests/ui/limits/issue-17913.stderr deleted file mode 100644 index e9c3c14e1814..000000000000 --- a/tests/ui/limits/issue-17913.stderr +++ /dev/null @@ -1,5 +0,0 @@ -error: values of the type `[&usize; usize::MAX]` are too big for the target architecture - --> $SRC_DIR/alloc/src/boxed.rs:LL:COL - -error: aborting due to 1 previous error - diff --git a/tests/ui/limits/issue-55878.rs b/tests/ui/limits/issue-55878.rs index 9e75f00a408f..10fa1dd06d64 100644 --- a/tests/ui/limits/issue-55878.rs +++ b/tests/ui/limits/issue-55878.rs @@ -2,5 +2,5 @@ fn main() { println!("Size: {}", std::mem::size_of::<[u8; u64::MAX as usize]>()); - //~^ ERROR too big for the target architecture + //~? ERROR too big for the target architecture } diff --git a/tests/ui/limits/issue-55878.stderr b/tests/ui/limits/issue-55878.stderr index a529efa2ad06..994e43854f82 100644 --- a/tests/ui/limits/issue-55878.stderr +++ b/tests/ui/limits/issue-55878.stderr @@ -1,11 +1,7 @@ error[E0080]: values of the type `[u8; usize::MAX]` are too big for the target architecture - --> $DIR/issue-55878.rs:4:26 - | -LL | println!("Size: {}", std::mem::size_of::<[u8; u64::MAX as usize]>()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `main` failed inside this call - | -note: inside `std::mem::size_of::<[u8; usize::MAX]>` --> $SRC_DIR/core/src/mem/mod.rs:LL:COL + | + = note: evaluation of `<[u8; usize::MAX] as std::mem::SizedTypeProperties>::SIZE` failed here error: aborting due to 1 previous error diff --git a/tests/ui/limits/issue-75158-64.rs b/tests/ui/limits/issue-75158-64.rs index b294b147a91a..a49195bb3dc1 100644 --- a/tests/ui/limits/issue-75158-64.rs +++ b/tests/ui/limits/issue-75158-64.rs @@ -1,4 +1,4 @@ -//~ ERROR +//~? ERROR values of the type `[u8; usize::MAX]` are too big for the target architecture //@ build-fail //@ ignore-32bit diff --git a/tests/ui/limits/issue-75158-64.stderr b/tests/ui/limits/issue-75158-64.stderr index a3772e509ed6..bab0e1b777c2 100644 --- a/tests/ui/limits/issue-75158-64.stderr +++ b/tests/ui/limits/issue-75158-64.stderr @@ -1,4 +1,14 @@ -error: values of the type `[u8; usize::MAX]` are too big for the target architecture +error[E0080]: values of the type `[u8; usize::MAX]` are too big for the target architecture + --> $SRC_DIR/core/src/mem/mod.rs:LL:COL + | + = note: evaluation of ` as std::mem::SizedTypeProperties>::SIZE` failed here + +note: the above error was encountered while instantiating `fn std::mem::size_of::>` + --> $DIR/issue-75158-64.rs:11:5 + | +LL | std::mem::size_of::>() + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 1 previous error +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/query-system/query_depth.rs b/tests/ui/query-system/query_depth.rs index 29514b58e242..da6bafa51ab2 100644 --- a/tests/ui/query-system/query_depth.rs +++ b/tests/ui/query-system/query_depth.rs @@ -26,6 +26,6 @@ type Byte = Option>>> >>>>; fn main() { -//~^ ERROR: queries overflow the depth limit! +//~? ERROR: queries overflow the depth limit! println!("{}", std::mem::size_of::()); } diff --git a/tests/ui/query-system/query_depth.stderr b/tests/ui/query-system/query_depth.stderr index f738b01ed6ca..abb6365765f0 100644 --- a/tests/ui/query-system/query_depth.stderr +++ b/tests/ui/query-system/query_depth.stderr @@ -1,11 +1,8 @@ error: queries overflow the depth limit! - --> $DIR/query_depth.rs:28:1 - | -LL | fn main() { - | ^^^^^^^^^ + --> $SRC_DIR/core/src/mem/mod.rs:LL:COL | = help: consider increasing the recursion limit by adding a `#![recursion_limit = "128"]` attribute to your crate (`query_depth`) - = note: query depth increased by 65 when computing layout of `core::option::Option>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` + = note: query depth increased by 64 when computing layout of `core::option::Option>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` error: aborting due to 1 previous error diff --git a/tests/ui/sanitizer/cfi/fn-trait-objects.rs b/tests/ui/sanitizer/cfi/fn-trait-objects.rs new file mode 100644 index 000000000000..977d4124fff0 --- /dev/null +++ b/tests/ui/sanitizer/cfi/fn-trait-objects.rs @@ -0,0 +1,32 @@ +// Verifies that types that implement the Fn, FnMut, or FnOnce traits can be +// called through their trait methods. +// +//@ needs-sanitizer-cfi +//@ only-linux +//@ ignore-backends: gcc +//@ compile-flags: -Ctarget-feature=-crt-static -Ccodegen-units=1 -Clto -Cprefer-dynamic=off -Copt-level=0 -Zsanitizer=cfi -Cunsafe-allow-abi-mismatch=sanitizer --test +//@ run-pass + +#![feature(fn_traits)] +#![feature(unboxed_closures)] + +fn foo(_a: u32) {} + +#[test] +fn test_fn_trait() { + let f: Box = Box::new(foo); + Fn::call(&f, (0,)); +} + +#[test] +fn test_fnmut_trait() { + let mut a = 0; + let mut f: Box = Box::new(|x| a += x); + FnMut::call_mut(&mut f, (1,)); +} + +#[test] +fn test_fnonce_trait() { + let f: Box = Box::new(foo); + FnOnce::call_once(f, (2,)); +} diff --git a/tests/ui/sanitizer/kcfi/fn-trait-objects.rs b/tests/ui/sanitizer/kcfi/fn-trait-objects.rs new file mode 100644 index 000000000000..3f6b78545a0a --- /dev/null +++ b/tests/ui/sanitizer/kcfi/fn-trait-objects.rs @@ -0,0 +1,32 @@ +// Verifies that types that implement the Fn, FnMut, or FnOnce traits can be +// called through their trait methods. +// +//@ needs-sanitizer-kcfi +//@ only-linux +//@ ignore-backends: gcc +//@ compile-flags: -Ctarget-feature=-crt-static -Zpanic_abort_tests -Cpanic=abort -Cprefer-dynamic=off -Copt-level=0 -Zsanitizer=kcfi -Cunsafe-allow-abi-mismatch=sanitizer --test +//@ run-pass + +#![feature(fn_traits)] +#![feature(unboxed_closures)] + +fn foo(_a: u32) {} + +#[test] +fn test_fn_trait() { + let f: Box = Box::new(foo); + Fn::call(&f, (0,)); +} + +#[test] +fn test_fnmut_trait() { + let mut a = 0; + let mut f: Box = Box::new(|x| a += x); + FnMut::call_mut(&mut f, (1,)); +} + +#[test] +fn test_fnonce_trait() { + let f: Box = Box::new(foo); + FnOnce::call_once(f, (2,)); +} diff --git a/tests/ui/structs-enums/rec-align-u32.rs b/tests/ui/structs-enums/rec-align-u32.rs index b18cd11198e8..058f06732b92 100644 --- a/tests/ui/structs-enums/rec-align-u32.rs +++ b/tests/ui/structs-enums/rec-align-u32.rs @@ -6,7 +6,6 @@ #![feature(core_intrinsics, rustc_attrs)] use std::mem; -use std::intrinsics; // This is the type with the questionable alignment #[derive(Debug)] @@ -34,12 +33,12 @@ pub fn main() { // Send it through the shape code let y = format!("{:?}", x); - println!("align inner = {:?}", intrinsics::align_of::()); + println!("align inner = {:?}", mem::align_of::()); println!("size outer = {:?}", mem::size_of::()); println!("y = {:?}", y); // per clang/gcc the alignment of `inner` is 4 on x86. - assert_eq!(intrinsics::align_of::(), m::align()); + assert_eq!(mem::align_of::(), m::align()); // per clang/gcc the size of `outer` should be 12 // because `inner`s alignment was 4. diff --git a/tests/ui/structs-enums/rec-align-u64.rs b/tests/ui/structs-enums/rec-align-u64.rs index df219892d737..41b196dc5c22 100644 --- a/tests/ui/structs-enums/rec-align-u64.rs +++ b/tests/ui/structs-enums/rec-align-u64.rs @@ -7,7 +7,6 @@ #![feature(core_intrinsics, rustc_attrs)] use std::mem; -use std::intrinsics; // This is the type with the questionable alignment #[derive(Debug)] @@ -84,12 +83,12 @@ pub fn main() { let y = format!("{:?}", x); - println!("align inner = {:?}", intrinsics::align_of::()); + println!("align inner = {:?}", mem::align_of::()); println!("size outer = {:?}", mem::size_of::()); println!("y = {:?}", y); // per clang/gcc the alignment of `Inner` is 4 on x86. - assert_eq!(intrinsics::align_of::(), m::m::align()); + assert_eq!(mem::align_of::(), m::m::align()); // per clang/gcc the size of `Outer` should be 12 // because `Inner`s alignment was 4. diff --git a/tests/ui/traits/generic-cow-inference-regression.rs b/tests/ui/traits/generic-cow-inference-regression.rs new file mode 100644 index 000000000000..6fd4715f85bb --- /dev/null +++ b/tests/ui/traits/generic-cow-inference-regression.rs @@ -0,0 +1,20 @@ +//@ run-pass + +// regression test for #147964: +// constification of these traits resulted in inference errors due to additional where clauses + +use std::borrow::{Cow, Borrow}; + +pub fn generic_deref<'a, T: ToOwned, U>(cow: Cow<'a, T>) { + let _: &T = &cow; +} + +pub fn generic_borrow<'a, T: ToOwned, U>(cow: Cow<'a, T>) { + let _: &T = cow.borrow(); +} + +pub fn generic_as_ref<'a, T: ToOwned, U>(cow: Cow<'a, T>) { + let _: &T = cow.as_ref(); +} + +fn main() {} diff --git a/tests/ui/where-clauses/cfg-attr-issue-138010-1.rs b/tests/ui/where-clauses/cfg-attr-issue-138010-1.rs new file mode 100644 index 000000000000..5d13e6e253a4 --- /dev/null +++ b/tests/ui/where-clauses/cfg-attr-issue-138010-1.rs @@ -0,0 +1,14 @@ +//@ check-pass + +#![feature(associated_type_defaults, where_clause_attrs)] +#![allow(deprecated_where_clause_location)] + +trait A { + type F + where + #[cfg(false)] + T: TraitB, + = T; +} + +fn main() {} diff --git a/tests/ui/where-clauses/cfg-attr-issue-138010-2.rs b/tests/ui/where-clauses/cfg-attr-issue-138010-2.rs new file mode 100644 index 000000000000..cf84bf3ee355 --- /dev/null +++ b/tests/ui/where-clauses/cfg-attr-issue-138010-2.rs @@ -0,0 +1,27 @@ +#![feature(where_clause_attrs, lazy_type_alias)] +#![expect(incomplete_features)] + +struct Foo; +trait Trait {} + +impl Trait for Foo {} + +type MixedWhereBounds1 +where + //~^ ERROR: where clauses are not allowed before the type for type aliases + #[cfg(true)] + Foo: Trait, += Foo +where + (): Sized; + +type MixedWhereBounds2 +where + //~^ ERROR: where clauses are not allowed before the type for type aliases + #[cfg(false)] + Foo: Trait, += Foo +where + (): Sized; + +fn main() {} diff --git a/tests/ui/where-clauses/cfg-attr-issue-138010-2.stderr b/tests/ui/where-clauses/cfg-attr-issue-138010-2.stderr new file mode 100644 index 000000000000..f59ce0fa1aca --- /dev/null +++ b/tests/ui/where-clauses/cfg-attr-issue-138010-2.stderr @@ -0,0 +1,31 @@ +error: where clauses are not allowed before the type for type aliases + --> $DIR/cfg-attr-issue-138010-2.rs:10:1 + | +LL | / where +LL | | +LL | | #[cfg(true)] +LL | | Foo: Trait, + | |_______________^ + | + = note: see issue #89122 for more information +help: move it to the end of the type declaration + | +LL + +LL | = Foo +LL | where +LL ~ (): Sized, Foo: Trait; + | + +error: where clauses are not allowed before the type for type aliases + --> $DIR/cfg-attr-issue-138010-2.rs:19:1 + | +LL | / where +LL | | +LL | | #[cfg(false)] +LL | | Foo: Trait, + | |_______________^ help: remove this `where` + | + = note: see issue #89122 for more information + +error: aborting due to 2 previous errors + diff --git a/triagebot.toml b/triagebot.toml index fbe29dd18245..a0d0b1892e4f 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -1370,6 +1370,7 @@ compiler = [ "@jackh726", "@jieyouxu", "@jdonszelmann", + "@JonathanBrouwer", "@lcnr", "@madsmtm", "@Nadrieril",