diff options
Diffstat (limited to 'compiler')
66 files changed, 445 insertions, 1032 deletions
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index f5418402377..286bbfb5ae8 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -2585,8 +2585,7 @@ pub enum TyPatKind { pub enum TraitObjectSyntax { // SAFETY: When adding new variants make sure to update the `Tag` impl. Dyn = 0, - DynStar = 1, - None = 2, + None = 1, } /// SAFETY: `TraitObjectSyntax` only has 3 data-less variants which means @@ -2602,8 +2601,7 @@ unsafe impl Tag for TraitObjectSyntax { unsafe fn from_usize(tag: usize) -> Self { match tag { 0 => TraitObjectSyntax::Dyn, - 1 => TraitObjectSyntax::DynStar, - 2 => TraitObjectSyntax::None, + 1 => TraitObjectSyntax::None, _ => unreachable!(), } } diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index 1ec56868f37..c7f41fc3cb1 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -505,7 +505,6 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) { ); gate_all!(associated_const_equality, "associated const equality is incomplete"); gate_all!(yeet_expr, "`do yeet` expression is experimental"); - gate_all!(dyn_star, "`dyn*` trait objects are experimental"); gate_all!(const_closures, "const closures are experimental"); gate_all!(builtin_syntax, "`builtin #` syntax is unstable"); gate_all!(ergonomic_clones, "ergonomic clones are experimental"); diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index 3d738fa31f2..9802ac90c9a 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -1303,7 +1303,6 @@ impl<'a> State<'a> { ast::TyKind::TraitObject(bounds, syntax) => { match syntax { ast::TraitObjectSyntax::Dyn => self.word_nbsp("dyn"), - ast::TraitObjectSyntax::DynStar => self.word_nbsp("dyn*"), ast::TraitObjectSyntax::None => {} } self.print_type_bounds(bounds); diff --git a/compiler/rustc_attr_data_structures/src/attributes.rs b/compiler/rustc_attr_data_structures/src/attributes.rs index 4651cf504fa..6f4cc83fd10 100644 --- a/compiler/rustc_attr_data_structures/src/attributes.rs +++ b/compiler/rustc_attr_data_structures/src/attributes.rs @@ -296,6 +296,9 @@ pub enum AttributeKind { /// Represents `#[rustc_layout_scalar_valid_range_start]`. RustcLayoutScalarValidRangeStart(Box<u128>, Span), + /// Represents `#[rustc_object_lifetime_default]`. + RustcObjectLifetimeDefault, + /// Represents `#[rustc_skip_during_method_dispatch]`. SkipDuringMethodDispatch { array: bool, boxed_slice: bool, span: Span }, diff --git a/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs b/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs index 17f7a7a2e6d..58ced8e3281 100644 --- a/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs +++ b/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs @@ -40,6 +40,7 @@ impl AttributeKind { PubTransparent(..) => Yes, RustcLayoutScalarValidRangeEnd(..) => Yes, RustcLayoutScalarValidRangeStart(..) => Yes, + RustcObjectLifetimeDefault => No, SkipDuringMethodDispatch { .. } => No, TrackCaller(..) => Yes, Used { .. } => No, diff --git a/compiler/rustc_attr_parsing/src/attributes/must_use.rs b/compiler/rustc_attr_parsing/src/attributes/must_use.rs index a672d956127..b5eb85f68b4 100644 --- a/compiler/rustc_attr_parsing/src/attributes/must_use.rs +++ b/compiler/rustc_attr_parsing/src/attributes/must_use.rs @@ -21,7 +21,16 @@ impl<S: Stage> SingleAttributeParser<S> for MustUseParser { span: cx.attr_span, reason: match args { ArgParser::NoArgs => None, - ArgParser::NameValue(name_value) => name_value.value_as_str(), + ArgParser::NameValue(name_value) => { + let Some(value_str) = name_value.value_as_str() else { + cx.expected_string_literal( + name_value.value_span, + Some(&name_value.value_as_lit()), + ); + return None; + }; + Some(value_str) + } ArgParser::List(_) => { let suggestions = <Self as SingleAttributeParser<S>>::TEMPLATE.suggestions(false, "must_use"); diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs index 7364a3f20e2..e6b6a6fe3c9 100644 --- a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs +++ b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs @@ -57,3 +57,21 @@ fn parse_rustc_layout_scalar_valid_range<S: Stage>( }; Some(Box::new(num.0)) } + +pub(crate) struct RustcObjectLifetimeDefaultParser; + +impl<S: Stage> SingleAttributeParser<S> for RustcObjectLifetimeDefaultParser { + const PATH: &[rustc_span::Symbol] = &[sym::rustc_object_lifetime_default]; + const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepFirst; + const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error; + const TEMPLATE: AttributeTemplate = template!(Word); + + fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> { + if let Err(span) = args.no_args() { + cx.expected_no_args(span); + return None; + } + + Some(AttributeKind::RustcObjectLifetimeDefault) + } +} diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 6a03cde3a53..cfba0650932 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -29,6 +29,7 @@ use crate::attributes::must_use::MustUseParser; use crate::attributes::repr::{AlignParser, ReprParser}; use crate::attributes::rustc_internal::{ RustcLayoutScalarValidRangeEnd, RustcLayoutScalarValidRangeStart, + RustcObjectLifetimeDefaultParser, }; use crate::attributes::semantics::MayDangleParser; use crate::attributes::stability::{ @@ -136,6 +137,7 @@ attribute_parsers!( Single<RustcForceInlineParser>, Single<RustcLayoutScalarValidRangeEnd>, Single<RustcLayoutScalarValidRangeStart>, + Single<RustcObjectLifetimeDefaultParser>, Single<SkipDuringMethodDispatchParser>, Single<TrackCallerParser>, Single<TransparencyParser>, diff --git a/compiler/rustc_attr_parsing/src/session_diagnostics.rs b/compiler/rustc_attr_parsing/src/session_diagnostics.rs index a815aa8c7a8..6145f1e1d3e 100644 --- a/compiler/rustc_attr_parsing/src/session_diagnostics.rs +++ b/compiler/rustc_attr_parsing/src/session_diagnostics.rs @@ -577,10 +577,7 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for AttributeParseError { diag.code(E0565); } AttributeParseErrorReason::ExpectedNameValue(None) => { - diag.span_label( - self.span, - format!("expected this to be of the form `{name} = \"...\"`"), - ); + // The suggestion we add below this match already contains enough information } AttributeParseErrorReason::ExpectedNameValue(Some(name)) => { diag.span_label( diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index fd8a2a6bc35..7c69baba62e 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -1168,6 +1168,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { _, mir::Rvalue::Use(mir::Operand::Copy(place)), )), + .. }) = self.body[location.block].statements.get(location.statement_index) { self.body.local_decls[place.local].source_info.span diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index e37b5a33af8..05bcd9f862e 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -25,9 +25,9 @@ use rustc_middle::traits::query::NoSolution; use rustc_middle::ty::adjustment::PointerCoercion; use rustc_middle::ty::cast::CastTy; use rustc_middle::ty::{ - self, Binder, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, CoroutineArgsExt, - Dynamic, GenericArgsRef, OpaqueHiddenType, OpaqueTypeKey, RegionVid, Ty, TyCtxt, - TypeVisitableExt, UserArgs, UserTypeAnnotationIndex, fold_regions, + self, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, CoroutineArgsExt, + GenericArgsRef, OpaqueHiddenType, OpaqueTypeKey, RegionVid, Ty, TyCtxt, TypeVisitableExt, + UserArgs, UserTypeAnnotationIndex, fold_regions, }; use rustc_middle::{bug, span_bug}; use rustc_mir_dataflow::move_paths::MoveData; @@ -1233,38 +1233,6 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { ); } - CastKind::PointerCoercion(PointerCoercion::DynStar, coercion_source) => { - // get the constraints from the target type (`dyn* Clone`) - // - // apply them to prove that the source type `Foo` implements `Clone` etc - let (existential_predicates, region) = match ty.kind() { - Dynamic(predicates, region, ty::DynStar) => (predicates, region), - _ => panic!("Invalid dyn* cast_ty"), - }; - - let self_ty = op.ty(self.body, tcx); - - let is_implicit_coercion = coercion_source == CoercionSource::Implicit; - self.prove_predicates( - existential_predicates - .iter() - .map(|predicate| predicate.with_self_ty(tcx, self_ty)), - location.to_locations(), - ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None }, - ); - - let outlives_predicate = tcx.mk_predicate(Binder::dummy( - ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives( - ty::OutlivesPredicate(self_ty, *region), - )), - )); - self.prove_predicate( - outlives_predicate, - location.to_locations(), - ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None }, - ); - } - CastKind::PointerCoercion( PointerCoercion::MutToConstPointer, coercion_source, diff --git a/compiler/rustc_codegen_cranelift/src/abi/mod.rs b/compiler/rustc_codegen_cranelift/src/abi/mod.rs index 4c6fd907815..8965e4a944d 100644 --- a/compiler/rustc_codegen_cranelift/src/abi/mod.rs +++ b/compiler/rustc_codegen_cranelift/src/abi/mod.rs @@ -753,51 +753,6 @@ pub(crate) fn codegen_drop<'tcx>( fx.bcx.ins().call_indirect(sig, drop_fn, &[ptr]); fx.bcx.ins().jump(ret_block, &[]); } - ty::Dynamic(_, _, ty::DynStar) => { - // IN THIS ARM, WE HAVE: - // ty = *mut (dyn* Trait) - // which is: *mut exists<T: sizeof(T) == sizeof(usize)> (T, Vtable<T: Trait>) - // - // args = [ * ] - // | - // v - // ( Data, Vtable ) - // | - // v - // /-------\ - // | ... | - // \-------/ - // - // - // WE CAN CONVERT THIS INTO THE ABOVE LOGIC BY DOING - // - // data = &(*args[0]).0 // gives a pointer to Data above (really the same pointer) - // vtable = (*args[0]).1 // loads the vtable out - // (data, vtable) // an equivalent Rust `*mut dyn Trait` - // - // SO THEN WE CAN USE THE ABOVE CODE. - let (data, vtable) = drop_place.to_cvalue(fx).dyn_star_force_data_on_stack(fx); - let drop_fn = crate::vtable::drop_fn_of_obj(fx, vtable); - - let is_null = fx.bcx.ins().icmp_imm(IntCC::Equal, drop_fn, 0); - let target_block = fx.get_block(target); - let continued = fx.bcx.create_block(); - fx.bcx.ins().brif(is_null, target_block, &[], continued, &[]); - fx.bcx.switch_to_block(continued); - - let virtual_drop = Instance { - def: ty::InstanceKind::Virtual(drop_instance.def_id(), 0), - args: drop_instance.args, - }; - let fn_abi = FullyMonomorphizedLayoutCx(fx.tcx) - .fn_abi_of_instance(virtual_drop, ty::List::empty()); - - let sig = clif_sig_from_fn_abi(fx.tcx, fx.target_config.default_call_conv, &fn_abi); - let sig = fx.bcx.import_signature(sig); - fx.bcx.ins().call_indirect(sig, drop_fn, &[data]); - // FIXME implement cleanup on exceptions - fx.bcx.ins().jump(ret_block, &[]); - } _ => { assert!(!matches!(drop_instance.def, InstanceKind::Virtual(_, _))); diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs index 1b68c6535da..bc0a0f034b2 100644 --- a/compiler/rustc_codegen_cranelift/src/base.rs +++ b/compiler/rustc_codegen_cranelift/src/base.rs @@ -790,14 +790,6 @@ fn codegen_stmt<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, cur_block: Block, stmt: let operand = codegen_operand(fx, operand); crate::unsize::coerce_unsized_into(fx, operand, lval); } - Rvalue::Cast( - CastKind::PointerCoercion(PointerCoercion::DynStar, _), - ref operand, - _, - ) => { - let operand = codegen_operand(fx, operand); - crate::unsize::coerce_dyn_star(fx, operand, lval); - } Rvalue::Cast(CastKind::Transmute, ref operand, _to_ty) => { let operand = codegen_operand(fx, operand); lval.write_cvalue_transmute(fx, operand); diff --git a/compiler/rustc_codegen_cranelift/src/unsize.rs b/compiler/rustc_codegen_cranelift/src/unsize.rs index df60b05c463..2aee0b2e974 100644 --- a/compiler/rustc_codegen_cranelift/src/unsize.rs +++ b/compiler/rustc_codegen_cranelift/src/unsize.rs @@ -112,21 +112,6 @@ fn unsize_ptr<'tcx>( } } -/// Coerces `src` to `dst_ty` which is guaranteed to be a `dyn*` type. -pub(crate) fn cast_to_dyn_star<'tcx>( - fx: &mut FunctionCx<'_, '_, 'tcx>, - src: Value, - src_ty_and_layout: TyAndLayout<'tcx>, - dst_ty: Ty<'tcx>, - old_info: Option<Value>, -) -> (Value, Value) { - assert!( - matches!(dst_ty.kind(), ty::Dynamic(_, _, ty::DynStar)), - "destination type must be a dyn*" - ); - (src, unsized_info(fx, src_ty_and_layout.ty, dst_ty, old_info)) -} - /// Coerce `src`, which is a reference to a value of type `src_ty`, /// to a value of type `dst_ty` and store the result in `dst` pub(crate) fn coerce_unsized_into<'tcx>( @@ -174,24 +159,6 @@ pub(crate) fn coerce_unsized_into<'tcx>( } } -pub(crate) fn coerce_dyn_star<'tcx>( - fx: &mut FunctionCx<'_, '_, 'tcx>, - src: CValue<'tcx>, - dst: CPlace<'tcx>, -) { - let (data, extra) = if let ty::Dynamic(_, _, ty::DynStar) = src.layout().ty.kind() { - let (data, vtable) = src.load_scalar_pair(fx); - (data, Some(vtable)) - } else { - let data = src.load_scalar(fx); - (data, None) - }; - - let (data, vtable) = cast_to_dyn_star(fx, data, src.layout(), dst.layout().ty, extra); - - dst.write_cvalue(fx, CValue::by_val_pair(data, vtable, dst.layout())); -} - // Adapted from https://github.com/rust-lang/rust/blob/2a663555ddf36f6b041445894a8c175cd1bc718c/src/librustc_codegen_ssa/glue.rs pub(crate) fn size_and_align_of<'tcx>( diff --git a/compiler/rustc_codegen_cranelift/src/value_and_place.rs b/compiler/rustc_codegen_cranelift/src/value_and_place.rs index cbfb215a892..9d73f200afe 100644 --- a/compiler/rustc_codegen_cranelift/src/value_and_place.rs +++ b/compiler/rustc_codegen_cranelift/src/value_and_place.rs @@ -121,43 +121,6 @@ impl<'tcx> CValue<'tcx> { } } - // FIXME remove - /// Forces the data value of a dyn* value to the stack and returns a pointer to it as well as the - /// vtable pointer. - pub(crate) fn dyn_star_force_data_on_stack( - self, - fx: &mut FunctionCx<'_, '_, 'tcx>, - ) -> (Value, Value) { - assert!(self.1.ty.is_dyn_star()); - - match self.0 { - CValueInner::ByRef(ptr, None) => { - let (a_scalar, b_scalar) = match self.1.backend_repr { - BackendRepr::ScalarPair(a, b) => (a, b), - _ => unreachable!("dyn_star_force_data_on_stack({:?})", self), - }; - let b_offset = scalar_pair_calculate_b_offset(fx.tcx, a_scalar, b_scalar); - let clif_ty2 = scalar_to_clif_type(fx.tcx, b_scalar); - let mut flags = MemFlags::new(); - flags.set_notrap(); - let vtable = ptr.offset(fx, b_offset).load(fx, clif_ty2, flags); - (ptr.get_addr(fx), vtable) - } - CValueInner::ByValPair(data, vtable) => { - let data_ptr = fx.create_stack_slot( - u32::try_from(fx.target_config.pointer_type().bytes()).unwrap(), - u32::try_from(fx.target_config.pointer_type().bytes()).unwrap(), - ); - data_ptr.store(fx, data, MemFlags::trusted()); - - (data_ptr.get_addr(fx), vtable) - } - CValueInner::ByRef(_, Some(_)) | CValueInner::ByVal(_) => { - unreachable!("dyn_star_force_data_on_stack({:?})", self) - } - } - } - pub(crate) fn try_to_ptr(self) -> Option<(Pointer, Option<Value>)> { match self.0 { CValueInner::ByRef(ptr, meta) => Some((ptr, meta)), diff --git a/compiler/rustc_codegen_cranelift/src/vtable.rs b/compiler/rustc_codegen_cranelift/src/vtable.rs index 1fae56949bc..423cc8d225b 100644 --- a/compiler/rustc_codegen_cranelift/src/vtable.rs +++ b/compiler/rustc_codegen_cranelift/src/vtable.rs @@ -46,34 +46,22 @@ pub(crate) fn get_ptr_and_method_ref<'tcx>( mut arg: CValue<'tcx>, idx: usize, ) -> (Pointer, Value) { - let (ptr, vtable) = 'block: { - if let BackendRepr::Scalar(_) = arg.layout().backend_repr { - while !arg.layout().ty.is_raw_ptr() && !arg.layout().ty.is_ref() { - let (idx, _) = arg - .layout() - .non_1zst_field(fx) - .expect("not exactly one non-1-ZST field in a `DispatchFromDyn` type"); - arg = arg.value_field(fx, idx); - } - } - - if let ty::Ref(_, ty, _) = arg.layout().ty.kind() { - if ty.is_dyn_star() { - let inner_layout = fx.layout_of(arg.layout().ty.builtin_deref(true).unwrap()); - let dyn_star = CPlace::for_ptr(Pointer::new(arg.load_scalar(fx)), inner_layout); - let ptr = dyn_star.place_field(fx, FieldIdx::ZERO).to_ptr(); - let vtable = dyn_star.place_field(fx, FieldIdx::ONE).to_cvalue(fx).load_scalar(fx); - break 'block (ptr, vtable); - } + if let BackendRepr::Scalar(_) = arg.layout().backend_repr { + while !arg.layout().ty.is_raw_ptr() && !arg.layout().ty.is_ref() { + let (idx, _) = arg + .layout() + .non_1zst_field(fx) + .expect("not exactly one non-1-ZST field in a `DispatchFromDyn` type"); + arg = arg.value_field(fx, idx); } + } - if let BackendRepr::ScalarPair(_, _) = arg.layout().backend_repr { - let (ptr, vtable) = arg.load_scalar_pair(fx); - (Pointer::new(ptr), vtable) - } else { - let (ptr, vtable) = arg.try_to_ptr().unwrap(); - (ptr, vtable.unwrap()) - } + let (ptr, vtable) = if let BackendRepr::ScalarPair(_, _) = arg.layout().backend_repr { + let (ptr, vtable) = arg.load_scalar_pair(fx); + (Pointer::new(ptr), vtable) + } else { + let (ptr, vtable) = arg.try_to_ptr().unwrap(); + (ptr, vtable.unwrap()) }; let usize_size = fx.layout_of(fx.tcx.types.usize).size.bytes(); diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index b06cfd1e473..102d4ea2fa6 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -262,28 +262,6 @@ pub(crate) fn unsize_ptr<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( } } -/// Coerces `src` to `dst_ty` which is guaranteed to be a `dyn*` type. -pub(crate) fn cast_to_dyn_star<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( - bx: &mut Bx, - src: Bx::Value, - src_ty_and_layout: TyAndLayout<'tcx>, - dst_ty: Ty<'tcx>, - old_info: Option<Bx::Value>, -) -> (Bx::Value, Bx::Value) { - debug!("cast_to_dyn_star: {:?} => {:?}", src_ty_and_layout.ty, dst_ty); - assert!( - matches!(dst_ty.kind(), ty::Dynamic(_, _, ty::DynStar)), - "destination type must be a dyn*" - ); - let src = match bx.cx().type_kind(bx.cx().backend_type(src_ty_and_layout)) { - TypeKind::Pointer => src, - TypeKind::Integer => bx.inttoptr(src, bx.type_ptr()), - // FIXME(dyn-star): We probably have to do a bitcast first, then inttoptr. - kind => bug!("unexpected TypeKind for left-hand side of `dyn*` cast: {kind:?}"), - }; - (src, unsized_info(bx, src_ty_and_layout.ty, dst_ty, old_info)) -} - /// Coerces `src`, which is a reference to a value of type `src_ty`, /// to a value of type `dst_ty`, and stores the result in `dst`. pub(crate) fn coerce_unsized_into<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index 1d5fbfc0896..bde63fd501a 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -628,50 +628,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { virtual_drop, ) } - ty::Dynamic(_, _, ty::DynStar) => { - // IN THIS ARM, WE HAVE: - // ty = *mut (dyn* Trait) - // which is: *mut exists<T: sizeof(T) == sizeof(usize)> (T, Vtable<T: Trait>) - // - // args = [ * ] - // | - // v - // ( Data, Vtable ) - // | - // v - // /-------\ - // | ... | - // \-------/ - // - // - // WE CAN CONVERT THIS INTO THE ABOVE LOGIC BY DOING - // - // data = &(*args[0]).0 // gives a pointer to Data above (really the same pointer) - // vtable = (*args[0]).1 // loads the vtable out - // (data, vtable) // an equivalent Rust `*mut dyn Trait` - // - // SO THEN WE CAN USE THE ABOVE CODE. - let virtual_drop = Instance { - def: ty::InstanceKind::Virtual(drop_fn.def_id(), 0), // idx 0: the drop function - args: drop_fn.args, - }; - debug!("ty = {:?}", ty); - debug!("drop_fn = {:?}", drop_fn); - debug!("args = {:?}", args); - let fn_abi = bx.fn_abi_of_instance(virtual_drop, ty::List::empty()); - let meta_ptr = place.project_field(bx, 1); - let meta = bx.load_operand(meta_ptr); - // Truncate vtable off of args list - args = &args[..1]; - debug!("args' = {:?}", args); - ( - true, - meth::VirtualIndex::from_index(ty::COMMON_VTABLE_ENTRIES_DROPINPLACE) - .get_optional_fn(bx, meta.immediate(), ty, fn_abi), - fn_abi, - virtual_drop, - ) - } _ => ( false, bx.get_fn_addr(drop_fn), @@ -1108,33 +1064,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { llargs.push(data_ptr); continue; } - Immediate(_) => { - // See comment above explaining why we peel these newtypes - while !op.layout.ty.is_raw_ptr() && !op.layout.ty.is_ref() { - let (idx, _) = op.layout.non_1zst_field(bx).expect( - "not exactly one non-1-ZST field in a `DispatchFromDyn` type", - ); - op = op.extract_field(self, bx, idx.as_usize()); - } - - // Make sure that we've actually unwrapped the rcvr down - // to a pointer or ref to `dyn* Trait`. - if !op.layout.ty.builtin_deref(true).unwrap().is_dyn_star() { - span_bug!(fn_span, "can't codegen a virtual call on {:#?}", op); - } - let place = op.deref(bx.cx()); - let data_place = place.project_field(bx, 0); - let meta_place = place.project_field(bx, 1); - let meta = bx.load_operand(meta_place); - llfn = Some(meth::VirtualIndex::from_index(idx).get_fn( - bx, - meta.immediate(), - op.layout.ty, - fn_abi, - )); - llargs.push(data_place.val.llval); - continue; - } _ => { span_bug!(fn_span, "can't codegen a virtual call on {:#?}", op); } diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index db5ac6a514f..7ef04213d32 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -468,12 +468,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { bug!("unexpected non-pair operand"); } } - mir::CastKind::PointerCoercion(PointerCoercion::DynStar, _) => { - let (lldata, llextra) = operand.val.pointer_parts(); - let (lldata, llextra) = - base::cast_to_dyn_star(bx, lldata, operand.layout, cast.ty, llextra); - OperandValue::Pair(lldata, llextra) - } | mir::CastKind::IntToInt | mir::CastKind::FloatToInt | mir::CastKind::FloatToFloat diff --git a/compiler/rustc_const_eval/src/check_consts/check.rs b/compiler/rustc_const_eval/src/check_consts/check.rs index c1d91f98957..0eb6f28bdb3 100644 --- a/compiler/rustc_const_eval/src/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/check_consts/check.rs @@ -638,14 +638,6 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { // These are all okay; they only change the type, not the data. } - Rvalue::Cast( - CastKind::PointerCoercion(PointerCoercion::Unsize | PointerCoercion::DynStar, _), - _, - _, - ) => { - // Unsizing and `dyn*` coercions are implemented for CTFE. - } - Rvalue::Cast(CastKind::PointerExposeProvenance, _, _) => { self.check_op(ops::RawPtrToIntCast); } diff --git a/compiler/rustc_const_eval/src/interpret/call.rs b/compiler/rustc_const_eval/src/interpret/call.rs index 79c14b204e3..ebaa5a97a4a 100644 --- a/compiler/rustc_const_eval/src/interpret/call.rs +++ b/compiler/rustc_const_eval/src/interpret/call.rs @@ -643,13 +643,6 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { break self.ref_to_mplace(&val)?; } ty::Dynamic(.., ty::Dyn) => break receiver.assert_mem_place(), // no immediate unsized values - ty::Dynamic(.., ty::DynStar) => { - // Not clear how to handle this, so far we assume the receiver is always a pointer. - span_bug!( - self.cur_span(), - "by-value calls on a `dyn*`... are those a thing?" - ); - } _ => { // Not there yet, search for the only non-ZST field. // (The rules for `DispatchFromDyn` ensure there's exactly one such field.) @@ -662,39 +655,23 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { }; // Obtain the underlying trait we are working on, and the adjusted receiver argument. - let (trait_, dyn_ty, adjusted_recv) = if let ty::Dynamic(data, _, ty::DynStar) = - receiver_place.layout.ty.kind() - { - let recv = self.unpack_dyn_star(&receiver_place, data)?; - - (data.principal(), recv.layout.ty, recv.ptr()) - } else { - // Doesn't have to be a `dyn Trait`, but the unsized tail must be `dyn Trait`. - // (For that reason we also cannot use `unpack_dyn_trait`.) - let receiver_tail = - self.tcx.struct_tail_for_codegen(receiver_place.layout.ty, self.typing_env); - let ty::Dynamic(receiver_trait, _, ty::Dyn) = receiver_tail.kind() else { - span_bug!( - self.cur_span(), - "dynamic call on non-`dyn` type {}", - receiver_tail - ) - }; - assert!(receiver_place.layout.is_unsized()); - - // Get the required information from the vtable. - let vptr = receiver_place.meta().unwrap_meta().to_pointer(self)?; - let dyn_ty = self.get_ptr_vtable_ty(vptr, Some(receiver_trait))?; - - // It might be surprising that we use a pointer as the receiver even if this - // is a by-val case; this works because by-val passing of an unsized `dyn - // Trait` to a function is actually desugared to a pointer. - (receiver_trait.principal(), dyn_ty, receiver_place.ptr()) + // Doesn't have to be a `dyn Trait`, but the unsized tail must be `dyn Trait`. + // (For that reason we also cannot use `unpack_dyn_trait`.) + let receiver_tail = + self.tcx.struct_tail_for_codegen(receiver_place.layout.ty, self.typing_env); + let ty::Dynamic(receiver_trait, _, ty::Dyn) = receiver_tail.kind() else { + span_bug!(self.cur_span(), "dynamic call on non-`dyn` type {}", receiver_tail) }; + assert!(receiver_place.layout.is_unsized()); + + // Get the required information from the vtable. + let vptr = receiver_place.meta().unwrap_meta().to_pointer(self)?; + let dyn_ty = self.get_ptr_vtable_ty(vptr, Some(receiver_trait))?; + let adjusted_recv = receiver_place.ptr(); // Now determine the actual method to call. Usually we use the easy way of just // looking up the method at index `idx`. - let vtable_entries = self.vtable_entries(trait_, dyn_ty); + let vtable_entries = self.vtable_entries(receiver_trait.principal(), dyn_ty); let Some(ty::VtblEntry::Method(fn_inst)) = vtable_entries.get(idx).copied() else { // FIXME(fee1-dead) these could be variants of the UB info enum instead of this throw_ub_custom!(fluent::const_eval_dyn_call_not_a_method); @@ -830,10 +807,6 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { // Dropping a trait object. Need to find actual drop fn. self.unpack_dyn_trait(&place, data)? } - ty::Dynamic(data, _, ty::DynStar) => { - // Dropping a `dyn*`. Need to find actual drop fn. - self.unpack_dyn_star(&place, data)? - } _ => { debug_assert_eq!( instance, diff --git a/compiler/rustc_const_eval/src/interpret/cast.rs b/compiler/rustc_const_eval/src/interpret/cast.rs index 1036935bb10..7a73d70fc85 100644 --- a/compiler/rustc_const_eval/src/interpret/cast.rs +++ b/compiler/rustc_const_eval/src/interpret/cast.rs @@ -126,20 +126,6 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { } } - CastKind::PointerCoercion(PointerCoercion::DynStar, _) => { - if let ty::Dynamic(data, _, ty::DynStar) = cast_ty.kind() { - // Initial cast from sized to dyn trait - let vtable = self.get_vtable_ptr(src.layout.ty, data)?; - let vtable = Scalar::from_maybe_pointer(vtable, self); - let data = self.read_immediate(src)?.to_scalar(); - let _assert_pointer_like = data.to_pointer(self)?; - let val = Immediate::ScalarPair(data, vtable); - self.write_immediate(val, dest)?; - } else { - bug!() - } - } - CastKind::Transmute => { assert!(src.layout.is_sized()); assert!(dest.layout.is_sized()); diff --git a/compiler/rustc_const_eval/src/interpret/stack.rs b/compiler/rustc_const_eval/src/interpret/stack.rs index 3361a586b8e..543d68d7f45 100644 --- a/compiler/rustc_const_eval/src/interpret/stack.rs +++ b/compiler/rustc_const_eval/src/interpret/stack.rs @@ -499,8 +499,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { | ty::Closure(..) | ty::CoroutineClosure(..) | ty::Never - | ty::Error(_) - | ty::Dynamic(_, _, ty::DynStar) => true, + | ty::Error(_) => true, ty::Str | ty::Slice(_) | ty::Dynamic(_, _, ty::Dyn) | ty::Foreign(..) => false, diff --git a/compiler/rustc_const_eval/src/interpret/traits.rs b/compiler/rustc_const_eval/src/interpret/traits.rs index 8b634955bb7..e4b5c82853a 100644 --- a/compiler/rustc_const_eval/src/interpret/traits.rs +++ b/compiler/rustc_const_eval/src/interpret/traits.rs @@ -1,4 +1,4 @@ -use rustc_abi::{Align, FieldIdx, Size}; +use rustc_abi::{Align, Size}; use rustc_middle::mir::interpret::{InterpResult, Pointer}; use rustc_middle::ty::{self, ExistentialPredicateStableCmpExt, Ty, TyCtxt, VtblEntry}; use tracing::trace; @@ -125,24 +125,4 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { )?; interp_ok(mplace) } - - /// Turn a `dyn* Trait` type into an value with the actual dynamic type. - pub(super) fn unpack_dyn_star<P: Projectable<'tcx, M::Provenance>>( - &self, - val: &P, - expected_trait: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>, - ) -> InterpResult<'tcx, P> { - assert!( - matches!(val.layout().ty.kind(), ty::Dynamic(_, _, ty::DynStar)), - "`unpack_dyn_star` only makes sense on `dyn*` types" - ); - let data = self.project_field(val, FieldIdx::ZERO)?; - let vtable = self.project_field(val, FieldIdx::ONE)?; - let vtable = self.read_pointer(&vtable.to_op(self)?)?; - let ty = self.get_ptr_vtable_ty(vtable, Some(expected_trait))?; - // `data` is already the right thing but has the wrong type. So we transmute it. - let layout = self.layout_of(ty)?; - let data = data.transmute(layout, self)?; - interp_ok(data) - } } diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs index 72680019380..e26cf0a4900 100644 --- a/compiler/rustc_const_eval/src/interpret/validity.rs +++ b/compiler/rustc_const_eval/src/interpret/validity.rs @@ -358,9 +358,6 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> { // arrays/slices ty::Array(..) | ty::Slice(..) => PathElem::ArrayElem(field), - // dyn* vtables - ty::Dynamic(_, _, ty::DynKind::DynStar) if field == 1 => PathElem::Vtable, - // dyn traits ty::Dynamic(..) => { assert_eq!(field, 0); diff --git a/compiler/rustc_const_eval/src/interpret/visitor.rs b/compiler/rustc_const_eval/src/interpret/visitor.rs index d5970b69baf..a27b6646131 100644 --- a/compiler/rustc_const_eval/src/interpret/visitor.rs +++ b/compiler/rustc_const_eval/src/interpret/visitor.rs @@ -101,26 +101,6 @@ pub trait ValueVisitor<'tcx, M: Machine<'tcx>>: Sized { // recurse with the inner type return self.visit_field(v, 0, &inner_mplace.into()); } - ty::Dynamic(data, _, ty::DynStar) => { - // DynStar types. Very different from a dyn type (but strangely part of the - // same variant in `TyKind`): These are pairs where the 2nd component is the - // vtable, and the first component is the data (which must be ptr-sized). - - // First make sure the vtable can be read at its type. - // The type of this vtable is fake, it claims to be a reference to some actual memory but that isn't true. - // So we transmute it to a raw pointer. - let raw_ptr_ty = Ty::new_mut_ptr(*self.ecx().tcx, self.ecx().tcx.types.unit); - let raw_ptr_ty = self.ecx().layout_of(raw_ptr_ty)?; - let vtable_field = self - .ecx() - .project_field(v, FieldIdx::ONE)? - .transmute(raw_ptr_ty, self.ecx())?; - self.visit_field(v, 1, &vtable_field)?; - - // Then unpack the first field, and continue. - let data = self.ecx().unpack_dyn_star(v, data)?; - return self.visit_field(v, 0, &data); - } // Slices do not need special handling here: they have `Array` field // placement with length 0, so we enter the `Array` case below which // indirectly uses the metadata to determine the actual length. diff --git a/compiler/rustc_feature/src/removed.rs b/compiler/rustc_feature/src/removed.rs index 57a75d6da0f..7e174c465d5 100644 --- a/compiler/rustc_feature/src/removed.rs +++ b/compiler/rustc_feature/src/removed.rs @@ -123,6 +123,9 @@ declare_features! ( /// [^1]: Formerly known as "object safe". (removed, dyn_compatible_for_dispatch, "1.87.0", Some(43561), Some("removed, not used heavily and represented additional complexity in dyn compatibility"), 136522), + /// Allows `dyn* Trait` objects. + (removed, dyn_star, "1.65.0", Some(102425), + Some("removed as it was no longer necessary for AFIDT (async fn in dyn trait) support")), /// Uses generic effect parameters for [const] bounds (removed, effects, "1.84.0", Some(102090), Some("removed, redundant with `#![feature(const_trait_impl)]`"), 132479), diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 4e4545d0400..269a9c60d86 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -481,8 +481,6 @@ declare_features! ( (unstable, doc_cfg_hide, "1.57.0", Some(43781)), /// Allows `#[doc(masked)]`. (unstable, doc_masked, "1.21.0", Some(44027)), - /// Allows `dyn* Trait` objects. - (incomplete, dyn_star, "1.65.0", Some(102425)), /// Allows the .use postfix syntax `x.use` and use closures `use |x| { ... }` (incomplete, ergonomic_clones, "1.87.0", Some(132290)), /// Allows exhaustive pattern matching on types that contain uninhabited types. diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 4bb6a796be4..c90cd93ff07 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -956,7 +956,7 @@ impl<'hir> Generics<'hir> { && let Some(ret_ty) = segment.args().paren_sugar_output() && let ret_ty = ret_ty.peel_refs() && let TyKind::TraitObject(_, tagged_ptr) = ret_ty.kind - && let TraitObjectSyntax::Dyn | TraitObjectSyntax::DynStar = tagged_ptr.tag() + && let TraitObjectSyntax::Dyn = tagged_ptr.tag() && ret_ty.span.can_be_used_for_suggestions() { Some(ret_ty.span) @@ -4400,27 +4400,6 @@ impl ItemKind<'_> { _ => return None, }) } - - pub fn descr(&self) -> &'static str { - match self { - ItemKind::ExternCrate(..) => "extern crate", - ItemKind::Use(..) => "`use` import", - ItemKind::Static(..) => "static item", - ItemKind::Const(..) => "constant item", - ItemKind::Fn { .. } => "function", - ItemKind::Macro(..) => "macro", - ItemKind::Mod(..) => "module", - ItemKind::ForeignMod { .. } => "extern block", - ItemKind::GlobalAsm { .. } => "global asm item", - ItemKind::TyAlias(..) => "type alias", - ItemKind::Enum(..) => "enum", - ItemKind::Struct(..) => "struct", - ItemKind::Union(..) => "union", - ItemKind::Trait(..) => "trait", - ItemKind::TraitAlias(..) => "trait alias", - ItemKind::Impl(..) => "implementation", - } - } } /// A reference from an trait to one of its associated items. This @@ -4834,6 +4813,10 @@ impl<'hir> Node<'hir> { ImplItemKind::Type(ty) => Some(ty), _ => None, }, + Node::ForeignItem(it) => match it.kind { + ForeignItemKind::Static(ty, ..) => Some(ty), + _ => None, + }, _ => None, } } diff --git a/compiler/rustc_hir/src/hir/tests.rs b/compiler/rustc_hir/src/hir/tests.rs index 1fd793bc161..4f9609fd360 100644 --- a/compiler/rustc_hir/src/hir/tests.rs +++ b/compiler/rustc_hir/src/hir/tests.rs @@ -45,7 +45,6 @@ define_tests! { #[test] fn trait_object_roundtrips() { trait_object_roundtrips_impl(TraitObjectSyntax::Dyn); - trait_object_roundtrips_impl(TraitObjectSyntax::DynStar); trait_object_roundtrips_impl(TraitObjectSyntax::None); } diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index a361679e8ad..f4fcb13b1a1 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -10,7 +10,7 @@ use rustc_errors::{EmissionGuarantee, MultiSpan}; use rustc_hir::def::{CtorKind, DefKind}; use rustc_hir::{LangItem, Node, intravisit}; use rustc_infer::infer::{RegionVariableOrigin, TyCtxtInferExt}; -use rustc_infer::traits::{Obligation, ObligationCauseCode}; +use rustc_infer::traits::{Obligation, ObligationCauseCode, WellFormedLoc}; use rustc_lint_defs::builtin::{ REPR_TRANSPARENT_EXTERNAL_PRIVATE_FIELDS, UNSUPPORTED_CALLING_CONVENTIONS, }; @@ -36,6 +36,10 @@ use {rustc_attr_data_structures as attrs, rustc_hir as hir}; use super::compare_impl_item::check_type_bounds; use super::*; +use crate::check::wfcheck::{ + check_associated_item, check_trait_item, check_variances_for_type_defn, check_where_clauses, + enter_wf_checking_ctxt, +}; fn add_abi_diag_help<T: EmissionGuarantee>(abi: ExternAbi, diag: &mut Diag<'_, T>) { if let ExternAbi::Cdecl { unwind } = abi { @@ -729,7 +733,8 @@ fn check_static_linkage(tcx: TyCtxt<'_>, def_id: LocalDefId) { } } -pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) { +pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), ErrorGuaranteed> { + let mut res = Ok(()); let generics = tcx.generics_of(def_id); for param in &generics.own_params { @@ -754,15 +759,39 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) { } match tcx.def_kind(def_id) { - DefKind::Static { .. } => { - check_static_inhabited(tcx, def_id); - check_static_linkage(tcx, def_id); + def_kind @ (DefKind::Static { .. } | DefKind::Const) => { + tcx.ensure_ok().generics_of(def_id); + tcx.ensure_ok().type_of(def_id); + tcx.ensure_ok().predicates_of(def_id); + match def_kind { + DefKind::Static { .. } => { + check_static_inhabited(tcx, def_id); + check_static_linkage(tcx, def_id); + res = res.and(wfcheck::check_static_item(tcx, def_id)); + + // Only `Node::Item` and `Node::ForeignItem` still have HIR based + // checks. Returning early here does not miss any checks and + // avoids this query from having a direct dependency edge on the HIR + return res; + } + DefKind::Const => {} + _ => unreachable!(), + } } - DefKind::Const => {} DefKind::Enum => { + tcx.ensure_ok().generics_of(def_id); + tcx.ensure_ok().type_of(def_id); + tcx.ensure_ok().predicates_of(def_id); + crate::collect::lower_enum_variant_types(tcx, def_id.to_def_id()); check_enum(tcx, def_id); + check_variances_for_type_defn(tcx, def_id); } DefKind::Fn => { + tcx.ensure_ok().generics_of(def_id); + tcx.ensure_ok().type_of(def_id); + tcx.ensure_ok().predicates_of(def_id); + tcx.ensure_ok().fn_sig(def_id); + tcx.ensure_ok().codegen_fn_attrs(def_id); if let Some(i) = tcx.intrinsic(def_id) { intrinsic::check_intrinsic_type( tcx, @@ -773,17 +802,31 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) { } } DefKind::Impl { of_trait } => { + tcx.ensure_ok().generics_of(def_id); + tcx.ensure_ok().type_of(def_id); + tcx.ensure_ok().impl_trait_header(def_id); + tcx.ensure_ok().predicates_of(def_id); + tcx.ensure_ok().associated_items(def_id); if of_trait && let Some(impl_trait_header) = tcx.impl_trait_header(def_id) { - if tcx - .ensure_ok() - .coherent_trait(impl_trait_header.trait_ref.instantiate_identity().def_id) - .is_ok() - { + res = res.and( + tcx.ensure_ok() + .coherent_trait(impl_trait_header.trait_ref.instantiate_identity().def_id), + ); + + if res.is_ok() { + // Checking this only makes sense if the all trait impls satisfy basic + // requirements (see `coherent_trait` query), otherwise + // we run into infinite recursions a lot. check_impl_items_against_trait(tcx, def_id, impl_trait_header); } } } DefKind::Trait => { + tcx.ensure_ok().generics_of(def_id); + tcx.ensure_ok().trait_def(def_id); + tcx.ensure_ok().explicit_super_predicates_of(def_id); + tcx.ensure_ok().predicates_of(def_id); + tcx.ensure_ok().associated_items(def_id); let assoc_items = tcx.associated_items(def_id); check_on_unimplemented(tcx, def_id); @@ -802,11 +845,33 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) { } } } - DefKind::Struct => { - check_struct(tcx, def_id); + DefKind::TraitAlias => { + tcx.ensure_ok().generics_of(def_id); + tcx.ensure_ok().explicit_implied_predicates_of(def_id); + tcx.ensure_ok().explicit_super_predicates_of(def_id); + tcx.ensure_ok().predicates_of(def_id); } - DefKind::Union => { - check_union(tcx, def_id); + def_kind @ (DefKind::Struct | DefKind::Union) => { + tcx.ensure_ok().generics_of(def_id); + tcx.ensure_ok().type_of(def_id); + tcx.ensure_ok().predicates_of(def_id); + + let adt = tcx.adt_def(def_id).non_enum_variant(); + for f in adt.fields.iter() { + tcx.ensure_ok().generics_of(f.did); + tcx.ensure_ok().type_of(f.did); + tcx.ensure_ok().predicates_of(f.did); + } + + if let Some((_, ctor_def_id)) = adt.ctor { + crate::collect::lower_variant_ctor(tcx, ctor_def_id.expect_local()); + } + match def_kind { + DefKind::Struct => check_struct(tcx, def_id), + DefKind::Union => check_union(tcx, def_id), + _ => unreachable!(), + } + check_variances_for_type_defn(tcx, def_id); } DefKind::OpaqueTy => { check_opaque_precise_captures(tcx, def_id); @@ -831,14 +896,37 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) { tcx.ensure_ok().explicit_implied_const_bounds(def_id); tcx.ensure_ok().const_conditions(def_id); } + + // Only `Node::Item` and `Node::ForeignItem` still have HIR based + // checks. Returning early here does not miss any checks and + // avoids this query from having a direct dependency edge on the HIR + return res; } DefKind::TyAlias => { + tcx.ensure_ok().generics_of(def_id); + tcx.ensure_ok().type_of(def_id); + tcx.ensure_ok().predicates_of(def_id); check_type_alias_type_params_are_used(tcx, def_id); + if tcx.type_alias_is_lazy(def_id) { + res = res.and(enter_wf_checking_ctxt(tcx, def_id, |wfcx| { + let ty = tcx.type_of(def_id).instantiate_identity(); + let span = tcx.def_span(def_id); + let item_ty = wfcx.deeply_normalize(span, Some(WellFormedLoc::Ty(def_id)), ty); + wfcx.register_wf_obligation( + span, + Some(WellFormedLoc::Ty(def_id)), + item_ty.into(), + ); + check_where_clauses(wfcx, def_id); + Ok(()) + })); + check_variances_for_type_defn(tcx, def_id); + } } DefKind::ForeignMod => { let it = tcx.hir_expect_item(def_id); let hir::ItemKind::ForeignMod { abi, items } = it.kind else { - return; + return Ok(()); }; check_abi(tcx, it.hir_id(), it.span, abi); @@ -877,15 +965,23 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) { } let item = tcx.hir_foreign_item(item.id); - match &item.kind { - hir::ForeignItemKind::Fn(sig, _, _) => { + tcx.ensure_ok().generics_of(item.owner_id); + tcx.ensure_ok().type_of(item.owner_id); + tcx.ensure_ok().predicates_of(item.owner_id); + if tcx.is_conditionally_const(def_id) { + tcx.ensure_ok().explicit_implied_const_bounds(def_id); + tcx.ensure_ok().const_conditions(def_id); + } + match item.kind { + hir::ForeignItemKind::Fn(sig, ..) => { + tcx.ensure_ok().codegen_fn_attrs(item.owner_id); + tcx.ensure_ok().fn_sig(item.owner_id); require_c_abi_if_c_variadic(tcx, sig.decl, abi, item.span); } hir::ForeignItemKind::Static(..) => { - check_static_inhabited(tcx, def_id); - check_static_linkage(tcx, def_id); + tcx.ensure_ok().codegen_fn_attrs(item.owner_id); } - _ => {} + _ => (), } } } @@ -897,9 +993,85 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) { // We do not call `type_of` for closures here as that // depends on typecheck and would therefore hide // any further errors in case one typeck fails. + + // Only `Node::Item` and `Node::ForeignItem` still have HIR based + // checks. Returning early here does not miss any checks and + // avoids this query from having a direct dependency edge on the HIR + return res; + } + DefKind::AssocFn => { + tcx.ensure_ok().codegen_fn_attrs(def_id); + tcx.ensure_ok().type_of(def_id); + tcx.ensure_ok().fn_sig(def_id); + tcx.ensure_ok().predicates_of(def_id); + res = res.and(check_associated_item(tcx, def_id)); + let assoc_item = tcx.associated_item(def_id); + match assoc_item.container { + ty::AssocItemContainer::Impl => {} + ty::AssocItemContainer::Trait => { + res = res.and(check_trait_item(tcx, def_id)); + } + } + + // Only `Node::Item` and `Node::ForeignItem` still have HIR based + // checks. Returning early here does not miss any checks and + // avoids this query from having a direct dependency edge on the HIR + return res; + } + DefKind::AssocConst => { + tcx.ensure_ok().type_of(def_id); + tcx.ensure_ok().predicates_of(def_id); + res = res.and(check_associated_item(tcx, def_id)); + let assoc_item = tcx.associated_item(def_id); + match assoc_item.container { + ty::AssocItemContainer::Impl => {} + ty::AssocItemContainer::Trait => { + res = res.and(check_trait_item(tcx, def_id)); + } + } + + // Only `Node::Item` and `Node::ForeignItem` still have HIR based + // checks. Returning early here does not miss any checks and + // avoids this query from having a direct dependency edge on the HIR + return res; } + DefKind::AssocTy => { + tcx.ensure_ok().predicates_of(def_id); + res = res.and(check_associated_item(tcx, def_id)); + + let assoc_item = tcx.associated_item(def_id); + let has_type = match assoc_item.container { + ty::AssocItemContainer::Impl => true, + ty::AssocItemContainer::Trait => { + tcx.ensure_ok().item_bounds(def_id); + tcx.ensure_ok().item_self_bounds(def_id); + res = res.and(check_trait_item(tcx, def_id)); + assoc_item.defaultness(tcx).has_value() + } + }; + if has_type { + tcx.ensure_ok().type_of(def_id); + } + + // Only `Node::Item` and `Node::ForeignItem` still have HIR based + // checks. Returning early here does not miss any checks and + // avoids this query from having a direct dependency edge on the HIR + return res; + } + + // Only `Node::Item` and `Node::ForeignItem` still have HIR based + // checks. Returning early here does not miss any checks and + // avoids this query from having a direct dependency edge on the HIR + DefKind::AnonConst | DefKind::InlineConst => return res, _ => {} } + let node = tcx.hir_node_by_def_id(def_id); + res.and(match node { + hir::Node::Crate(_) => bug!("check_well_formed cannot be applied to the crate root"), + hir::Node::Item(item) => wfcheck::check_item(tcx, item), + hir::Node::ForeignItem(item) => wfcheck::check_foreign_item(tcx, item), + _ => unreachable!("{node:?}"), + }) } pub(super) fn check_on_unimplemented(tcx: TyCtxt<'_>, def_id: LocalDefId) { diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index b9124ea0e5e..ed8d25e9915 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -25,7 +25,7 @@ use rustc_middle::ty::{ }; use rustc_middle::{bug, span_bug}; use rustc_session::parse::feature_err; -use rustc_span::{DUMMY_SP, Ident, Span, sym}; +use rustc_span::{DUMMY_SP, Span, sym}; use rustc_trait_selection::error_reporting::InferCtxtErrorExt; use rustc_trait_selection::regions::{InferCtxtRegionExt, OutlivesEnvironmentBuildExt}; use rustc_trait_selection::traits::misc::{ @@ -46,7 +46,6 @@ use crate::{errors, fluent_generated as fluent}; pub(super) struct WfCheckingCtxt<'a, 'tcx> { pub(super) ocx: ObligationCtxt<'a, 'tcx, FulfillmentError<'tcx>>, - span: Span, body_def_id: LocalDefId, param_env: ty::ParamEnv<'tcx>, } @@ -84,7 +83,7 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> { /// signature types for implied bounds when checking regions. // FIXME(-Znext-solver): This should be removed when we compute implied outlives // bounds using the unnormalized signature of the function we're checking. - fn deeply_normalize<T>(&self, span: Span, loc: Option<WellFormedLoc>, value: T) -> T + pub(super) fn deeply_normalize<T>(&self, span: Span, loc: Option<WellFormedLoc>, value: T) -> T where T: TypeFoldable<TyCtxt<'tcx>>, { @@ -105,7 +104,12 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> { } } - fn register_wf_obligation(&self, span: Span, loc: Option<WellFormedLoc>, term: ty::Term<'tcx>) { + pub(super) fn register_wf_obligation( + &self, + span: Span, + loc: Option<WellFormedLoc>, + term: ty::Term<'tcx>, + ) { let cause = traits::ObligationCause::new( span, self.body_def_id, @@ -122,7 +126,6 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> { pub(super) fn enter_wf_checking_ctxt<'tcx, F>( tcx: TyCtxt<'tcx>, - span: Span, body_def_id: LocalDefId, f: F, ) -> Result<(), ErrorGuaranteed> @@ -133,7 +136,7 @@ where let infcx = &tcx.infer_ctxt().build(TypingMode::non_body_analysis()); let ocx = ObligationCtxt::new_with_diagnostics(infcx); - let mut wfcx = WfCheckingCtxt { ocx, span, body_def_id, param_env }; + let mut wfcx = WfCheckingCtxt { ocx, body_def_id, param_env }; if !tcx.features().trivial_bounds() { wfcx.check_false_global_bounds() @@ -187,23 +190,10 @@ where } fn check_well_formed(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), ErrorGuaranteed> { - let node = tcx.hir_node_by_def_id(def_id); - let mut res = match node { - hir::Node::Crate(_) => bug!("check_well_formed cannot be applied to the crate root"), - hir::Node::Item(item) => check_item(tcx, item), - hir::Node::TraitItem(item) => check_trait_item(tcx, item), - hir::Node::ImplItem(item) => check_impl_item(tcx, item), - hir::Node::ForeignItem(item) => check_foreign_item(tcx, item), - hir::Node::ConstBlock(_) | hir::Node::Expr(_) | hir::Node::OpaqueTy(_) => { - Ok(crate::check::check::check_item_type(tcx, def_id)) - } - _ => unreachable!("{node:?}"), - }; + let mut res = crate::check::check::check_item_type(tcx, def_id); - if let Some(generics) = node.generics() { - for param in generics.params { - res = res.and(check_param_wf(tcx, param)); - } + for param in &tcx.generics_of(def_id).own_params { + res = res.and(check_param_wf(tcx, param)); } res @@ -223,16 +213,18 @@ fn check_well_formed(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), ErrorGua /// not included it frequently leads to confusing errors in fn bodies. So it's better to check /// the types first. #[instrument(skip(tcx), level = "debug")] -fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) -> Result<(), ErrorGuaranteed> { +pub(super) fn check_item<'tcx>( + tcx: TyCtxt<'tcx>, + item: &'tcx hir::Item<'tcx>, +) -> Result<(), ErrorGuaranteed> { let def_id = item.owner_id.def_id; debug!( ?item.owner_id, item.name = ? tcx.def_path_str(def_id) ); - crate::collect::lower_item(tcx, item.item_id()); - let res = match item.kind { + match item.kind { // Right now we check that every default trait implementation // has an implementation of itself. Basically, a case like: // @@ -295,57 +287,18 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) -> Result<() } res } - hir::ItemKind::Fn { ident, sig, .. } => { - check_item_fn(tcx, def_id, ident, item.span, sig.decl) - } - hir::ItemKind::Static(_, _, ty, _) => { - check_static_item(tcx, def_id, ty.span, UnsizedHandling::Forbid) - } - hir::ItemKind::Const(_, _, ty, _) => check_const_item(tcx, def_id, ty.span, item.span), - hir::ItemKind::Struct(_, generics, _) => { - let res = check_type_defn(tcx, item, false); - check_variances_for_type_defn(tcx, item, generics); - res - } - hir::ItemKind::Union(_, generics, _) => { - let res = check_type_defn(tcx, item, true); - check_variances_for_type_defn(tcx, item, generics); - res - } - hir::ItemKind::Enum(_, generics, _) => { - let res = check_type_defn(tcx, item, true); - check_variances_for_type_defn(tcx, item, generics); - res - } + hir::ItemKind::Fn { sig, .. } => check_item_fn(tcx, def_id, sig.decl), + hir::ItemKind::Const(_, _, ty, _) => check_const_item(tcx, def_id, ty.span), + hir::ItemKind::Struct(..) => check_type_defn(tcx, item, false), + hir::ItemKind::Union(..) => check_type_defn(tcx, item, true), + hir::ItemKind::Enum(..) => check_type_defn(tcx, item, true), hir::ItemKind::Trait(..) => check_trait(tcx, item), hir::ItemKind::TraitAlias(..) => check_trait(tcx, item), - // `ForeignItem`s are handled separately. - hir::ItemKind::ForeignMod { .. } => Ok(()), - hir::ItemKind::TyAlias(_, generics, hir_ty) if tcx.type_alias_is_lazy(item.owner_id) => { - let res = enter_wf_checking_ctxt(tcx, item.span, def_id, |wfcx| { - let ty = tcx.type_of(def_id).instantiate_identity(); - let item_ty = - wfcx.deeply_normalize(hir_ty.span, Some(WellFormedLoc::Ty(def_id)), ty); - wfcx.register_wf_obligation( - hir_ty.span, - Some(WellFormedLoc::Ty(def_id)), - item_ty.into(), - ); - check_where_clauses(wfcx, item.span, def_id); - Ok(()) - }); - check_variances_for_type_defn(tcx, item, generics); - res - } _ => Ok(()), - }; - - crate::check::check::check_item_type(tcx, def_id); - - res + } } -fn check_foreign_item<'tcx>( +pub(super) fn check_foreign_item<'tcx>( tcx: TyCtxt<'tcx>, item: &'tcx hir::ForeignItem<'tcx>, ) -> Result<(), ErrorGuaranteed> { @@ -357,43 +310,23 @@ fn check_foreign_item<'tcx>( ); match item.kind { - hir::ForeignItemKind::Fn(sig, ..) => { - check_item_fn(tcx, def_id, item.ident, item.span, sig.decl) - } - hir::ForeignItemKind::Static(ty, ..) => { - check_static_item(tcx, def_id, ty.span, UnsizedHandling::AllowIfForeignTail) - } - hir::ForeignItemKind::Type => Ok(()), + hir::ForeignItemKind::Fn(sig, ..) => check_item_fn(tcx, def_id, sig.decl), + hir::ForeignItemKind::Static(..) | hir::ForeignItemKind::Type => Ok(()), } } -fn check_trait_item<'tcx>( +pub(crate) fn check_trait_item<'tcx>( tcx: TyCtxt<'tcx>, - trait_item: &'tcx hir::TraitItem<'tcx>, + def_id: LocalDefId, ) -> Result<(), ErrorGuaranteed> { - let def_id = trait_item.owner_id.def_id; - - crate::collect::lower_trait_item(tcx, trait_item.trait_item_id()); - - let (method_sig, span) = match trait_item.kind { - hir::TraitItemKind::Fn(ref sig, _) => (Some(sig), trait_item.span), - hir::TraitItemKind::Type(_bounds, Some(ty)) => (None, ty.span), - _ => (None, trait_item.span), - }; - // Check that an item definition in a subtrait is shadowing a supertrait item. lint_item_shadowing_supertrait_item(tcx, def_id); - let mut res = check_associated_item(tcx, def_id, span, method_sig); + let mut res = Ok(()); - if matches!(trait_item.kind, hir::TraitItemKind::Fn(..)) { + if matches!(tcx.def_kind(def_id), DefKind::AssocFn) { for &assoc_ty_def_id in tcx.associated_types_for_impl_traits_in_associated_fn(def_id) { - res = res.and(check_associated_item( - tcx, - assoc_ty_def_id.expect_local(), - tcx.def_span(assoc_ty_def_id), - None, - )); + res = res.and(check_associated_item(tcx, assoc_ty_def_id.expect_local())); } } res @@ -872,67 +805,54 @@ fn lint_item_shadowing_supertrait_item<'tcx>(tcx: TyCtxt<'tcx>, trait_item_def_i } } -fn check_impl_item<'tcx>( - tcx: TyCtxt<'tcx>, - impl_item: &'tcx hir::ImplItem<'tcx>, -) -> Result<(), ErrorGuaranteed> { - crate::collect::lower_impl_item(tcx, impl_item.impl_item_id()); - - let (method_sig, span) = match impl_item.kind { - hir::ImplItemKind::Fn(ref sig, _) => (Some(sig), impl_item.span), - // Constrain binding and overflow error spans to `<Ty>` in `type foo = <Ty>`. - hir::ImplItemKind::Type(ty) if ty.span != DUMMY_SP => (None, ty.span), - _ => (None, impl_item.span), - }; - check_associated_item(tcx, impl_item.owner_id.def_id, span, method_sig) -} - -fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) -> Result<(), ErrorGuaranteed> { +fn check_param_wf(tcx: TyCtxt<'_>, param: &ty::GenericParamDef) -> Result<(), ErrorGuaranteed> { match param.kind { // We currently only check wf of const params here. - hir::GenericParamKind::Lifetime { .. } | hir::GenericParamKind::Type { .. } => Ok(()), + ty::GenericParamDefKind::Lifetime | ty::GenericParamDefKind::Type { .. } => Ok(()), // Const parameters are well formed if their type is structural match. - hir::GenericParamKind::Const { ty: hir_ty, default: _, synthetic: _ } => { + ty::GenericParamDefKind::Const { .. } => { let ty = tcx.type_of(param.def_id).instantiate_identity(); + let span = tcx.def_span(param.def_id); + let def_id = param.def_id.expect_local(); if tcx.features().unsized_const_params() { - enter_wf_checking_ctxt(tcx, hir_ty.span, tcx.local_parent(param.def_id), |wfcx| { + enter_wf_checking_ctxt(tcx, tcx.local_parent(def_id), |wfcx| { wfcx.register_bound( - ObligationCause::new( - hir_ty.span, - param.def_id, - ObligationCauseCode::ConstParam(ty), - ), + ObligationCause::new(span, def_id, ObligationCauseCode::ConstParam(ty)), wfcx.param_env, ty, - tcx.require_lang_item(LangItem::UnsizedConstParamTy, hir_ty.span), + tcx.require_lang_item(LangItem::UnsizedConstParamTy, span), ); Ok(()) }) } else if tcx.features().adt_const_params() { - enter_wf_checking_ctxt(tcx, hir_ty.span, tcx.local_parent(param.def_id), |wfcx| { + enter_wf_checking_ctxt(tcx, tcx.local_parent(def_id), |wfcx| { wfcx.register_bound( - ObligationCause::new( - hir_ty.span, - param.def_id, - ObligationCauseCode::ConstParam(ty), - ), + ObligationCause::new(span, def_id, ObligationCauseCode::ConstParam(ty)), wfcx.param_env, ty, - tcx.require_lang_item(LangItem::ConstParamTy, hir_ty.span), + tcx.require_lang_item(LangItem::ConstParamTy, span), ); Ok(()) }) } else { + let span = || { + let hir::GenericParamKind::Const { ty: &hir::Ty { span, .. }, .. } = + tcx.hir_node_by_def_id(def_id).expect_generic_param().kind + else { + bug!() + }; + span + }; let mut diag = match ty.kind() { ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Error(_) => return Ok(()), ty::FnPtr(..) => tcx.dcx().struct_span_err( - hir_ty.span, + span(), "using function pointers as const generic parameters is forbidden", ), ty::RawPtr(_, _) => tcx.dcx().struct_span_err( - hir_ty.span, + span(), "using raw pointers as const generic parameters is forbidden", ), _ => { @@ -940,7 +860,7 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) -> Result<(), ty.error_reported()?; tcx.dcx().struct_span_err( - hir_ty.span, + span(), format!( "`{ty}` is forbidden as the type of a const generic parameter", ), @@ -950,7 +870,7 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) -> Result<(), diag.note("the only supported types are integers, `bool`, and `char`"); - let cause = ObligationCause::misc(hir_ty.span, param.def_id); + let cause = ObligationCause::misc(span(), def_id); let adt_const_params_feature_string = " more complex and user defined types".to_string(); let may_suggest_feature = match type_allowed_to_implement_const_param_ty( @@ -1010,15 +930,13 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) -> Result<(), } } -#[instrument(level = "debug", skip(tcx, span, sig_if_method))] -fn check_associated_item( +#[instrument(level = "debug", skip(tcx))] +pub(crate) fn check_associated_item( tcx: TyCtxt<'_>, item_id: LocalDefId, - span: Span, - sig_if_method: Option<&hir::FnSig<'_>>, ) -> Result<(), ErrorGuaranteed> { let loc = Some(WellFormedLoc::Ty(item_id)); - enter_wf_checking_ctxt(tcx, span, item_id, |wfcx| { + enter_wf_checking_ctxt(tcx, item_id, |wfcx| { let item = tcx.associated_item(item_id); // Avoid bogus "type annotations needed `Foo: Bar`" errors on `impl Bar for Foo` in case @@ -1033,6 +951,8 @@ fn check_associated_item( } }; + let span = tcx.def_span(item_id); + match item.kind { ty::AssocKind::Const { .. } => { let ty = tcx.type_of(item.def_id).instantiate_identity(); @@ -1049,14 +969,9 @@ fn check_associated_item( } ty::AssocKind::Fn { .. } => { let sig = tcx.fn_sig(item.def_id).instantiate_identity(); - let hir_sig = sig_if_method.expect("bad signature for method"); - check_fn_or_method( - wfcx, - item.ident(tcx).span, - sig, - hir_sig.decl, - item.def_id.expect_local(), - ); + let hir_sig = + tcx.hir_node_by_def_id(item_id).fn_sig().expect("bad signature for method"); + check_fn_or_method(wfcx, sig, hir_sig.decl, item_id); check_method_receiver(wfcx, hir_sig, item, self_ty) } ty::AssocKind::Type { .. } => { @@ -1083,7 +998,7 @@ fn check_type_defn<'tcx>( let _ = tcx.representability(item.owner_id.def_id); let adt_def = tcx.adt_def(item.owner_id); - enter_wf_checking_ctxt(tcx, item.span, item.owner_id.def_id, |wfcx| { + enter_wf_checking_ctxt(tcx, item.owner_id.def_id, |wfcx| { let variants = adt_def.variants(); let packed = adt_def.repr().packed(); @@ -1185,7 +1100,7 @@ fn check_type_defn<'tcx>( } } - check_where_clauses(wfcx, item.span, item.owner_id.def_id); + check_where_clauses(wfcx, item.owner_id.def_id); Ok(()) }) } @@ -1215,8 +1130,8 @@ fn check_trait(tcx: TyCtxt<'_>, item: &hir::Item<'_>) -> Result<(), ErrorGuarant } } - let res = enter_wf_checking_ctxt(tcx, item.span, def_id, |wfcx| { - check_where_clauses(wfcx, item.span, def_id); + let res = enter_wf_checking_ctxt(tcx, def_id, |wfcx| { + check_where_clauses(wfcx, def_id); Ok(()) }); @@ -1252,72 +1167,63 @@ fn check_associated_type_bounds(wfcx: &WfCheckingCtxt<'_, '_>, item: ty::AssocIt fn check_item_fn( tcx: TyCtxt<'_>, def_id: LocalDefId, - ident: Ident, - span: Span, decl: &hir::FnDecl<'_>, ) -> Result<(), ErrorGuaranteed> { - enter_wf_checking_ctxt(tcx, span, def_id, |wfcx| { + enter_wf_checking_ctxt(tcx, def_id, |wfcx| { let sig = tcx.fn_sig(def_id).instantiate_identity(); - check_fn_or_method(wfcx, ident.span, sig, decl, def_id); + check_fn_or_method(wfcx, sig, decl, def_id); Ok(()) }) } -enum UnsizedHandling { - Forbid, - AllowIfForeignTail, -} - -#[instrument(level = "debug", skip(tcx, ty_span, unsized_handling))] -fn check_static_item( +#[instrument(level = "debug", skip(tcx))] +pub(super) fn check_static_item( tcx: TyCtxt<'_>, item_id: LocalDefId, - ty_span: Span, - unsized_handling: UnsizedHandling, ) -> Result<(), ErrorGuaranteed> { - enter_wf_checking_ctxt(tcx, ty_span, item_id, |wfcx| { + enter_wf_checking_ctxt(tcx, item_id, |wfcx| { let ty = tcx.type_of(item_id).instantiate_identity(); - let item_ty = wfcx.deeply_normalize(ty_span, Some(WellFormedLoc::Ty(item_id)), ty); - - let forbid_unsized = match unsized_handling { - UnsizedHandling::Forbid => true, - UnsizedHandling::AllowIfForeignTail => { - let tail = - tcx.struct_tail_for_codegen(item_ty, wfcx.infcx.typing_env(wfcx.param_env)); - !matches!(tail.kind(), ty::Foreign(_)) - } + let item_ty = wfcx.deeply_normalize(DUMMY_SP, Some(WellFormedLoc::Ty(item_id)), ty); + + let is_foreign_item = tcx.is_foreign_item(item_id); + + let forbid_unsized = !is_foreign_item || { + let tail = tcx.struct_tail_for_codegen(item_ty, wfcx.infcx.typing_env(wfcx.param_env)); + !matches!(tail.kind(), ty::Foreign(_)) }; - wfcx.register_wf_obligation(ty_span, Some(WellFormedLoc::Ty(item_id)), item_ty.into()); + wfcx.register_wf_obligation(DUMMY_SP, Some(WellFormedLoc::Ty(item_id)), item_ty.into()); if forbid_unsized { + let span = tcx.def_span(item_id); wfcx.register_bound( traits::ObligationCause::new( - ty_span, + span, wfcx.body_def_id, ObligationCauseCode::SizedConstOrStatic, ), wfcx.param_env, item_ty, - tcx.require_lang_item(LangItem::Sized, ty_span), + tcx.require_lang_item(LangItem::Sized, span), ); } // Ensure that the end result is `Sync` in a non-thread local `static`. let should_check_for_sync = tcx.static_mutability(item_id.to_def_id()) == Some(hir::Mutability::Not) - && !tcx.is_foreign_item(item_id.to_def_id()) + && !is_foreign_item && !tcx.is_thread_local_static(item_id.to_def_id()); if should_check_for_sync { + let span = tcx.def_span(item_id); wfcx.register_bound( traits::ObligationCause::new( - ty_span, + span, wfcx.body_def_id, ObligationCauseCode::SharedStatic, ), wfcx.param_env, item_ty, - tcx.require_lang_item(LangItem::Sync, ty_span), + tcx.require_lang_item(LangItem::Sync, span), ); } Ok(()) @@ -1328,9 +1234,8 @@ fn check_const_item( tcx: TyCtxt<'_>, def_id: LocalDefId, ty_span: Span, - item_span: Span, ) -> Result<(), ErrorGuaranteed> { - enter_wf_checking_ctxt(tcx, ty_span, def_id, |wfcx| { + enter_wf_checking_ctxt(tcx, def_id, |wfcx| { let ty = tcx.type_of(def_id).instantiate_identity(); let ty = wfcx.deeply_normalize(ty_span, Some(WellFormedLoc::Ty(def_id)), ty); @@ -1346,7 +1251,7 @@ fn check_const_item( tcx.require_lang_item(LangItem::Sized, ty_span), ); - check_where_clauses(wfcx, item_span, def_id); + check_where_clauses(wfcx, def_id); Ok(()) }) @@ -1359,7 +1264,7 @@ fn check_impl<'tcx>( hir_self_ty: &hir::Ty<'_>, hir_trait_ref: &Option<hir::TraitRef<'_>>, ) -> Result<(), ErrorGuaranteed> { - enter_wf_checking_ctxt(tcx, item.span, item.owner_id.def_id, |wfcx| { + enter_wf_checking_ctxt(tcx, item.owner_id.def_id, |wfcx| { match hir_trait_ref { Some(hir_trait_ref) => { // `#[rustc_reservation_impl]` impls are not real impls and @@ -1443,14 +1348,14 @@ fn check_impl<'tcx>( } } - check_where_clauses(wfcx, item.span, item.owner_id.def_id); + check_where_clauses(wfcx, item.owner_id.def_id); Ok(()) }) } /// Checks where-clauses and inline bounds that are declared on `def_id`. #[instrument(level = "debug", skip(wfcx))] -fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id: LocalDefId) { +pub(super) fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, def_id: LocalDefId) { let infcx = wfcx.infcx; let tcx = wfcx.tcx(); @@ -1605,21 +1510,18 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id let predicates = predicates.instantiate_identity(tcx); - let predicates = wfcx.normalize(span, None, predicates); - - debug!(?predicates.predicates); assert_eq!(predicates.predicates.len(), predicates.spans.len()); let wf_obligations = predicates.into_iter().flat_map(|(p, sp)| { + let p = wfcx.normalize(sp, None, p); traits::wf::clause_obligations(infcx, wfcx.param_env, wfcx.body_def_id, p, sp) }); let obligations: Vec<_> = wf_obligations.chain(default_obligations).collect(); wfcx.register_obligations(obligations); } -#[instrument(level = "debug", skip(wfcx, span, hir_decl))] +#[instrument(level = "debug", skip(wfcx, hir_decl))] fn check_fn_or_method<'tcx>( wfcx: &WfCheckingCtxt<'_, 'tcx>, - span: Span, sig: ty::PolyFnSig<'tcx>, hir_decl: &hir::FnDecl<'_>, def_id: LocalDefId, @@ -1657,7 +1559,7 @@ fn check_fn_or_method<'tcx>( ); } - check_where_clauses(wfcx, span, def_id); + check_where_clauses(wfcx, def_id); if sig.abi == ExternAbi::RustCall { let span = tcx.def_span(def_id); @@ -1746,17 +1648,18 @@ fn check_method_receiver<'tcx>( } let span = fn_sig.decl.inputs[0].span; + let loc = Some(WellFormedLoc::Param { function: method.def_id.expect_local(), param_idx: 0 }); let sig = tcx.fn_sig(method.def_id).instantiate_identity(); let sig = tcx.liberate_late_bound_regions(method.def_id, sig); - let sig = wfcx.normalize(span, None, sig); + let sig = wfcx.normalize(DUMMY_SP, loc, sig); debug!("check_method_receiver: sig={:?}", sig); - let self_ty = wfcx.normalize(span, None, self_ty); + let self_ty = wfcx.normalize(DUMMY_SP, loc, self_ty); let receiver_ty = sig.inputs()[0]; - let receiver_ty = wfcx.normalize(span, None, receiver_ty); + let receiver_ty = wfcx.normalize(DUMMY_SP, loc, receiver_ty); // If the receiver already has errors reported, consider it valid to avoid // unnecessary errors (#58712). @@ -2004,27 +1907,23 @@ fn legacy_receiver_is_implemented<'tcx>( } } -fn check_variances_for_type_defn<'tcx>( - tcx: TyCtxt<'tcx>, - item: &'tcx hir::Item<'tcx>, - hir_generics: &hir::Generics<'tcx>, -) { - match item.kind { - ItemKind::Enum(..) | ItemKind::Struct(..) | ItemKind::Union(..) => { +pub(super) fn check_variances_for_type_defn<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) { + match tcx.def_kind(def_id) { + DefKind::Enum | DefKind::Struct | DefKind::Union => { // Ok } - ItemKind::TyAlias(..) => { + DefKind::TyAlias => { assert!( - tcx.type_alias_is_lazy(item.owner_id), + tcx.type_alias_is_lazy(def_id), "should not be computing variance of non-free type alias" ); } - kind => span_bug!(item.span, "cannot compute the variances of {kind:?}"), + kind => span_bug!(tcx.def_span(def_id), "cannot compute the variances of {kind:?}"), } - let ty_predicates = tcx.predicates_of(item.owner_id); + let ty_predicates = tcx.predicates_of(def_id); assert_eq!(ty_predicates.parent, None); - let variances = tcx.variances_of(item.owner_id); + let variances = tcx.variances_of(def_id); let mut constrained_parameters: FxHashSet<_> = variances .iter() @@ -2037,8 +1936,10 @@ fn check_variances_for_type_defn<'tcx>( // Lazily calculated because it is only needed in case of an error. let explicitly_bounded_params = LazyCell::new(|| { - let icx = crate::collect::ItemCtxt::new(tcx, item.owner_id.def_id); - hir_generics + let icx = crate::collect::ItemCtxt::new(tcx, def_id); + tcx.hir_node_by_def_id(def_id) + .generics() + .unwrap() .predicates .iter() .filter_map(|predicate| match predicate.kind { @@ -2053,8 +1954,6 @@ fn check_variances_for_type_defn<'tcx>( .collect::<FxHashSet<_>>() }); - let ty_generics = tcx.generics_of(item.owner_id); - for (index, _) in variances.iter().enumerate() { let parameter = Parameter(index as u32); @@ -2062,9 +1961,13 @@ fn check_variances_for_type_defn<'tcx>( continue; } - let ty_param = &ty_generics.own_params[index]; + let node = tcx.hir_node_by_def_id(def_id); + let item = node.expect_item(); + let hir_generics = node.generics().unwrap(); let hir_param = &hir_generics.params[index]; + let ty_param = &tcx.generics_of(item.owner_id).own_params[index]; + if ty_param.def_id != hir_param.def_id.into() { // Valid programs always have lifetimes before types in the generic parameter list. // ty_generics are normalized to be in this required order, and variances are built @@ -2082,7 +1985,7 @@ fn check_variances_for_type_defn<'tcx>( // Look for `ErrorGuaranteed` deeply within this type. if let ControlFlow::Break(ErrorGuaranteed { .. }) = tcx - .type_of(item.owner_id) + .type_of(def_id) .instantiate_identity() .visit_with(&mut HasErrorDeep { tcx, seen: Default::default() }) { @@ -2301,7 +2204,7 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> { #[instrument(level = "debug", skip(self))] fn check_false_global_bounds(&mut self) { let tcx = self.ocx.infcx.tcx; - let mut span = self.span; + let mut span = tcx.def_span(self.body_def_id); let empty_env = ty::ParamEnv::empty(); let predicates_with_span = tcx.predicates_of(self.body_def_id).predicates.iter().copied(); diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 3ee39fb71b2..b10d5b55789 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -605,159 +605,13 @@ fn get_new_lifetime_name<'tcx>( (1..).flat_map(a_to_z_repeat_n).find(|lt| !existing_lifetimes.contains(lt.as_str())).unwrap() } -#[instrument(level = "debug", skip_all)] -pub(super) fn lower_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) { - let it = tcx.hir_item(item_id); - debug!(item = ?it.kind.ident(), id = %it.hir_id()); - let def_id = item_id.owner_id.def_id; - - match &it.kind { - // These don't define types. - hir::ItemKind::ExternCrate(..) - | hir::ItemKind::Use(..) - | hir::ItemKind::Macro(..) - | hir::ItemKind::Mod(..) - | hir::ItemKind::GlobalAsm { .. } => {} - hir::ItemKind::ForeignMod { items, .. } => { - for item in *items { - let item = tcx.hir_foreign_item(item.id); - tcx.ensure_ok().generics_of(item.owner_id); - tcx.ensure_ok().type_of(item.owner_id); - tcx.ensure_ok().predicates_of(item.owner_id); - if tcx.is_conditionally_const(def_id) { - tcx.ensure_ok().explicit_implied_const_bounds(def_id); - tcx.ensure_ok().const_conditions(def_id); - } - match item.kind { - hir::ForeignItemKind::Fn(..) => { - tcx.ensure_ok().codegen_fn_attrs(item.owner_id); - tcx.ensure_ok().fn_sig(item.owner_id) - } - hir::ForeignItemKind::Static(..) => { - tcx.ensure_ok().codegen_fn_attrs(item.owner_id); - } - _ => (), - } - } - } - hir::ItemKind::Enum(..) => { - tcx.ensure_ok().generics_of(def_id); - tcx.ensure_ok().type_of(def_id); - tcx.ensure_ok().predicates_of(def_id); - lower_enum_variant_types(tcx, def_id.to_def_id()); - } - hir::ItemKind::Impl { .. } => { - tcx.ensure_ok().generics_of(def_id); - tcx.ensure_ok().type_of(def_id); - tcx.ensure_ok().impl_trait_header(def_id); - tcx.ensure_ok().predicates_of(def_id); - tcx.ensure_ok().associated_items(def_id); - } - hir::ItemKind::Trait(..) => { - tcx.ensure_ok().generics_of(def_id); - tcx.ensure_ok().trait_def(def_id); - tcx.at(it.span).explicit_super_predicates_of(def_id); - tcx.ensure_ok().predicates_of(def_id); - tcx.ensure_ok().associated_items(def_id); - } - hir::ItemKind::TraitAlias(..) => { - tcx.ensure_ok().generics_of(def_id); - tcx.at(it.span).explicit_implied_predicates_of(def_id); - tcx.at(it.span).explicit_super_predicates_of(def_id); - tcx.ensure_ok().predicates_of(def_id); - } - hir::ItemKind::Struct(_, _, struct_def) | hir::ItemKind::Union(_, _, struct_def) => { - tcx.ensure_ok().generics_of(def_id); - tcx.ensure_ok().type_of(def_id); - tcx.ensure_ok().predicates_of(def_id); - - for f in struct_def.fields() { - tcx.ensure_ok().generics_of(f.def_id); - tcx.ensure_ok().type_of(f.def_id); - tcx.ensure_ok().predicates_of(f.def_id); - } - - if let Some(ctor_def_id) = struct_def.ctor_def_id() { - lower_variant_ctor(tcx, ctor_def_id); - } - } - - hir::ItemKind::TyAlias(..) => { - tcx.ensure_ok().generics_of(def_id); - tcx.ensure_ok().type_of(def_id); - tcx.ensure_ok().predicates_of(def_id); - } - - hir::ItemKind::Static(..) | hir::ItemKind::Const(..) => { - tcx.ensure_ok().generics_of(def_id); - tcx.ensure_ok().type_of(def_id); - tcx.ensure_ok().predicates_of(def_id); - } - - hir::ItemKind::Fn { .. } => { - tcx.ensure_ok().generics_of(def_id); - tcx.ensure_ok().type_of(def_id); - tcx.ensure_ok().predicates_of(def_id); - tcx.ensure_ok().fn_sig(def_id); - tcx.ensure_ok().codegen_fn_attrs(def_id); - } - } -} - -pub(crate) fn lower_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) { - let trait_item = tcx.hir_trait_item(trait_item_id); - let def_id = trait_item_id.owner_id; - tcx.ensure_ok().generics_of(def_id); - - match trait_item.kind { - hir::TraitItemKind::Fn(..) => { - tcx.ensure_ok().codegen_fn_attrs(def_id); - tcx.ensure_ok().type_of(def_id); - tcx.ensure_ok().fn_sig(def_id); - } - - hir::TraitItemKind::Const(..) => { - tcx.ensure_ok().type_of(def_id); - } - - hir::TraitItemKind::Type(_, Some(_)) => { - tcx.ensure_ok().item_bounds(def_id); - tcx.ensure_ok().item_self_bounds(def_id); - tcx.ensure_ok().type_of(def_id); - } - - hir::TraitItemKind::Type(_, None) => { - tcx.ensure_ok().item_bounds(def_id); - tcx.ensure_ok().item_self_bounds(def_id); - } - }; - - tcx.ensure_ok().predicates_of(def_id); -} - -pub(super) fn lower_impl_item(tcx: TyCtxt<'_>, impl_item_id: hir::ImplItemId) { - let def_id = impl_item_id.owner_id; - tcx.ensure_ok().generics_of(def_id); - tcx.ensure_ok().type_of(def_id); - tcx.ensure_ok().predicates_of(def_id); - let impl_item = tcx.hir_impl_item(impl_item_id); - match impl_item.kind { - hir::ImplItemKind::Fn(..) => { - tcx.ensure_ok().codegen_fn_attrs(def_id); - tcx.ensure_ok().fn_sig(def_id); - } - hir::ImplItemKind::Type(_) => {} - hir::ImplItemKind::Const(..) => {} - } -} - -fn lower_variant_ctor(tcx: TyCtxt<'_>, def_id: LocalDefId) { +pub(super) fn lower_variant_ctor(tcx: TyCtxt<'_>, def_id: LocalDefId) { tcx.ensure_ok().generics_of(def_id); tcx.ensure_ok().type_of(def_id); tcx.ensure_ok().predicates_of(def_id); } -fn lower_enum_variant_types(tcx: TyCtxt<'_>, def_id: DefId) { +pub(super) fn lower_enum_variant_types(tcx: TyCtxt<'_>, def_id: DefId) { let def = tcx.adt_def(def_id); let repr_type = def.repr().discr_type(); let initial = repr_type.initial_discriminant(tcx); diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index 55bf2ab6b50..6b2854d96af 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -2433,7 +2433,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } else { let repr = match repr { TraitObjectSyntax::Dyn | TraitObjectSyntax::None => ty::Dyn, - TraitObjectSyntax::DynStar => ty::DynStar, }; self.lower_trait_object_ty(hir_ty.span, hir_ty.hir_id, bounds, lifetime, repr) } diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index e00c22c47aa..c523a03e012 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -420,7 +420,6 @@ impl<'a> State<'a> { let syntax = lifetime.tag(); match syntax { ast::TraitObjectSyntax::Dyn => self.word_nbsp("dyn"), - ast::TraitObjectSyntax::DynStar => self.word_nbsp("dyn*"), ast::TraitObjectSyntax::None => {} } let mut first = true; diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs index 6f8abc1e67d..3eeb0eac023 100644 --- a/compiler/rustc_hir_typeck/src/cast.rs +++ b/compiler/rustc_hir_typeck/src/cast.rs @@ -143,7 +143,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { | ty::Coroutine(..) | ty::Adt(..) | ty::Never - | ty::Dynamic(_, _, ty::DynStar) | ty::Error(_) => { let guar = self .dcx() @@ -734,14 +733,6 @@ impl<'a, 'tcx> CastCheck<'tcx> { use rustc_middle::ty::cast::CastTy::*; use rustc_middle::ty::cast::IntTy::*; - if self.cast_ty.is_dyn_star() { - // This coercion will fail if the feature is not enabled, OR - // if the coercion is (currently) illegal (e.g. `dyn* Foo + Send` - // to `dyn* Foo`). Report "casting is invalid" rather than - // "non-primitive cast". - return Err(CastError::IllegalCast); - } - let (t_from, t_cast) = match (CastTy::from_ty(self.expr_ty), CastTy::from_ty(self.cast_ty)) { (Some(t_from), Some(t_cast)) => (t_from, t_cast), diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index 57d3c5da873..3ca04ba330b 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -231,9 +231,6 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { ty::Ref(r_b, _, mutbl_b) => { return self.coerce_borrowed_pointer(a, b, r_b, mutbl_b); } - ty::Dynamic(predicates, region, ty::DynStar) if self.tcx.features().dyn_star() => { - return self.coerce_dyn_star(a, b, predicates, region); - } ty::Adt(pin, _) if self.tcx.features().pin_ergonomics() && self.tcx.is_lang_item(pin.did(), hir::LangItem::Pin) => @@ -773,71 +770,6 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { Ok(coercion) } - fn coerce_dyn_star( - &self, - a: Ty<'tcx>, - b: Ty<'tcx>, - predicates: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>, - b_region: ty::Region<'tcx>, - ) -> CoerceResult<'tcx> { - if !self.tcx.features().dyn_star() { - return Err(TypeError::Mismatch); - } - - // FIXME(dyn_star): We should probably allow things like casting from - // `dyn* Foo + Send` to `dyn* Foo`. - if let ty::Dynamic(a_data, _, ty::DynStar) = a.kind() - && let ty::Dynamic(b_data, _, ty::DynStar) = b.kind() - && a_data.principal_def_id() == b_data.principal_def_id() - { - return self.unify(a, b); - } - - // Check the obligations of the cast -- for example, when casting - // `usize` to `dyn* Clone + 'static`: - let obligations = predicates - .iter() - .map(|predicate| { - // For each existential predicate (e.g., `?Self: Clone`) instantiate - // the type of the expression (e.g., `usize` in our example above) - // and then require that the resulting predicate (e.g., `usize: Clone`) - // holds (it does). - let predicate = predicate.with_self_ty(self.tcx, a); - Obligation::new(self.tcx, self.cause.clone(), self.param_env, predicate) - }) - .chain([ - // Enforce the region bound (e.g., `usize: 'static`, in our example). - Obligation::new( - self.tcx, - self.cause.clone(), - self.param_env, - ty::Binder::dummy(ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives( - ty::OutlivesPredicate(a, b_region), - ))), - ), - // Enforce that the type is `usize`/pointer-sized. - Obligation::new( - self.tcx, - self.cause.clone(), - self.param_env, - ty::TraitRef::new( - self.tcx, - self.tcx.require_lang_item(hir::LangItem::PointerLike, self.cause.span), - [a], - ), - ), - ]) - .collect(); - - Ok(InferOk { - value: ( - vec![Adjustment { kind: Adjust::Pointer(PointerCoercion::DynStar), target: b }], - b, - ), - obligations, - }) - } - /// Applies reborrowing for `Pin` /// /// We currently only support reborrowing `Pin<&mut T>` as `Pin<&mut T>`. This is accomplished diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 9f39908c3b2..33e97766a02 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -1336,6 +1336,7 @@ impl BasicBlock { /// /// See [`BasicBlock`] for documentation on what basic blocks are at a high level. #[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable)] +#[non_exhaustive] pub struct BasicBlockData<'tcx> { /// List of statements in this block. pub statements: Vec<Statement<'tcx>>, diff --git a/compiler/rustc_middle/src/mir/statement.rs b/compiler/rustc_middle/src/mir/statement.rs index d16477adb77..683d7b48617 100644 --- a/compiler/rustc_middle/src/mir/statement.rs +++ b/compiler/rustc_middle/src/mir/statement.rs @@ -11,6 +11,7 @@ use crate::ty::CoroutineArgsExt; /// A statement in a basic block, including information about its source code. #[derive(Clone, TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable)] +#[non_exhaustive] pub struct Statement<'tcx> { pub source_info: SourceInfo, pub kind: StatementKind<'tcx>, diff --git a/compiler/rustc_middle/src/ty/adjustment.rs b/compiler/rustc_middle/src/ty/adjustment.rs index 3bacdfe5ac8..74573455f53 100644 --- a/compiler/rustc_middle/src/ty/adjustment.rs +++ b/compiler/rustc_middle/src/ty/adjustment.rs @@ -36,9 +36,6 @@ pub enum PointerCoercion { /// type. Codegen backends and miri figure out what has to be done /// based on the precise source/target type at hand. Unsize, - - /// Go from a pointer-like type to a `dyn*` object. - DynStar, } /// Represents coercing a value to a different type of value. diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index 90b832df281..09379d9d805 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -946,21 +946,6 @@ where } } - ty::Dynamic(_, _, ty::DynStar) => { - if i == 0 { - TyMaybeWithLayout::Ty(Ty::new_mut_ptr(tcx, tcx.types.unit)) - } else if i == 1 { - // FIXME(dyn-star) same FIXME as above applies here too - TyMaybeWithLayout::Ty(Ty::new_imm_ref( - tcx, - tcx.lifetimes.re_static, - Ty::new_array(tcx, tcx.types.usize, 3), - )) - } else { - bug!("no field {i} on dyn*") - } - } - ty::Alias(..) | ty::Bound(..) | ty::Placeholder(..) diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index bee490b3648..b4c4f48a0a6 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -810,7 +810,6 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { } match repr { ty::Dyn => p!("dyn "), - ty::DynStar => p!("dyn* "), } p!(print(data)); if print_r { diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 3971ac13bbe..399a6d6ebc5 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -1322,11 +1322,6 @@ impl<'tcx> Ty<'tcx> { } #[inline] - pub fn is_dyn_star(self) -> bool { - matches!(self.kind(), Dynamic(_, _, ty::DynStar)) - } - - #[inline] pub fn is_enum(self) -> bool { matches!(self.kind(), Adt(adt_def, _) if adt_def.is_enum()) } @@ -1629,8 +1624,6 @@ impl<'tcx> Ty<'tcx> { | ty::Error(_) // Extern types have metadata = (). | ty::Foreign(..) - // `dyn*` has metadata = (). - | ty::Dynamic(_, _, ty::DynStar) // If returned by `struct_tail_raw` this is a unit struct // without any fields, or not a struct, and therefore is Sized. | ty::Adt(..) @@ -1820,8 +1813,7 @@ impl<'tcx> Ty<'tcx> { | ty::Closure(..) | ty::CoroutineClosure(..) | ty::Never - | ty::Error(_) - | ty::Dynamic(_, _, ty::DynStar) => true, + | ty::Error(_) => true, ty::Str | ty::Slice(_) | ty::Dynamic(_, _, ty::Dyn) => match sizedness { SizedTraitKind::Sized => false, diff --git a/compiler/rustc_mir_transform/src/check_enums.rs b/compiler/rustc_mir_transform/src/check_enums.rs index e06e0c6122e..240da87ab27 100644 --- a/compiler/rustc_mir_transform/src/check_enums.rs +++ b/compiler/rustc_mir_transform/src/check_enums.rs @@ -230,11 +230,11 @@ fn split_block( let block_data = &mut basic_blocks[location.block]; // Drain every statement after this one and move the current terminator to a new basic block. - let new_block = BasicBlockData { - statements: block_data.statements.split_off(location.statement_index), - terminator: block_data.terminator.take(), - is_cleanup: block_data.is_cleanup, - }; + let new_block = BasicBlockData::new_stmts( + block_data.statements.split_off(location.statement_index), + block_data.terminator.take(), + block_data.is_cleanup, + ); basic_blocks.push(new_block) } @@ -270,10 +270,9 @@ fn insert_discr_cast_to_u128<'tcx>( let mu_array = local_decls.push(LocalDecl::with_source_info(mu_array_ty, source_info)).into(); let rvalue = Rvalue::Cast(CastKind::Transmute, source_op, mu_array_ty); - block_data.statements.push(Statement { - source_info, - kind: StatementKind::Assign(Box::new((mu_array, rvalue))), - }); + block_data + .statements + .push(Statement::new(source_info, StatementKind::Assign(Box::new((mu_array, rvalue))))); // Index into the array of MaybeUninit to get something that is actually // as wide as the discriminant. @@ -294,10 +293,10 @@ fn insert_discr_cast_to_u128<'tcx>( let op_as_int = local_decls.push(LocalDecl::with_source_info(operand_int_ty, source_info)).into(); let rvalue = Rvalue::Cast(CastKind::Transmute, source_op, operand_int_ty); - block_data.statements.push(Statement { + block_data.statements.push(Statement::new( source_info, - kind: StatementKind::Assign(Box::new((op_as_int, rvalue))), - }); + StatementKind::Assign(Box::new((op_as_int, rvalue))), + )); (CastKind::IntToInt, Operand::Copy(op_as_int)) }; @@ -306,10 +305,10 @@ fn insert_discr_cast_to_u128<'tcx>( let rvalue = Rvalue::Cast(cast_kind, discr_ty_bits, discr.ty); let discr_in_discr_ty = local_decls.push(LocalDecl::with_source_info(discr.ty, source_info)).into(); - block_data.statements.push(Statement { + block_data.statements.push(Statement::new( source_info, - kind: StatementKind::Assign(Box::new((discr_in_discr_ty, rvalue))), - }); + StatementKind::Assign(Box::new((discr_in_discr_ty, rvalue))), + )); // Cast the discriminant to a u128 (base for comparisions of enum discriminants). let const_u128 = Ty::new_uint(tcx, ty::UintTy::U128); @@ -317,7 +316,7 @@ fn insert_discr_cast_to_u128<'tcx>( let discr = local_decls.push(LocalDecl::with_source_info(const_u128, source_info)).into(); block_data .statements - .push(Statement { source_info, kind: StatementKind::Assign(Box::new((discr, rvalue))) }); + .push(Statement::new(source_info, StatementKind::Assign(Box::new((discr, rvalue))))); discr } @@ -390,9 +389,9 @@ fn insert_uninhabited_enum_check<'tcx>( ) { let is_ok: Place<'_> = local_decls.push(LocalDecl::with_source_info(tcx.types.bool, source_info)).into(); - block_data.statements.push(Statement { + block_data.statements.push(Statement::new( source_info, - kind: StatementKind::Assign(Box::new(( + StatementKind::Assign(Box::new(( is_ok, Rvalue::Use(Operand::Constant(Box::new(ConstOperand { span: source_info.span, @@ -400,7 +399,7 @@ fn insert_uninhabited_enum_check<'tcx>( const_: Const::Val(ConstValue::from_bool(false), tcx.types.bool), }))), ))), - }); + )); block_data.terminator = Some(Terminator { source_info, @@ -463,19 +462,19 @@ fn insert_niche_check<'tcx>( let discr_diff: Place<'_> = local_decls.push(LocalDecl::with_source_info(tcx.types.u128, source_info)).into(); - block_data.statements.push(Statement { + block_data.statements.push(Statement::new( source_info, - kind: StatementKind::Assign(Box::new(( + StatementKind::Assign(Box::new(( discr_diff, Rvalue::BinaryOp(BinOp::Sub, Box::new((Operand::Copy(discr), start_const))), ))), - }); + )); let is_ok: Place<'_> = local_decls.push(LocalDecl::with_source_info(tcx.types.bool, source_info)).into(); - block_data.statements.push(Statement { + block_data.statements.push(Statement::new( source_info, - kind: StatementKind::Assign(Box::new(( + StatementKind::Assign(Box::new(( is_ok, Rvalue::BinaryOp( // This is a `WrappingRange`, so make sure to get the wrapping right. @@ -483,7 +482,7 @@ fn insert_niche_check<'tcx>( Box::new((Operand::Copy(discr_diff), end_start_diff_const)), ), ))), - }); + )); block_data.terminator = Some(Terminator { source_info, diff --git a/compiler/rustc_mir_transform/src/mentioned_items.rs b/compiler/rustc_mir_transform/src/mentioned_items.rs index 9fd8d81d64a..f011d394f61 100644 --- a/compiler/rustc_mir_transform/src/mentioned_items.rs +++ b/compiler/rustc_mir_transform/src/mentioned_items.rs @@ -74,8 +74,7 @@ impl<'tcx> Visitor<'tcx> for MentionedItemsVisitor<'_, 'tcx> { match *rvalue { // We need to detect unsizing casts that required vtables. mir::Rvalue::Cast( - mir::CastKind::PointerCoercion(PointerCoercion::Unsize, _) - | mir::CastKind::PointerCoercion(PointerCoercion::DynStar, _), + mir::CastKind::PointerCoercion(PointerCoercion::Unsize, _), ref operand, target_ty, ) => { diff --git a/compiler/rustc_mir_transform/src/validate.rs b/compiler/rustc_mir_transform/src/validate.rs index 7dcdd7999f2..cbb9bbfd12f 100644 --- a/compiler/rustc_mir_transform/src/validate.rs +++ b/compiler/rustc_mir_transform/src/validate.rs @@ -1260,9 +1260,6 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { self.fail(location, format!("Unsize coercion, but `{op_ty}` isn't coercible to `{target_type}`")); } } - CastKind::PointerCoercion(PointerCoercion::DynStar, _) => { - // FIXME(dyn-star): make sure nothing needs to be done here. - } CastKind::IntToInt | CastKind::IntToFloat => { let input_valid = op_ty.is_integral() || op_ty.is_char() || op_ty.is_bool(); let target_valid = target_type.is_numeric() || target_type.is_char(); diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 798f4da9b3b..91e371d697d 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -694,8 +694,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirUsedCollector<'a, 'tcx> { // have to instantiate all methods of the trait being cast to, so we // can build the appropriate vtable. mir::Rvalue::Cast( - mir::CastKind::PointerCoercion(PointerCoercion::Unsize, _) - | mir::CastKind::PointerCoercion(PointerCoercion::DynStar, _), + mir::CastKind::PointerCoercion(PointerCoercion::Unsize, _), ref operand, target_ty, ) => { @@ -710,9 +709,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirUsedCollector<'a, 'tcx> { // This could also be a different Unsize instruction, like // from a fixed sized array to a slice. But we are only // interested in things that produce a vtable. - if (target_ty.is_trait() && !source_ty.is_trait()) - || (target_ty.is_dyn_star() && !source_ty.is_dyn_star()) - { + if target_ty.is_trait() && !source_ty.is_trait() { create_mono_items_for_vtable_methods( self.tcx, target_ty, @@ -1109,14 +1106,6 @@ fn find_tails_for_unsizing<'tcx>( find_tails_for_unsizing(tcx, source_field, target_field) } - // `T` as `dyn* Trait` unsizes *directly*. - // - // FIXME(dyn_star): This case is a bit awkward, b/c we're not really computing - // a tail here. We probably should handle this separately in the *caller* of - // this function, rather than returning something that is semantically different - // than what we return above. - (_, &ty::Dynamic(_, _, ty::DynStar)) => (source_ty, target_ty), - _ => bug!( "find_vtable_types_for_unsizing: invalid coercion {:?} -> {:?}", source_ty, @@ -1344,9 +1333,7 @@ fn visit_mentioned_item<'tcx>( // This could also be a different Unsize instruction, like // from a fixed sized array to a slice. But we are only // interested in things that produce a vtable. - if (target_ty.is_trait() && !source_ty.is_trait()) - || (target_ty.is_dyn_star() && !source_ty.is_dyn_star()) - { + if target_ty.is_trait() && !source_ty.is_trait() { create_mono_items_for_vtable_methods(tcx, target_ty, source_ty, span, output); } } diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs index 73bb1508de9..c0bebdf6fb6 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs @@ -135,7 +135,6 @@ where | ty::Closure(..) | ty::CoroutineClosure(..) | ty::Never - | ty::Dynamic(_, _, ty::DynStar) | ty::Error(_) => Ok(ty::Binder::dummy(vec![])), // impl {Meta,}Sized for str, [T], dyn Trait diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs index edb354b4a84..1e0a90eb2ee 100644 --- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs @@ -657,8 +657,7 @@ where | ty::Coroutine(..) | ty::CoroutineWitness(..) | ty::Never - | ty::Foreign(..) - | ty::Dynamic(_, _, ty::DynStar) => Ty::new_unit(cx), + | ty::Foreign(..) => Ty::new_unit(cx), ty::Error(e) => Ty::new_error(cx, e), diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index d874a071cee..8221c709027 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -796,16 +796,10 @@ impl<'a> Parser<'a> { /// /// Note that this does *not* parse bare trait objects. fn parse_dyn_ty(&mut self, impl_dyn_multi: &mut bool) -> PResult<'a, TyKind> { - let lo = self.token.span; self.bump(); // `dyn` - // parse dyn* types - let syntax = if self.eat(exp!(Star)) { - self.psess.gated_spans.gate(sym::dyn_star, lo.to(self.prev_token.span)); - TraitObjectSyntax::DynStar - } else { - TraitObjectSyntax::Dyn - }; + // We used to parse `*` for `dyn*` here. + let syntax = TraitObjectSyntax::Dyn; // Always parse bounds greedily for better error recovery. let bounds = self.parse_generic_bounds()?; diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs index 8b1d864c995..6c2c571d240 100644 --- a/compiler/rustc_parse/src/validate_attr.rs +++ b/compiler/rustc_parse/src/validate_attr.rs @@ -303,6 +303,11 @@ fn emit_malformed_attribute( | sym::must_use | sym::track_caller | sym::link_name + | sym::export_name + | sym::rustc_macro_transparency + | sym::link_section + | sym::rustc_layout_scalar_valid_range_start + | sym::rustc_layout_scalar_valid_range_end ) { return; } diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 4bc48cb6aca..1b965b9545c 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -164,7 +164,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } Attribute::Parsed(AttributeKind::Repr(_)) => { /* handled below this loop and elsewhere */ } - + Attribute::Parsed(AttributeKind::RustcObjectLifetimeDefault) => { + self.check_object_lifetime_default(hir_id); + } &Attribute::Parsed(AttributeKind::PubTransparent(attr_span)) => { self.check_rustc_pub_transparent(attr_span, span, attrs) } @@ -303,7 +305,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { [sym::no_implicit_prelude, ..] => { self.check_generic_attr(hir_id, attr, target, Target::Mod) } - [sym::rustc_object_lifetime_default, ..] => self.check_object_lifetime_default(hir_id), [sym::proc_macro, ..] => { self.check_proc_macro(hir_id, target, ProcMacroKind::FunctionLike) } @@ -2831,7 +2832,7 @@ fn check_invalid_crate_level_attr(tcx: TyCtxt<'_>, attrs: &[Attribute]) { .find(|item| !item.span.is_dummy()) // Skip prelude `use`s .map(|item| errors::ItemFollowingInnerAttr { span: if let Some(ident) = item.kind.ident() { ident.span } else { item.span }, - kind: item.kind.descr(), + kind: tcx.def_descr(item.owner_id.to_def_id()), }); let err = tcx.dcx().create_err(errors::InvalidAttrAtCrateLevel { span, diff --git a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs index 9d1d3412f8d..f4a14b36ce5 100644 --- a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs +++ b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs @@ -631,7 +631,6 @@ pub(crate) fn encode_ty<'tcx>( // vendor extended type. let mut s = String::from(match kind { ty::Dyn => "u3dynI", - ty::DynStar => "u7dynstarI", }); s.push_str(&encode_predicates(tcx, predicates, dict, options)); s.push_str(&encode_region(*region, dict)); diff --git a/compiler/rustc_smir/src/rustc_internal/internal.rs b/compiler/rustc_smir/src/rustc_internal/internal.rs index 24351eee1c4..f878b6e6b71 100644 --- a/compiler/rustc_smir/src/rustc_internal/internal.rs +++ b/compiler/rustc_smir/src/rustc_internal/internal.rs @@ -369,7 +369,6 @@ impl RustcInternal for DynKind { fn internal<'tcx>(&self, _tables: &mut Tables<'_>, _tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { match self { DynKind::Dyn => rustc_ty::DynKind::Dyn, - DynKind::DynStar => rustc_ty::DynKind::DynStar, } } } diff --git a/compiler/rustc_smir/src/rustc_smir/convert/mir.rs b/compiler/rustc_smir/src/rustc_smir/convert/mir.rs index 85e71ed2c25..daea4acc36c 100644 --- a/compiler/rustc_smir/src/rustc_smir/convert/mir.rs +++ b/compiler/rustc_smir/src/rustc_smir/convert/mir.rs @@ -301,11 +301,9 @@ impl<'tcx> Stable<'tcx> for mir::CastKind { type T = stable_mir::mir::CastKind; fn stable(&self, tables: &mut Tables<'_>) -> Self::T { use rustc_middle::mir::CastKind::*; - use rustc_middle::ty::adjustment::PointerCoercion; match self { PointerExposeProvenance => stable_mir::mir::CastKind::PointerExposeAddress, PointerWithExposedProvenance => stable_mir::mir::CastKind::PointerWithExposedProvenance, - PointerCoercion(PointerCoercion::DynStar, _) => stable_mir::mir::CastKind::DynStar, PointerCoercion(c, _) => stable_mir::mir::CastKind::PointerCoercion(c.stable(tables)), IntToInt => stable_mir::mir::CastKind::IntToInt, FloatToInt => stable_mir::mir::CastKind::FloatToInt, diff --git a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs index 7abec488151..ff0b8e833dc 100644 --- a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs +++ b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs @@ -43,7 +43,6 @@ impl<'tcx> Stable<'tcx> for ty::DynKind { fn stable(&self, _: &mut Tables<'_>) -> Self::T { match self { ty::Dyn => stable_mir::ty::DynKind::Dyn, - ty::DynStar => stable_mir::ty::DynKind::DynStar, } } } @@ -120,7 +119,6 @@ impl<'tcx> Stable<'tcx> for ty::adjustment::PointerCoercion { } PointerCoercion::ArrayToPointer => stable_mir::mir::PointerCoercion::ArrayToPointer, PointerCoercion::Unsize => stable_mir::mir::PointerCoercion::Unsize, - PointerCoercion::DynStar => unreachable!("represented as `CastKind::DynStar` in smir"), } } } diff --git a/compiler/rustc_smir/src/stable_mir/mir/body.rs b/compiler/rustc_smir/src/stable_mir/mir/body.rs index e4b7659ce7f..90d4a06b177 100644 --- a/compiler/rustc_smir/src/stable_mir/mir/body.rs +++ b/compiler/rustc_smir/src/stable_mir/mir/body.rs @@ -1025,8 +1025,6 @@ pub enum CastKind { PointerExposeAddress, PointerWithExposedProvenance, PointerCoercion(PointerCoercion), - // FIXME(smir-rename): change this to PointerCoercion(DynStar) - DynStar, IntToInt, FloatToInt, FloatToFloat, diff --git a/compiler/rustc_smir/src/stable_mir/ty.rs b/compiler/rustc_smir/src/stable_mir/ty.rs index 7f6237e7062..4ea2bb04c5d 100644 --- a/compiler/rustc_smir/src/stable_mir/ty.rs +++ b/compiler/rustc_smir/src/stable_mir/ty.rs @@ -1205,7 +1205,6 @@ pub enum BoundRegionKind { #[derive(Clone, Debug, Eq, PartialEq, Serialize)] pub enum DynKind { Dyn, - DynStar, } #[derive(Clone, Debug, Eq, PartialEq, Serialize)] diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index 1db8ad72b32..fe0f8e6113e 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -576,8 +576,6 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> { ty::Dynamic(predicates, r, kind) => { self.push(match kind { ty::Dyn => "D", - // FIXME(dyn-star): need to update v0 mangling docs - ty::DynStar => "D*", }); self.print_dyn_existential(predicates)?; r.print(self)?; diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs index 0a4a9144c94..aea42df4dfd 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs @@ -353,26 +353,6 @@ impl<T> Trait<T> for X { )); } } - (ty::Dynamic(t, _, ty::DynKind::DynStar), _) - if let Some(def_id) = t.principal_def_id() => - { - let mut has_matching_impl = false; - tcx.for_each_relevant_impl(def_id, values.found, |did| { - if DeepRejectCtxt::relate_rigid_infer(tcx) - .types_may_unify(values.found, tcx.type_of(did).skip_binder()) - { - has_matching_impl = true; - } - }); - if has_matching_impl { - let trait_name = tcx.item_name(def_id); - diag.help(format!( - "`{}` implements `{trait_name}`, `#[feature(dyn_star)]` is likely \ - not enabled; that feature it is currently incomplete", - values.found, - )); - } - } (_, ty::Alias(ty::Opaque, opaque_ty)) | (ty::Alias(ty::Opaque, opaque_ty), _) => { if opaque_ty.def_id.is_local() diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index 02edf482795..c72eff1d231 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs @@ -1186,7 +1186,12 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { ty: Ty<'tcx>, obligation: &PredicateObligation<'tcx>, ) -> Diag<'a> { - let span = obligation.cause.span; + let param = obligation.cause.body_id; + let hir::GenericParamKind::Const { ty: &hir::Ty { span, .. }, .. } = + self.tcx.hir_node_by_def_id(param).expect_generic_param().kind + else { + bug!() + }; let mut diag = match ty.kind() { ty::Float(_) => { diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 316b4dfc15f..af3641c22ed 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -2129,7 +2129,6 @@ impl<'tcx> SelectionContext<'_, 'tcx> { | ty::Closure(..) | ty::CoroutineClosure(..) | ty::Never - | ty::Dynamic(_, _, ty::DynStar) | ty::Error(_) => { // safe for everything Where(ty::Binder::dummy(Vec::new())) diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index d5222822461..a225b712d4b 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -449,14 +449,6 @@ fn layout_of_uncached<'tcx>( tcx.mk_layout(LayoutData::scalar_pair(cx, data_ptr, metadata)) } - ty::Dynamic(_, _, ty::DynStar) => { - let mut data = scalar_unit(Pointer(AddressSpace::DATA)); - data.valid_range_mut().start = 0; - let mut vtable = scalar_unit(Pointer(AddressSpace::DATA)); - vtable.valid_range_mut().start = 1; - tcx.mk_layout(LayoutData::scalar_pair(cx, data, vtable)) - } - // Arrays and slices. ty::Array(element, count) => { let count = extract_const_value(cx, ty, count)? diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index 553f5e0e1b5..f8d793464a9 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -38,8 +38,7 @@ fn sizedness_constraint_for_ty<'tcx>( | ty::CoroutineClosure(..) | ty::Coroutine(..) | ty::CoroutineWitness(..) - | ty::Never - | ty::Dynamic(_, _, ty::DynStar) => None, + | ty::Never => None, ty::Str | ty::Slice(..) | ty::Dynamic(_, _, ty::Dyn) => match sizedness { // Never `Sized` @@ -383,8 +382,7 @@ fn impl_self_is_guaranteed_unsized<'tcx>(tcx: TyCtxt<'tcx>, impl_def_id: DefId) | ty::Bound(_, _) | ty::Placeholder(_) | ty::Infer(_) - | ty::Error(_) - | ty::Dynamic(_, _, ty::DynStar) => false, + | ty::Error(_) => false, } } diff --git a/compiler/rustc_type_ir/src/inherent.rs b/compiler/rustc_type_ir/src/inherent.rs index 272fca5b026..2754d40fd36 100644 --- a/compiler/rustc_type_ir/src/inherent.rs +++ b/compiler/rustc_type_ir/src/inherent.rs @@ -183,8 +183,7 @@ pub trait Ty<I: Interner<Ty = Self>>: | ty::Bound(_, _) | ty::Placeholder(_) | ty::Infer(_) - | ty::Error(_) - | ty::Dynamic(_, _, ty::DynStar) => false, + | ty::Error(_) => false, } } } diff --git a/compiler/rustc_type_ir/src/ty_kind.rs b/compiler/rustc_type_ir/src/ty_kind.rs index 9669772d1a6..db6fbefcf05 100644 --- a/compiler/rustc_type_ir/src/ty_kind.rs +++ b/compiler/rustc_type_ir/src/ty_kind.rs @@ -20,6 +20,9 @@ use crate::{self as ty, DebruijnIndex, Interner}; mod closure; /// Specifies how a trait object is represented. +/// +/// This used to have a variant `DynStar`, but that variant has been removed, +/// and it's likely this whole enum will be removed soon. #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] #[cfg_attr( feature = "nightly", @@ -28,13 +31,6 @@ mod closure; pub enum DynKind { /// An unsized `dyn Trait` object Dyn, - /// A sized `dyn* Trait` object - /// - /// These objects are represented as a `(data, vtable)` pair where `data` is a value of some - /// ptr-sized and ptr-aligned dynamically determined type `T` and `vtable` is a pointer to the - /// vtable of `impl T for Trait`. This allows a `dyn*` object to be treated agnostically with - /// respect to whether it points to a `Box<T>`, `Rc<T>`, etc. - DynStar, } #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] @@ -371,7 +367,6 @@ impl<I: Interner> fmt::Debug for TyKind<I> { UnsafeBinder(binder) => write!(f, "{:?}", binder), Dynamic(p, r, repr) => match repr { DynKind::Dyn => write!(f, "dyn {p:?} + {r:?}"), - DynKind::DynStar => write!(f, "dyn* {p:?} + {r:?}"), }, Closure(d, s) => f.debug_tuple("Closure").field(d).field(&s).finish(), CoroutineClosure(d, s) => f.debug_tuple("CoroutineClosure").field(d).field(&s).finish(), |
