From 86a8a3beb46f7b64a5bdd393b86b2916fe082f88 Mon Sep 17 00:00:00 2001 From: Boxy Date: Fri, 30 Sep 2022 17:47:39 +0100 Subject: [PATCH 1/5] make `compare_const_impl` a query and use it in `instance.rs` --- .../rustc_hir_analysis/src/check/check.rs | 8 +- .../src/check/compare_method.rs | 98 +++++++++---------- compiler/rustc_hir_analysis/src/check/mod.rs | 1 + compiler/rustc_middle/src/query/mod.rs | 6 ++ compiler/rustc_query_impl/src/keys.rs | 11 +++ compiler/rustc_ty_utils/src/instance.rs | 38 ++----- .../associated-consts/mismatched_impl_ty_1.rs | 18 ++++ .../associated-consts/mismatched_impl_ty_2.rs | 11 +++ .../associated-consts/mismatched_impl_ty_3.rs | 11 +++ 9 files changed, 118 insertions(+), 84 deletions(-) create mode 100644 src/test/ui/associated-consts/mismatched_impl_ty_1.rs create mode 100644 src/test/ui/associated-consts/mismatched_impl_ty_2.rs create mode 100644 src/test/ui/associated-consts/mismatched_impl_ty_3.rs diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 4bbe9abaf98df..5e65446e10001 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -2,7 +2,7 @@ use crate::check::intrinsicck::InlineAsmCtxt; use super::coercion::CoerceMany; use super::compare_method::check_type_bounds; -use super::compare_method::{compare_const_impl, compare_impl_method, compare_ty_impl}; +use super::compare_method::{compare_impl_method, compare_ty_impl}; use super::*; use rustc_attr as attr; use rustc_errors::{Applicability, ErrorGuaranteed, MultiSpan}; @@ -1045,13 +1045,11 @@ fn check_impl_items_against_trait<'tcx>( match impl_item_full.kind { hir::ImplItemKind::Const(..) => { // Find associated const definition. - compare_const_impl( - tcx, + let _ = tcx.compare_assoc_const_impl_item_with_trait_item(( &ty_impl_item, - impl_item.span, &ty_trait_item, impl_trait_ref, - ); + )); } hir::ImplItemKind::Fn(..) => { let opt_trait_span = tcx.hir().span_if_local(ty_trait_item.def_id); diff --git a/compiler/rustc_hir_analysis/src/check/compare_method.rs b/compiler/rustc_hir_analysis/src/check/compare_method.rs index ae98a8f6209de..c859796d388aa 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_method.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_method.rs @@ -1300,15 +1300,15 @@ fn compare_generic_param_kinds<'tcx>( Ok(()) } -pub(crate) fn compare_const_impl<'tcx>( +/// Use `tcx.compare_assoc_const_impl_item_with_trait_item` instead +pub(crate) fn raw_compare_const_impl<'tcx>( tcx: TyCtxt<'tcx>, - impl_c: &ty::AssocItem, - impl_c_span: Span, - trait_c: &ty::AssocItem, - impl_trait_ref: ty::TraitRef<'tcx>, -) { + (impl_c, trait_c, impl_trait_ref): (&ty::AssocItem, &ty::AssocItem, ty::TraitRef<'tcx>), +) -> Result<(), ErrorGuaranteed> { debug!("compare_const_impl(impl_trait_ref={:?})", impl_trait_ref); + let impl_c_span = tcx.def_span(impl_c.def_id); + tcx.infer_ctxt().enter(|infcx| { let param_env = tcx.param_env(impl_c.def_id); let ocx = ObligationCtxt::new(&infcx); @@ -1346,68 +1346,68 @@ pub(crate) fn compare_const_impl<'tcx>( debug!("compare_const_impl: trait_ty={:?}", trait_ty); - let err = infcx + let maybe_error_reported = infcx .at(&cause, param_env) .sup(trait_ty, impl_ty) - .map(|ok| ocx.register_infer_ok_obligations(ok)); + .map(|ok| ocx.register_infer_ok_obligations(ok)) + .map_err(|terr| { + debug!( + "checking associated const for compatibility: impl ty {:?}, trait ty {:?}", + impl_ty, trait_ty + ); - if let Err(terr) = err { - debug!( - "checking associated const for compatibility: impl ty {:?}, trait ty {:?}", - impl_ty, trait_ty - ); + // Locate the Span containing just the type of the offending impl + match tcx.hir().expect_impl_item(impl_c.def_id.expect_local()).kind { + ImplItemKind::Const(ref ty, _) => cause.span = ty.span, + _ => bug!("{:?} is not a impl const", impl_c), + } - // Locate the Span containing just the type of the offending impl - match tcx.hir().expect_impl_item(impl_c.def_id.expect_local()).kind { - ImplItemKind::Const(ref ty, _) => cause.span = ty.span, - _ => bug!("{:?} is not a impl const", impl_c), - } + let mut diag = struct_span_err!( + tcx.sess, + cause.span, + E0326, + "implemented const `{}` has an incompatible type for trait", + trait_c.name + ); - let mut diag = struct_span_err!( - tcx.sess, - cause.span, - E0326, - "implemented const `{}` has an incompatible type for trait", - trait_c.name - ); + let trait_c_span = trait_c.def_id.as_local().map(|trait_c_def_id| { + // Add a label to the Span containing just the type of the const + match tcx.hir().expect_trait_item(trait_c_def_id).kind { + TraitItemKind::Const(ref ty, _) => ty.span, + _ => bug!("{:?} is not a trait const", trait_c), + } + }); - let trait_c_span = trait_c.def_id.as_local().map(|trait_c_def_id| { - // Add a label to the Span containing just the type of the const - match tcx.hir().expect_trait_item(trait_c_def_id).kind { - TraitItemKind::Const(ref ty, _) => ty.span, - _ => bug!("{:?} is not a trait const", trait_c), - } + infcx.note_type_err( + &mut diag, + &cause, + trait_c_span.map(|span| (span, "type in trait".to_owned())), + Some(infer::ValuePairs::Terms(ExpectedFound { + expected: trait_ty.into(), + found: impl_ty.into(), + })), + terr, + false, + false, + ); + diag.emit() }); - infcx.note_type_err( - &mut diag, - &cause, - trait_c_span.map(|span| (span, "type in trait".to_owned())), - Some(infer::ValuePairs::Terms(ExpectedFound { - expected: trait_ty.into(), - found: impl_ty.into(), - })), - terr, - false, - false, - ); - diag.emit(); - } - // Check that all obligations are satisfied by the implementation's // version. let errors = ocx.select_all_or_error(); if !errors.is_empty() { - infcx.report_fulfillment_errors(&errors, None, false); - return; + return Err(infcx.report_fulfillment_errors(&errors, None, false)); } + // FIXME return `ErrorReported` if region obligations error? let outlives_environment = OutlivesEnvironment::new(param_env); infcx.check_region_obligations_and_report_errors( impl_c.def_id.expect_local(), &outlives_environment, ); - }); + maybe_error_reported + }) } pub(crate) fn compare_ty_impl<'tcx>( diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs index 593a9776bde30..04e8c9c22d159 100644 --- a/compiler/rustc_hir_analysis/src/check/mod.rs +++ b/compiler/rustc_hir_analysis/src/check/mod.rs @@ -251,6 +251,7 @@ pub fn provide(providers: &mut Providers) { check_mod_item_types, region_scope_tree, collect_trait_impl_trait_tys, + compare_assoc_const_impl_item_with_trait_item: compare_method::raw_compare_const_impl, ..*providers }; } diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index fb867f8b46b10..3fdeb3dd8ba00 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -2100,4 +2100,10 @@ rustc_queries! { query permits_zero_init(key: TyAndLayout<'tcx>) -> bool { desc { "checking to see if {:?} permits being left zeroed", key.ty } } + + query compare_assoc_const_impl_item_with_trait_item( + key: (&'tcx ty::AssocItem, &'tcx ty::AssocItem, ty::TraitRef<'tcx>) + ) -> Result<(), ErrorGuaranteed> { + desc { |tcx| "checking assoc const `{}` has the same type as trait item", tcx.def_path_str(key.0.def_id) } + } } diff --git a/compiler/rustc_query_impl/src/keys.rs b/compiler/rustc_query_impl/src/keys.rs index 47762440e290b..68debcffc8570 100644 --- a/compiler/rustc_query_impl/src/keys.rs +++ b/compiler/rustc_query_impl/src/keys.rs @@ -557,3 +557,14 @@ impl<'tcx> Key for (Ty<'tcx>, ty::ValTree<'tcx>) { DUMMY_SP } } + +impl<'tcx> Key for (&'tcx ty::AssocItem, &'tcx ty::AssocItem, ty::TraitRef<'tcx>) { + #[inline(always)] + fn query_crate_is_local(&self) -> bool { + self.0.def_id.krate == LOCAL_CRATE + } + + fn default_span(&self, tcx: TyCtxt<'_>) -> Span { + tcx.def_span(self.0.def_id) + } +} diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index fa1dc90e4a24b..97e2a146d2860 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -182,40 +182,18 @@ fn resolve_associated_item<'tcx>( // a `trait` to an associated `const` definition in an `impl`, where // the definition in the `impl` has the wrong type (for which an // error has already been/will be emitted elsewhere). - // - // NB: this may be expensive, we try to skip it in all the cases where - // we know the error would've been caught (e.g. in an upstream crate). - // - // A better approach might be to just introduce a query (returning - // `Result<(), ErrorGuaranteed>`) for the check that `rustc_hir_analysis` - // performs (i.e. that the definition's type in the `impl` matches - // the declaration in the `trait`), so that we can cheaply check - // here if it failed, instead of approximating it. if leaf_def.item.kind == ty::AssocKind::Const && trait_item_id != leaf_def.item.def_id && leaf_def.item.def_id.is_local() { - let normalized_type_of = |def_id, substs| { - tcx.subst_and_normalize_erasing_regions(substs, param_env, tcx.type_of(def_id)) - }; - - let original_ty = normalized_type_of(trait_item_id, rcvr_substs); - let resolved_ty = normalized_type_of(leaf_def.item.def_id, substs); - - if original_ty != resolved_ty { - let msg = format!( - "Instance::resolve: inconsistent associated `const` type: \ - was `{}: {}` but resolved to `{}: {}`", - tcx.def_path_str_with_substs(trait_item_id, rcvr_substs), - original_ty, - tcx.def_path_str_with_substs(leaf_def.item.def_id, substs), - resolved_ty, - ); - let span = tcx.def_span(leaf_def.item.def_id); - let reported = tcx.sess.delay_span_bug(span, &msg); - - return Err(reported); - } + let impl_item = tcx.associated_item(leaf_def.item.def_id); + let trait_item = tcx.associated_item(trait_item_id); + let impl_trait_ref = tcx.impl_trait_ref(impl_item.container_id(tcx)).unwrap(); + tcx.compare_assoc_const_impl_item_with_trait_item(( + impl_item, + trait_item, + impl_trait_ref, + ))?; } Some(ty::Instance::new(leaf_def.item.def_id, substs)) diff --git a/src/test/ui/associated-consts/mismatched_impl_ty_1.rs b/src/test/ui/associated-consts/mismatched_impl_ty_1.rs new file mode 100644 index 0000000000000..4dc6c2e47a9ea --- /dev/null +++ b/src/test/ui/associated-consts/mismatched_impl_ty_1.rs @@ -0,0 +1,18 @@ +// run-pass +#![feature(generic_const_exprs)] +#![allow(incomplete_features)] + +trait MyTrait { + type ArrayType; + const SIZE: usize; + const ARRAY: Self::ArrayType; +} +impl MyTrait for () { + type ArrayType = [u8; Self::SIZE]; + const SIZE: usize = 4; + const ARRAY: [u8; Self::SIZE] = [1, 2, 3, 4]; +} + +fn main() { + let _ = <() as MyTrait>::ARRAY; +} diff --git a/src/test/ui/associated-consts/mismatched_impl_ty_2.rs b/src/test/ui/associated-consts/mismatched_impl_ty_2.rs new file mode 100644 index 0000000000000..539becfdc7c82 --- /dev/null +++ b/src/test/ui/associated-consts/mismatched_impl_ty_2.rs @@ -0,0 +1,11 @@ +// run-pass +trait Trait { + const ASSOC: fn(&'static u32); +} +impl Trait for () { + const ASSOC: for<'a> fn(&'a u32) = |_| (); +} + +fn main() { + let _ = <() as Trait>::ASSOC; +} diff --git a/src/test/ui/associated-consts/mismatched_impl_ty_3.rs b/src/test/ui/associated-consts/mismatched_impl_ty_3.rs new file mode 100644 index 0000000000000..17bcc8fe5768c --- /dev/null +++ b/src/test/ui/associated-consts/mismatched_impl_ty_3.rs @@ -0,0 +1,11 @@ +// run-pass +trait Trait { + const ASSOC: for<'a, 'b> fn(&'a u32, &'b u32); +} +impl Trait for () { + const ASSOC: for<'a> fn(&'a u32, &'a u32) = |_, _| (); +} + +fn main() { + let _ = <() as Trait>::ASSOC; +} From 831f4402aa8531544d3589158e56d5f5f5d51373 Mon Sep 17 00:00:00 2001 From: Boxy Date: Fri, 30 Sep 2022 17:56:07 +0100 Subject: [PATCH 2/5] bless --- .../associated-const-impl-wrong-lifetime.stderr | 2 +- src/test/ui/nll/trait-associated-constant.stderr | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/ui/associated-consts/associated-const-impl-wrong-lifetime.stderr b/src/test/ui/associated-consts/associated-const-impl-wrong-lifetime.stderr index de1d9589e9961..742b81535dfdf 100644 --- a/src/test/ui/associated-consts/associated-const-impl-wrong-lifetime.stderr +++ b/src/test/ui/associated-consts/associated-const-impl-wrong-lifetime.stderr @@ -2,7 +2,7 @@ error[E0308]: const not compatible with trait --> $DIR/associated-const-impl-wrong-lifetime.rs:7:5 | LL | const NAME: &'a str = "unit"; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetime mismatch + | ^^^^^^^^^^^^^^^^^^^ lifetime mismatch | = note: expected reference `&'static str` found reference `&'a str` diff --git a/src/test/ui/nll/trait-associated-constant.stderr b/src/test/ui/nll/trait-associated-constant.stderr index ae0ffd904e799..cf1c52ba7cc43 100644 --- a/src/test/ui/nll/trait-associated-constant.stderr +++ b/src/test/ui/nll/trait-associated-constant.stderr @@ -2,7 +2,7 @@ error[E0308]: const not compatible with trait --> $DIR/trait-associated-constant.rs:21:5 | LL | const AC: Option<&'c str> = None; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetime mismatch + | ^^^^^^^^^^^^^^^^^^^^^^^^^ lifetime mismatch | = note: expected enum `Option<&'b str>` found enum `Option<&'c str>` From c1a9cf42b400bab235d2d1c11d35270879d8fd60 Mon Sep 17 00:00:00 2001 From: Boxy Date: Fri, 30 Sep 2022 18:53:32 +0100 Subject: [PATCH 3/5] make query take `(LocalDefId, DefId)` --- .../rustc_hir_analysis/src/check/check.rs | 5 +-- .../src/check/compare_method.rs | 39 ++++++++++--------- compiler/rustc_middle/src/query/mod.rs | 4 +- compiler/rustc_ty_utils/src/instance.rs | 10 ++--- compiler/rustc_ty_utils/src/lib.rs | 1 + 5 files changed, 28 insertions(+), 31 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 5e65446e10001..c47fdaefd60e9 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -1046,9 +1046,8 @@ fn check_impl_items_against_trait<'tcx>( hir::ImplItemKind::Const(..) => { // Find associated const definition. let _ = tcx.compare_assoc_const_impl_item_with_trait_item(( - &ty_impl_item, - &ty_trait_item, - impl_trait_ref, + impl_item.id.def_id.def_id, + ty_impl_item.trait_item_def_id.unwrap(), )); } hir::ImplItemKind::Fn(..) => { diff --git a/compiler/rustc_hir_analysis/src/check/compare_method.rs b/compiler/rustc_hir_analysis/src/check/compare_method.rs index c859796d388aa..75e56cd4be78e 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_method.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_method.rs @@ -1,6 +1,6 @@ use super::potentially_plural_count; use crate::errors::LifetimesOrBoundsMismatchOnTrait; -use hir::def_id::DefId; +use hir::def_id::{DefId, LocalDefId}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticId, ErrorGuaranteed}; use rustc_hir as hir; @@ -1303,14 +1303,17 @@ fn compare_generic_param_kinds<'tcx>( /// Use `tcx.compare_assoc_const_impl_item_with_trait_item` instead pub(crate) fn raw_compare_const_impl<'tcx>( tcx: TyCtxt<'tcx>, - (impl_c, trait_c, impl_trait_ref): (&ty::AssocItem, &ty::AssocItem, ty::TraitRef<'tcx>), + (impl_const_item_def, trait_const_item_def): (LocalDefId, DefId), ) -> Result<(), ErrorGuaranteed> { + let impl_const_item = tcx.associated_item(impl_const_item_def); + let trait_const_item = tcx.associated_item(trait_const_item_def); + let impl_trait_ref = tcx.impl_trait_ref(impl_const_item.container_id(tcx)).unwrap(); debug!("compare_const_impl(impl_trait_ref={:?})", impl_trait_ref); - let impl_c_span = tcx.def_span(impl_c.def_id); + let impl_c_span = tcx.def_span(impl_const_item_def.to_def_id()); tcx.infer_ctxt().enter(|infcx| { - let param_env = tcx.param_env(impl_c.def_id); + let param_env = tcx.param_env(impl_const_item_def.to_def_id()); let ocx = ObligationCtxt::new(&infcx); // The below is for the most part highly similar to the procedure @@ -1322,18 +1325,18 @@ pub(crate) fn raw_compare_const_impl<'tcx>( // Create a parameter environment that represents the implementation's // method. - let impl_c_hir_id = tcx.hir().local_def_id_to_hir_id(impl_c.def_id.expect_local()); + let impl_c_hir_id = tcx.hir().local_def_id_to_hir_id(impl_const_item_def); // Compute placeholder form of impl and trait const tys. - let impl_ty = tcx.type_of(impl_c.def_id); - let trait_ty = tcx.bound_type_of(trait_c.def_id).subst(tcx, trait_to_impl_substs); + let impl_ty = tcx.type_of(impl_const_item_def.to_def_id()); + let trait_ty = tcx.bound_type_of(trait_const_item_def).subst(tcx, trait_to_impl_substs); let mut cause = ObligationCause::new( impl_c_span, impl_c_hir_id, ObligationCauseCode::CompareImplItemObligation { - impl_item_def_id: impl_c.def_id.expect_local(), - trait_item_def_id: trait_c.def_id, - kind: impl_c.kind, + impl_item_def_id: impl_const_item_def, + trait_item_def_id: trait_const_item_def, + kind: impl_const_item.kind, }, ); @@ -1357,9 +1360,9 @@ pub(crate) fn raw_compare_const_impl<'tcx>( ); // Locate the Span containing just the type of the offending impl - match tcx.hir().expect_impl_item(impl_c.def_id.expect_local()).kind { + match tcx.hir().expect_impl_item(impl_const_item_def).kind { ImplItemKind::Const(ref ty, _) => cause.span = ty.span, - _ => bug!("{:?} is not a impl const", impl_c), + _ => bug!("{:?} is not a impl const", impl_const_item), } let mut diag = struct_span_err!( @@ -1367,14 +1370,14 @@ pub(crate) fn raw_compare_const_impl<'tcx>( cause.span, E0326, "implemented const `{}` has an incompatible type for trait", - trait_c.name + trait_const_item.name ); - let trait_c_span = trait_c.def_id.as_local().map(|trait_c_def_id| { + let trait_c_span = trait_const_item_def.as_local().map(|trait_c_def_id| { // Add a label to the Span containing just the type of the const match tcx.hir().expect_trait_item(trait_c_def_id).kind { TraitItemKind::Const(ref ty, _) => ty.span, - _ => bug!("{:?} is not a trait const", trait_c), + _ => bug!("{:?} is not a trait const", trait_const_item), } }); @@ -1402,10 +1405,8 @@ pub(crate) fn raw_compare_const_impl<'tcx>( // FIXME return `ErrorReported` if region obligations error? let outlives_environment = OutlivesEnvironment::new(param_env); - infcx.check_region_obligations_and_report_errors( - impl_c.def_id.expect_local(), - &outlives_environment, - ); + infcx + .check_region_obligations_and_report_errors(impl_const_item_def, &outlives_environment); maybe_error_reported }) } diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 3fdeb3dd8ba00..10dc441b187a3 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -2102,8 +2102,8 @@ rustc_queries! { } query compare_assoc_const_impl_item_with_trait_item( - key: (&'tcx ty::AssocItem, &'tcx ty::AssocItem, ty::TraitRef<'tcx>) + key: (LocalDefId, DefId) ) -> Result<(), ErrorGuaranteed> { - desc { |tcx| "checking assoc const `{}` has the same type as trait item", tcx.def_path_str(key.0.def_id) } + desc { |tcx| "checking assoc const `{}` has the same type as trait item", tcx.def_path_str(key.0.to_def_id()) } } } diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index 97e2a146d2860..ff3cdde75a418 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -184,15 +184,11 @@ fn resolve_associated_item<'tcx>( // error has already been/will be emitted elsewhere). if leaf_def.item.kind == ty::AssocKind::Const && trait_item_id != leaf_def.item.def_id - && leaf_def.item.def_id.is_local() + && let Some(leaf_def_item) = leaf_def.item.def_id.as_local() { - let impl_item = tcx.associated_item(leaf_def.item.def_id); - let trait_item = tcx.associated_item(trait_item_id); - let impl_trait_ref = tcx.impl_trait_ref(impl_item.container_id(tcx)).unwrap(); tcx.compare_assoc_const_impl_item_with_trait_item(( - impl_item, - trait_item, - impl_trait_ref, + leaf_def_item, + trait_item_id, ))?; } diff --git a/compiler/rustc_ty_utils/src/lib.rs b/compiler/rustc_ty_utils/src/lib.rs index 10c18789f7476..9fd51e75b0e4c 100644 --- a/compiler/rustc_ty_utils/src/lib.rs +++ b/compiler/rustc_ty_utils/src/lib.rs @@ -5,6 +5,7 @@ //! This API is completely unstable and subject to change. #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] +#![feature(let_chains)] #![feature(control_flow_enum)] #![feature(never_type)] #![feature(box_patterns)] From 611db1d3f397005199c9bd9ea70535da9d16bfcd Mon Sep 17 00:00:00 2001 From: Boxy Date: Fri, 30 Sep 2022 22:52:02 +0100 Subject: [PATCH 4/5] remove unnecessary `Key` impl --- compiler/rustc_query_impl/src/keys.rs | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/compiler/rustc_query_impl/src/keys.rs b/compiler/rustc_query_impl/src/keys.rs index 68debcffc8570..47762440e290b 100644 --- a/compiler/rustc_query_impl/src/keys.rs +++ b/compiler/rustc_query_impl/src/keys.rs @@ -557,14 +557,3 @@ impl<'tcx> Key for (Ty<'tcx>, ty::ValTree<'tcx>) { DUMMY_SP } } - -impl<'tcx> Key for (&'tcx ty::AssocItem, &'tcx ty::AssocItem, ty::TraitRef<'tcx>) { - #[inline(always)] - fn query_crate_is_local(&self) -> bool { - self.0.def_id.krate == LOCAL_CRATE - } - - fn default_span(&self, tcx: TyCtxt<'_>) -> Span { - tcx.def_span(self.0.def_id) - } -} From 25ed5d5db295e1fbf27e511c9159e67c22b08f43 Mon Sep 17 00:00:00 2001 From: Boxy Date: Thu, 6 Oct 2022 07:00:38 +0100 Subject: [PATCH 5/5] reviews --- .../rustc_hir_analysis/src/check/check.rs | 1 - .../src/check/compare_method.rs | 81 ++++++++++--------- 2 files changed, 41 insertions(+), 41 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index c47fdaefd60e9..f331354a044e0 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -1044,7 +1044,6 @@ fn check_impl_items_against_trait<'tcx>( let impl_item_full = tcx.hir().impl_item(impl_item.id); match impl_item_full.kind { hir::ImplItemKind::Const(..) => { - // Find associated const definition. let _ = tcx.compare_assoc_const_impl_item_with_trait_item(( impl_item.id.def_id.def_id, ty_impl_item.trait_item_def_id.unwrap(), diff --git a/compiler/rustc_hir_analysis/src/check/compare_method.rs b/compiler/rustc_hir_analysis/src/check/compare_method.rs index 75e56cd4be78e..d006948c58793 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_method.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_method.rs @@ -1349,53 +1349,54 @@ pub(crate) fn raw_compare_const_impl<'tcx>( debug!("compare_const_impl: trait_ty={:?}", trait_ty); - let maybe_error_reported = infcx + let err = infcx .at(&cause, param_env) .sup(trait_ty, impl_ty) - .map(|ok| ocx.register_infer_ok_obligations(ok)) - .map_err(|terr| { - debug!( - "checking associated const for compatibility: impl ty {:?}, trait ty {:?}", - impl_ty, trait_ty - ); + .map(|ok| ocx.register_infer_ok_obligations(ok)); - // Locate the Span containing just the type of the offending impl - match tcx.hir().expect_impl_item(impl_const_item_def).kind { - ImplItemKind::Const(ref ty, _) => cause.span = ty.span, - _ => bug!("{:?} is not a impl const", impl_const_item), - } + if let Err(terr) = err { + debug!( + "checking associated const for compatibility: impl ty {:?}, trait ty {:?}", + impl_ty, trait_ty + ); - let mut diag = struct_span_err!( - tcx.sess, - cause.span, - E0326, - "implemented const `{}` has an incompatible type for trait", - trait_const_item.name - ); + // Locate the Span containing just the type of the offending impl + match tcx.hir().expect_impl_item(impl_const_item_def).kind { + ImplItemKind::Const(ref ty, _) => cause.span = ty.span, + _ => bug!("{:?} is not a impl const", impl_const_item), + } - let trait_c_span = trait_const_item_def.as_local().map(|trait_c_def_id| { - // Add a label to the Span containing just the type of the const - match tcx.hir().expect_trait_item(trait_c_def_id).kind { - TraitItemKind::Const(ref ty, _) => ty.span, - _ => bug!("{:?} is not a trait const", trait_const_item), - } - }); + let mut diag = struct_span_err!( + tcx.sess, + cause.span, + E0326, + "implemented const `{}` has an incompatible type for trait", + trait_const_item.name + ); - infcx.note_type_err( - &mut diag, - &cause, - trait_c_span.map(|span| (span, "type in trait".to_owned())), - Some(infer::ValuePairs::Terms(ExpectedFound { - expected: trait_ty.into(), - found: impl_ty.into(), - })), - terr, - false, - false, - ); - diag.emit() + let trait_c_span = trait_const_item_def.as_local().map(|trait_c_def_id| { + // Add a label to the Span containing just the type of the const + match tcx.hir().expect_trait_item(trait_c_def_id).kind { + TraitItemKind::Const(ref ty, _) => ty.span, + _ => bug!("{:?} is not a trait const", trait_const_item), + } }); + infcx.note_type_err( + &mut diag, + &cause, + trait_c_span.map(|span| (span, "type in trait".to_owned())), + Some(infer::ValuePairs::Terms(ExpectedFound { + expected: trait_ty.into(), + found: impl_ty.into(), + })), + terr, + false, + false, + ); + return Err(diag.emit()); + }; + // Check that all obligations are satisfied by the implementation's // version. let errors = ocx.select_all_or_error(); @@ -1407,7 +1408,7 @@ pub(crate) fn raw_compare_const_impl<'tcx>( let outlives_environment = OutlivesEnvironment::new(param_env); infcx .check_region_obligations_and_report_errors(impl_const_item_def, &outlives_environment); - maybe_error_reported + Ok(()) }) }