about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2024-09-23 18:07:42 -0400
committerMichael Goulet <michael@errs.io>2024-09-24 10:12:05 -0400
commitcfb8419900c1511b09320d70105128ce13de6e71 (patch)
tree18639f6acb0e7039aea584d3d77bde7e2c7cfa68
parent11e760b7f4e4aaa11bf51a64d4bb7f1171f6e466 (diff)
downloadrust-cfb8419900c1511b09320d70105128ce13de6e71.tar.gz
rust-cfb8419900c1511b09320d70105128ce13de6e71.zip
Separate collection of crate-local inherent impls from error reporting
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs34
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs3
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/mod.rs6
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/lib.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/expr.rs1
-rw-r--r--compiler/rustc_hir_typeck/src/method/probe.rs4
-rw-r--r--compiler/rustc_hir_typeck/src/method/suggest.rs11
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs4
-rw-r--r--compiler/rustc_metadata/src/rmeta/encoder.rs4
-rw-r--r--compiler/rustc_middle/src/query/erase.rs6
-rw-r--r--compiler/rustc_middle/src/query/mod.rs14
-rw-r--r--compiler/rustc_middle/src/ty/trait_def.rs20
-rw-r--r--compiler/rustc_monomorphize/src/collector.rs2
-rw-r--r--compiler/rustc_resolve/src/late/diagnostics.rs6
-rw-r--r--tests/ui/const-generics/wrong-normalization.rs1
-rw-r--r--tests/ui/const-generics/wrong-normalization.stderr16
-rw-r--r--tests/ui/impl-trait/where-allowed.rs3
-rw-r--r--tests/ui/impl-trait/where-allowed.stderr86
-rw-r--r--tests/ui/traits/incoherent-impl-ambiguity.rs14
-rw-r--r--tests/ui/traits/incoherent-impl-ambiguity.stderr11
22 files changed, 127 insertions, 125 deletions
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/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/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/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/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_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs
index 8d137b8d8f9..ee6b56ca753 100644
--- a/compiler/rustc_monomorphize/src/collector.rs
+++ b/compiler/rustc_monomorphize/src/collector.rs
@@ -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/tests/ui/const-generics/wrong-normalization.rs b/tests/ui/const-generics/wrong-normalization.rs
index 8b2323e3d47..f1ce317b3f7 100644
--- a/tests/ui/const-generics/wrong-normalization.rs
+++ b/tests/ui/const-generics/wrong-normalization.rs
@@ -15,6 +15,5 @@ pub struct I8<const F: i8>;
 
 impl <I8<{i8::MIN}> as Identity>::Identity {
 //~^ ERROR no nominal type found for inherent implementation
-//~| ERROR no associated item named `MIN` found for type `i8`
     pub fn foo(&self) {}
 }
diff --git a/tests/ui/const-generics/wrong-normalization.stderr b/tests/ui/const-generics/wrong-normalization.stderr
index 379a5593dd6..2f8dfc895b2 100644
--- a/tests/ui/const-generics/wrong-normalization.stderr
+++ b/tests/ui/const-generics/wrong-normalization.stderr
@@ -6,18 +6,6 @@ LL | impl <I8<{i8::MIN}> as Identity>::Identity {
    |
    = note: either implement a trait on it or create a newtype to wrap it instead
 
-error[E0599]: no associated item named `MIN` found for type `i8` in the current scope
-  --> $DIR/wrong-normalization.rs:16:15
-   |
-LL | impl <I8<{i8::MIN}> as Identity>::Identity {
-   |               ^^^ associated item not found in `i8`
-   |
-help: you are looking for the module in `std`, not the primitive type
-   |
-LL | impl <I8<{std::i8::MIN}> as Identity>::Identity {
-   |           +++++
-
-error: aborting due to 2 previous errors
+error: aborting due to 1 previous error
 
-Some errors have detailed explanations: E0118, E0599.
-For more information about an error, try `rustc --explain E0118`.
+For more information about this error, try `rustc --explain E0118`.
diff --git a/tests/ui/impl-trait/where-allowed.rs b/tests/ui/impl-trait/where-allowed.rs
index 72ce617693e..3f435f0f443 100644
--- a/tests/ui/impl-trait/where-allowed.rs
+++ b/tests/ui/impl-trait/where-allowed.rs
@@ -42,7 +42,7 @@ fn in_dyn_Fn_return_in_parameters(_: &dyn Fn() -> impl Debug) { panic!() }
 fn in_dyn_Fn_parameter_in_return() -> &'static dyn Fn(impl Debug) { panic!() }
 //~^ ERROR `impl Trait` is not allowed in the parameters of `Fn` trait bounds
 
-// Allowed
+// Allowed (but it's still ambiguous; nothing constrains the RPIT in this body).
 fn in_dyn_Fn_return_in_return() -> &'static dyn Fn() -> impl Debug { panic!() }
 //~^ ERROR: type annotations needed
 
@@ -79,7 +79,6 @@ fn in_impl_Trait_in_parameters(_: impl Iterator<Item = impl Iterator>) { panic!(
 // Allowed
 fn in_impl_Trait_in_return() -> impl IntoIterator<Item = impl IntoIterator> {
     vec![vec![0; 10], vec![12; 7], vec![8; 3]]
-    //~^ ERROR: no function or associated item named `into_vec` found for slice `[_]`
 }
 
 // Disallowed
diff --git a/tests/ui/impl-trait/where-allowed.stderr b/tests/ui/impl-trait/where-allowed.stderr
index 1fb69db98c1..2770a6cc40e 100644
--- a/tests/ui/impl-trait/where-allowed.stderr
+++ b/tests/ui/impl-trait/where-allowed.stderr
@@ -17,7 +17,7 @@ LL | fn in_impl_Fn_parameter_in_return() -> &'static impl Fn(impl Debug) { panic
    |                                                 outer `impl Trait`
 
 error[E0658]: `impl Trait` in associated types is unstable
-  --> $DIR/where-allowed.rs:122:16
+  --> $DIR/where-allowed.rs:121:16
    |
 LL |     type Out = impl Debug;
    |                ^^^^^^^^^^
@@ -27,7 +27,7 @@ LL |     type Out = impl Debug;
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: `impl Trait` in type aliases is unstable
-  --> $DIR/where-allowed.rs:159:23
+  --> $DIR/where-allowed.rs:158:23
    |
 LL | type InTypeAlias<R> = impl Debug;
    |                       ^^^^^^^^^^
@@ -37,7 +37,7 @@ LL | type InTypeAlias<R> = impl Debug;
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: `impl Trait` in type aliases is unstable
-  --> $DIR/where-allowed.rs:162:39
+  --> $DIR/where-allowed.rs:161:39
    |
 LL | type InReturnInTypeAlias<R> = fn() -> impl Debug;
    |                                       ^^^^^^^^^^
@@ -143,7 +143,7 @@ LL | fn in_Fn_return_in_generics<F: Fn() -> impl Debug> (_: F) { panic!() }
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
 error[E0562]: `impl Trait` is not allowed in field types
-  --> $DIR/where-allowed.rs:86:32
+  --> $DIR/where-allowed.rs:85:32
    |
 LL | struct InBraceStructField { x: impl Debug }
    |                                ^^^^^^^^^^
@@ -151,7 +151,7 @@ LL | struct InBraceStructField { x: impl Debug }
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
 error[E0562]: `impl Trait` is not allowed in field types
-  --> $DIR/where-allowed.rs:90:41
+  --> $DIR/where-allowed.rs:89:41
    |
 LL | struct InAdtInBraceStructField { x: Vec<impl Debug> }
    |                                         ^^^^^^^^^^
@@ -159,7 +159,7 @@ LL | struct InAdtInBraceStructField { x: Vec<impl Debug> }
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
 error[E0562]: `impl Trait` is not allowed in field types
-  --> $DIR/where-allowed.rs:94:27
+  --> $DIR/where-allowed.rs:93:27
    |
 LL | struct InTupleStructField(impl Debug);
    |                           ^^^^^^^^^^
@@ -167,7 +167,7 @@ LL | struct InTupleStructField(impl Debug);
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
 error[E0562]: `impl Trait` is not allowed in field types
-  --> $DIR/where-allowed.rs:99:25
+  --> $DIR/where-allowed.rs:98:25
    |
 LL |     InBraceVariant { x: impl Debug },
    |                         ^^^^^^^^^^
@@ -175,7 +175,7 @@ LL |     InBraceVariant { x: impl Debug },
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
 error[E0562]: `impl Trait` is not allowed in field types
-  --> $DIR/where-allowed.rs:101:20
+  --> $DIR/where-allowed.rs:100:20
    |
 LL |     InTupleVariant(impl Debug),
    |                    ^^^^^^^^^^
@@ -183,7 +183,7 @@ LL |     InTupleVariant(impl Debug),
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
 error[E0562]: `impl Trait` is not allowed in `extern fn` parameters
-  --> $DIR/where-allowed.rs:143:33
+  --> $DIR/where-allowed.rs:142:33
    |
 LL |     fn in_foreign_parameters(_: impl Debug);
    |                                 ^^^^^^^^^^
@@ -191,7 +191,7 @@ LL |     fn in_foreign_parameters(_: impl Debug);
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
 error[E0562]: `impl Trait` is not allowed in `extern fn` return types
-  --> $DIR/where-allowed.rs:146:31
+  --> $DIR/where-allowed.rs:145:31
    |
 LL |     fn in_foreign_return() -> impl Debug;
    |                               ^^^^^^^^^^
@@ -199,7 +199,7 @@ LL |     fn in_foreign_return() -> impl Debug;
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
 error[E0562]: `impl Trait` is not allowed in `fn` pointer return types
-  --> $DIR/where-allowed.rs:162:39
+  --> $DIR/where-allowed.rs:161:39
    |
 LL | type InReturnInTypeAlias<R> = fn() -> impl Debug;
    |                                       ^^^^^^^^^^
@@ -207,7 +207,7 @@ LL | type InReturnInTypeAlias<R> = fn() -> impl Debug;
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
 error[E0562]: `impl Trait` is not allowed in traits
-  --> $DIR/where-allowed.rs:167:16
+  --> $DIR/where-allowed.rs:166:16
    |
 LL | impl PartialEq<impl Debug> for () {
    |                ^^^^^^^^^^
@@ -215,7 +215,7 @@ LL | impl PartialEq<impl Debug> for () {
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
 error[E0562]: `impl Trait` is not allowed in impl headers
-  --> $DIR/where-allowed.rs:172:24
+  --> $DIR/where-allowed.rs:171:24
    |
 LL | impl PartialEq<()> for impl Debug {
    |                        ^^^^^^^^^^
@@ -223,7 +223,7 @@ LL | impl PartialEq<()> for impl Debug {
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
 error[E0562]: `impl Trait` is not allowed in impl headers
-  --> $DIR/where-allowed.rs:177:6
+  --> $DIR/where-allowed.rs:176:6
    |
 LL | impl impl Debug {
    |      ^^^^^^^^^^
@@ -231,7 +231,7 @@ LL | impl impl Debug {
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
 error[E0562]: `impl Trait` is not allowed in impl headers
-  --> $DIR/where-allowed.rs:183:24
+  --> $DIR/where-allowed.rs:182:24
    |
 LL | impl InInherentImplAdt<impl Debug> {
    |                        ^^^^^^^^^^
@@ -239,7 +239,7 @@ LL | impl InInherentImplAdt<impl Debug> {
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
 error[E0562]: `impl Trait` is not allowed in bounds
-  --> $DIR/where-allowed.rs:189:11
+  --> $DIR/where-allowed.rs:188:11
    |
 LL |     where impl Debug: Debug
    |           ^^^^^^^^^^
@@ -247,7 +247,7 @@ LL |     where impl Debug: Debug
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
 error[E0562]: `impl Trait` is not allowed in bounds
-  --> $DIR/where-allowed.rs:196:15
+  --> $DIR/where-allowed.rs:195:15
    |
 LL |     where Vec<impl Debug>: Debug
    |               ^^^^^^^^^^
@@ -255,7 +255,7 @@ LL |     where Vec<impl Debug>: Debug
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
 error[E0562]: `impl Trait` is not allowed in bounds
-  --> $DIR/where-allowed.rs:203:24
+  --> $DIR/where-allowed.rs:202:24
    |
 LL |     where T: PartialEq<impl Debug>
    |                        ^^^^^^^^^^
@@ -263,7 +263,7 @@ LL |     where T: PartialEq<impl Debug>
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
 error[E0562]: `impl Trait` is not allowed in the parameters of `Fn` trait bounds
-  --> $DIR/where-allowed.rs:210:17
+  --> $DIR/where-allowed.rs:209:17
    |
 LL |     where T: Fn(impl Debug)
    |                 ^^^^^^^^^^
@@ -271,7 +271,7 @@ LL |     where T: Fn(impl Debug)
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
 error[E0562]: `impl Trait` is not allowed in the return type of `Fn` trait bounds
-  --> $DIR/where-allowed.rs:217:22
+  --> $DIR/where-allowed.rs:216:22
    |
 LL |     where T: Fn() -> impl Debug
    |                      ^^^^^^^^^^
@@ -279,7 +279,7 @@ LL |     where T: Fn() -> impl Debug
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
 error[E0562]: `impl Trait` is not allowed in generic parameter defaults
-  --> $DIR/where-allowed.rs:223:40
+  --> $DIR/where-allowed.rs:222:40
    |
 LL | struct InStructGenericParamDefault<T = impl Debug>(T);
    |                                        ^^^^^^^^^^
@@ -287,7 +287,7 @@ LL | struct InStructGenericParamDefault<T = impl Debug>(T);
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
 error[E0562]: `impl Trait` is not allowed in generic parameter defaults
-  --> $DIR/where-allowed.rs:227:36
+  --> $DIR/where-allowed.rs:226:36
    |
 LL | enum InEnumGenericParamDefault<T = impl Debug> { Variant(T) }
    |                                    ^^^^^^^^^^
@@ -295,7 +295,7 @@ LL | enum InEnumGenericParamDefault<T = impl Debug> { Variant(T) }
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
 error[E0562]: `impl Trait` is not allowed in generic parameter defaults
-  --> $DIR/where-allowed.rs:231:38
+  --> $DIR/where-allowed.rs:230:38
    |
 LL | trait InTraitGenericParamDefault<T = impl Debug> {}
    |                                      ^^^^^^^^^^
@@ -303,7 +303,7 @@ LL | trait InTraitGenericParamDefault<T = impl Debug> {}
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
 error[E0562]: `impl Trait` is not allowed in generic parameter defaults
-  --> $DIR/where-allowed.rs:235:41
+  --> $DIR/where-allowed.rs:234:41
    |
 LL | type InTypeAliasGenericParamDefault<T = impl Debug> = T;
    |                                         ^^^^^^^^^^
@@ -311,7 +311,7 @@ LL | type InTypeAliasGenericParamDefault<T = impl Debug> = T;
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
 error[E0562]: `impl Trait` is not allowed in generic parameter defaults
-  --> $DIR/where-allowed.rs:239:11
+  --> $DIR/where-allowed.rs:238:11
    |
 LL | impl <T = impl Debug> T {}
    |           ^^^^^^^^^^
@@ -319,7 +319,7 @@ LL | impl <T = impl Debug> T {}
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
 error[E0562]: `impl Trait` is not allowed in generic parameter defaults
-  --> $DIR/where-allowed.rs:246:40
+  --> $DIR/where-allowed.rs:245:40
    |
 LL | fn in_method_generic_param_default<T = impl Debug>(_: T) {}
    |                                        ^^^^^^^^^^
@@ -327,7 +327,7 @@ LL | fn in_method_generic_param_default<T = impl Debug>(_: T) {}
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
 error[E0562]: `impl Trait` is not allowed in the type of variable bindings
-  --> $DIR/where-allowed.rs:252:29
+  --> $DIR/where-allowed.rs:251:29
    |
 LL |     let _in_local_variable: impl Fn() = || {};
    |                             ^^^^^^^^^
@@ -335,7 +335,7 @@ LL |     let _in_local_variable: impl Fn() = || {};
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
 error[E0562]: `impl Trait` is not allowed in closure return types
-  --> $DIR/where-allowed.rs:254:46
+  --> $DIR/where-allowed.rs:253:46
    |
 LL |     let _in_return_in_local_variable = || -> impl Fn() { || {} };
    |                                              ^^^^^^^^^
@@ -363,7 +363,7 @@ LL | fn in_impl_Fn_return_in_return() -> &'static impl Fn() -> impl Debug { pani
              where Args: Tuple, F: Fn<Args>, A: Allocator, F: ?Sized;
 
 error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
-  --> $DIR/where-allowed.rs:239:7
+  --> $DIR/where-allowed.rs:238:7
    |
 LL | impl <T = impl Debug> T {}
    |       ^^^^^^^^^^^^^^
@@ -373,25 +373,15 @@ LL | impl <T = impl Debug> T {}
    = note: `#[deny(invalid_type_param_default)]` on by default
 
 error[E0118]: no nominal type found for inherent implementation
-  --> $DIR/where-allowed.rs:239:1
+  --> $DIR/where-allowed.rs:238:1
    |
 LL | impl <T = impl Debug> T {}
    | ^^^^^^^^^^^^^^^^^^^^^^^ impl requires a nominal type
    |
    = note: either implement a trait on it or create a newtype to wrap it instead
 
-error[E0599]: no function or associated item named `into_vec` found for slice `[_]` in the current scope
-  --> $DIR/where-allowed.rs:81:5
-   |
-LL |     vec![vec![0; 10], vec![12; 7], vec![8; 3]]
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function or associated item not found in `[_]`
-   |
-help: there is an associated function `to_vec` with a similar name
-  --> $SRC_DIR/alloc/src/slice.rs:LL:COL
-   = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info)
-
 error[E0053]: method `in_trait_impl_return` has an incompatible type for trait
-  --> $DIR/where-allowed.rs:129:34
+  --> $DIR/where-allowed.rs:128:34
    |
 LL |     type Out = impl Debug;
    |                ---------- the expected opaque type
@@ -400,7 +390,7 @@ LL |     fn in_trait_impl_return() -> impl Debug { () }
    |                                  ^^^^^^^^^^ expected opaque type, found a different opaque type
    |
 note: type in trait
-  --> $DIR/where-allowed.rs:119:34
+  --> $DIR/where-allowed.rs:118:34
    |
 LL |     fn in_trait_impl_return() -> Self::Out;
    |                                  ^^^^^^^^^
@@ -413,7 +403,7 @@ LL |     fn in_trait_impl_return() -> <() as DummyTrait>::Out { () }
    |                                  ~~~~~~~~~~~~~~~~~~~~~~~
 
 error: unconstrained opaque type
-  --> $DIR/where-allowed.rs:122:16
+  --> $DIR/where-allowed.rs:121:16
    |
 LL |     type Out = impl Debug;
    |                ^^^^^^^^^^
@@ -421,7 +411,7 @@ LL |     type Out = impl Debug;
    = note: `Out` must be used in combination with a concrete type within the same impl
 
 error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
-  --> $DIR/where-allowed.rs:246:36
+  --> $DIR/where-allowed.rs:245:36
    |
 LL | fn in_method_generic_param_default<T = impl Debug>(_: T) {}
    |                                    ^^^^^^^^^^^^^^
@@ -429,13 +419,13 @@ LL | fn in_method_generic_param_default<T = impl Debug>(_: T) {}
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #36887 <https://github.com/rust-lang/rust/issues/36887>
 
-error: aborting due to 50 previous errors
+error: aborting due to 49 previous errors
 
-Some errors have detailed explanations: E0053, E0118, E0283, E0562, E0599, E0658, E0666.
+Some errors have detailed explanations: E0053, E0118, E0283, E0562, E0658, E0666.
 For more information about an error, try `rustc --explain E0053`.
 Future incompatibility report: Future breakage diagnostic:
 error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
-  --> $DIR/where-allowed.rs:239:7
+  --> $DIR/where-allowed.rs:238:7
    |
 LL | impl <T = impl Debug> T {}
    |       ^^^^^^^^^^^^^^
@@ -446,7 +436,7 @@ LL | impl <T = impl Debug> T {}
 
 Future breakage diagnostic:
 error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
-  --> $DIR/where-allowed.rs:246:36
+  --> $DIR/where-allowed.rs:245:36
    |
 LL | fn in_method_generic_param_default<T = impl Debug>(_: T) {}
    |                                    ^^^^^^^^^^^^^^
diff --git a/tests/ui/traits/incoherent-impl-ambiguity.rs b/tests/ui/traits/incoherent-impl-ambiguity.rs
new file mode 100644
index 00000000000..b5fed95e11c
--- /dev/null
+++ b/tests/ui/traits/incoherent-impl-ambiguity.rs
@@ -0,0 +1,14 @@
+// Make sure that an invalid inherent impl doesn't totally clobber all of the
+// other inherent impls, which lead to mysterious method/assoc-item probing errors.
+
+impl () {}
+//~^ ERROR cannot define inherent `impl` for primitive types
+
+struct W;
+impl W {
+    const CONST: u32 = 0;
+}
+
+fn main() {
+    let _ = W::CONST;
+}
diff --git a/tests/ui/traits/incoherent-impl-ambiguity.stderr b/tests/ui/traits/incoherent-impl-ambiguity.stderr
new file mode 100644
index 00000000000..9c050a72955
--- /dev/null
+++ b/tests/ui/traits/incoherent-impl-ambiguity.stderr
@@ -0,0 +1,11 @@
+error[E0390]: cannot define inherent `impl` for primitive types
+  --> $DIR/incoherent-impl-ambiguity.rs:4:1
+   |
+LL | impl () {}
+   | ^^^^^^^
+   |
+   = help: consider using an extension trait instead
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0390`.