diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:20:39 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:20:39 +0000 |
commit | 1376c5a617be5c25655d0d7cb63e3beaa5a6e026 (patch) | |
tree | 3bb8d61aee02bc7a15eab3f36e3b921afc2075d0 /compiler/rustc_hir_analysis/src/coherence | |
parent | Releasing progress-linux version 1.69.0+dfsg1-1~progress7.99u1. (diff) | |
download | rustc-1376c5a617be5c25655d0d7cb63e3beaa5a6e026.tar.xz rustc-1376c5a617be5c25655d0d7cb63e3beaa5a6e026.zip |
Merging upstream version 1.70.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_hir_analysis/src/coherence')
5 files changed, 48 insertions, 46 deletions
diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs index ffb68abf9..0f40cca94 100644 --- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs +++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs @@ -2,21 +2,23 @@ //! up data structures required by type-checking/codegen. use crate::errors::{CopyImplOnNonAdt, CopyImplOnTypeWithDtor, DropImplOnWrongItem}; +use rustc_data_structures::fx::FxHashSet; use rustc_errors::{struct_span_err, MultiSpan}; use rustc_hir as hir; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::lang_items::LangItem; use rustc_hir::ItemKind; use rustc_infer::infer::outlives::env::OutlivesEnvironment; -use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::infer::{self, RegionResolutionError}; +use rustc_infer::infer::{DefineOpaqueTypes, TyCtxtInferExt}; +use rustc_infer::traits::Obligation; use rustc_middle::ty::adjustment::CoerceUnsizedInfo; use rustc_middle::ty::{self, suggest_constraining_type_params, Ty, TyCtxt, TypeVisitableExt}; use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt; use rustc_trait_selection::traits::misc::{ type_allowed_to_implement_copy, CopyImplementationError, InfringingFieldsReason, }; -use rustc_trait_selection::traits::predicate_for_trait_def; +use rustc_trait_selection::traits::ObligationCtxt; use rustc_trait_selection::traits::{self, ObligationCause}; use std::collections::BTreeMap; @@ -86,7 +88,7 @@ fn visit_implementation_of_copy(tcx: TyCtxt<'_>, impl_did: LocalDefId) { tcx.sess, span, E0204, - "the trait `Copy` may not be implemented for this type" + "the trait `Copy` cannot be implemented for this type" ); // We'll try to suggest constraining type parameters to fulfill the requirements of @@ -94,7 +96,14 @@ fn visit_implementation_of_copy(tcx: TyCtxt<'_>, impl_did: LocalDefId) { let mut errors: BTreeMap<_, Vec<_>> = Default::default(); let mut bounds = vec![]; + let mut seen_tys = FxHashSet::default(); + for (field, ty, reason) in fields { + // Only report an error once per type. + if !seen_tys.insert(ty) { + continue; + } + let field_span = tcx.def_span(field.did); err.span_label(field_span, "this field does not implement `Copy`"); @@ -227,7 +236,8 @@ fn visit_implementation_of_dispatch_from_dyn(tcx: TyCtxt<'_>, impl_did: LocalDef use rustc_type_ir::sty::TyKind::*; match (source.kind(), target.kind()) { (&Ref(r_a, _, mutbl_a), Ref(r_b, _, mutbl_b)) - if infcx.at(&cause, param_env).eq(r_a, *r_b).is_ok() && mutbl_a == *mutbl_b => {} + if infcx.at(&cause, param_env).eq(DefineOpaqueTypes::No, r_a, *r_b).is_ok() + && mutbl_a == *mutbl_b => {} (&RawPtr(tm_a), &RawPtr(tm_b)) if tm_a.mutbl == tm_b.mutbl => (), (&Adt(def_a, substs_a), &Adt(def_b, substs_b)) if def_a.is_struct() && def_b.is_struct() => @@ -270,7 +280,9 @@ fn visit_implementation_of_dispatch_from_dyn(tcx: TyCtxt<'_>, impl_did: LocalDef } } - if let Ok(ok) = infcx.at(&cause, param_env).eq(ty_a, ty_b) { + if let Ok(ok) = + infcx.at(&cause, param_env).eq(DefineOpaqueTypes::No, ty_a, ty_b) + { if ok.obligations.is_empty() { create_err( "the trait `DispatchFromDyn` may only be implemented \ @@ -323,28 +335,26 @@ fn visit_implementation_of_dispatch_from_dyn(tcx: TyCtxt<'_>, impl_did: LocalDef )) .emit(); } else { - let errors = traits::fully_solve_obligations( - &infcx, - coerced_fields.into_iter().map(|field| { - predicate_for_trait_def( - tcx, - param_env, - cause.clone(), + let ocx = ObligationCtxt::new(&infcx); + for field in coerced_fields { + ocx.register_obligation(Obligation::new( + tcx, + cause.clone(), + param_env, + ty::Binder::dummy(tcx.mk_trait_ref( dispatch_from_dyn_trait, - 0, [field.ty(tcx, substs_a), field.ty(tcx, substs_b)], - ) - }), - ); + )), + )); + } + let errors = ocx.select_all_or_error(); if !errors.is_empty() { - infcx.err_ctxt().report_fulfillment_errors(&errors, None); + infcx.err_ctxt().report_fulfillment_errors(&errors); } // Finally, resolve all regions. let outlives_env = OutlivesEnvironment::new(param_env); - let _ = infcx - .err_ctxt() - .check_region_obligations_and_report_errors(impl_did, &outlives_env); + let _ = ocx.resolve_regions_and_report_errors(impl_did, &outlives_env); } } _ => { @@ -357,11 +367,8 @@ fn visit_implementation_of_dispatch_from_dyn(tcx: TyCtxt<'_>, impl_did: LocalDef } } -pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: DefId) -> CoerceUnsizedInfo { +pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: LocalDefId) -> CoerceUnsizedInfo { debug!("compute_coerce_unsized_info(impl_did={:?})", impl_did); - - // this provider should only get invoked for local def-ids - let impl_did = impl_did.expect_local(); let span = tcx.def_span(impl_did); let coerce_unsized_trait = tcx.require_lang_item(LangItem::CoerceUnsized, Some(span)); @@ -477,8 +484,7 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: DefId) -> CoerceUn // U` can be coerced to `*mut V` if `U: Unsize<V>`. let fields = &def_a.non_enum_variant().fields; let diff_fields = fields - .iter() - .enumerate() + .iter_enumerated() .filter_map(|(i, f)| { let (a, b) = (f.ty(tcx, substs_a), f.ty(tcx, substs_b)); @@ -496,7 +502,7 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: DefId) -> CoerceUn // we may have to evaluate constraint // expressions in the course of execution.) // See e.g., #41936. - if let Ok(ok) = infcx.at(&cause, param_env).eq(a, b) { + if let Ok(ok) = infcx.at(&cause, param_env).eq(DefineOpaqueTypes::No, a, b) { if ok.obligations.is_empty() { return None; } @@ -572,17 +578,19 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: DefId) -> CoerceUn }; // Register an obligation for `A: Trait<B>`. + let ocx = ObligationCtxt::new(&infcx); let cause = traits::ObligationCause::misc(span, impl_did); - let predicate = - predicate_for_trait_def(tcx, param_env, cause, trait_def_id, 0, [source, target]); - let errors = traits::fully_solve_obligation(&infcx, predicate); + let obligation = + Obligation::new(tcx, cause, param_env, tcx.mk_trait_ref(trait_def_id, [source, target])); + ocx.register_obligation(obligation); + let errors = ocx.select_all_or_error(); if !errors.is_empty() { - infcx.err_ctxt().report_fulfillment_errors(&errors, None); + infcx.err_ctxt().report_fulfillment_errors(&errors); } // Finally, resolve all regions. let outlives_env = OutlivesEnvironment::new(param_env); - let _ = infcx.err_ctxt().check_region_obligations_and_report_errors(impl_did, &outlives_env); + let _ = ocx.resolve_regions_and_report_errors(impl_did, &outlives_env); CoerceUnsizedInfo { custom_kind: kind } } diff --git a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs index 02f3eeee0..3d37e0ce0 100644 --- a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs +++ b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs @@ -10,7 +10,7 @@ use rustc_errors::struct_span_err; use rustc_hir as hir; use rustc_hir::def::DefKind; -use rustc_hir::def_id::{CrateNum, DefId, LocalDefId}; +use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_middle::ty::fast_reject::{simplify_type, SimplifiedType, TreatParams}; use rustc_middle::ty::{self, CrateInherentImpls, Ty, TyCtxt}; use rustc_span::symbol::sym; @@ -24,7 +24,7 @@ pub fn crate_inherent_impls(tcx: TyCtxt<'_>, (): ()) -> CrateInherentImpls { collect.impls_map } -pub fn crate_incoherent_impls(tcx: TyCtxt<'_>, (_, simp): (CrateNum, SimplifiedType)) -> &[DefId] { +pub 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()), @@ -32,9 +32,7 @@ pub fn crate_incoherent_impls(tcx: TyCtxt<'_>, (_, simp): (CrateNum, SimplifiedT } /// On-demand query: yields a vector of the inherent impls for a specific type. -pub fn inherent_impls(tcx: TyCtxt<'_>, ty_def_id: DefId) -> &[DefId] { - let ty_def_id = ty_def_id.expect_local(); - +pub 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[..], @@ -99,7 +97,7 @@ impl<'tcx> InherentCollect<'tcx> { } } - if let Some(simp) = simplify_type(self.tcx, self_ty, TreatParams::AsInfer) { + if let Some(simp) = simplify_type(self.tcx, self_ty, TreatParams::AsCandidateKey) { self.impls_map.incoherent_impls.entry(simp).or_default().push(impl_def_id); } else { bug!("unexpected self type: {:?}", self_ty); @@ -159,7 +157,7 @@ impl<'tcx> InherentCollect<'tcx> { } } - if let Some(simp) = simplify_type(self.tcx, ty, TreatParams::AsInfer) { + if let Some(simp) = simplify_type(self.tcx, ty, TreatParams::AsCandidateKey) { self.impls_map.incoherent_impls.entry(simp).or_default().push(impl_def_id); } else { bug!("unexpected primitive type: {:?}", ty); 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 7bca4edcc..ad76e2bed 100644 --- a/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs +++ b/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs @@ -302,7 +302,7 @@ impl<'tcx> InherentOverlapChecker<'tcx> { .iter() .flatten() .map(|r| r.impl_blocks.len() as isize - avg as isize) - .map(|v| v.abs() as usize) + .map(|v| v.unsigned_abs()) .sum::<usize>(); s / connected_regions.len() }, diff --git a/compiler/rustc_hir_analysis/src/coherence/mod.rs b/compiler/rustc_hir_analysis/src/coherence/mod.rs index 23490bc09..465e787c9 100644 --- a/compiler/rustc_hir_analysis/src/coherence/mod.rs +++ b/compiler/rustc_hir_analysis/src/coherence/mod.rs @@ -133,8 +133,8 @@ fn coherent_trait(tcx: TyCtxt<'_>, def_id: DefId) { check_impl(tcx, impl_def_id, trait_ref); check_object_overlap(tcx, impl_def_id, trait_ref); - tcx.sess.time("unsafety_checking", || unsafety::check_item(tcx, impl_def_id)); - tcx.sess.time("orphan_checking", || tcx.ensure().orphan_check_impl(impl_def_id)); + unsafety::check_item(tcx, impl_def_id); + tcx.ensure().orphan_check_impl(impl_def_id); } builtin::check_trait(tcx, def_id); diff --git a/compiler/rustc_hir_analysis/src/coherence/orphan.rs b/compiler/rustc_hir_analysis/src/coherence/orphan.rs index 1f2de3f21..47c47de8c 100644 --- a/compiler/rustc_hir_analysis/src/coherence/orphan.rs +++ b/compiler/rustc_hir_analysis/src/coherence/orphan.rs @@ -478,10 +478,6 @@ fn lint_auto_trait_impl<'tcx>( trait_ref: ty::TraitRef<'tcx>, impl_def_id: LocalDefId, ) { - if tcx.impl_polarity(impl_def_id) != ImplPolarity::Positive { - return; - } - assert_eq!(trait_ref.substs.len(), 1); let self_ty = trait_ref.self_ty(); let (self_type_did, substs) = match self_ty.kind() { |