diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:20:29 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:20:29 +0000 |
commit | 631cd5845e8de329d0e227aaa707d7ea228b8f8f (patch) | |
tree | a1b87c8f8cad01cf18f7c5f57a08f102771ed303 /compiler/rustc_hir_analysis/src/coherence/builtin.rs | |
parent | Adding debian version 1.69.0+dfsg1-1. (diff) | |
download | rustc-631cd5845e8de329d0e227aaa707d7ea228b8f8f.tar.xz rustc-631cd5845e8de329d0e227aaa707d7ea228b8f8f.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/builtin.rs')
-rw-r--r-- | compiler/rustc_hir_analysis/src/coherence/builtin.rs | 72 |
1 files changed, 40 insertions, 32 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 } } |