Rollup merge of #130764 - compiler-errors:inherent, r=estebank

Separate collection of crate-local inherent impls from error tracking

#119895 changed the return type of the `crate_inherent_impls` query from `CrateInherentImpls` to `Result<CrateInherentImpls, ErrorGuaranteed>` to avoid needing to use the non-parallel-friendly `track_errors()` to track if an error was reporting from within the query... This was mostly fine until #121113, which stopped halting compilation when we hit an `Err(ErrorGuaranteed)` in the `crate_inherent_impls` query.

Thus we proceed onwards to typeck, and since a return type of `Result<CrateInherentImpls, ErrorGuaranteed>` means that the query can *either* return one of "the list inherent impls" or "error has been reported", later on when we want to assemble method or associated item candidates for inherent impls, we were just treating any `Err(ErrorGuaranteed)` return value as if Rust had no inherent impls defined anywhere at all! This leads to basically every inherent method call failing with an error, lol, which was reported in #127798.

This PR changes the `crate_inherent_impls` query to return `(CrateInherentImpls, Result<(), ErrorGuaranteed>)`, i.e. returning the inherent impls collected *and* whether an error was reported in the query itself. It firewalls the latter part of that query into a new `crate_inherent_impls_validity_check` just for the `ensure()` call.

This fixes #127798.
This commit is contained in:
Trevor Gross 2024-09-24 19:47:50 -04:00 committed by GitHub
commit 3b45f8f310
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
31 changed files with 136 additions and 144 deletions

View File

@ -22,36 +22,38 @@
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> {

View File

@ -177,8 +177,7 @@ fn check_item(&mut self, id: hir::ItemId) -> Result<(), ErrorGuaranteed> {
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

View File

@ -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,

View File

@ -1028,7 +1028,7 @@ pub(crate) fn maybe_report_similar_assoc_fn(
..
}) = 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)

View File

@ -1272,7 +1272,7 @@ fn probe_inherent_assoc_ty(
}
let candidates: Vec<_> = tcx
.inherent_impls(adt_did)?
.inherent_impls(adt_did)
.iter()
.filter_map(|&impl_| {
let (item, scope) =

View File

@ -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(());
});

View File

@ -2126,7 +2126,6 @@ fn report_private_fields(
.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| {

View File

@ -728,13 +728,13 @@ fn assemble_inherent_candidates_for_incoherent_ty(&mut self, self_ty: Ty<'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);
}

View File

@ -680,7 +680,6 @@ fn report_no_match_method_error(
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 @@ fn report_no_match_method_error(
.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 @@ pub(crate) fn confusable_method_name(
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 @@ fn find_builder_fn(&self, err: &mut Diag<'_>, rcvr_ty: Ty<'tcx>, expr_id: hir::H
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 @@ fn report_failed_method_call_on_numerical_infer_var(
.and_then(|simp| {
tcx.incoherent_impls(simp)
.into_iter()
.flatten()
.find_map(|&id| self.associated_value(id, item_name))
})
.is_some()

View File

@ -347,7 +347,7 @@ fn into_args(self) -> (DefId, SimplifiedType) {
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 @@ fn into_args(self) -> (DefId, SimplifiedType) {
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 => {

View File

@ -1540,7 +1540,7 @@ fn encode_def_ids(&mut self) {
}
}
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 @@ fn encode_incoherent_impls(&mut self) -> LazyArray<IncoherentImpls> {
let all_impls: Vec<_> = tcx
.crate_inherent_impls(())
.unwrap()
.0
.incoherent_impls
.iter()
.map(|(&simp, impls)| IncoherentImpls {

View File

@ -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),+ $(,)?) => {
$(

View File

@ -881,13 +881,13 @@
/// 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 @@
/// 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 @@
///
/// 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
}

View File

@ -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] {

View File

@ -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,

View File

@ -1825,10 +1825,12 @@ fn suggest_alternative_construction_methods(
// 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.

View File

@ -373,7 +373,7 @@ pub(crate) fn build_impls(
let tcx = cx.tcx;
// for each implementation of an item represented by `did`, build the clean::Item for that impl
for &did in tcx.inherent_impls(did).into_iter().flatten() {
for &did in tcx.inherent_impls(did).into_iter() {
cx.with_param_env(did, |cx| {
build_impl(cx, did, attrs, ret);
});
@ -388,7 +388,7 @@ pub(crate) fn build_impls(
if tcx.has_attr(did, sym::rustc_has_incoherent_inherent_impls) {
let type_ =
if tcx.is_trait(did) { SimplifiedType::Trait(did) } else { SimplifiedType::Adt(did) };
for &did in tcx.incoherent_impls(type_).into_iter().flatten() {
for &did in tcx.incoherent_impls(type_).into_iter() {
cx.with_param_env(did, |cx| {
build_impl(cx, did, attrs, ret);
});

View File

@ -1863,7 +1863,7 @@ pub(crate) fn impls<'tcx>(&self, tcx: TyCtxt<'tcx>) -> impl Iterator<Item = DefI
.get(self)
.into_iter()
.flatten()
.flat_map(move |&simp| tcx.incoherent_impls(simp).into_iter().flatten())
.flat_map(move |&simp| tcx.incoherent_impls(simp).into_iter())
.copied()
}
@ -1871,7 +1871,7 @@ pub(crate) fn all_impls(tcx: TyCtxt<'_>) -> impl Iterator<Item = DefId> + '_ {
Self::simplified_types()
.values()
.flatten()
.flat_map(move |&simp| tcx.incoherent_impls(simp).into_iter().flatten())
.flat_map(move |&simp| tcx.incoherent_impls(simp).into_iter())
.copied()
}

View File

@ -608,7 +608,6 @@ fn resolve_associated_item(
let mut assoc_items: Vec<_> = tcx
.inherent_impls(did)
.into_iter()
.flatten()
.flat_map(|&imp| {
filter_assoc_items_by_name_and_namespace(
tcx,

View File

@ -386,7 +386,6 @@ fn has_unsafe<'tcx>(cx: &LateContext<'tcx>, item: &'tcx Item<'_>) -> bool {
.tcx
.inherent_impls(def.did())
.into_iter()
.flatten()
.map(|imp_did| cx.tcx.hir().expect_item(imp_did.expect_local()))
.any(|imp| has_unsafe(cx, imp))
{

View File

@ -51,9 +51,7 @@ fn check_crate_post(&mut self, cx: &LateContext<'tcx>) {
// List of spans to lint. (lint_span, first_span)
let mut lint_spans = Vec::new();
let Ok(impls) = cx.tcx.crate_inherent_impls(()) else {
return;
};
let (impls, _) = cx.tcx.crate_inherent_impls(());
for (&id, impl_ids) in &impls.inherent_impls {
if impl_ids.len() < 2

View File

@ -448,7 +448,6 @@ fn check_for_is_empty(
.tcx
.inherent_impls(impl_ty)
.into_iter()
.flatten()
.flat_map(|&id| cx.tcx.associated_items(id).filter_by_name_unhygienic(is_empty))
.find(|item| item.kind == AssocKind::Fn);
@ -616,7 +615,7 @@ fn is_is_empty(cx: &LateContext<'_>, item: &ty::AssocItem) -> bool {
/// Checks the inherent impl's items for an `is_empty(self)` method.
fn has_is_empty_impl(cx: &LateContext<'_>, id: DefId) -> bool {
let is_empty = sym!(is_empty);
cx.tcx.inherent_impls(id).into_iter().flatten().any(|imp| {
cx.tcx.inherent_impls(id).into_iter().any(|imp| {
cx.tcx
.associated_items(*imp)
.filter_by_name_unhygienic(is_empty)

View File

@ -78,7 +78,6 @@ fn check_unwrap_or_default(
cx.tcx
.inherent_impls(adt_def.did())
.into_iter()
.flatten()
.flat_map(|impl_id| cx.tcx.associated_items(impl_id).filter_by_name_unhygienic(sugg))
.find_map(|assoc| {
if assoc.fn_has_self_parameter

View File

@ -589,14 +589,11 @@ fn find_primitive_impls<'tcx>(tcx: TyCtxt<'tcx>, name: &str) -> impl Iterator<It
"f32" => SimplifiedType::Float(FloatTy::F32),
"f64" => SimplifiedType::Float(FloatTy::F64),
_ => {
return Result::<&[_], rustc_errors::ErrorGuaranteed>::Ok(&[])
.into_iter()
.flatten()
.copied();
return [].iter().copied();
},
};
tcx.incoherent_impls(ty).into_iter().flatten().copied()
tcx.incoherent_impls(ty).into_iter().copied()
}
fn non_local_item_children_by_name(tcx: TyCtxt<'_>, def_id: DefId, name: Symbol) -> Vec<Res> {
@ -721,7 +718,6 @@ fn find_crates(tcx: TyCtxt<'_>, name: Symbol) -> impl Iterator<Item = DefId> + '
let inherent_impl_children = tcx
.inherent_impls(def_id)
.into_iter()
.flatten()
.flat_map(|&impl_def_id| item_children_by_name(tcx, impl_def_id, segment));
let direct_children = item_children_by_name(tcx, def_id, segment);

View File

@ -1316,7 +1316,7 @@ pub fn deref_chain<'cx, 'tcx>(cx: &'cx LateContext<'tcx>, ty: Ty<'tcx>) -> impl
/// If you need this, you should wrap this call in `clippy_utils::ty::deref_chain().any(...)`.
pub fn get_adt_inherent_method<'a>(cx: &'a LateContext<'_>, ty: Ty<'_>, method_name: Symbol) -> Option<&'a AssocItem> {
if let Some(ty_did) = ty.ty_adt_def().map(AdtDef::did) {
cx.tcx.inherent_impls(ty_did).into_iter().flatten().find_map(|&did| {
cx.tcx.inherent_impls(ty_did).into_iter().find_map(|&did| {
cx.tcx
.associated_items(did)
.filter_by_name_unhygienic(method_name)

View File

@ -15,6 +15,5 @@ impl<T: ?Sized> Identity for T {
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) {}
}

View File

@ -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 1 previous error
error: aborting due to 2 previous errors
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`.

View File

@ -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

View File

@ -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) {}
| ^^^^^^^^^^^^^^

View File

@ -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;
}

View File

@ -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`.