diff options
Diffstat (limited to 'compiler')
49 files changed, 381 insertions, 235 deletions
diff --git a/compiler/rustc_ast/Cargo.toml b/compiler/rustc_ast/Cargo.toml index d33f9666b48..34c612dac69 100644 --- a/compiler/rustc_ast/Cargo.toml +++ b/compiler/rustc_ast/Cargo.toml @@ -4,10 +4,9 @@ version = "0.0.0" edition = "2021" [dependencies] -# FIXME: bumping memchr to 2.7.1 causes linker errors in MSVC thin-lto # tidy-alphabetical-start bitflags = "2.4.1" -memchr = "=2.5.0" +memchr = "2.7.4" rustc_ast_ir = { path = "../rustc_ast_ir" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_index = { path = "../rustc_index" } diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs index dcc4cf2478f..762ebc47ca9 100644 --- a/compiler/rustc_attr/src/builtin.rs +++ b/compiler/rustc_attr/src/builtin.rs @@ -153,7 +153,7 @@ pub enum StabilityLevel { } /// Rust release in which a feature is stabilized. -#[derive(Encodable, Decodable, PartialEq, Copy, Clone, Debug, Eq, Hash)] +#[derive(Encodable, Decodable, PartialEq, Copy, Clone, Debug, Eq, PartialOrd, Ord, Hash)] #[derive(HashStable_Generic)] pub enum StableSince { Version(RustcVersion), diff --git a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs index 7077d78f459..31a5d451ff6 100644 --- a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs +++ b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs @@ -333,7 +333,11 @@ impl<'tcx> BorrowExplanation<'tcx> { } } - if let ConstraintCategory::Cast { unsize_to: Some(unsize_ty) } = category { + if let ConstraintCategory::Cast { + is_implicit_coercion: true, + unsize_to: Some(unsize_ty), + } = category + { self.add_object_lifetime_default_note(tcx, err, unsize_ty); } self.add_lifetime_bound_suggestion_to_diagnostic(err, &category, span, region_name); @@ -740,7 +744,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> { // If we see an unsized cast, then if it is our data we should check // whether it is being cast to a trait object. Rvalue::Cast( - CastKind::PointerCoercion(PointerCoercion::Unsize), + CastKind::PointerCoercion(PointerCoercion::Unsize, _), operand, ty, ) => { diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index ca0a3c66130..39175b406a4 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -47,7 +47,8 @@ impl<'tcx> ConstraintDescription for ConstraintCategory<'tcx> { ConstraintCategory::Yield => "yielding this value ", ConstraintCategory::UseAsConst => "using this value as a constant ", ConstraintCategory::UseAsStatic => "using this value as a static ", - ConstraintCategory::Cast { .. } => "cast ", + ConstraintCategory::Cast { is_implicit_coercion: false, .. } => "cast ", + ConstraintCategory::Cast { is_implicit_coercion: true, .. } => "coercion ", ConstraintCategory::CallArgument(_) => "argument ", ConstraintCategory::TypeAnnotation => "type annotation ", ConstraintCategory::ClosureBounds => "closure body ", diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 4056b423548..16e51e82f85 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -1975,8 +1975,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { Rvalue::Cast(cast_kind, op, ty) => { self.check_operand(op, location); - match cast_kind { - CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer) => { + match *cast_kind { + CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer, coercion_source) => { + let is_implicit_coercion = coercion_source == CoercionSource::Implicit; let src_sig = op.ty(body, tcx).fn_sig(tcx); // HACK: This shouldn't be necessary... We can remove this when we actually @@ -2007,7 +2008,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { self.prove_predicate( ty::ClauseKind::WellFormed(src_ty.into()), location.to_locations(), - ConstraintCategory::Cast { unsize_to: None }, + ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None }, ); let src_ty = self.normalize(src_ty, location); @@ -2015,7 +2016,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { src_ty, *ty, location.to_locations(), - ConstraintCategory::Cast { unsize_to: None }, + ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None }, ) { span_mirbug!( self, @@ -2036,7 +2037,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { self.prove_predicate( ty::ClauseKind::WellFormed(src_ty.into()), location.to_locations(), - ConstraintCategory::Cast { unsize_to: None }, + ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None }, ); // The type that we see in the fcx is like @@ -2049,7 +2050,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { src_ty, *ty, location.to_locations(), - ConstraintCategory::Cast { unsize_to: None }, + ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None }, ) { span_mirbug!( self, @@ -2062,19 +2063,23 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } } - CastKind::PointerCoercion(PointerCoercion::ClosureFnPointer(safety)) => { + CastKind::PointerCoercion( + PointerCoercion::ClosureFnPointer(safety), + coercion_source, + ) => { let sig = match op.ty(body, tcx).kind() { ty::Closure(_, args) => args.as_closure().sig(), _ => bug!(), }; let ty_fn_ptr_from = - Ty::new_fn_ptr(tcx, tcx.signature_unclosure(sig, *safety)); + Ty::new_fn_ptr(tcx, tcx.signature_unclosure(sig, safety)); + let is_implicit_coercion = coercion_source == CoercionSource::Implicit; if let Err(terr) = self.sub_types( ty_fn_ptr_from, *ty, location.to_locations(), - ConstraintCategory::Cast { unsize_to: None }, + ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None }, ) { span_mirbug!( self, @@ -2087,7 +2092,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } } - CastKind::PointerCoercion(PointerCoercion::UnsafeFnPointer) => { + CastKind::PointerCoercion( + PointerCoercion::UnsafeFnPointer, + coercion_source, + ) => { let fn_sig = op.ty(body, tcx).fn_sig(tcx); // The type that we see in the fcx is like @@ -2099,11 +2107,12 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { let ty_fn_ptr_from = tcx.safe_to_unsafe_fn_ty(fn_sig); + let is_implicit_coercion = coercion_source == CoercionSource::Implicit; if let Err(terr) = self.sub_types( ty_fn_ptr_from, *ty, location.to_locations(), - ConstraintCategory::Cast { unsize_to: None }, + ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None }, ) { span_mirbug!( self, @@ -2116,7 +2125,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } } - CastKind::PointerCoercion(PointerCoercion::Unsize) => { + CastKind::PointerCoercion(PointerCoercion::Unsize, coercion_source) => { let &ty = ty; let trait_ref = ty::TraitRef::new( tcx, @@ -2124,22 +2133,21 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { [op.ty(body, tcx), ty], ); + let is_implicit_coercion = coercion_source == CoercionSource::Implicit; + let unsize_to = tcx.fold_regions(ty, |r, _| { + if let ty::ReVar(_) = r.kind() { tcx.lifetimes.re_erased } else { r } + }); self.prove_trait_ref( trait_ref, location.to_locations(), ConstraintCategory::Cast { - unsize_to: Some(tcx.fold_regions(ty, |r, _| { - if let ty::ReVar(_) = r.kind() { - tcx.lifetimes.re_erased - } else { - r - } - })), + is_implicit_coercion, + unsize_to: Some(unsize_to), }, ); } - CastKind::DynStar => { + 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 @@ -2150,12 +2158,13 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { let self_ty = op.ty(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 { unsize_to: None }, + ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None }, ); let outlives_predicate = tcx.mk_predicate(Binder::dummy( @@ -2166,11 +2175,14 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { self.prove_predicate( outlives_predicate, location.to_locations(), - ConstraintCategory::Cast { unsize_to: None }, + ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None }, ); } - CastKind::PointerCoercion(PointerCoercion::MutToConstPointer) => { + CastKind::PointerCoercion( + PointerCoercion::MutToConstPointer, + coercion_source, + ) => { let ty::RawPtr(ty_from, hir::Mutability::Mut) = op.ty(body, tcx).kind() else { span_mirbug!(self, rvalue, "unexpected base type for cast {:?}", ty,); @@ -2180,11 +2192,12 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { span_mirbug!(self, rvalue, "unexpected target type for cast {:?}", ty,); return; }; + let is_implicit_coercion = coercion_source == CoercionSource::Implicit; if let Err(terr) = self.sub_types( *ty_from, *ty_to, location.to_locations(), - ConstraintCategory::Cast { unsize_to: None }, + ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None }, ) { span_mirbug!( self, @@ -2197,7 +2210,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } } - CastKind::PointerCoercion(PointerCoercion::ArrayToPointer) => { + CastKind::PointerCoercion(PointerCoercion::ArrayToPointer, coercion_source) => { let ty_from = op.ty(body, tcx); let opt_ty_elem_mut = match ty_from.kind() { @@ -2242,11 +2255,12 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { return; } + let is_implicit_coercion = coercion_source == CoercionSource::Implicit; if let Err(terr) = self.sub_types( *ty_elem, *ty_to, location.to_locations(), - ConstraintCategory::Cast { unsize_to: None }, + ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None }, ) { span_mirbug!( self, @@ -2427,7 +2441,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { src_obj, dst_obj, location.to_locations(), - ConstraintCategory::Cast { unsize_to: None }, + ConstraintCategory::Cast { + is_implicit_coercion: false, + unsize_to: None, + }, ) .unwrap(); } diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs index dc342e151f3..1ce0aacab49 100644 --- a/compiler/rustc_codegen_cranelift/src/base.rs +++ b/compiler/rustc_codegen_cranelift/src/base.rs @@ -652,7 +652,7 @@ fn codegen_stmt<'tcx>( lval.write_cvalue(fx, res); } Rvalue::Cast( - CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer), + CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer, _), ref operand, to_ty, ) => { @@ -677,7 +677,7 @@ fn codegen_stmt<'tcx>( } } Rvalue::Cast( - CastKind::PointerCoercion(PointerCoercion::UnsafeFnPointer), + CastKind::PointerCoercion(PointerCoercion::UnsafeFnPointer, _), ref operand, to_ty, ) => { @@ -688,6 +688,7 @@ fn codegen_stmt<'tcx>( Rvalue::Cast( CastKind::PointerCoercion( PointerCoercion::MutToConstPointer | PointerCoercion::ArrayToPointer, + _, ), .., ) => { @@ -741,7 +742,7 @@ fn codegen_stmt<'tcx>( } } Rvalue::Cast( - CastKind::PointerCoercion(PointerCoercion::ClosureFnPointer(_)), + CastKind::PointerCoercion(PointerCoercion::ClosureFnPointer(_), _), ref operand, _to_ty, ) => { @@ -763,14 +764,18 @@ fn codegen_stmt<'tcx>( } } Rvalue::Cast( - CastKind::PointerCoercion(PointerCoercion::Unsize), + CastKind::PointerCoercion(PointerCoercion::Unsize, _), ref operand, _to_ty, ) => { let operand = codegen_operand(fx, operand); crate::unsize::coerce_unsized_into(fx, operand, lval); } - Rvalue::Cast(CastKind::DynStar, ref operand, _) => { + Rvalue::Cast( + CastKind::PointerCoercion(PointerCoercion::DynStar, _), + ref operand, + _, + ) => { let operand = codegen_operand(fx, operand); crate::unsize::coerce_dyn_star(fx, operand, lval); } diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index ad0e03fc263..f9c0f3ce941 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -34,7 +34,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } mir::Rvalue::Cast( - mir::CastKind::PointerCoercion(PointerCoercion::Unsize), + mir::CastKind::PointerCoercion(PointerCoercion::Unsize, _), ref source, _, ) => { @@ -465,7 +465,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let lladdr = bx.ptrtoint(llptr, llcast_ty); OperandValue::Immediate(lladdr) } - mir::CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer) => { + mir::CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer, _) => { match *operand.layout.ty.kind() { ty::FnDef(def_id, args) => { let instance = ty::Instance::resolve_for_fn_ptr( @@ -481,7 +481,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { _ => bug!("{} cannot be reified to a fn ptr", operand.layout.ty), } } - mir::CastKind::PointerCoercion(PointerCoercion::ClosureFnPointer(_)) => { + mir::CastKind::PointerCoercion(PointerCoercion::ClosureFnPointer(_), _) => { match *operand.layout.ty.kind() { ty::Closure(def_id, args) => { let instance = Instance::resolve_closure( @@ -496,11 +496,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { _ => bug!("{} cannot be cast to a fn ptr", operand.layout.ty), } } - mir::CastKind::PointerCoercion(PointerCoercion::UnsafeFnPointer) => { + mir::CastKind::PointerCoercion(PointerCoercion::UnsafeFnPointer, _) => { // This is a no-op at the LLVM level. operand.val } - mir::CastKind::PointerCoercion(PointerCoercion::Unsize) => { + mir::CastKind::PointerCoercion(PointerCoercion::Unsize, _) => { assert!(bx.cx().is_backend_scalar_pair(cast)); let (lldata, llextra) = operand.val.pointer_parts(); let (lldata, llextra) = @@ -508,7 +508,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { OperandValue::Pair(lldata, llextra) } mir::CastKind::PointerCoercion( - PointerCoercion::MutToConstPointer | PointerCoercion::ArrayToPointer, + PointerCoercion::MutToConstPointer | PointerCoercion::ArrayToPointer, _ ) => { bug!("{kind:?} is for borrowck, and should never appear in codegen"); } @@ -526,7 +526,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { bug!("unexpected non-pair operand"); } } - mir::CastKind::DynStar => { + 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); diff --git a/compiler/rustc_const_eval/src/check_consts/check.rs b/compiler/rustc_const_eval/src/check_consts/check.rs index 2c33ff9d219..e1b60597997 100644 --- a/compiler/rustc_const_eval/src/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/check_consts/check.rs @@ -440,6 +440,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { | PointerCoercion::UnsafeFnPointer | PointerCoercion::ClosureFnPointer(_) | PointerCoercion::ReifyFnPointer, + _, ), _, _, @@ -447,8 +448,12 @@ 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), _, _) => { - // Unsizing is implemented for CTFE. + Rvalue::Cast( + CastKind::PointerCoercion(PointerCoercion::Unsize | PointerCoercion::DynStar, _), + _, + _, + ) => { + // Unsizing and `dyn*` coercions are implemented for CTFE. } Rvalue::Cast(CastKind::PointerExposeProvenance, _, _) => { @@ -458,10 +463,6 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { // Since no pointer can ever get exposed (rejected above), this is easy to support. } - Rvalue::Cast(CastKind::DynStar, _, _) => { - // `dyn*` coercion is implemented for CTFE. - } - Rvalue::Cast(_, _, _) => {} Rvalue::NullaryOp( diff --git a/compiler/rustc_const_eval/src/interpret/cast.rs b/compiler/rustc_const_eval/src/interpret/cast.rs index 70d074cfdc5..85e7d91c2ad 100644 --- a/compiler/rustc_const_eval/src/interpret/cast.rs +++ b/compiler/rustc_const_eval/src/interpret/cast.rs @@ -32,7 +32,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { if cast_ty == dest.layout.ty { dest.layout } else { self.layout_of(cast_ty)? }; // FIXME: In which cases should we trigger UB when the source is uninit? match cast_kind { - CastKind::PointerCoercion(PointerCoercion::Unsize) => { + CastKind::PointerCoercion(PointerCoercion::Unsize, _) => { self.unsize_into(src, cast_layout, dest)?; } @@ -68,11 +68,12 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { CastKind::PointerCoercion( PointerCoercion::MutToConstPointer | PointerCoercion::ArrayToPointer, + _, ) => { bug!("{cast_kind:?} casts are for borrowck only, not runtime MIR"); } - CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer) => { + CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer, _) => { // All reifications must be monomorphic, bail out otherwise. ensure_monomorphic_enough(*self.tcx, src.layout.ty)?; @@ -94,7 +95,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { } } - CastKind::PointerCoercion(PointerCoercion::UnsafeFnPointer) => { + CastKind::PointerCoercion(PointerCoercion::UnsafeFnPointer, _) => { let src = self.read_immediate(src)?; match cast_ty.kind() { ty::FnPtr(..) => { @@ -105,7 +106,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { } } - CastKind::PointerCoercion(PointerCoercion::ClosureFnPointer(_)) => { + CastKind::PointerCoercion(PointerCoercion::ClosureFnPointer(_), _) => { // All reifications must be monomorphic, bail out otherwise. ensure_monomorphic_enough(*self.tcx, src.layout.ty)?; @@ -125,7 +126,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { } } - CastKind::DynStar => { + 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)?; diff --git a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs index c07d8009aa5..dfb3c088afb 100644 --- a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs +++ b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs @@ -22,36 +22,38 @@ use crate::errors; pub(crate) fn crate_inherent_impls( tcx: TyCtxt<'_>, (): (), -) -> Result<&'_ CrateInherentImpls, ErrorGuaranteed> { +) -> (&'_ CrateInherentImpls, Result<(), ErrorGuaranteed>) { let mut collect = InherentCollect { tcx, impls_map: Default::default() }; + let mut res = Ok(()); for id in tcx.hir().items() { res = res.and(collect.check_item(id)); } - res?; - Ok(tcx.arena.alloc(collect.impls_map)) + + (tcx.arena.alloc(collect.impls_map), res) } -pub(crate) fn crate_incoherent_impls( +pub(crate) fn crate_inherent_impls_validity_check( tcx: TyCtxt<'_>, - simp: SimplifiedType, -) -> Result<&[DefId], ErrorGuaranteed> { - let crate_map = tcx.crate_inherent_impls(())?; - Ok(tcx.arena.alloc_from_iter( + (): (), +) -> Result<(), ErrorGuaranteed> { + tcx.crate_inherent_impls(()).1 +} + +pub(crate) fn crate_incoherent_impls(tcx: TyCtxt<'_>, simp: SimplifiedType) -> &[DefId] { + let (crate_map, _) = tcx.crate_inherent_impls(()); + tcx.arena.alloc_from_iter( crate_map.incoherent_impls.get(&simp).unwrap_or(&Vec::new()).iter().map(|d| d.to_def_id()), - )) + ) } /// On-demand query: yields a vector of the inherent impls for a specific type. -pub(crate) fn inherent_impls( - tcx: TyCtxt<'_>, - ty_def_id: LocalDefId, -) -> Result<&[DefId], ErrorGuaranteed> { - let crate_map = tcx.crate_inherent_impls(())?; - Ok(match crate_map.inherent_impls.get(&ty_def_id) { +pub(crate) fn inherent_impls(tcx: TyCtxt<'_>, ty_def_id: LocalDefId) -> &[DefId] { + let (crate_map, _) = tcx.crate_inherent_impls(()); + match crate_map.inherent_impls.get(&ty_def_id) { Some(v) => &v[..], None => &[], - }) + } } struct InherentCollect<'tcx> { diff --git a/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs b/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs index 43b9093ecac..b8066b4b47d 100644 --- a/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs +++ b/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs @@ -177,8 +177,7 @@ impl<'tcx> InherentOverlapChecker<'tcx> { return Ok(()); } - let impls = self.tcx.inherent_impls(id.owner_id)?; - + let impls = self.tcx.inherent_impls(id.owner_id); let overlap_mode = OverlapMode::get(self.tcx, id.owner_id.to_def_id()); let impls_items = impls diff --git a/compiler/rustc_hir_analysis/src/coherence/mod.rs b/compiler/rustc_hir_analysis/src/coherence/mod.rs index 185f3176f07..b25406583f6 100644 --- a/compiler/rustc_hir_analysis/src/coherence/mod.rs +++ b/compiler/rustc_hir_analysis/src/coherence/mod.rs @@ -124,7 +124,10 @@ fn enforce_empty_impls_for_marker_traits( pub(crate) fn provide(providers: &mut Providers) { use self::builtin::coerce_unsized_info; - use self::inherent_impls::{crate_incoherent_impls, crate_inherent_impls, inherent_impls}; + use self::inherent_impls::{ + crate_incoherent_impls, crate_inherent_impls, crate_inherent_impls_validity_check, + inherent_impls, + }; use self::inherent_impls_overlap::crate_inherent_impls_overlap_check; use self::orphan::orphan_check_impl; @@ -133,6 +136,7 @@ pub(crate) fn provide(providers: &mut Providers) { crate_inherent_impls, crate_incoherent_impls, inherent_impls, + crate_inherent_impls_validity_check, crate_inherent_impls_overlap_check, coerce_unsized_info, orphan_check_impl, diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs index 5e3203e8473..5775a8867b1 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs @@ -1028,7 +1028,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { .. }) = node && let Some(ty_def_id) = qself_ty.ty_def_id() - && let Ok([inherent_impl]) = tcx.inherent_impls(ty_def_id) + && let [inherent_impl] = tcx.inherent_impls(ty_def_id) && let name = format!("{ident2}_{ident3}") && let Some(ty::AssocItem { kind: ty::AssocKind::Fn, .. }) = tcx .associated_items(inherent_impl) 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 e95b5142559..d7d4a98e63f 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -1272,7 +1272,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } let candidates: Vec<_> = tcx - .inherent_impls(adt_did)? + .inherent_impls(adt_did) .iter() .filter_map(|&impl_| { let (item, scope) = diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index 1dc85c4903e..92d85d48a42 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -170,7 +170,7 @@ pub fn check_crate(tcx: TyCtxt<'_>) { let _ = tcx.ensure().coherent_trait(trait_def_id); } // these queries are executed for side-effects (error reporting): - let _ = tcx.ensure().crate_inherent_impls(()); + let _ = tcx.ensure().crate_inherent_impls_validity_check(()); let _ = tcx.ensure().crate_inherent_impls_overlap_check(()); }); diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs index aab0c4c116a..fcd2940b83a 100644 --- a/compiler/rustc_hir_typeck/src/cast.rs +++ b/compiler/rustc_hir_typeck/src/cast.rs @@ -32,13 +32,14 @@ use rustc_data_structures::fx::FxHashSet; use rustc_errors::codes::*; use rustc_errors::{Applicability, Diag, ErrorGuaranteed}; use rustc_hir::{self as hir, ExprKind}; +use rustc_infer::infer::DefineOpaqueTypes; use rustc_macros::{TypeFoldable, TypeVisitable}; -use rustc_middle::bug; use rustc_middle::mir::Mutability; use rustc_middle::ty::adjustment::AllowTwoPhase; use rustc_middle::ty::cast::{CastKind, CastTy}; use rustc_middle::ty::error::TypeError; use rustc_middle::ty::{self, Ty, TyCtxt, TypeAndMut, TypeVisitableExt, VariantDef}; +use rustc_middle::{bug, span_bug}; use rustc_session::lint; use rustc_span::def_id::LOCAL_CRATE; use rustc_span::symbol::sym; @@ -152,12 +153,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } #[derive(Copy, Clone, Debug)] -pub enum CastError { +enum CastError<'tcx> { ErrorGuaranteed(ErrorGuaranteed), CastToBool, CastToChar, - DifferingKinds, + DifferingKinds { + src_kind: PointerKind<'tcx>, + dst_kind: PointerKind<'tcx>, + }, /// Cast of thin to fat raw ptr (e.g., `*const () as *const [u8]`). SizedUnsizedCast, IllegalCast, @@ -177,7 +181,7 @@ pub enum CastError { ForeignNonExhaustiveAdt, } -impl From<ErrorGuaranteed> for CastError { +impl From<ErrorGuaranteed> for CastError<'_> { fn from(err: ErrorGuaranteed) -> Self { CastError::ErrorGuaranteed(err) } @@ -251,7 +255,7 @@ impl<'a, 'tcx> CastCheck<'tcx> { } } - fn report_cast_error(&self, fcx: &FnCtxt<'a, 'tcx>, e: CastError) { + fn report_cast_error(&self, fcx: &FnCtxt<'a, 'tcx>, e: CastError<'tcx>) { match e { CastError::ErrorGuaranteed(_) => { // an error has already been reported @@ -303,10 +307,52 @@ impl<'a, 'tcx> CastCheck<'tcx> { CastError::IllegalCast => { make_invalid_casting_error(self.span, self.expr_ty, self.cast_ty, fcx).emit(); } - CastError::DifferingKinds => { - make_invalid_casting_error(self.span, self.expr_ty, self.cast_ty, fcx) - .with_note("vtable kinds may not match") - .emit(); + CastError::DifferingKinds { src_kind, dst_kind } => { + let mut err = + make_invalid_casting_error(self.span, self.expr_ty, self.cast_ty, fcx); + + match (src_kind, dst_kind) { + (PointerKind::VTable(_), PointerKind::VTable(_)) => { + err.note("the trait objects may have different vtables"); + } + ( + PointerKind::OfParam(_) | PointerKind::OfAlias(_), + PointerKind::OfParam(_) + | PointerKind::OfAlias(_) + | PointerKind::VTable(_) + | PointerKind::Length, + ) + | ( + PointerKind::VTable(_) | PointerKind::Length, + PointerKind::OfParam(_) | PointerKind::OfAlias(_), + ) => { + err.note("the pointers may have different metadata"); + } + (PointerKind::VTable(_), PointerKind::Length) + | (PointerKind::Length, PointerKind::VTable(_)) => { + err.note("the pointers have different metadata"); + } + ( + PointerKind::Thin, + PointerKind::Thin + | PointerKind::VTable(_) + | PointerKind::Length + | PointerKind::OfParam(_) + | PointerKind::OfAlias(_), + ) + | ( + PointerKind::VTable(_) + | PointerKind::Length + | PointerKind::OfParam(_) + | PointerKind::OfAlias(_), + PointerKind::Thin, + ) + | (PointerKind::Length, PointerKind::Length) => { + span_bug!(self.span, "unexpected cast error: {e:?}") + } + } + + err.emit(); } CastError::CastToBool => { let expr_ty = fcx.resolve_vars_if_possible(self.expr_ty); @@ -670,10 +716,20 @@ impl<'a, 'tcx> CastCheck<'tcx> { /// Checks a cast, and report an error if one exists. In some cases, this /// can return Ok and create type errors in the fcx rather than returning /// directly. coercion-cast is handled in check instead of here. - fn do_check(&self, fcx: &FnCtxt<'a, 'tcx>) -> Result<CastKind, CastError> { + fn do_check(&self, fcx: &FnCtxt<'a, 'tcx>) -> Result<CastKind, CastError<'tcx>> { use rustc_middle::ty::cast::CastTy::*; use rustc_middle::ty::cast::IntTy::*; + if self.cast_ty.is_dyn_star() { + if fcx.tcx.features().dyn_star { + span_bug!(self.span, "should be handled by `coerce`"); + } else { + // Report "casting is invalid" rather than "non-primitive cast" + // if the feature is not enabled. + 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), @@ -780,16 +836,6 @@ impl<'a, 'tcx> CastCheck<'tcx> { (Int(Char) | Int(Bool), Int(_)) => Ok(CastKind::PrimIntCast), (Int(_) | Float, Int(_) | Float) => Ok(CastKind::NumericCast), - - (_, DynStar) => { - if fcx.tcx.features().dyn_star { - bug!("should be handled by `coerce`") - } else { - Err(CastError::IllegalCast) - } - } - - (DynStar, _) => Err(CastError::IllegalCast), } } @@ -798,27 +844,34 @@ impl<'a, 'tcx> CastCheck<'tcx> { fcx: &FnCtxt<'a, 'tcx>, m_src: ty::TypeAndMut<'tcx>, m_dst: ty::TypeAndMut<'tcx>, - ) -> Result<CastKind, CastError> { + ) -> Result<CastKind, CastError<'tcx>> { debug!("check_ptr_ptr_cast m_src={m_src:?} m_dst={m_dst:?}"); - // ptr-ptr cast. vtables must match. + // ptr-ptr cast. metadata must match. let src_kind = fcx.tcx.erase_regions(fcx.pointer_kind(m_src.ty, self.span)?); let dst_kind = fcx.tcx.erase_regions(fcx.pointer_kind(m_dst.ty, self.span)?); - match (src_kind, dst_kind) { - // We can't cast if target pointer kind is unknown - (_, None) => Err(CastError::UnknownCastPtrKind), - // Cast to thin pointer is OK - (_, Some(PointerKind::Thin)) => Ok(CastKind::PtrPtrCast), + // We can't cast if target pointer kind is unknown + let Some(dst_kind) = dst_kind else { + return Err(CastError::UnknownCastPtrKind); + }; + + // Cast to thin pointer is OK + if dst_kind == PointerKind::Thin { + return Ok(CastKind::PtrPtrCast); + } - // We can't cast to fat pointer if source pointer kind is unknown - (None, _) => Err(CastError::UnknownExprPtrKind), + // We can't cast to fat pointer if source pointer kind is unknown + let Some(src_kind) = src_kind else { + return Err(CastError::UnknownCastPtrKind); + }; + match (src_kind, dst_kind) { // thin -> fat? report invalid cast (don't complain about vtable kinds) - (Some(PointerKind::Thin), _) => Err(CastError::SizedUnsizedCast), + (PointerKind::Thin, _) => Err(CastError::SizedUnsizedCast), // trait object -> trait object? need to do additional checks - (Some(PointerKind::VTable(src_tty)), Some(PointerKind::VTable(dst_tty))) => { + (PointerKind::VTable(src_tty), PointerKind::VTable(dst_tty)) => { match (src_tty.principal(), dst_tty.principal()) { // A<dyn Src<...> + SrcAuto> -> B<dyn Dst<...> + DstAuto>. need to make sure // - `Src` and `Dst` traits are the same @@ -834,7 +887,7 @@ impl<'a, 'tcx> CastCheck<'tcx> { // Note that trait upcasting goes through a different mechanism (`coerce_unsized`) // and is unaffected by this check. if src_principal.def_id() != dst_principal.def_id() { - return Err(CastError::DifferingKinds); + return Err(CastError::DifferingKinds { src_kind, dst_kind }); } // We need to reconstruct trait object types. @@ -860,7 +913,16 @@ impl<'a, 'tcx> CastCheck<'tcx> { )); // `dyn Src = dyn Dst`, this checks for matching traits/generics - fcx.demand_eqtype(self.span, src_obj, dst_obj); + // This is `demand_eqtype`, but inlined to give a better error. + let cause = fcx.misc(self.span); + if fcx + .at(&cause, fcx.param_env) + .eq(DefineOpaqueTypes::Yes, src_obj, dst_obj) + .map(|infer_ok| fcx.register_infer_ok_obligations(infer_ok)) + .is_err() + { + return Err(CastError::DifferingKinds { src_kind, dst_kind }); + } // Check that `SrcAuto` (+auto traits implied by `Src`) is a superset of `DstAuto`. // Emit an FCW otherwise. @@ -905,17 +967,17 @@ impl<'a, 'tcx> CastCheck<'tcx> { // dyn Trait -> dyn Auto? should be ok, but we used to not allow it. // FIXME: allow this - (Some(_), None) => Err(CastError::DifferingKinds), + (Some(_), None) => Err(CastError::DifferingKinds { src_kind, dst_kind }), // dyn Auto -> dyn Trait? not ok. - (None, Some(_)) => Err(CastError::DifferingKinds), + (None, Some(_)) => Err(CastError::DifferingKinds { src_kind, dst_kind }), } } // fat -> fat? metadata kinds must match - (Some(src_kind), Some(dst_kind)) if src_kind == dst_kind => Ok(CastKind::PtrPtrCast), + (src_kind, dst_kind) if src_kind == dst_kind => Ok(CastKind::PtrPtrCast), - (_, _) => Err(CastError::DifferingKinds), + (_, _) => Err(CastError::DifferingKinds { src_kind, dst_kind }), } } @@ -923,7 +985,7 @@ impl<'a, 'tcx> CastCheck<'tcx> { &self, fcx: &FnCtxt<'a, 'tcx>, m_cast: ty::TypeAndMut<'tcx>, - ) -> Result<CastKind, CastError> { + ) -> Result<CastKind, CastError<'tcx>> { // fptr-ptr cast. must be to thin ptr match fcx.pointer_kind(m_cast.ty, self.span)? { @@ -937,7 +999,7 @@ impl<'a, 'tcx> CastCheck<'tcx> { &self, fcx: &FnCtxt<'a, 'tcx>, m_expr: ty::TypeAndMut<'tcx>, - ) -> Result<CastKind, CastError> { + ) -> Result<CastKind, CastError<'tcx>> { // ptr-addr cast. must be from thin ptr match fcx.pointer_kind(m_expr.ty, self.span)? { @@ -952,7 +1014,7 @@ impl<'a, 'tcx> CastCheck<'tcx> { fcx: &FnCtxt<'a, 'tcx>, m_expr: ty::TypeAndMut<'tcx>, m_cast: ty::TypeAndMut<'tcx>, - ) -> Result<CastKind, CastError> { + ) -> Result<CastKind, CastError<'tcx>> { // array-ptr-cast: allow mut-to-mut, mut-to-const, const-to-const if m_expr.mutbl >= m_cast.mutbl { if let ty::Array(ety, _) = m_expr.ty.kind() { @@ -987,7 +1049,7 @@ impl<'a, 'tcx> CastCheck<'tcx> { &self, fcx: &FnCtxt<'a, 'tcx>, m_cast: TypeAndMut<'tcx>, - ) -> Result<CastKind, CastError> { + ) -> Result<CastKind, CastError<'tcx>> { // ptr-addr cast. pointer must be thin. match fcx.pointer_kind(m_cast.ty, self.span)? { None => Err(CastError::UnknownCastPtrKind), diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index 7be91d78e19..b08c5bc6d9a 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -769,7 +769,10 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { )); Ok(InferOk { - value: (vec![Adjustment { kind: Adjust::DynStar, target: b }], b), + value: ( + vec![Adjustment { kind: Adjust::Pointer(PointerCoercion::DynStar), target: b }], + b, + ), obligations, }) } diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 015a7283250..b34ed4640db 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -2126,7 +2126,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .tcx .inherent_impls(def_id) .into_iter() - .flatten() .flat_map(|i| self.tcx.associated_items(i).in_definition_order()) // Only assoc fn with no receivers. .filter(|item| { diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs index 29feed56290..bb5f3511373 100644 --- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs @@ -759,9 +759,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx for adjustment in adjustments { debug!("walk_adjustment expr={:?} adj={:?}", expr, adjustment); match adjustment.kind { - adjustment::Adjust::NeverToAny - | adjustment::Adjust::Pointer(_) - | adjustment::Adjust::DynStar => { + adjustment::Adjust::NeverToAny | adjustment::Adjust::Pointer(_) => { // Creating a closure/fn-pointer or unsizing consumes // the input and stores it into the resulting rvalue. self.consume_or_copy(&place_with_id, place_with_id.hir_id); @@ -1296,8 +1294,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx adjustment::Adjust::NeverToAny | adjustment::Adjust::Pointer(_) | adjustment::Adjust::Borrow(_) - | adjustment::Adjust::ReborrowPin(..) - | adjustment::Adjust::DynStar => { + | adjustment::Adjust::ReborrowPin(..) => { // Result is an rvalue. Ok(self.cat_rvalue(expr.hir_id, target)) } diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index 3828b40b885..1a8afcf003d 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -728,13 +728,13 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { let Some(simp) = simplify_type(self.tcx, self_ty, TreatParams::InstantiateWithInfer) else { bug!("unexpected incoherent type: {:?}", self_ty) }; - for &impl_def_id in self.tcx.incoherent_impls(simp).into_iter().flatten() { + for &impl_def_id in self.tcx.incoherent_impls(simp).into_iter() { self.assemble_inherent_impl_probe(impl_def_id); } } fn assemble_inherent_impl_candidates_for_type(&mut self, def_id: DefId) { - let impl_def_ids = self.tcx.at(self.span).inherent_impls(def_id).into_iter().flatten(); + let impl_def_ids = self.tcx.at(self.span).inherent_impls(def_id).into_iter(); for &impl_def_id in impl_def_ids { self.assemble_inherent_impl_probe(impl_def_id); } diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index feb47209f5e..e03be4f43f7 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -680,7 +680,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.tcx .inherent_impls(adt_def.did()) .into_iter() - .flatten() .any(|def_id| self.associated_value(*def_id, item_name).is_some()) } else { false @@ -1438,7 +1437,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .tcx .inherent_impls(adt.did()) .into_iter() - .flatten() .copied() .filter(|def_id| { if let Some(assoc) = self.associated_value(*def_id, item_name) { @@ -1900,7 +1898,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { call_args: Option<Vec<Ty<'tcx>>>, ) -> Option<Symbol> { if let ty::Adt(adt, adt_args) = rcvr_ty.kind() { - for inherent_impl_did in self.tcx.inherent_impls(adt.did()).into_iter().flatten() { + for inherent_impl_did in self.tcx.inherent_impls(adt.did()).into_iter() { for inherent_method in self.tcx.associated_items(inherent_impl_did).in_definition_order() { @@ -2114,9 +2112,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let ty::Adt(adt_def, _) = rcvr_ty.kind() else { return; }; - // FIXME(oli-obk): try out bubbling this error up one level and cancelling the other error in that case. - let Ok(impls) = self.tcx.inherent_impls(adt_def.did()) else { return }; - let mut items = impls + let mut items = self + .tcx + .inherent_impls(adt_def.did()) .iter() .flat_map(|i| self.tcx.associated_items(i).in_definition_order()) // Only assoc fn with no receivers and only if @@ -2495,7 +2493,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .and_then(|simp| { tcx.incoherent_impls(simp) .into_iter() - .flatten() .find_map(|&id| self.associated_value(id, item_name)) }) .is_some() diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index 53d2089296d..69707fdbe8f 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -347,7 +347,7 @@ provide! { tcx, def_id, other, cdata, tcx.arena.alloc_from_iter(cdata.get_associated_item_or_field_def_ids(def_id.index)) } associated_item => { cdata.get_associated_item(def_id.index, tcx.sess) } - inherent_impls => { Ok(cdata.get_inherent_implementations_for_type(tcx, def_id.index)) } + inherent_impls => { cdata.get_inherent_implementations_for_type(tcx, def_id.index) } item_attrs => { tcx.arena.alloc_from_iter(cdata.get_item_attrs(def_id.index, tcx.sess)) } is_mir_available => { cdata.is_item_mir_available(def_id.index) } is_ctfe_mir_available => { cdata.is_ctfe_mir_available(def_id.index) } @@ -393,7 +393,7 @@ provide! { tcx, def_id, other, cdata, traits => { tcx.arena.alloc_from_iter(cdata.get_traits()) } trait_impls_in_crate => { tcx.arena.alloc_from_iter(cdata.get_trait_impls()) } implementations_of_trait => { cdata.get_implementations_of_trait(tcx, other) } - crate_incoherent_impls => { Ok(cdata.get_incoherent_impls(tcx, other)) } + crate_incoherent_impls => { cdata.get_incoherent_impls(tcx, other) } dep_kind => { cdata.dep_kind } module_children => { diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 891f1793441..5f756672b04 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1540,7 +1540,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { } } - for (def_id, impls) in &tcx.crate_inherent_impls(()).unwrap().inherent_impls { + for (def_id, impls) in &tcx.crate_inherent_impls(()).0.inherent_impls { record_defaulted_array!(self.tables.inherent_impls[def_id.to_def_id()] <- impls.iter().map(|def_id| { assert!(def_id.is_local()); def_id.index @@ -2089,7 +2089,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let all_impls: Vec<_> = tcx .crate_inherent_impls(()) - .unwrap() + .0 .incoherent_impls .iter() .map(|(&simp, impls)| IncoherentImpls { diff --git a/compiler/rustc_middle/src/mir/query.rs b/compiler/rustc_middle/src/mir/query.rs index 1002f64f849..70331214ac5 100644 --- a/compiler/rustc_middle/src/mir/query.rs +++ b/compiler/rustc_middle/src/mir/query.rs @@ -234,7 +234,9 @@ pub enum ConstraintCategory<'tcx> { UseAsStatic, TypeAnnotation, Cast { - /// Whether this is an unsizing cast and if yes, this contains the target type. + /// Whether this cast is a coercion that was automatically inserted by the compiler. + is_implicit_coercion: bool, + /// Whether this is an unsizing coercion and if yes, this contains the target type. /// Region variables are erased to ReErased. #[derive_where(skip)] unsize_to: Option<Ty<'tcx>>, diff --git a/compiler/rustc_middle/src/mir/statement.rs b/compiler/rustc_middle/src/mir/statement.rs index bc7dfa6205e..88ed90c3114 100644 --- a/compiler/rustc_middle/src/mir/statement.rs +++ b/compiler/rustc_middle/src/mir/statement.rs @@ -432,9 +432,8 @@ impl<'tcx> Rvalue<'tcx> { | CastKind::IntToFloat | CastKind::FnPtrToPtr | CastKind::PtrToPtr - | CastKind::PointerCoercion(_) + | CastKind::PointerCoercion(_, _) | CastKind::PointerWithExposedProvenance - | CastKind::DynStar | CastKind::Transmute, _, _, diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs index 231eb198983..ae75f2d4187 100644 --- a/compiler/rustc_middle/src/mir/syntax.rs +++ b/compiler/rustc_middle/src/mir/syntax.rs @@ -579,7 +579,8 @@ pub struct CopyNonOverlapping<'tcx> { pub count: Operand<'tcx>, } -/// Represents how a `TerminatorKind::Call` was constructed, used for diagnostics +/// Represents how a [`TerminatorKind::Call`] was constructed. +/// Used only for diagnostics. #[derive(Clone, Copy, TyEncodable, TyDecodable, Debug, PartialEq, Hash, HashStable)] #[derive(TypeFoldable, TypeVisitable)] pub enum CallSource { @@ -1403,9 +1404,7 @@ pub enum CastKind { /// * [`PointerCoercion::MutToConstPointer`] /// /// Both are runtime nops, so should be [`CastKind::PtrToPtr`] instead in runtime MIR. - PointerCoercion(PointerCoercion), - /// Cast into a dyn* object. - DynStar, + PointerCoercion(PointerCoercion, CoercionSource), IntToInt, FloatToInt, FloatToFloat, @@ -1421,6 +1420,16 @@ pub enum CastKind { Transmute, } +/// Represents how a [`CastKind::PointerCoercion`] was constructed. +/// Used only for diagnostics. +#[derive(Clone, Copy, Debug, PartialEq, Eq, TyEncodable, TyDecodable, Hash, HashStable)] +pub enum CoercionSource { + /// The coercion was manually written by the user with an `as` cast. + AsCast, + /// The coercion was automatically inserted by the compiler. + Implicit, +} + #[derive(Clone, Debug, PartialEq, Eq, TyEncodable, TyDecodable, Hash, HashStable)] #[derive(TypeFoldable, TypeVisitable)] pub enum AggregateKind<'tcx> { diff --git a/compiler/rustc_middle/src/query/erase.rs b/compiler/rustc_middle/src/query/erase.rs index bd20e6aa005..48bf4ffced0 100644 --- a/compiler/rustc_middle/src/query/erase.rs +++ b/compiler/rustc_middle/src/query/erase.rs @@ -1,6 +1,8 @@ use std::intrinsics::transmute_unchecked; use std::mem::MaybeUninit; +use rustc_span::ErrorGuaranteed; + use crate::query::CyclePlaceholder; use crate::ty::adjustment::CoerceUnsizedInfo; use crate::ty::{self, Ty}; @@ -216,6 +218,10 @@ impl<T0, T1> EraseType for (&'_ T0, &'_ [T1]) { type Result = [u8; size_of::<(&'static (), &'static [()])>()]; } +impl<T0> EraseType for (&'_ T0, Result<(), ErrorGuaranteed>) { + type Result = [u8; size_of::<(&'static (), Result<(), ErrorGuaranteed>)>()]; +} + macro_rules! trivial { ($($ty:ty),+ $(,)?) => { $( diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 00036097ef5..9609ef46d5c 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -881,13 +881,13 @@ rustc_queries! { /// Maps a `DefId` of a type to a list of its inherent impls. /// Contains implementations of methods that are inherent to a type. /// Methods in these implementations don't need to be exported. - query inherent_impls(key: DefId) -> Result<&'tcx [DefId], ErrorGuaranteed> { + query inherent_impls(key: DefId) -> &'tcx [DefId] { desc { |tcx| "collecting inherent impls for `{}`", tcx.def_path_str(key) } cache_on_disk_if { key.is_local() } separate_provide_extern } - query incoherent_impls(key: SimplifiedType) -> Result<&'tcx [DefId], ErrorGuaranteed> { + query incoherent_impls(key: SimplifiedType) -> &'tcx [DefId] { desc { |tcx| "collecting all inherent impls for `{:?}`", key } } @@ -1017,8 +1017,14 @@ rustc_queries! { /// Gets a complete map from all types to their inherent impls. /// Not meant to be used directly outside of coherence. - query crate_inherent_impls(k: ()) -> Result<&'tcx CrateInherentImpls, ErrorGuaranteed> { + query crate_inherent_impls(k: ()) -> (&'tcx CrateInherentImpls, Result<(), ErrorGuaranteed>) { desc { "finding all inherent impls defined in crate" } + } + + /// Checks all types in the crate for overlap in their inherent impls. Reports errors. + /// Not meant to be used directly outside of coherence. + query crate_inherent_impls_validity_check(_: ()) -> Result<(), ErrorGuaranteed> { + desc { "check for inherent impls that should not be defined in crate" } ensure_forwards_result_if_red } @@ -1715,7 +1721,7 @@ rustc_queries! { /// /// Do not call this directly, but instead use the `incoherent_impls` query. /// This query is only used to get the data necessary for that query. - query crate_incoherent_impls(key: (CrateNum, SimplifiedType)) -> Result<&'tcx [DefId], ErrorGuaranteed> { + query crate_incoherent_impls(key: (CrateNum, SimplifiedType)) -> &'tcx [DefId] { desc { |tcx| "collecting all impls for a type in a crate" } separate_provide_extern } diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs index 32234d6b55d..e614d41899a 100644 --- a/compiler/rustc_middle/src/thir.rs +++ b/compiler/rustc_middle/src/thir.rs @@ -338,6 +338,8 @@ pub enum ExprKind<'tcx> { PointerCoercion { cast: PointerCoercion, source: ExprId, + /// Whether this coercion is written with an `as` cast in the source code. + is_from_as_cast: bool, }, /// A `loop` expression. Loop { @@ -453,12 +455,14 @@ pub enum ExprKind<'tcx> { source: ExprId, /// Type that the user gave to this expression user_ty: UserTy<'tcx>, + user_ty_span: Span, }, - /// A type ascription on a value, e.g. `42: i32`. + /// A type ascription on a value, e.g. `type_ascribe!(42, i32)` or `42 as i32`. ValueTypeAscription { source: ExprId, /// Type that the user gave to this expression user_ty: UserTy<'tcx>, + user_ty_span: Span, }, /// A closure definition. Closure(Box<ClosureExpr<'tcx>>), diff --git a/compiler/rustc_middle/src/thir/visit.rs b/compiler/rustc_middle/src/thir/visit.rs index e246ecebbec..58e2ebaeaf8 100644 --- a/compiler/rustc_middle/src/thir/visit.rs +++ b/compiler/rustc_middle/src/thir/visit.rs @@ -68,7 +68,9 @@ pub fn walk_expr<'thir, 'tcx: 'thir, V: Visitor<'thir, 'tcx>>( Cast { source } => visitor.visit_expr(&visitor.thir()[source]), Use { source } => visitor.visit_expr(&visitor.thir()[source]), NeverToAny { source } => visitor.visit_expr(&visitor.thir()[source]), - PointerCoercion { source, cast: _ } => visitor.visit_expr(&visitor.thir()[source]), + PointerCoercion { source, cast: _, is_from_as_cast: _ } => { + visitor.visit_expr(&visitor.thir()[source]) + } Let { expr, ref pat } => { visitor.visit_expr(&visitor.thir()[expr]); visitor.visit_pat(pat); @@ -129,7 +131,8 @@ pub fn walk_expr<'thir, 'tcx: 'thir, V: Visitor<'thir, 'tcx>>( visitor.visit_expr(&visitor.thir()[base.base]); } } - PlaceTypeAscription { source, user_ty: _ } | ValueTypeAscription { source, user_ty: _ } => { + PlaceTypeAscription { source, user_ty: _, user_ty_span: _ } + | ValueTypeAscription { source, user_ty: _, user_ty_span: _ } => { visitor.visit_expr(&visitor.thir()[source]) } Closure(box ClosureExpr { diff --git a/compiler/rustc_middle/src/ty/adjustment.rs b/compiler/rustc_middle/src/ty/adjustment.rs index 5a32078760e..41a20e89cbf 100644 --- a/compiler/rustc_middle/src/ty/adjustment.rs +++ b/compiler/rustc_middle/src/ty/adjustment.rs @@ -35,6 +35,9 @@ 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. @@ -102,9 +105,6 @@ pub enum Adjust<'tcx> { Pointer(PointerCoercion), - /// Cast into a dyn* object. - DynStar, - /// Take a pinned reference and reborrow as a `Pin<&mut T>` or `Pin<&T>`. ReborrowPin(ty::Region<'tcx>, hir::Mutability), } diff --git a/compiler/rustc_middle/src/ty/cast.rs b/compiler/rustc_middle/src/ty/cast.rs index 46f37659536..b1316ceef5a 100644 --- a/compiler/rustc_middle/src/ty/cast.rs +++ b/compiler/rustc_middle/src/ty/cast.rs @@ -34,15 +34,12 @@ pub enum CastTy<'tcx> { FnPtr, /// Raw pointers. Ptr(ty::TypeAndMut<'tcx>), - /// Casting into a `dyn*` value. - DynStar, } /// Cast Kind. See [RFC 401](https://rust-lang.github.io/rfcs/0401-coercions.html) /// (or rustc_hir_analysis/check/cast.rs). #[derive(Copy, Clone, Debug, TyEncodable, TyDecodable, HashStable)] pub enum CastKind { - CoercionCast, PtrPtrCast, PtrAddrCast, AddrPtrCast, @@ -53,7 +50,6 @@ pub enum CastKind { ArrayPtrCast, FnPtrPtrCast, FnPtrAddrCast, - DynStarCast, } impl<'tcx> CastTy<'tcx> { @@ -71,7 +67,6 @@ impl<'tcx> CastTy<'tcx> { ty::Adt(d, _) if d.is_enum() && d.is_payloadfree() => Some(CastTy::Int(IntTy::CEnum)), ty::RawPtr(ty, mutbl) => Some(CastTy::Ptr(ty::TypeAndMut { ty, mutbl })), ty::FnPtr(..) => Some(CastTy::FnPtr), - ty::Dynamic(_, _, ty::DynStar) => Some(CastTy::DynStar), _ => None, } } @@ -86,7 +81,6 @@ pub fn mir_cast_kind<'tcx>(from_ty: Ty<'tcx>, cast_ty: Ty<'tcx>) -> mir::CastKin mir::CastKind::PointerExposeProvenance } (Some(CastTy::Int(_)), Some(CastTy::Ptr(_))) => mir::CastKind::PointerWithExposedProvenance, - (_, Some(CastTy::DynStar)) => mir::CastKind::DynStar, (Some(CastTy::Int(_)), Some(CastTy::Int(_))) => mir::CastKind::IntToInt, (Some(CastTy::FnPtr), Some(CastTy::Ptr(_))) => mir::CastKind::FnPtrToPtr, diff --git a/compiler/rustc_middle/src/ty/trait_def.rs b/compiler/rustc_middle/src/ty/trait_def.rs index 82690f70e5f..188107e5d54 100644 --- a/compiler/rustc_middle/src/ty/trait_def.rs +++ b/compiler/rustc_middle/src/ty/trait_def.rs @@ -253,30 +253,16 @@ pub(super) fn trait_impls_of_provider(tcx: TyCtxt<'_>, trait_id: DefId) -> Trait } /// Query provider for `incoherent_impls`. -pub(super) fn incoherent_impls_provider( - tcx: TyCtxt<'_>, - simp: SimplifiedType, -) -> Result<&[DefId], ErrorGuaranteed> { +pub(super) fn incoherent_impls_provider(tcx: TyCtxt<'_>, simp: SimplifiedType) -> &[DefId] { let mut impls = Vec::new(); - - let mut res = Ok(()); for cnum in iter::once(LOCAL_CRATE).chain(tcx.crates(()).iter().copied()) { - let incoherent_impls = match tcx.crate_incoherent_impls((cnum, simp)) { - Ok(impls) => impls, - Err(e) => { - res = Err(e); - continue; - } - }; - for &impl_def_id in incoherent_impls { + for &impl_def_id in tcx.crate_incoherent_impls((cnum, simp)) { impls.push(impl_def_id) } } - debug!(?impls); - res?; - Ok(tcx.arena.alloc_slice(&impls)) + tcx.arena.alloc_slice(&impls) } pub(super) fn traits_provider(tcx: TyCtxt<'_>, _: LocalCrate) -> &[DefId] { diff --git a/compiler/rustc_mir_build/src/build/expr/as_place.rs b/compiler/rustc_mir_build/src/build/expr/as_place.rs index 2084bcae7b7..c7298e3ddfa 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_place.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_place.rs @@ -470,21 +470,22 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { block.and(place_builder) } - ExprKind::PlaceTypeAscription { source, ref user_ty } => { + ExprKind::PlaceTypeAscription { source, ref user_ty, user_ty_span } => { let place_builder = unpack!( block = this.expr_as_place(block, source, mutability, fake_borrow_temps,) ); if let Some(user_ty) = user_ty { + let ty_source_info = this.source_info(user_ty_span); let annotation_index = this.canonical_user_type_annotations.push(CanonicalUserTypeAnnotation { - span: source_info.span, + span: user_ty_span, user_ty: user_ty.clone(), inferred_ty: expr.ty, }); let place = place_builder.to_place(this); this.cfg.push(block, Statement { - source_info, + source_info: ty_source_info, kind: StatementKind::AscribeUserType( Box::new((place, UserTypeProjection { base: annotation_index, @@ -496,20 +497,21 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } block.and(place_builder) } - ExprKind::ValueTypeAscription { source, ref user_ty } => { + ExprKind::ValueTypeAscription { source, ref user_ty, user_ty_span } => { let source_expr = &this.thir[source]; let temp = unpack!( block = this.as_temp(block, source_expr.temp_lifetime, source, mutability) ); if let Some(user_ty) = user_ty { + let ty_source_info = this.source_info(user_ty_span); let annotation_index = this.canonical_user_type_annotations.push(CanonicalUserTypeAnnotation { - span: source_info.span, + span: user_ty_span, user_ty: user_ty.clone(), inferred_ty: expr.ty, }); this.cfg.push(block, Statement { - source_info, + source_info: ty_source_info, kind: StatementKind::AscribeUserType( Box::new((Place::from(temp), UserTypeProjection { base: annotation_index, diff --git a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs index ffedee8a1e8..fd949a53384 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs @@ -292,7 +292,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let cast_kind = mir_cast_kind(ty, expr.ty); block.and(Rvalue::Cast(cast_kind, source, expr.ty)) } - ExprKind::PointerCoercion { cast, source } => { + ExprKind::PointerCoercion { cast, source, is_from_as_cast } => { let source = unpack!( block = this.as_operand( block, @@ -302,7 +302,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { NeedsTemporary::No ) ); - block.and(Rvalue::Cast(CastKind::PointerCoercion(cast), source, expr.ty)) + let origin = + if is_from_as_cast { CoercionSource::AsCast } else { CoercionSource::Implicit }; + block.and(Rvalue::Cast(CastKind::PointerCoercion(cast, origin), source, expr.ty)) } ExprKind::Array { ref fields } => { // (*) We would (maybe) be closer to codegen if we diff --git a/compiler/rustc_mir_build/src/build/matches/test.rs b/compiler/rustc_mir_build/src/build/matches/test.rs index 63873aad02a..020c202f965 100644 --- a/compiler/rustc_mir_build/src/build/matches/test.rs +++ b/compiler/rustc_mir_build/src/build/matches/test.rs @@ -407,7 +407,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { source_info, temp, Rvalue::Cast( - CastKind::PointerCoercion(PointerCoercion::Unsize), + CastKind::PointerCoercion( + PointerCoercion::Unsize, + CoercionSource::Implicit, + ), Operand::Copy(val), ty, ), @@ -421,7 +424,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { source_info, slice, Rvalue::Cast( - CastKind::PointerCoercion(PointerCoercion::Unsize), + CastKind::PointerCoercion( + PointerCoercion::Unsize, + CoercionSource::Implicit, + ), expect, ty, ), diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs index 55236933922..fbd45f59a4f 100644 --- a/compiler/rustc_mir_build/src/thir/cx/expr.rs +++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs @@ -104,16 +104,29 @@ impl<'tcx> Cx<'tcx> { }; let kind = match adjustment.kind { - Adjust::Pointer(PointerCoercion::Unsize) => { - adjust_span(&mut expr); + Adjust::Pointer(cast) => { + if cast == PointerCoercion::Unsize { + adjust_span(&mut expr); + } + + let is_from_as_cast = if let hir::Node::Expr(hir::Expr { + kind: hir::ExprKind::Cast(..), + span: cast_span, + .. + }) = self.tcx.parent_hir_node(hir_expr.hir_id) + { + // Use the whole span of the `x as T` expression for the coercion. + span = *cast_span; + true + } else { + false + }; ExprKind::PointerCoercion { - cast: PointerCoercion::Unsize, + cast, source: self.thir.exprs.push(expr), + is_from_as_cast, } } - Adjust::Pointer(cast) => { - ExprKind::PointerCoercion { cast, source: self.thir.exprs.push(expr) } - } Adjust::NeverToAny if adjustment.target.is_never() => return expr, Adjust::NeverToAny => ExprKind::NeverToAny { source: self.thir.exprs.push(expr) }, Adjust::Deref(None) => { @@ -146,7 +159,6 @@ impl<'tcx> Cx<'tcx> { Adjust::Borrow(AutoBorrow::RawPtr(mutability)) => { ExprKind::RawBorrow { mutability, arg: self.thir.exprs.push(expr) } } - Adjust::DynStar => ExprKind::Cast { source: self.thir.exprs.push(expr) }, Adjust::ReborrowPin(region, mutbl) => { debug!("apply ReborrowPin adjustment"); // Rewrite `$expr` as `Pin { __pointer: &(mut)? *($expr).__pointer }` @@ -236,6 +248,7 @@ impl<'tcx> Cx<'tcx> { ExprKind::PointerCoercion { source: self.mirror_expr(source), cast: PointerCoercion::ArrayToPointer, + is_from_as_cast: true, } } else if let hir::ExprKind::Path(ref qpath) = source.kind && let res = self.typeck_results().qpath_res(qpath, source.hir_id) @@ -841,6 +854,7 @@ impl<'tcx> Cx<'tcx> { ExprKind::ValueTypeAscription { source: cast_expr, user_ty: Some(Box::new(*user_ty)), + user_ty_span: cast_ty.span, } } else { cast @@ -852,9 +866,17 @@ impl<'tcx> Cx<'tcx> { debug!("make_mirror_unadjusted: (type) user_ty={:?}", user_ty); let mirrored = self.mirror_expr(source); if source.is_syntactic_place_expr() { - ExprKind::PlaceTypeAscription { source: mirrored, user_ty } + ExprKind::PlaceTypeAscription { + source: mirrored, + user_ty, + user_ty_span: ty.span, + } } else { - ExprKind::ValueTypeAscription { source: mirrored, user_ty } + ExprKind::ValueTypeAscription { + source: mirrored, + user_ty, + user_ty_span: ty.span, + } } } hir::ExprKind::DropTemps(source) => ExprKind::Use { source: self.mirror_expr(source) }, diff --git a/compiler/rustc_mir_build/src/thir/print.rs b/compiler/rustc_mir_build/src/thir/print.rs index ce7774f5948..61317925d09 100644 --- a/compiler/rustc_mir_build/src/thir/print.rs +++ b/compiler/rustc_mir_build/src/thir/print.rs @@ -292,9 +292,14 @@ impl<'a, 'tcx> ThirPrinter<'a, 'tcx> { self.print_expr(*source, depth_lvl + 2); print_indented!(self, "}", depth_lvl); } - PointerCoercion { cast, source } => { + PointerCoercion { cast, is_from_as_cast, source } => { print_indented!(self, "Pointer {", depth_lvl); print_indented!(self, format!("cast: {:?}", cast), depth_lvl + 1); + print_indented!( + self, + format!("is_from_as_cast: {:?}", is_from_as_cast), + depth_lvl + 1 + ); print_indented!(self, "source:", depth_lvl + 1); self.print_expr(*source, depth_lvl + 2); print_indented!(self, "}", depth_lvl); @@ -454,16 +459,18 @@ impl<'a, 'tcx> ThirPrinter<'a, 'tcx> { self.print_adt_expr(&**adt_expr, depth_lvl + 1); print_indented!(self, "}", depth_lvl); } - PlaceTypeAscription { source, user_ty } => { + PlaceTypeAscription { source, user_ty, user_ty_span } => { print_indented!(self, "PlaceTypeAscription {", depth_lvl); print_indented!(self, format!("user_ty: {:?}", user_ty), depth_lvl + 1); + print_indented!(self, format!("user_ty_span: {:?}", user_ty_span), depth_lvl + 1); print_indented!(self, "source:", depth_lvl + 1); self.print_expr(*source, depth_lvl + 2); print_indented!(self, "}", depth_lvl); } - ValueTypeAscription { source, user_ty } => { + ValueTypeAscription { source, user_ty, user_ty_span } => { print_indented!(self, "ValueTypeAscription {", depth_lvl); print_indented!(self, format!("user_ty: {:?}", user_ty), depth_lvl + 1); + print_indented!(self, format!("user_ty_span: {:?}", user_ty_span), depth_lvl + 1); print_indented!(self, "source:", depth_lvl + 1); self.print_expr(*source, depth_lvl + 2); print_indented!(self, "}", depth_lvl); diff --git a/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs b/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs index 5395e1b0e94..6a22a58470c 100644 --- a/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs +++ b/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs @@ -42,6 +42,7 @@ impl<'tcx> crate::MirPass<'tcx> for CleanupPostBorrowck { ref mut cast_kind @ CastKind::PointerCoercion( PointerCoercion::ArrayToPointer | PointerCoercion::MutToConstPointer, + _, ), .., ), diff --git a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs index 2026b789315..88dc8e74a8c 100644 --- a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs +++ b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs @@ -189,7 +189,7 @@ impl<'tcx> ValueAnalysis<'tcx> for ConstAnalysis<'_, 'tcx> { } } Rvalue::Cast( - CastKind::PointerCoercion(ty::adjustment::PointerCoercion::Unsize), + CastKind::PointerCoercion(ty::adjustment::PointerCoercion::Unsize, _), operand, _, ) => { diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs index 4d44669fa3e..f735d08fca5 100644 --- a/compiler/rustc_mir_transform/src/gvn.rs +++ b/compiler/rustc_mir_transform/src/gvn.rs @@ -576,7 +576,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { } value.offset(Size::ZERO, to, &self.ecx).ok()? } - CastKind::PointerCoercion(ty::adjustment::PointerCoercion::Unsize) => { + CastKind::PointerCoercion(ty::adjustment::PointerCoercion::Unsize, _) => { let src = self.evaluated[value].as_ref()?; let to = self.ecx.layout_of(to).ok()?; let dest = self.ecx.allocate(to, MemoryKind::Stack).ok()?; @@ -593,7 +593,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { let ret = self.ecx.ptr_to_ptr(&src, to).ok()?; ret.into() } - CastKind::PointerCoercion(ty::adjustment::PointerCoercion::UnsafeFnPointer) => { + CastKind::PointerCoercion(ty::adjustment::PointerCoercion::UnsafeFnPointer, _) => { let src = self.evaluated[value].as_ref()?; let src = self.ecx.read_immediate(src).ok()?; let to = self.ecx.layout_of(to).ok()?; @@ -1138,7 +1138,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { ( UnOp::PtrMetadata, Value::Cast { - kind: CastKind::PointerCoercion(ty::adjustment::PointerCoercion::Unsize), + kind: CastKind::PointerCoercion(ty::adjustment::PointerCoercion::Unsize, _), from, to, .. @@ -1342,7 +1342,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { return Some(value); } - if let CastKind::PointerCoercion(ReifyFnPointer | ClosureFnPointer(_)) = kind { + if let CastKind::PointerCoercion(ReifyFnPointer | ClosureFnPointer(_), _) = kind { // Each reification of a generic fn may get a different pointer. // Do not try to merge them. return self.new_opaque(); @@ -1429,7 +1429,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { // We have an unsizing cast, which assigns the length to fat pointer metadata. if let Value::Cast { kind, from, to, .. } = self.get(inner) - && let CastKind::PointerCoercion(ty::adjustment::PointerCoercion::Unsize) = kind + && let CastKind::PointerCoercion(ty::adjustment::PointerCoercion::Unsize, _) = kind && let Some(from) = from.builtin_deref(true) && let ty::Array(_, len) = from.kind() && let Some(to) = to.builtin_deref(true) diff --git a/compiler/rustc_mir_transform/src/mentioned_items.rs b/compiler/rustc_mir_transform/src/mentioned_items.rs index f24de609e6b..cf5c5f85a9f 100644 --- a/compiler/rustc_mir_transform/src/mentioned_items.rs +++ b/compiler/rustc_mir_transform/src/mentioned_items.rs @@ -70,11 +70,11 @@ 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::Unsize, _) + | mir::CastKind::PointerCoercion(PointerCoercion::DynStar, _), ref operand, target_ty, - ) - | mir::Rvalue::Cast(mir::CastKind::DynStar, ref operand, target_ty) => { + ) => { // This isn't monomorphized yet so we can't tell what the actual types are -- just // add everything that may involve a vtable. let source_ty = operand.ty(self.body, self.tcx); @@ -96,7 +96,7 @@ impl<'tcx> Visitor<'tcx> for MentionedItemsVisitor<'_, 'tcx> { } // Similarly, record closures that are turned into function pointers. mir::Rvalue::Cast( - mir::CastKind::PointerCoercion(PointerCoercion::ClosureFnPointer(_)), + mir::CastKind::PointerCoercion(PointerCoercion::ClosureFnPointer(_), _), ref operand, _, ) => { @@ -106,7 +106,7 @@ impl<'tcx> Visitor<'tcx> for MentionedItemsVisitor<'_, 'tcx> { } // And finally, function pointer reification casts. mir::Rvalue::Cast( - mir::CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer), + mir::CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer, _), ref operand, _, ) => { diff --git a/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs b/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs index c206252c15a..71723f040b3 100644 --- a/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs +++ b/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs @@ -7,9 +7,10 @@ use rustc_hir::def_id::DefId; use rustc_hir::lang_items::LangItem; use rustc_index::{Idx, IndexVec}; use rustc_middle::mir::{ - BasicBlock, BasicBlockData, Body, CallSource, CastKind, Const, ConstOperand, ConstValue, Local, - LocalDecl, MirSource, Operand, Place, PlaceElem, RETURN_PLACE, Rvalue, SourceInfo, Statement, - StatementKind, Terminator, TerminatorKind, UnwindAction, UnwindTerminateReason, + BasicBlock, BasicBlockData, Body, CallSource, CastKind, CoercionSource, Const, ConstOperand, + ConstValue, Local, LocalDecl, MirSource, Operand, Place, PlaceElem, RETURN_PLACE, Rvalue, + SourceInfo, Statement, StatementKind, Terminator, TerminatorKind, UnwindAction, + UnwindTerminateReason, }; use rustc_middle::ty::adjustment::PointerCoercion; use rustc_middle::ty::util::{AsyncDropGlueMorphology, Discr}; @@ -329,7 +330,7 @@ impl<'tcx> AsyncDestructorCtorShimBuilder<'tcx> { fn put_array_as_slice(&mut self, elem_ty: Ty<'tcx>) { let slice_ptr_ty = Ty::new_mut_ptr(self.tcx, Ty::new_slice(self.tcx, elem_ty)); self.put_temp_rvalue(Rvalue::Cast( - CastKind::PointerCoercion(PointerCoercion::Unsize), + CastKind::PointerCoercion(PointerCoercion::Unsize, CoercionSource::Implicit), Operand::Copy(Self::SELF_PTR.into()), slice_ptr_ty, )) diff --git a/compiler/rustc_mir_transform/src/validate.rs b/compiler/rustc_mir_transform/src/validate.rs index 914dddc1a56..eda0b8c75f3 100644 --- a/compiler/rustc_mir_transform/src/validate.rs +++ b/compiler/rustc_mir_transform/src/validate.rs @@ -1128,12 +1128,9 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { Rvalue::Cast(kind, operand, target_type) => { let op_ty = operand.ty(self.body, self.tcx); match kind { - CastKind::DynStar => { - // FIXME(dyn-star): make sure nothing needs to be done here. - } // FIXME: Add Checks for these CastKind::PointerWithExposedProvenance | CastKind::PointerExposeProvenance => {} - CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer) => { + CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer, _) => { // FIXME: check signature compatibility. check_kinds!( op_ty, @@ -1146,7 +1143,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { ty::FnPtr(..) ); } - CastKind::PointerCoercion(PointerCoercion::UnsafeFnPointer) => { + CastKind::PointerCoercion(PointerCoercion::UnsafeFnPointer, _) => { // FIXME: check safety and signature compatibility. check_kinds!( op_ty, @@ -1159,7 +1156,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { ty::FnPtr(..) ); } - CastKind::PointerCoercion(PointerCoercion::ClosureFnPointer(..)) => { + CastKind::PointerCoercion(PointerCoercion::ClosureFnPointer(..), _) => { // FIXME: check safety, captures, and signature compatibility. check_kinds!( op_ty, @@ -1172,7 +1169,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { ty::FnPtr(..) ); } - CastKind::PointerCoercion(PointerCoercion::MutToConstPointer) => { + CastKind::PointerCoercion(PointerCoercion::MutToConstPointer, _) => { // FIXME: check same pointee? check_kinds!( op_ty, @@ -1188,7 +1185,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { self.fail(location, format!("After borrowck, MIR disallows {kind:?}")); } } - CastKind::PointerCoercion(PointerCoercion::ArrayToPointer) => { + CastKind::PointerCoercion(PointerCoercion::ArrayToPointer, _) => { // FIXME: Check pointee types check_kinds!( op_ty, @@ -1204,10 +1201,13 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { self.fail(location, format!("After borrowck, MIR disallows {kind:?}")); } } - CastKind::PointerCoercion(PointerCoercion::Unsize) => { + CastKind::PointerCoercion(PointerCoercion::Unsize, _) => { // This is used for all `CoerceUnsized` types, // not just pointers/references, so is hard to check. } + 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 8d137b8d8f9..276098a8400 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -665,11 +665,11 @@ 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::Unsize, _) + | mir::CastKind::PointerCoercion(PointerCoercion::DynStar, _), ref operand, target_ty, - ) - | mir::Rvalue::Cast(mir::CastKind::DynStar, ref operand, target_ty) => { + ) => { let source_ty = operand.ty(self.body, self.tcx); // *Before* monomorphizing, record that we already handled this mention. self.used_mentioned_items @@ -694,7 +694,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirUsedCollector<'a, 'tcx> { } } mir::Rvalue::Cast( - mir::CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer), + mir::CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer, _), ref operand, _, ) => { @@ -705,7 +705,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirUsedCollector<'a, 'tcx> { visit_fn_use(self.tcx, fn_ty, false, span, self.used_items); } mir::Rvalue::Cast( - mir::CastKind::PointerCoercion(PointerCoercion::ClosureFnPointer(_)), + mir::CastKind::PointerCoercion(PointerCoercion::ClosureFnPointer(_), _), ref operand, _, ) => { @@ -1183,7 +1183,7 @@ fn collect_alloc<'tcx>(tcx: TyCtxt<'tcx>, alloc_id: AllocId, output: &mut MonoIt } fn assoc_fn_of_type<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, fn_ident: Ident) -> Option<DefId> { - for impl_def_id in tcx.inherent_impls(def_id).ok()? { + for impl_def_id in tcx.inherent_impls(def_id) { if let Some(new) = tcx.associated_items(impl_def_id).find_by_name_and_kind( tcx, fn_ident, diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 7ea057c7b4b..35d166e8b4a 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -1825,10 +1825,12 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { // Doing analysis on local `DefId`s would cause infinite recursion. return; } - let Ok(impls) = self.r.tcx.inherent_impls(def_id) else { return }; // Look at all the associated functions without receivers in the type's // inherent impls to look for builders that return `Self` - let mut items = impls + let mut items = self + .r + .tcx + .inherent_impls(def_id) .iter() .flat_map(|i| self.r.tcx.associated_items(i).in_definition_order()) // Only assoc fn with no receivers. diff --git a/compiler/rustc_smir/src/rustc_smir/convert/mir.rs b/compiler/rustc_smir/src/rustc_smir/convert/mir.rs index f4c7fd7c900..0dbbc338e73 100644 --- a/compiler/rustc_smir/src/rustc_smir/convert/mir.rs +++ b/compiler/rustc_smir/src/rustc_smir/convert/mir.rs @@ -282,11 +282,12 @@ 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(c) => stable_mir::mir::CastKind::PointerCoercion(c.stable(tables)), - DynStar => stable_mir::mir::CastKind::DynStar, + 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, FloatToFloat => stable_mir::mir::CastKind::FloatToFloat, diff --git a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs index e54ab1f7e24..ac9a0235762 100644 --- a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs +++ b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs @@ -119,6 +119,7 @@ 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/stable_mir/src/mir/body.rs b/compiler/stable_mir/src/mir/body.rs index 7c09fe1a085..ab9fc218d19 100644 --- a/compiler/stable_mir/src/mir/body.rs +++ b/compiler/stable_mir/src/mir/body.rs @@ -960,6 +960,7 @@ pub enum CastKind { PointerExposeAddress, PointerWithExposedProvenance, PointerCoercion(PointerCoercion), + // FIXME(smir-rename): change this to PointerCoercion(DynStar) DynStar, IntToInt, FloatToInt,  | 
