mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 06:44:35 +00:00
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:
commit
3b45f8f310
@ -22,36 +22,38 @@ use crate::errors;
|
|||||||
pub(crate) fn crate_inherent_impls(
|
pub(crate) fn crate_inherent_impls(
|
||||||
tcx: TyCtxt<'_>,
|
tcx: TyCtxt<'_>,
|
||||||
(): (),
|
(): (),
|
||||||
) -> Result<&'_ CrateInherentImpls, ErrorGuaranteed> {
|
) -> (&'_ CrateInherentImpls, Result<(), ErrorGuaranteed>) {
|
||||||
let mut collect = InherentCollect { tcx, impls_map: Default::default() };
|
let mut collect = InherentCollect { tcx, impls_map: Default::default() };
|
||||||
|
|
||||||
let mut res = Ok(());
|
let mut res = Ok(());
|
||||||
for id in tcx.hir().items() {
|
for id in tcx.hir().items() {
|
||||||
res = res.and(collect.check_item(id));
|
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<'_>,
|
tcx: TyCtxt<'_>,
|
||||||
simp: SimplifiedType,
|
(): (),
|
||||||
) -> Result<&[DefId], ErrorGuaranteed> {
|
) -> Result<(), ErrorGuaranteed> {
|
||||||
let crate_map = tcx.crate_inherent_impls(())?;
|
tcx.crate_inherent_impls(()).1
|
||||||
Ok(tcx.arena.alloc_from_iter(
|
}
|
||||||
|
|
||||||
|
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()),
|
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.
|
/// On-demand query: yields a vector of the inherent impls for a specific type.
|
||||||
pub(crate) fn inherent_impls(
|
pub(crate) fn inherent_impls(tcx: TyCtxt<'_>, ty_def_id: LocalDefId) -> &[DefId] {
|
||||||
tcx: TyCtxt<'_>,
|
let (crate_map, _) = tcx.crate_inherent_impls(());
|
||||||
ty_def_id: LocalDefId,
|
match crate_map.inherent_impls.get(&ty_def_id) {
|
||||||
) -> Result<&[DefId], ErrorGuaranteed> {
|
|
||||||
let crate_map = tcx.crate_inherent_impls(())?;
|
|
||||||
Ok(match crate_map.inherent_impls.get(&ty_def_id) {
|
|
||||||
Some(v) => &v[..],
|
Some(v) => &v[..],
|
||||||
None => &[],
|
None => &[],
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct InherentCollect<'tcx> {
|
struct InherentCollect<'tcx> {
|
||||||
|
@ -177,8 +177,7 @@ impl<'tcx> InherentOverlapChecker<'tcx> {
|
|||||||
return Ok(());
|
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 overlap_mode = OverlapMode::get(self.tcx, id.owner_id.to_def_id());
|
||||||
|
|
||||||
let impls_items = impls
|
let impls_items = impls
|
||||||
|
@ -124,7 +124,10 @@ fn enforce_empty_impls_for_marker_traits(
|
|||||||
|
|
||||||
pub(crate) fn provide(providers: &mut Providers) {
|
pub(crate) fn provide(providers: &mut Providers) {
|
||||||
use self::builtin::coerce_unsized_info;
|
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::inherent_impls_overlap::crate_inherent_impls_overlap_check;
|
||||||
use self::orphan::orphan_check_impl;
|
use self::orphan::orphan_check_impl;
|
||||||
|
|
||||||
@ -133,6 +136,7 @@ pub(crate) fn provide(providers: &mut Providers) {
|
|||||||
crate_inherent_impls,
|
crate_inherent_impls,
|
||||||
crate_incoherent_impls,
|
crate_incoherent_impls,
|
||||||
inherent_impls,
|
inherent_impls,
|
||||||
|
crate_inherent_impls_validity_check,
|
||||||
crate_inherent_impls_overlap_check,
|
crate_inherent_impls_overlap_check,
|
||||||
coerce_unsized_info,
|
coerce_unsized_info,
|
||||||
orphan_check_impl,
|
orphan_check_impl,
|
||||||
|
@ -1028,7 +1028,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||||||
..
|
..
|
||||||
}) = node
|
}) = node
|
||||||
&& let Some(ty_def_id) = qself_ty.ty_def_id()
|
&& 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 name = format!("{ident2}_{ident3}")
|
||||||
&& let Some(ty::AssocItem { kind: ty::AssocKind::Fn, .. }) = tcx
|
&& let Some(ty::AssocItem { kind: ty::AssocKind::Fn, .. }) = tcx
|
||||||
.associated_items(inherent_impl)
|
.associated_items(inherent_impl)
|
||||||
|
@ -1272,7 +1272,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let candidates: Vec<_> = tcx
|
let candidates: Vec<_> = tcx
|
||||||
.inherent_impls(adt_did)?
|
.inherent_impls(adt_did)
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|&impl_| {
|
.filter_map(|&impl_| {
|
||||||
let (item, scope) =
|
let (item, scope) =
|
||||||
|
@ -170,7 +170,7 @@ pub fn check_crate(tcx: TyCtxt<'_>) {
|
|||||||
let _ = tcx.ensure().coherent_trait(trait_def_id);
|
let _ = tcx.ensure().coherent_trait(trait_def_id);
|
||||||
}
|
}
|
||||||
// these queries are executed for side-effects (error reporting):
|
// 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(());
|
let _ = tcx.ensure().crate_inherent_impls_overlap_check(());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -2126,7 +2126,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
.tcx
|
.tcx
|
||||||
.inherent_impls(def_id)
|
.inherent_impls(def_id)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.flatten()
|
|
||||||
.flat_map(|i| self.tcx.associated_items(i).in_definition_order())
|
.flat_map(|i| self.tcx.associated_items(i).in_definition_order())
|
||||||
// Only assoc fn with no receivers.
|
// Only assoc fn with no receivers.
|
||||||
.filter(|item| {
|
.filter(|item| {
|
||||||
|
@ -728,13 +728,13 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
|||||||
let Some(simp) = simplify_type(self.tcx, self_ty, TreatParams::InstantiateWithInfer) else {
|
let Some(simp) = simplify_type(self.tcx, self_ty, TreatParams::InstantiateWithInfer) else {
|
||||||
bug!("unexpected incoherent type: {:?}", self_ty)
|
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);
|
self.assemble_inherent_impl_probe(impl_def_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn assemble_inherent_impl_candidates_for_type(&mut self, def_id: DefId) {
|
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 {
|
for &impl_def_id in impl_def_ids {
|
||||||
self.assemble_inherent_impl_probe(impl_def_id);
|
self.assemble_inherent_impl_probe(impl_def_id);
|
||||||
}
|
}
|
||||||
|
@ -680,7 +680,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
self.tcx
|
self.tcx
|
||||||
.inherent_impls(adt_def.did())
|
.inherent_impls(adt_def.did())
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.flatten()
|
|
||||||
.any(|def_id| self.associated_value(*def_id, item_name).is_some())
|
.any(|def_id| self.associated_value(*def_id, item_name).is_some())
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
@ -1438,7 +1437,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
.tcx
|
.tcx
|
||||||
.inherent_impls(adt.did())
|
.inherent_impls(adt.did())
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.flatten()
|
|
||||||
.copied()
|
.copied()
|
||||||
.filter(|def_id| {
|
.filter(|def_id| {
|
||||||
if let Some(assoc) = self.associated_value(*def_id, item_name) {
|
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>>>,
|
call_args: Option<Vec<Ty<'tcx>>>,
|
||||||
) -> Option<Symbol> {
|
) -> Option<Symbol> {
|
||||||
if let ty::Adt(adt, adt_args) = rcvr_ty.kind() {
|
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
|
for inherent_method in
|
||||||
self.tcx.associated_items(inherent_impl_did).in_definition_order()
|
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 {
|
let ty::Adt(adt_def, _) = rcvr_ty.kind() else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
// FIXME(oli-obk): try out bubbling this error up one level and cancelling the other error in that case.
|
let mut items = self
|
||||||
let Ok(impls) = self.tcx.inherent_impls(adt_def.did()) else { return };
|
.tcx
|
||||||
let mut items = impls
|
.inherent_impls(adt_def.did())
|
||||||
.iter()
|
.iter()
|
||||||
.flat_map(|i| self.tcx.associated_items(i).in_definition_order())
|
.flat_map(|i| self.tcx.associated_items(i).in_definition_order())
|
||||||
// Only assoc fn with no receivers and only if
|
// Only assoc fn with no receivers and only if
|
||||||
@ -2495,7 +2493,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
.and_then(|simp| {
|
.and_then(|simp| {
|
||||||
tcx.incoherent_impls(simp)
|
tcx.incoherent_impls(simp)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.flatten()
|
|
||||||
.find_map(|&id| self.associated_value(id, item_name))
|
.find_map(|&id| self.associated_value(id, item_name))
|
||||||
})
|
})
|
||||||
.is_some()
|
.is_some()
|
||||||
|
@ -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))
|
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) }
|
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)) }
|
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_mir_available => { cdata.is_item_mir_available(def_id.index) }
|
||||||
is_ctfe_mir_available => { cdata.is_ctfe_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()) }
|
traits => { tcx.arena.alloc_from_iter(cdata.get_traits()) }
|
||||||
trait_impls_in_crate => { tcx.arena.alloc_from_iter(cdata.get_trait_impls()) }
|
trait_impls_in_crate => { tcx.arena.alloc_from_iter(cdata.get_trait_impls()) }
|
||||||
implementations_of_trait => { cdata.get_implementations_of_trait(tcx, other) }
|
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 }
|
dep_kind => { cdata.dep_kind }
|
||||||
module_children => {
|
module_children => {
|
||||||
|
@ -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| {
|
record_defaulted_array!(self.tables.inherent_impls[def_id.to_def_id()] <- impls.iter().map(|def_id| {
|
||||||
assert!(def_id.is_local());
|
assert!(def_id.is_local());
|
||||||
def_id.index
|
def_id.index
|
||||||
@ -2089,7 +2089,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
|||||||
|
|
||||||
let all_impls: Vec<_> = tcx
|
let all_impls: Vec<_> = tcx
|
||||||
.crate_inherent_impls(())
|
.crate_inherent_impls(())
|
||||||
.unwrap()
|
.0
|
||||||
.incoherent_impls
|
.incoherent_impls
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(&simp, impls)| IncoherentImpls {
|
.map(|(&simp, impls)| IncoherentImpls {
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
use std::intrinsics::transmute_unchecked;
|
use std::intrinsics::transmute_unchecked;
|
||||||
use std::mem::MaybeUninit;
|
use std::mem::MaybeUninit;
|
||||||
|
|
||||||
|
use rustc_span::ErrorGuaranteed;
|
||||||
|
|
||||||
use crate::query::CyclePlaceholder;
|
use crate::query::CyclePlaceholder;
|
||||||
use crate::ty::adjustment::CoerceUnsizedInfo;
|
use crate::ty::adjustment::CoerceUnsizedInfo;
|
||||||
use crate::ty::{self, Ty};
|
use crate::ty::{self, Ty};
|
||||||
@ -216,6 +218,10 @@ impl<T0, T1> EraseType for (&'_ T0, &'_ [T1]) {
|
|||||||
type Result = [u8; size_of::<(&'static (), &'static [()])>()];
|
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 {
|
macro_rules! trivial {
|
||||||
($($ty:ty),+ $(,)?) => {
|
($($ty:ty),+ $(,)?) => {
|
||||||
$(
|
$(
|
||||||
|
@ -881,13 +881,13 @@ rustc_queries! {
|
|||||||
/// Maps a `DefId` of a type to a list of its inherent impls.
|
/// Maps a `DefId` of a type to a list of its inherent impls.
|
||||||
/// Contains implementations of methods that are inherent to a type.
|
/// Contains implementations of methods that are inherent to a type.
|
||||||
/// Methods in these implementations don't need to be exported.
|
/// 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) }
|
desc { |tcx| "collecting inherent impls for `{}`", tcx.def_path_str(key) }
|
||||||
cache_on_disk_if { key.is_local() }
|
cache_on_disk_if { key.is_local() }
|
||||||
separate_provide_extern
|
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 }
|
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.
|
/// Gets a complete map from all types to their inherent impls.
|
||||||
/// Not meant to be used directly outside of coherence.
|
/// 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" }
|
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
|
ensure_forwards_result_if_red
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1715,7 +1721,7 @@ rustc_queries! {
|
|||||||
///
|
///
|
||||||
/// Do not call this directly, but instead use the `incoherent_impls` query.
|
/// 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.
|
/// 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" }
|
desc { |tcx| "collecting all impls for a type in a crate" }
|
||||||
separate_provide_extern
|
separate_provide_extern
|
||||||
}
|
}
|
||||||
|
@ -253,30 +253,16 @@ pub(super) fn trait_impls_of_provider(tcx: TyCtxt<'_>, trait_id: DefId) -> Trait
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Query provider for `incoherent_impls`.
|
/// Query provider for `incoherent_impls`.
|
||||||
pub(super) fn incoherent_impls_provider(
|
pub(super) fn incoherent_impls_provider(tcx: TyCtxt<'_>, simp: SimplifiedType) -> &[DefId] {
|
||||||
tcx: TyCtxt<'_>,
|
|
||||||
simp: SimplifiedType,
|
|
||||||
) -> Result<&[DefId], ErrorGuaranteed> {
|
|
||||||
let mut impls = Vec::new();
|
let mut impls = Vec::new();
|
||||||
|
|
||||||
let mut res = Ok(());
|
|
||||||
for cnum in iter::once(LOCAL_CRATE).chain(tcx.crates(()).iter().copied()) {
|
for cnum in iter::once(LOCAL_CRATE).chain(tcx.crates(()).iter().copied()) {
|
||||||
let incoherent_impls = match tcx.crate_incoherent_impls((cnum, simp)) {
|
for &impl_def_id in tcx.crate_incoherent_impls((cnum, simp)) {
|
||||||
Ok(impls) => impls,
|
|
||||||
Err(e) => {
|
|
||||||
res = Err(e);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
for &impl_def_id in incoherent_impls {
|
|
||||||
impls.push(impl_def_id)
|
impls.push(impl_def_id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
debug!(?impls);
|
debug!(?impls);
|
||||||
res?;
|
|
||||||
|
|
||||||
Ok(tcx.arena.alloc_slice(&impls))
|
tcx.arena.alloc_slice(&impls)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn traits_provider(tcx: TyCtxt<'_>, _: LocalCrate) -> &[DefId] {
|
pub(super) fn traits_provider(tcx: TyCtxt<'_>, _: LocalCrate) -> &[DefId] {
|
||||||
|
@ -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> {
|
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(
|
if let Some(new) = tcx.associated_items(impl_def_id).find_by_name_and_kind(
|
||||||
tcx,
|
tcx,
|
||||||
fn_ident,
|
fn_ident,
|
||||||
|
@ -1825,10 +1825,12 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
|
|||||||
// Doing analysis on local `DefId`s would cause infinite recursion.
|
// Doing analysis on local `DefId`s would cause infinite recursion.
|
||||||
return;
|
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
|
// Look at all the associated functions without receivers in the type's
|
||||||
// inherent impls to look for builders that return `Self`
|
// inherent impls to look for builders that return `Self`
|
||||||
let mut items = impls
|
let mut items = self
|
||||||
|
.r
|
||||||
|
.tcx
|
||||||
|
.inherent_impls(def_id)
|
||||||
.iter()
|
.iter()
|
||||||
.flat_map(|i| self.r.tcx.associated_items(i).in_definition_order())
|
.flat_map(|i| self.r.tcx.associated_items(i).in_definition_order())
|
||||||
// Only assoc fn with no receivers.
|
// Only assoc fn with no receivers.
|
||||||
|
@ -373,7 +373,7 @@ pub(crate) fn build_impls(
|
|||||||
let tcx = cx.tcx;
|
let tcx = cx.tcx;
|
||||||
|
|
||||||
// for each implementation of an item represented by `did`, build the clean::Item for that impl
|
// 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| {
|
cx.with_param_env(did, |cx| {
|
||||||
build_impl(cx, did, attrs, ret);
|
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) {
|
if tcx.has_attr(did, sym::rustc_has_incoherent_inherent_impls) {
|
||||||
let type_ =
|
let type_ =
|
||||||
if tcx.is_trait(did) { SimplifiedType::Trait(did) } else { SimplifiedType::Adt(did) };
|
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| {
|
cx.with_param_env(did, |cx| {
|
||||||
build_impl(cx, did, attrs, ret);
|
build_impl(cx, did, attrs, ret);
|
||||||
});
|
});
|
||||||
|
@ -1863,7 +1863,7 @@ impl PrimitiveType {
|
|||||||
.get(self)
|
.get(self)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.flatten()
|
.flatten()
|
||||||
.flat_map(move |&simp| tcx.incoherent_impls(simp).into_iter().flatten())
|
.flat_map(move |&simp| tcx.incoherent_impls(simp).into_iter())
|
||||||
.copied()
|
.copied()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1871,7 +1871,7 @@ impl PrimitiveType {
|
|||||||
Self::simplified_types()
|
Self::simplified_types()
|
||||||
.values()
|
.values()
|
||||||
.flatten()
|
.flatten()
|
||||||
.flat_map(move |&simp| tcx.incoherent_impls(simp).into_iter().flatten())
|
.flat_map(move |&simp| tcx.incoherent_impls(simp).into_iter())
|
||||||
.copied()
|
.copied()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -608,7 +608,6 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
|
|||||||
let mut assoc_items: Vec<_> = tcx
|
let mut assoc_items: Vec<_> = tcx
|
||||||
.inherent_impls(did)
|
.inherent_impls(did)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.flatten()
|
|
||||||
.flat_map(|&imp| {
|
.flat_map(|&imp| {
|
||||||
filter_assoc_items_by_name_and_namespace(
|
filter_assoc_items_by_name_and_namespace(
|
||||||
tcx,
|
tcx,
|
||||||
|
@ -386,7 +386,6 @@ fn check_unsafe_derive_deserialize<'tcx>(
|
|||||||
.tcx
|
.tcx
|
||||||
.inherent_impls(def.did())
|
.inherent_impls(def.did())
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.flatten()
|
|
||||||
.map(|imp_did| cx.tcx.hir().expect_item(imp_did.expect_local()))
|
.map(|imp_did| cx.tcx.hir().expect_item(imp_did.expect_local()))
|
||||||
.any(|imp| has_unsafe(cx, imp))
|
.any(|imp| has_unsafe(cx, imp))
|
||||||
{
|
{
|
||||||
|
@ -51,9 +51,7 @@ impl<'tcx> LateLintPass<'tcx> for MultipleInherentImpl {
|
|||||||
// List of spans to lint. (lint_span, first_span)
|
// List of spans to lint. (lint_span, first_span)
|
||||||
let mut lint_spans = Vec::new();
|
let mut lint_spans = Vec::new();
|
||||||
|
|
||||||
let Ok(impls) = cx.tcx.crate_inherent_impls(()) else {
|
let (impls, _) = cx.tcx.crate_inherent_impls(());
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
for (&id, impl_ids) in &impls.inherent_impls {
|
for (&id, impl_ids) in &impls.inherent_impls {
|
||||||
if impl_ids.len() < 2
|
if impl_ids.len() < 2
|
||||||
|
@ -448,7 +448,6 @@ fn check_for_is_empty(
|
|||||||
.tcx
|
.tcx
|
||||||
.inherent_impls(impl_ty)
|
.inherent_impls(impl_ty)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.flatten()
|
|
||||||
.flat_map(|&id| cx.tcx.associated_items(id).filter_by_name_unhygienic(is_empty))
|
.flat_map(|&id| cx.tcx.associated_items(id).filter_by_name_unhygienic(is_empty))
|
||||||
.find(|item| item.kind == AssocKind::Fn);
|
.find(|item| item.kind == AssocKind::Fn);
|
||||||
|
|
||||||
@ -616,7 +615,7 @@ fn has_is_empty(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
|
|||||||
/// Checks the inherent impl's items for an `is_empty(self)` method.
|
/// Checks the inherent impl's items for an `is_empty(self)` method.
|
||||||
fn has_is_empty_impl(cx: &LateContext<'_>, id: DefId) -> bool {
|
fn has_is_empty_impl(cx: &LateContext<'_>, id: DefId) -> bool {
|
||||||
let is_empty = sym!(is_empty);
|
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
|
cx.tcx
|
||||||
.associated_items(*imp)
|
.associated_items(*imp)
|
||||||
.filter_by_name_unhygienic(is_empty)
|
.filter_by_name_unhygienic(is_empty)
|
||||||
|
@ -78,7 +78,6 @@ pub(super) fn check<'tcx>(
|
|||||||
cx.tcx
|
cx.tcx
|
||||||
.inherent_impls(adt_def.did())
|
.inherent_impls(adt_def.did())
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.flatten()
|
|
||||||
.flat_map(|impl_id| cx.tcx.associated_items(impl_id).filter_by_name_unhygienic(sugg))
|
.flat_map(|impl_id| cx.tcx.associated_items(impl_id).filter_by_name_unhygienic(sugg))
|
||||||
.find_map(|assoc| {
|
.find_map(|assoc| {
|
||||||
if assoc.fn_has_self_parameter
|
if assoc.fn_has_self_parameter
|
||||||
|
@ -589,14 +589,11 @@ fn find_primitive_impls<'tcx>(tcx: TyCtxt<'tcx>, name: &str) -> impl Iterator<It
|
|||||||
"f32" => SimplifiedType::Float(FloatTy::F32),
|
"f32" => SimplifiedType::Float(FloatTy::F32),
|
||||||
"f64" => SimplifiedType::Float(FloatTy::F64),
|
"f64" => SimplifiedType::Float(FloatTy::F64),
|
||||||
_ => {
|
_ => {
|
||||||
return Result::<&[_], rustc_errors::ErrorGuaranteed>::Ok(&[])
|
return [].iter().copied();
|
||||||
.into_iter()
|
|
||||||
.flatten()
|
|
||||||
.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> {
|
fn non_local_item_children_by_name(tcx: TyCtxt<'_>, def_id: DefId, name: Symbol) -> Vec<Res> {
|
||||||
@ -721,7 +718,6 @@ pub fn def_path_res(tcx: TyCtxt<'_>, path: &[&str]) -> Vec<Res> {
|
|||||||
let inherent_impl_children = tcx
|
let inherent_impl_children = tcx
|
||||||
.inherent_impls(def_id)
|
.inherent_impls(def_id)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.flatten()
|
|
||||||
.flat_map(|&impl_def_id| item_children_by_name(tcx, impl_def_id, segment));
|
.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);
|
let direct_children = item_children_by_name(tcx, def_id, segment);
|
||||||
|
@ -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(...)`.
|
/// 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> {
|
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) {
|
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
|
cx.tcx
|
||||||
.associated_items(did)
|
.associated_items(did)
|
||||||
.filter_by_name_unhygienic(method_name)
|
.filter_by_name_unhygienic(method_name)
|
||||||
|
@ -15,6 +15,5 @@ pub struct I8<const F: i8>;
|
|||||||
|
|
||||||
impl <I8<{i8::MIN}> as Identity>::Identity {
|
impl <I8<{i8::MIN}> as Identity>::Identity {
|
||||||
//~^ ERROR no nominal type found for inherent implementation
|
//~^ ERROR no nominal type found for inherent implementation
|
||||||
//~| ERROR no associated item named `MIN` found for type `i8`
|
|
||||||
pub fn foo(&self) {}
|
pub fn foo(&self) {}
|
||||||
}
|
}
|
||||||
|
@ -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
|
= 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
|
error: aborting due to 1 previous error
|
||||||
--> $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
|
For more information about this error, try `rustc --explain E0118`.
|
||||||
|
|
||||||
Some errors have detailed explanations: E0118, E0599.
|
|
||||||
For more information about an error, try `rustc --explain E0118`.
|
|
||||||
|
@ -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!() }
|
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
|
//~^ 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!() }
|
fn in_dyn_Fn_return_in_return() -> &'static dyn Fn() -> impl Debug { panic!() }
|
||||||
//~^ ERROR: type annotations needed
|
//~^ ERROR: type annotations needed
|
||||||
|
|
||||||
@ -79,7 +79,6 @@ fn in_impl_Trait_in_parameters(_: impl Iterator<Item = impl Iterator>) { panic!(
|
|||||||
// Allowed
|
// Allowed
|
||||||
fn in_impl_Trait_in_return() -> impl IntoIterator<Item = impl IntoIterator> {
|
fn in_impl_Trait_in_return() -> impl IntoIterator<Item = impl IntoIterator> {
|
||||||
vec![vec![0; 10], vec![12; 7], vec![8; 3]]
|
vec![vec![0; 10], vec![12; 7], vec![8; 3]]
|
||||||
//~^ ERROR: no function or associated item named `into_vec` found for slice `[_]`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Disallowed
|
// Disallowed
|
||||||
|
@ -17,7 +17,7 @@ LL | fn in_impl_Fn_parameter_in_return() -> &'static impl Fn(impl Debug) { panic
|
|||||||
| outer `impl Trait`
|
| outer `impl Trait`
|
||||||
|
|
||||||
error[E0658]: `impl Trait` in associated types is unstable
|
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;
|
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
|
= 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
|
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;
|
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
|
= 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
|
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;
|
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
|
= 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
|
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 }
|
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
|
= 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
|
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> }
|
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
|
= 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
|
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);
|
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
|
= 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
|
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 },
|
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
|
= 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
|
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),
|
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
|
= 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
|
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);
|
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
|
= 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
|
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;
|
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
|
= 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
|
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;
|
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
|
= note: `impl Trait` is only allowed in arguments and return types of functions and methods
|
||||||
|
|
||||||
error[E0562]: `impl Trait` is not allowed in traits
|
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 () {
|
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
|
= 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
|
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 {
|
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
|
= 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
|
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 {
|
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
|
= 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
|
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> {
|
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
|
= note: `impl Trait` is only allowed in arguments and return types of functions and methods
|
||||||
|
|
||||||
error[E0562]: `impl Trait` is not allowed in bounds
|
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
|
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
|
= note: `impl Trait` is only allowed in arguments and return types of functions and methods
|
||||||
|
|
||||||
error[E0562]: `impl Trait` is not allowed in bounds
|
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
|
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
|
= note: `impl Trait` is only allowed in arguments and return types of functions and methods
|
||||||
|
|
||||||
error[E0562]: `impl Trait` is not allowed in bounds
|
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>
|
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
|
= 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
|
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)
|
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
|
= 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
|
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
|
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
|
= 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
|
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);
|
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
|
= 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
|
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) }
|
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
|
= 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
|
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> {}
|
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
|
= 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
|
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;
|
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
|
= 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
|
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 {}
|
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
|
= 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
|
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) {}
|
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
|
= 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
|
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() = || {};
|
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
|
= 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
|
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() { || {} };
|
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;
|
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
|
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 {}
|
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
|
= note: `#[deny(invalid_type_param_default)]` on by default
|
||||||
|
|
||||||
error[E0118]: no nominal type found for inherent implementation
|
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 {}
|
LL | impl <T = impl Debug> T {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^ impl requires a nominal type
|
| ^^^^^^^^^^^^^^^^^^^^^^^ impl requires a nominal type
|
||||||
|
|
|
|
||||||
= note: either implement a trait on it or create a newtype to wrap it instead
|
= 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
|
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;
|
LL | type Out = impl Debug;
|
||||||
| ---------- the expected opaque type
|
| ---------- the expected opaque type
|
||||||
@ -400,7 +390,7 @@ LL | fn in_trait_impl_return() -> impl Debug { () }
|
|||||||
| ^^^^^^^^^^ expected opaque type, found a different opaque type
|
| ^^^^^^^^^^ expected opaque type, found a different opaque type
|
||||||
|
|
|
|
||||||
note: type in trait
|
note: type in trait
|
||||||
--> $DIR/where-allowed.rs:119:34
|
--> $DIR/where-allowed.rs:118:34
|
||||||
|
|
|
|
||||||
LL | fn in_trait_impl_return() -> Self::Out;
|
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
|
error: unconstrained opaque type
|
||||||
--> $DIR/where-allowed.rs:122:16
|
--> $DIR/where-allowed.rs:121:16
|
||||||
|
|
|
|
||||||
LL | type Out = impl Debug;
|
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
|
= 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
|
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) {}
|
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!
|
= 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>
|
= 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`.
|
For more information about an error, try `rustc --explain E0053`.
|
||||||
Future incompatibility report: Future breakage diagnostic:
|
Future incompatibility report: Future breakage diagnostic:
|
||||||
error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
|
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 {}
|
LL | impl <T = impl Debug> T {}
|
||||||
| ^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^
|
||||||
@ -446,7 +436,7 @@ LL | impl <T = impl Debug> T {}
|
|||||||
|
|
||||||
Future breakage diagnostic:
|
Future breakage diagnostic:
|
||||||
error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
|
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) {}
|
LL | fn in_method_generic_param_default<T = impl Debug>(_: T) {}
|
||||||
| ^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^
|
||||||
|
14
tests/ui/traits/incoherent-impl-ambiguity.rs
Normal file
14
tests/ui/traits/incoherent-impl-ambiguity.rs
Normal 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;
|
||||||
|
}
|
11
tests/ui/traits/incoherent-impl-ambiguity.stderr
Normal file
11
tests/ui/traits/incoherent-impl-ambiguity.stderr
Normal 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`.
|
Loading…
Reference in New Issue
Block a user