Auto merge of #120812 - compiler-errors:impl-sorting, r=lcnr
Remove unnecessary impl sorting in queries and metadata Removes unnecessary impl sorting because queries already return their keys in HIR definition order: https://github.com/rust-lang/rust/issues/120371#issuecomment-1926422838 r? `@cjgillot` or `@lcnr` -- unless I totally misunderstood what was being asked for here? 😆 fixes #120371
This commit is contained in:
commit
0f8534e79e
@ -177,13 +177,12 @@ pub fn report_object_safety_error<'tcx>(
|
|||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
impls => {
|
impls => {
|
||||||
let mut types = impls
|
let types = impls
|
||||||
.iter()
|
.iter()
|
||||||
.map(|t| {
|
.map(|t| {
|
||||||
with_no_trimmed_paths!(format!(" {}", tcx.type_of(*t).instantiate_identity(),))
|
with_no_trimmed_paths!(format!(" {}", tcx.type_of(*t).instantiate_identity(),))
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
types.sort();
|
|
||||||
err.help(format!(
|
err.help(format!(
|
||||||
"the following types implement the trait, consider defining an enum where each \
|
"the following types implement the trait, consider defining an enum where each \
|
||||||
variant holds one of these types, implementing `{}` for this new enum and using \
|
variant holds one of these types, implementing `{}` for this new enum and using \
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
use rustc_ast as ast;
|
use rustc_ast as ast;
|
||||||
use rustc_data_structures::captures::Captures;
|
use rustc_data_structures::captures::Captures;
|
||||||
use rustc_data_structures::fingerprint::Fingerprint;
|
use rustc_data_structures::fingerprint::Fingerprint;
|
||||||
|
use rustc_data_structures::fx::FxIndexMap;
|
||||||
use rustc_data_structures::owned_slice::OwnedSlice;
|
use rustc_data_structures::owned_slice::OwnedSlice;
|
||||||
use rustc_data_structures::sync::{Lock, Lrc, OnceLock};
|
use rustc_data_structures::sync::{Lock, Lrc, OnceLock};
|
||||||
use rustc_data_structures::unhash::UnhashMap;
|
use rustc_data_structures::unhash::UnhashMap;
|
||||||
@ -83,12 +84,12 @@ pub(crate) struct CrateMetadata {
|
|||||||
/// Trait impl data.
|
/// Trait impl data.
|
||||||
/// FIXME: Used only from queries and can use query cache,
|
/// FIXME: Used only from queries and can use query cache,
|
||||||
/// so pre-decoding can probably be avoided.
|
/// so pre-decoding can probably be avoided.
|
||||||
trait_impls: FxHashMap<(u32, DefIndex), LazyArray<(DefIndex, Option<SimplifiedType>)>>,
|
trait_impls: FxIndexMap<(u32, DefIndex), LazyArray<(DefIndex, Option<SimplifiedType>)>>,
|
||||||
/// Inherent impls which do not follow the normal coherence rules.
|
/// Inherent impls which do not follow the normal coherence rules.
|
||||||
///
|
///
|
||||||
/// These can be introduced using either `#![rustc_coherence_is_core]`
|
/// These can be introduced using either `#![rustc_coherence_is_core]`
|
||||||
/// or `#[rustc_allow_incoherent_impl]`.
|
/// or `#[rustc_allow_incoherent_impl]`.
|
||||||
incoherent_impls: FxHashMap<SimplifiedType, LazyArray<DefIndex>>,
|
incoherent_impls: FxIndexMap<SimplifiedType, LazyArray<DefIndex>>,
|
||||||
/// Proc macro descriptions for this crate, if it's a proc macro crate.
|
/// Proc macro descriptions for this crate, if it's a proc macro crate.
|
||||||
raw_proc_macros: Option<&'static [ProcMacro]>,
|
raw_proc_macros: Option<&'static [ProcMacro]>,
|
||||||
/// Source maps for code from the crate.
|
/// Source maps for code from the crate.
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
use crate::rmeta::*;
|
use crate::rmeta::*;
|
||||||
|
|
||||||
use rustc_ast::Attribute;
|
use rustc_ast::Attribute;
|
||||||
use rustc_data_structures::fx::FxIndexSet;
|
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
|
||||||
use rustc_data_structures::memmap::{Mmap, MmapMut};
|
use rustc_data_structures::memmap::{Mmap, MmapMut};
|
||||||
use rustc_data_structures::sync::{join, par_for_each_in, Lrc};
|
use rustc_data_structures::sync::{join, par_for_each_in, Lrc};
|
||||||
use rustc_data_structures::temp_dir::MaybeTempDir;
|
use rustc_data_structures::temp_dir::MaybeTempDir;
|
||||||
@ -13,7 +13,6 @@
|
|||||||
use rustc_middle::middle::dependency_format::Linkage;
|
use rustc_middle::middle::dependency_format::Linkage;
|
||||||
use rustc_middle::middle::exported_symbols::metadata_symbol_name;
|
use rustc_middle::middle::exported_symbols::metadata_symbol_name;
|
||||||
use rustc_middle::mir::interpret;
|
use rustc_middle::mir::interpret;
|
||||||
use rustc_middle::query::LocalCrate;
|
|
||||||
use rustc_middle::query::Providers;
|
use rustc_middle::query::Providers;
|
||||||
use rustc_middle::traits::specialization_graph;
|
use rustc_middle::traits::specialization_graph;
|
||||||
use rustc_middle::ty::codec::TyEncoder;
|
use rustc_middle::ty::codec::TyEncoder;
|
||||||
@ -1509,10 +1508,7 @@ fn encode_def_ids(&mut self) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let inherent_impls = tcx.with_stable_hashing_context(|hcx| {
|
for (def_id, impls) in &tcx.crate_inherent_impls(()).unwrap().inherent_impls {
|
||||||
tcx.crate_inherent_impls(()).unwrap().inherent_impls.to_sorted(&hcx, true)
|
|
||||||
});
|
|
||||||
for (def_id, impls) in 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
|
||||||
@ -2002,8 +1998,8 @@ fn encode_traits(&mut self) -> LazyArray<DefIndex> {
|
|||||||
fn encode_impls(&mut self) -> LazyArray<TraitImpls> {
|
fn encode_impls(&mut self) -> LazyArray<TraitImpls> {
|
||||||
empty_proc_macro!(self);
|
empty_proc_macro!(self);
|
||||||
let tcx = self.tcx;
|
let tcx = self.tcx;
|
||||||
let mut fx_hash_map: FxHashMap<DefId, Vec<(DefIndex, Option<SimplifiedType>)>> =
|
let mut trait_impls: FxIndexMap<DefId, Vec<(DefIndex, Option<SimplifiedType>)>> =
|
||||||
FxHashMap::default();
|
FxIndexMap::default();
|
||||||
|
|
||||||
for id in tcx.hir().items() {
|
for id in tcx.hir().items() {
|
||||||
let DefKind::Impl { of_trait } = tcx.def_kind(id.owner_id) else {
|
let DefKind::Impl { of_trait } = tcx.def_kind(id.owner_id) else {
|
||||||
@ -2022,7 +2018,7 @@ fn encode_impls(&mut self) -> LazyArray<TraitImpls> {
|
|||||||
trait_ref.self_ty(),
|
trait_ref.self_ty(),
|
||||||
TreatParams::AsCandidateKey,
|
TreatParams::AsCandidateKey,
|
||||||
);
|
);
|
||||||
fx_hash_map
|
trait_impls
|
||||||
.entry(trait_ref.def_id)
|
.entry(trait_ref.def_id)
|
||||||
.or_default()
|
.or_default()
|
||||||
.push((id.owner_id.def_id.local_def_index, simplified_self_ty));
|
.push((id.owner_id.def_id.local_def_index, simplified_self_ty));
|
||||||
@ -2043,47 +2039,30 @@ fn encode_impls(&mut self) -> LazyArray<TraitImpls> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut all_impls: Vec<_> = fx_hash_map.into_iter().collect();
|
let trait_impls: Vec<_> = trait_impls
|
||||||
|
|
||||||
// Bring everything into deterministic order for hashing
|
|
||||||
all_impls.sort_by_cached_key(|&(trait_def_id, _)| tcx.def_path_hash(trait_def_id));
|
|
||||||
|
|
||||||
let all_impls: Vec<_> = all_impls
|
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|(trait_def_id, mut impls)| {
|
.map(|(trait_def_id, impls)| TraitImpls {
|
||||||
// Bring everything into deterministic order for hashing
|
trait_id: (trait_def_id.krate.as_u32(), trait_def_id.index),
|
||||||
impls.sort_by_cached_key(|&(index, _)| {
|
impls: self.lazy_array(&impls),
|
||||||
tcx.hir().def_path_hash(LocalDefId { local_def_index: index })
|
|
||||||
});
|
|
||||||
|
|
||||||
TraitImpls {
|
|
||||||
trait_id: (trait_def_id.krate.as_u32(), trait_def_id.index),
|
|
||||||
impls: self.lazy_array(&impls),
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
self.lazy_array(&all_impls)
|
self.lazy_array(&trait_impls)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(level = "debug", skip(self))]
|
#[instrument(level = "debug", skip(self))]
|
||||||
fn encode_incoherent_impls(&mut self) -> LazyArray<IncoherentImpls> {
|
fn encode_incoherent_impls(&mut self) -> LazyArray<IncoherentImpls> {
|
||||||
empty_proc_macro!(self);
|
empty_proc_macro!(self);
|
||||||
let tcx = self.tcx;
|
let tcx = self.tcx;
|
||||||
let all_impls = tcx.with_stable_hashing_context(|hcx| {
|
|
||||||
tcx.crate_inherent_impls(()).unwrap().incoherent_impls.to_sorted(&hcx, true)
|
|
||||||
});
|
|
||||||
|
|
||||||
let all_impls: Vec<_> = all_impls
|
let all_impls: Vec<_> = tcx
|
||||||
.into_iter()
|
.crate_inherent_impls(())
|
||||||
.map(|(&simp, impls)| {
|
.unwrap()
|
||||||
let mut impls: Vec<_> =
|
.incoherent_impls
|
||||||
impls.into_iter().map(|def_id| def_id.local_def_index).collect();
|
.iter()
|
||||||
impls.sort_by_cached_key(|&local_def_index| {
|
.map(|(&simp, impls)| IncoherentImpls {
|
||||||
tcx.hir().def_path_hash(LocalDefId { local_def_index })
|
self_ty: simp,
|
||||||
});
|
impls: self.lazy_array(impls.iter().map(|def_id| def_id.local_def_index)),
|
||||||
|
|
||||||
IncoherentImpls { self_ty: simp, impls: self.lazy_array(impls) }
|
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
@ -2327,32 +2306,6 @@ pub fn provide(providers: &mut Providers) {
|
|||||||
span_bug!(tcx.def_span(def_id), "no traits in scope for a doc link")
|
span_bug!(tcx.def_span(def_id), "no traits in scope for a doc link")
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
traits: |tcx, LocalCrate| {
|
|
||||||
let mut traits = Vec::new();
|
|
||||||
for id in tcx.hir().items() {
|
|
||||||
if matches!(tcx.def_kind(id.owner_id), DefKind::Trait | DefKind::TraitAlias) {
|
|
||||||
traits.push(id.owner_id.to_def_id())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bring everything into deterministic order.
|
|
||||||
traits.sort_by_cached_key(|&def_id| tcx.def_path_hash(def_id));
|
|
||||||
tcx.arena.alloc_slice(&traits)
|
|
||||||
},
|
|
||||||
trait_impls_in_crate: |tcx, LocalCrate| {
|
|
||||||
let mut trait_impls = Vec::new();
|
|
||||||
for id in tcx.hir().items() {
|
|
||||||
if matches!(tcx.def_kind(id.owner_id), DefKind::Impl { .. })
|
|
||||||
&& tcx.impl_trait_ref(id.owner_id).is_some()
|
|
||||||
{
|
|
||||||
trait_impls.push(id.owner_id.to_def_id())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bring everything into deterministic order.
|
|
||||||
trait_impls.sort_by_cached_key(|&def_id| tcx.def_path_hash(def_id));
|
|
||||||
tcx.arena.alloc_slice(&trait_impls)
|
|
||||||
},
|
|
||||||
|
|
||||||
..*providers
|
..*providers
|
||||||
}
|
}
|
||||||
|
@ -40,7 +40,6 @@
|
|||||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
||||||
use rustc_data_structures::steal::Steal;
|
use rustc_data_structures::steal::Steal;
|
||||||
use rustc_data_structures::tagged_ptr::CopyTaggedPtr;
|
use rustc_data_structures::tagged_ptr::CopyTaggedPtr;
|
||||||
use rustc_data_structures::unord::UnordMap;
|
|
||||||
use rustc_errors::{Diag, ErrorGuaranteed, StashKey};
|
use rustc_errors::{Diag, ErrorGuaranteed, StashKey};
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::def::{CtorKind, CtorOf, DefKind, DocLinkResMap, LifetimeRes, Res};
|
use rustc_hir::def::{CtorKind, CtorOf, DefKind, DocLinkResMap, LifetimeRes, Res};
|
||||||
@ -2083,6 +2082,8 @@ pub fn provide(providers: &mut Providers) {
|
|||||||
*providers = Providers {
|
*providers = Providers {
|
||||||
trait_impls_of: trait_def::trait_impls_of_provider,
|
trait_impls_of: trait_def::trait_impls_of_provider,
|
||||||
incoherent_impls: trait_def::incoherent_impls_provider,
|
incoherent_impls: trait_def::incoherent_impls_provider,
|
||||||
|
trait_impls_in_crate: trait_def::trait_impls_in_crate_provider,
|
||||||
|
traits: trait_def::traits_provider,
|
||||||
const_param_default: consts::const_param_default,
|
const_param_default: consts::const_param_default,
|
||||||
vtable_allocation: vtable::vtable_allocation_provider,
|
vtable_allocation: vtable::vtable_allocation_provider,
|
||||||
..*providers
|
..*providers
|
||||||
@ -2096,8 +2097,8 @@ pub fn provide(providers: &mut Providers) {
|
|||||||
/// (constructing this map requires touching the entire crate).
|
/// (constructing this map requires touching the entire crate).
|
||||||
#[derive(Clone, Debug, Default, HashStable)]
|
#[derive(Clone, Debug, Default, HashStable)]
|
||||||
pub struct CrateInherentImpls {
|
pub struct CrateInherentImpls {
|
||||||
pub inherent_impls: LocalDefIdMap<Vec<DefId>>,
|
pub inherent_impls: FxIndexMap<LocalDefId, Vec<DefId>>,
|
||||||
pub incoherent_impls: UnordMap<SimplifiedType, Vec<LocalDefId>>,
|
pub incoherent_impls: FxIndexMap<SimplifiedType, Vec<LocalDefId>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, HashStable)]
|
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, HashStable)]
|
||||||
|
@ -1,16 +1,19 @@
|
|||||||
use crate::traits::specialization_graph;
|
|
||||||
use crate::ty::fast_reject::{self, SimplifiedType, TreatParams};
|
|
||||||
use crate::ty::{Ident, Ty, TyCtxt};
|
|
||||||
use hir::def_id::LOCAL_CRATE;
|
|
||||||
use rustc_hir as hir;
|
|
||||||
use rustc_hir::def_id::DefId;
|
|
||||||
use std::iter;
|
use std::iter;
|
||||||
use tracing::debug;
|
use tracing::debug;
|
||||||
|
|
||||||
use rustc_data_structures::fx::FxIndexMap;
|
use rustc_data_structures::fx::FxIndexMap;
|
||||||
use rustc_errors::ErrorGuaranteed;
|
use rustc_errors::ErrorGuaranteed;
|
||||||
|
use rustc_hir as hir;
|
||||||
|
use rustc_hir::def::DefKind;
|
||||||
|
use rustc_hir::def_id::DefId;
|
||||||
|
use rustc_hir::def_id::LOCAL_CRATE;
|
||||||
use rustc_macros::{Decodable, Encodable, HashStable};
|
use rustc_macros::{Decodable, Encodable, HashStable};
|
||||||
|
|
||||||
|
use crate::query::LocalCrate;
|
||||||
|
use crate::traits::specialization_graph;
|
||||||
|
use crate::ty::fast_reject::{self, SimplifiedType, TreatParams};
|
||||||
|
use crate::ty::{Ident, Ty, TyCtxt};
|
||||||
|
|
||||||
/// A trait's definition with type information.
|
/// A trait's definition with type information.
|
||||||
#[derive(HashStable, Encodable, Decodable)]
|
#[derive(HashStable, Encodable, Decodable)]
|
||||||
pub struct TraitDef {
|
pub struct TraitDef {
|
||||||
@ -274,3 +277,27 @@ pub(super) fn incoherent_impls_provider(
|
|||||||
|
|
||||||
Ok(tcx.arena.alloc_slice(&impls))
|
Ok(tcx.arena.alloc_slice(&impls))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(super) fn traits_provider(tcx: TyCtxt<'_>, _: LocalCrate) -> &[DefId] {
|
||||||
|
let mut traits = Vec::new();
|
||||||
|
for id in tcx.hir().items() {
|
||||||
|
if matches!(tcx.def_kind(id.owner_id), DefKind::Trait | DefKind::TraitAlias) {
|
||||||
|
traits.push(id.owner_id.to_def_id())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tcx.arena.alloc_slice(&traits)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(super) fn trait_impls_in_crate_provider(tcx: TyCtxt<'_>, _: LocalCrate) -> &[DefId] {
|
||||||
|
let mut trait_impls = Vec::new();
|
||||||
|
for id in tcx.hir().items() {
|
||||||
|
if matches!(tcx.def_kind(id.owner_id), DefKind::Impl { .. })
|
||||||
|
&& tcx.impl_trait_ref(id.owner_id).is_some()
|
||||||
|
{
|
||||||
|
trait_impls.push(id.owner_id.to_def_id())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tcx.arena.alloc_slice(&trait_impls)
|
||||||
|
}
|
||||||
|
@ -56,19 +56,18 @@ fn check_crate_post(&mut self, cx: &LateContext<'tcx>) {
|
|||||||
let Ok(impls) = cx.tcx.crate_inherent_impls(()) else {
|
let Ok(impls) = cx.tcx.crate_inherent_impls(()) else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
let inherent_impls = cx
|
|
||||||
.tcx
|
|
||||||
.with_stable_hashing_context(|hcx| impls.inherent_impls.to_sorted(&hcx, true));
|
|
||||||
|
|
||||||
for (_, impl_ids) in inherent_impls.into_iter().filter(|(&id, impls)| {
|
for (&id, impl_ids) in &impls.inherent_impls {
|
||||||
impls.len() > 1
|
if impl_ids.len() < 2
|
||||||
// Check for `#[allow]` on the type definition
|
// Check for `#[allow]` on the type definition
|
||||||
&& !is_lint_allowed(
|
|| is_lint_allowed(
|
||||||
cx,
|
cx,
|
||||||
MULTIPLE_INHERENT_IMPL,
|
MULTIPLE_INHERENT_IMPL,
|
||||||
cx.tcx.local_def_id_to_hir_id(id),
|
cx.tcx.local_def_id_to_hir_id(id),
|
||||||
)
|
) {
|
||||||
}) {
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
for impl_id in impl_ids.iter().map(|id| id.expect_local()) {
|
for impl_id in impl_ids.iter().map(|id| id.expect_local()) {
|
||||||
let impl_ty = cx.tcx.type_of(impl_id).instantiate_identity();
|
let impl_ty = cx.tcx.type_of(impl_id).instantiate_identity();
|
||||||
match type_map.entry(impl_ty) {
|
match type_map.entry(impl_ty) {
|
||||||
|
@ -24,14 +24,14 @@ pub fn pass() -> isize { 42 }
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Bar for Foo<T> {
|
impl<T> Bar for Foo<T> {
|
||||||
//@ has - '//*[@id="associatedtype.Item-1"]//h4[@class="code-header"]' 'type Item = T'
|
// @has - '//*[@id="associatedtype.Item"]//h4[@class="code-header"]' 'type Item = T'
|
||||||
type Item=T;
|
type Item=T;
|
||||||
|
|
||||||
//@ has - '//*[@id="method.quux"]//h4[@class="code-header"]' 'fn quux(self)'
|
//@ has - '//*[@id="method.quux"]//h4[@class="code-header"]' 'fn quux(self)'
|
||||||
fn quux(self) {}
|
fn quux(self) {}
|
||||||
}
|
}
|
||||||
impl<'a, T> Bar for &'a Foo<T> {
|
impl<'a, T> Bar for &'a Foo<T> {
|
||||||
//@ has - '//*[@id="associatedtype.Item"]//h4[@class="code-header"]' "type Item = &'a T"
|
// @has - '//*[@id="associatedtype.Item-1"]//h4[@class="code-header"]' "type Item = &'a T"
|
||||||
type Item=&'a T;
|
type Item=&'a T;
|
||||||
|
|
||||||
//@ has - '//*[@id="method.quux-1"]//h4[@class="code-header"]' 'fn quux(self)'
|
//@ has - '//*[@id="method.quux-1"]//h4[@class="code-header"]' 'fn quux(self)'
|
||||||
|
@ -13,8 +13,8 @@ LL | type A<'a> where Self: 'a;
|
|||||||
| ^ ...because it contains the generic associated type `A`
|
| ^ ...because it contains the generic associated type `A`
|
||||||
= help: consider moving `A` to another trait
|
= help: consider moving `A` to another trait
|
||||||
= help: the following types implement the trait, consider defining an enum where each variant holds one of these types, implementing `Foo` for this new enum and using it instead:
|
= help: the following types implement the trait, consider defining an enum where each variant holds one of these types, implementing `Foo` for this new enum and using it instead:
|
||||||
Fooer<T>
|
|
||||||
Fooy
|
Fooy
|
||||||
|
Fooer<T>
|
||||||
|
|
||||||
error[E0038]: the trait `Foo` cannot be made into an object
|
error[E0038]: the trait `Foo` cannot be made into an object
|
||||||
--> $DIR/gat-in-trait-path.rs:32:5
|
--> $DIR/gat-in-trait-path.rs:32:5
|
||||||
@ -31,8 +31,8 @@ LL | type A<'a> where Self: 'a;
|
|||||||
| ^ ...because it contains the generic associated type `A`
|
| ^ ...because it contains the generic associated type `A`
|
||||||
= help: consider moving `A` to another trait
|
= help: consider moving `A` to another trait
|
||||||
= help: the following types implement the trait, consider defining an enum where each variant holds one of these types, implementing `Foo` for this new enum and using it instead:
|
= help: the following types implement the trait, consider defining an enum where each variant holds one of these types, implementing `Foo` for this new enum and using it instead:
|
||||||
Fooer<T>
|
|
||||||
Fooy
|
Fooy
|
||||||
|
Fooer<T>
|
||||||
|
|
||||||
error[E0038]: the trait `Foo` cannot be made into an object
|
error[E0038]: the trait `Foo` cannot be made into an object
|
||||||
--> $DIR/gat-in-trait-path.rs:32:5
|
--> $DIR/gat-in-trait-path.rs:32:5
|
||||||
@ -49,8 +49,8 @@ LL | type A<'a> where Self: 'a;
|
|||||||
| ^ ...because it contains the generic associated type `A`
|
| ^ ...because it contains the generic associated type `A`
|
||||||
= help: consider moving `A` to another trait
|
= help: consider moving `A` to another trait
|
||||||
= help: the following types implement the trait, consider defining an enum where each variant holds one of these types, implementing `Foo` for this new enum and using it instead:
|
= help: the following types implement the trait, consider defining an enum where each variant holds one of these types, implementing `Foo` for this new enum and using it instead:
|
||||||
Fooer<T>
|
|
||||||
Fooy
|
Fooy
|
||||||
|
Fooer<T>
|
||||||
= note: required for the cast from `Box<Fooer<{integer}>>` to `Box<(dyn Foo<A = &'a ()> + 'static)>`
|
= note: required for the cast from `Box<Fooer<{integer}>>` to `Box<(dyn Foo<A = &'a ()> + 'static)>`
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
error: aborting due to 3 previous errors
|
||||||
|
@ -29,8 +29,8 @@ LL | type VRefCont<'a>: RefCont<'a, V> where Self: 'a;
|
|||||||
| ^^^^^^^^ ...because it contains the generic associated type `VRefCont`
|
| ^^^^^^^^ ...because it contains the generic associated type `VRefCont`
|
||||||
= help: consider moving `VRefCont` to another trait
|
= help: consider moving `VRefCont` to another trait
|
||||||
= help: the following types implement the trait, consider defining an enum where each variant holds one of these types, implementing `MapLike` for this new enum and using it instead:
|
= help: the following types implement the trait, consider defining an enum where each variant holds one of these types, implementing `MapLike` for this new enum and using it instead:
|
||||||
Source
|
|
||||||
std::collections::BTreeMap<K, V>
|
std::collections::BTreeMap<K, V>
|
||||||
|
Source
|
||||||
|
|
||||||
error[E0038]: the trait `MapLike` cannot be made into an object
|
error[E0038]: the trait `MapLike` cannot be made into an object
|
||||||
--> $DIR/issue-79422.rs:44:13
|
--> $DIR/issue-79422.rs:44:13
|
||||||
@ -47,8 +47,8 @@ LL | type VRefCont<'a>: RefCont<'a, V> where Self: 'a;
|
|||||||
| ^^^^^^^^ ...because it contains the generic associated type `VRefCont`
|
| ^^^^^^^^ ...because it contains the generic associated type `VRefCont`
|
||||||
= help: consider moving `VRefCont` to another trait
|
= help: consider moving `VRefCont` to another trait
|
||||||
= help: the following types implement the trait, consider defining an enum where each variant holds one of these types, implementing `MapLike` for this new enum and using it instead:
|
= help: the following types implement the trait, consider defining an enum where each variant holds one of these types, implementing `MapLike` for this new enum and using it instead:
|
||||||
Source
|
|
||||||
std::collections::BTreeMap<K, V>
|
std::collections::BTreeMap<K, V>
|
||||||
|
Source
|
||||||
= note: required for the cast from `Box<BTreeMap<u8, u8>>` to `Box<dyn MapLike<u8, u8, VRefCont = (dyn RefCont<'_, u8> + 'static)>>`
|
= note: required for the cast from `Box<BTreeMap<u8, u8>>` to `Box<dyn MapLike<u8, u8, VRefCont = (dyn RefCont<'_, u8> + 'static)>>`
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
error: aborting due to 3 previous errors
|
||||||
|
@ -26,8 +26,8 @@ LL | trait Trait: Sized {}
|
|||||||
| |
|
| |
|
||||||
| this trait cannot be made into an object...
|
| this trait cannot be made into an object...
|
||||||
= help: the following types implement the trait, consider defining an enum where each variant holds one of these types, implementing `Trait` for this new enum and using it instead:
|
= help: the following types implement the trait, consider defining an enum where each variant holds one of these types, implementing `Trait` for this new enum and using it instead:
|
||||||
R
|
|
||||||
S
|
S
|
||||||
|
R
|
||||||
= note: required for the cast from `&S` to `&dyn Trait`
|
= note: required for the cast from `&S` to `&dyn Trait`
|
||||||
|
|
||||||
error[E0038]: the trait `Trait` cannot be made into an object
|
error[E0038]: the trait `Trait` cannot be made into an object
|
||||||
@ -48,8 +48,8 @@ LL | trait Trait: Sized {}
|
|||||||
| |
|
| |
|
||||||
| this trait cannot be made into an object...
|
| this trait cannot be made into an object...
|
||||||
= help: the following types implement the trait, consider defining an enum where each variant holds one of these types, implementing `Trait` for this new enum and using it instead:
|
= help: the following types implement the trait, consider defining an enum where each variant holds one of these types, implementing `Trait` for this new enum and using it instead:
|
||||||
R
|
|
||||||
S
|
S
|
||||||
|
R
|
||||||
= note: required for the cast from `&R` to `&dyn Trait`
|
= note: required for the cast from `&R` to `&dyn Trait`
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
error: aborting due to 3 previous errors
|
||||||
|
Loading…
Reference in New Issue
Block a user