diff options
Diffstat (limited to 'compiler')
7 files changed, 46 insertions, 13 deletions
diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index 379c1154e5f..d0683686d38 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -1990,6 +1990,10 @@ pub(super) fn check_type_bounds<'tcx>( impl_ty: ty::AssocItem, impl_trait_ref: ty::TraitRef<'tcx>, ) -> Result<(), ErrorGuaranteed> { + // Avoid bogus "type annotations needed `Foo: Bar`" errors on `impl Bar for Foo` in case + // other `Foo` impls are incoherent. + tcx.ensure().coherent_trait(impl_trait_ref.def_id)?; + let param_env = tcx.param_env(impl_ty.def_id); debug!(?param_env); diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 885cfbd0fe2..646a84b043c 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -1005,6 +1005,11 @@ fn check_associated_item( enter_wf_checking_ctxt(tcx, span, item_id, |wfcx| { let item = tcx.associated_item(item_id); + // Avoid bogus "type annotations needed `Foo: Bar`" errors on `impl Bar for Foo` in case + // other `Foo` impls are incoherent. + tcx.ensure() + .coherent_trait(tcx.parent(item.trait_item_def_id.unwrap_or(item_id.into())))?; + let self_ty = match item.container { ty::TraitContainer => tcx.types.self_param, ty::ImplContainer => tcx.type_of(item.container_id(tcx)).instantiate_identity(), @@ -1291,6 +1296,9 @@ fn check_impl<'tcx>( // therefore don't need to be WF (the trait's `Self: Trait` predicate // won't hold). let trait_ref = tcx.impl_trait_ref(item.owner_id).unwrap().instantiate_identity(); + // Avoid bogus "type annotations needed `Foo: Bar`" errors on `impl Bar for Foo` in case + // other `Foo` impls are incoherent. + tcx.ensure().coherent_trait(trait_ref.def_id)?; let trait_ref = wfcx.normalize( ast_trait_ref.path.span, Some(WellFormedLoc::Ty(item.hir_id().expect_owner().def_id)), diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index 454cb97ac14..2e85da98269 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -169,11 +169,11 @@ pub fn check_crate(tcx: TyCtxt<'_>) -> Result<(), ErrorGuaranteed> { tcx.sess.time("coherence_checking", || { // Check impls constrain their parameters - let mut res = + let res = tcx.hir().try_par_for_each_module(|module| tcx.ensure().check_mod_impl_wf(module)); for &trait_def_id in tcx.all_local_trait_impls(()).keys() { - res = res.and(tcx.ensure().coherent_trait(trait_def_id)); + let _ = tcx.ensure().coherent_trait(trait_def_id); } // these queries are executed for side-effects (error reporting): res.and(tcx.ensure().crate_inherent_impls(())) diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index fbe6f454dbc..1cd4b4cc4fc 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -41,7 +41,7 @@ pub fn check_legal_trait_for_method_call( receiver: Option<Span>, expr_span: Span, trait_id: DefId, -) { +) -> Result<(), ErrorGuaranteed> { if tcx.lang_items().drop_trait() == Some(trait_id) { let sugg = if let Some(receiver) = receiver.filter(|s| !s.is_empty()) { errors::ExplicitDestructorCallSugg::Snippet { @@ -51,8 +51,9 @@ pub fn check_legal_trait_for_method_call( } else { errors::ExplicitDestructorCallSugg::Empty(span) }; - tcx.dcx().emit_err(errors::ExplicitDestructorCall { span, sugg }); + return Err(tcx.dcx().emit_err(errors::ExplicitDestructorCall { span, sugg })); } + tcx.coherent_trait(trait_id) } #[derive(Debug)] diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 60eb40bd8fe..9935a215009 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -1105,13 +1105,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let container_id = assoc_item.container_id(tcx); debug!(?def_id, ?container, ?container_id); match container { - ty::TraitContainer => callee::check_legal_trait_for_method_call( - tcx, - path_span, - None, - span, - container_id, - ), + ty::TraitContainer => { + if let Err(e) = callee::check_legal_trait_for_method_call( + tcx, + path_span, + None, + span, + container_id, + ) { + self.set_tainted_by_errors(e); + } + } ty::ImplContainer => { if segments.len() == 1 { // `<T>::assoc` will end up here, and so diff --git a/compiler/rustc_hir_typeck/src/method/confirm.rs b/compiler/rustc_hir_typeck/src/method/confirm.rs index 6f18cc51b11..c8a235761de 100644 --- a/compiler/rustc_hir_typeck/src/method/confirm.rs +++ b/compiler/rustc_hir_typeck/src/method/confirm.rs @@ -630,13 +630,15 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { fn enforce_illegal_method_limitations(&self, pick: &probe::Pick<'_>) { // Disallow calls to the method `drop` defined in the `Drop` trait. if let Some(trait_def_id) = pick.item.trait_container(self.tcx) { - callee::check_legal_trait_for_method_call( + if let Err(e) = callee::check_legal_trait_for_method_call( self.tcx, self.span, Some(self.self_expr.span), self.call_expr.span, trait_def_id, - ) + ) { + self.set_tainted_by_errors(e); + } } } diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs index 1ac0f172ef4..4ef490758a3 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs @@ -2371,6 +2371,12 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { return e; } + if let Err(guar) = self.tcx.ensure().coherent_trait(trait_ref.def_id()) { + // Avoid bogus "type annotations needed `Foo: Bar`" errors on `impl Bar for Foo` in case + // other `Foo` impls are incoherent. + return guar; + } + // This is kind of a hack: it frequently happens that some earlier // error prevents types from being fully inferred, and then we get // a bunch of uninteresting errors saying something like "<generic @@ -2666,6 +2672,14 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { if let Some(e) = self.tainted_by_errors() { return e; } + + if let Err(guar) = + self.tcx.ensure().coherent_trait(self.tcx.parent(data.projection_ty.def_id)) + { + // Avoid bogus "type annotations needed `Foo: Bar`" errors on `impl Bar for Foo` in case + // other `Foo` impls are incoherent. + return guar; + } let subst = data .projection_ty .args |
