mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-23 07:14:28 +00:00
Auto merge of #59445 - alexreg:ban-multi-trait-objects-via-aliases, r=oli-obk
Ban multi-trait objects via trait aliases
Obviously, multi-trait objects are not normally supported, so they should not be supported via trait aliases.
This has been factored out from the previous PR https://github.com/rust-lang/rust/pull/55994 (see point 1).
r? @Centril
CC @nikomatsakis
------------------
### RELNOTES:
We now allow `dyn Send + fmt::Debug` with equivalent semantics to `dyn fmt::Debug + Send`.
That is, the order of the mentioned traits does not matter wrt. principal/not-principal traits.
This is a small change that might deserve a mention in the blog post because it is a language change but most likely not.
See ce2ee305f9/src/test/ui/traits/wf-trait-object-reverse-order.rs
.
// @Centril
This commit is contained in:
commit
37ff5d388f
@ -123,12 +123,12 @@ pub use core::slice::{RChunks, RChunksMut, RChunksExact, RChunksExactMut};
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// HACK(japaric) needed for the implementation of `vec!` macro during testing
|
||||
// NB see the hack module in this file for more details
|
||||
// N.B., see the `hack` module in this file for more details.
|
||||
#[cfg(test)]
|
||||
pub use hack::into_vec;
|
||||
|
||||
// HACK(japaric) needed for the implementation of `Vec::clone` during testing
|
||||
// NB see the hack module in this file for more details
|
||||
// N.B., see the `hack` module in this file for more details.
|
||||
#[cfg(test)]
|
||||
pub use hack::to_vec;
|
||||
|
||||
@ -376,7 +376,7 @@ impl<T> [T] {
|
||||
pub fn to_vec(&self) -> Vec<T>
|
||||
where T: Clone
|
||||
{
|
||||
// NB see hack module in this file
|
||||
// N.B., see the `hack` module in this file for more details.
|
||||
hack::to_vec(self)
|
||||
}
|
||||
|
||||
@ -397,7 +397,7 @@ impl<T> [T] {
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn into_vec(self: Box<Self>) -> Vec<T> {
|
||||
// NB see hack module in this file
|
||||
// N.B., see the `hack` module in this file for more details.
|
||||
hack::into_vec(self)
|
||||
}
|
||||
|
||||
|
@ -957,7 +957,7 @@ impl<'hir> Map<'hir> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the name associated with the given NodeId's AST.
|
||||
/// Returns the name associated with the given `NodeId`'s AST.
|
||||
pub fn name(&self, id: NodeId) -> Name {
|
||||
let hir_id = self.node_to_hir_id(id);
|
||||
self.name_by_hir_id(hir_id)
|
||||
|
@ -2143,11 +2143,11 @@ pub enum UseKind {
|
||||
ListStem,
|
||||
}
|
||||
|
||||
/// TraitRef's appear in impls.
|
||||
/// References to traits in impls.
|
||||
///
|
||||
/// resolve maps each TraitRef's ref_id to its defining trait; that's all
|
||||
/// that the ref_id is for. Note that ref_id's value is not the NodeId of the
|
||||
/// trait being referred to but just a unique NodeId that serves as a key
|
||||
/// `resolve` maps each `TraitRef`'s `ref_id` to its defining trait; that's all
|
||||
/// that the `ref_id` is for. Note that `ref_id`'s value is not the `NodeId` of the
|
||||
/// trait being referred to but just a unique `NodeId` that serves as a key
|
||||
/// within the resolution map.
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
|
||||
pub struct TraitRef {
|
||||
|
@ -168,7 +168,7 @@ rustc_queries! {
|
||||
query predicates_defined_on(_: DefId)
|
||||
-> Lrc<ty::GenericPredicates<'tcx>> {}
|
||||
|
||||
/// Returns the predicates written explicit by the user.
|
||||
/// Returns the predicates written explicitly by the user.
|
||||
query explicit_predicates_of(_: DefId)
|
||||
-> Lrc<ty::GenericPredicates<'tcx>> {}
|
||||
|
||||
@ -216,9 +216,9 @@ rustc_queries! {
|
||||
_: DefId
|
||||
) -> Result<DtorckConstraint<'tcx>, NoSolution> {}
|
||||
|
||||
/// True if this is a const fn, use the `is_const_fn` to know whether your crate actually
|
||||
/// sees it as const fn (e.g., the const-fn-ness might be unstable and you might not have
|
||||
/// the feature gate active)
|
||||
/// Returns `true` if this is a const fn, use the `is_const_fn` to know whether your crate
|
||||
/// actually sees it as const fn (e.g., the const-fn-ness might be unstable and you might
|
||||
/// not have the feature gate active).
|
||||
///
|
||||
/// **Do not call this function manually.** It is only meant to cache the base data for the
|
||||
/// `is_const_fn` function.
|
||||
@ -226,7 +226,7 @@ rustc_queries! {
|
||||
desc { |tcx| "checking if item is const fn: `{}`", tcx.def_path_str(key) }
|
||||
}
|
||||
|
||||
/// Returns true if calls to the function may be promoted
|
||||
/// Returns `true` if calls to the function may be promoted.
|
||||
///
|
||||
/// This is either because the function is e.g., a tuple-struct or tuple-variant
|
||||
/// constructor, or because it has the `#[rustc_promotable]` attribute. The attribute should
|
||||
@ -237,25 +237,23 @@ rustc_queries! {
|
||||
|
||||
query const_fn_is_allowed_fn_ptr(_: DefId) -> bool {}
|
||||
|
||||
/// True if this is a foreign item (i.e., linked via `extern { ... }`).
|
||||
/// Returns `true` if this is a foreign item (i.e., linked via `extern { ... }`).
|
||||
query is_foreign_item(_: DefId) -> bool {}
|
||||
|
||||
/// Returns `Some(mutability)` if the node pointed to by `def_id` is a static item.
|
||||
query static_mutability(_: DefId) -> Option<hir::Mutability> {}
|
||||
|
||||
/// Get a map with the variance of every item; use `item_variance`
|
||||
/// instead.
|
||||
/// Gets a map with the variance of every item; use `item_variance` instead.
|
||||
query crate_variances(_: CrateNum) -> Lrc<ty::CrateVariancesMap<'tcx>> {
|
||||
desc { "computing the variances for items in this crate" }
|
||||
}
|
||||
|
||||
/// Maps from def-id of a type or region parameter to its
|
||||
/// (inferred) variance.
|
||||
/// Maps from the `DefId` of a type or region parameter to its (inferred) variance.
|
||||
query variances_of(_: DefId) -> &'tcx [ty::Variance] {}
|
||||
}
|
||||
|
||||
TypeChecking {
|
||||
/// Maps from def-id of a type to its (inferred) outlives.
|
||||
/// Maps from thee `DefId` of a type to its (inferred) outlives.
|
||||
query inferred_outlives_crate(_: CrateNum)
|
||||
-> Lrc<ty::CratePredicatesMap<'tcx>> {
|
||||
desc { "computing the inferred outlives predicates for items in this crate" }
|
||||
@ -263,10 +261,10 @@ rustc_queries! {
|
||||
}
|
||||
|
||||
Other {
|
||||
/// Maps from an impl/trait def-id to a list of the def-ids of its items
|
||||
/// Maps from an impl/trait `DefId to a list of the `DefId`s of its items.
|
||||
query associated_item_def_ids(_: DefId) -> Lrc<Vec<DefId>> {}
|
||||
|
||||
/// Maps from a trait item to the trait item "descriptor"
|
||||
/// Maps from a trait item to the trait item "descriptor".
|
||||
query associated_item(_: DefId) -> ty::AssociatedItem {}
|
||||
|
||||
query impl_trait_ref(_: DefId) -> Option<ty::TraitRef<'tcx>> {}
|
||||
@ -276,7 +274,7 @@ rustc_queries! {
|
||||
}
|
||||
|
||||
TypeChecking {
|
||||
/// 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.
|
||||
/// Methods in these implementations don't need to be exported.
|
||||
query inherent_impls(_: DefId) -> Lrc<Vec<DefId>> {
|
||||
@ -300,7 +298,7 @@ rustc_queries! {
|
||||
desc { |tcx| "linting {}", key.describe_as_module(tcx) }
|
||||
}
|
||||
|
||||
/// Checks the attributes in the module
|
||||
/// Checks the attributes in the module.
|
||||
query check_mod_attrs(key: DefId) -> () {
|
||||
desc { |tcx| "checking attributes in {}", key.describe_as_module(tcx) }
|
||||
}
|
||||
@ -309,7 +307,7 @@ rustc_queries! {
|
||||
desc { |tcx| "checking for unstable API usage in {}", key.describe_as_module(tcx) }
|
||||
}
|
||||
|
||||
/// Checks the loops in the module
|
||||
/// Checks the loops in the module.
|
||||
query check_mod_loops(key: DefId) -> () {
|
||||
desc { |tcx| "checking loops in {}", key.describe_as_module(tcx) }
|
||||
}
|
||||
@ -338,7 +336,7 @@ rustc_queries! {
|
||||
desc { |tcx| "collecting item types in {}", key.describe_as_module(tcx) }
|
||||
}
|
||||
|
||||
/// Caches CoerceUnsized kinds for impls on custom types.
|
||||
/// Caches `CoerceUnsized` kinds for impls on custom types.
|
||||
query coerce_unsized_info(_: DefId)
|
||||
-> ty::adjustment::CoerceUnsizedInfo {}
|
||||
}
|
||||
@ -375,7 +373,7 @@ rustc_queries! {
|
||||
BorrowChecking {
|
||||
query borrowck(_: DefId) -> Lrc<BorrowCheckResult> {}
|
||||
|
||||
/// Borrow checks the function body. If this is a closure, returns
|
||||
/// Borrow-checks the function body. If this is a closure, returns
|
||||
/// additional requirements that the closure's creator must verify.
|
||||
query mir_borrowck(_: DefId) -> mir::BorrowCheckResult<'tcx> {}
|
||||
}
|
||||
@ -401,11 +399,11 @@ rustc_queries! {
|
||||
}
|
||||
|
||||
Other {
|
||||
/// Evaluate a constant without running sanity checks
|
||||
/// Evaluates a constant without running sanity checks.
|
||||
///
|
||||
/// **Do not use this** outside const eval. Const eval uses this to break query cycles
|
||||
/// during validation. Please add a comment to every use site explaining why using
|
||||
/// `const_eval` isn't sufficient
|
||||
/// `const_eval` isn't sufficient.
|
||||
query const_eval_raw(key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>)
|
||||
-> ConstEvalRawResult<'tcx> {
|
||||
no_force
|
||||
@ -660,12 +658,12 @@ rustc_queries! {
|
||||
}
|
||||
|
||||
Linking {
|
||||
// The DefIds of all non-generic functions and statics in the given crate
|
||||
// The `DefId`s of all non-generic functions and statics in the given crate
|
||||
// that can be reached from outside the crate.
|
||||
//
|
||||
// We expect this items to be available for being linked to.
|
||||
//
|
||||
// This query can also be called for LOCAL_CRATE. In this case it will
|
||||
// This query can also be called for `LOCAL_CRATE`. In this case it will
|
||||
// compute which items will be reachable to other crates, taking into account
|
||||
// the kind of crate that is currently compiled. Crates with only a
|
||||
// C interface have fewer reachable things.
|
||||
|
@ -60,8 +60,10 @@ pub use self::specialize::specialization_graph::FutureCompatOverlapError;
|
||||
pub use self::specialize::specialization_graph::FutureCompatOverlapErrorKind;
|
||||
pub use self::engine::{TraitEngine, TraitEngineExt};
|
||||
pub use self::util::{elaborate_predicates, elaborate_trait_ref, elaborate_trait_refs};
|
||||
pub use self::util::{supertraits, supertrait_def_ids, transitive_bounds,
|
||||
Supertraits, SupertraitDefIds};
|
||||
pub use self::util::{
|
||||
supertraits, supertrait_def_ids, transitive_bounds, Supertraits, SupertraitDefIds,
|
||||
};
|
||||
pub use self::util::{expand_trait_aliases, TraitAliasExpander};
|
||||
|
||||
pub use self::chalk_fulfill::{
|
||||
CanonicalGoal as ChalkCanonicalGoal,
|
||||
@ -1043,7 +1045,7 @@ fn vtable_methods<'a, 'tcx>(
|
||||
)
|
||||
}
|
||||
|
||||
impl<'tcx,O> Obligation<'tcx,O> {
|
||||
impl<'tcx, O> Obligation<'tcx, O> {
|
||||
pub fn new(cause: ObligationCause<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
predicate: O)
|
||||
|
@ -1772,7 +1772,8 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
||||
bounds
|
||||
);
|
||||
|
||||
let matching_bound = util::elaborate_predicates(self.tcx(), bounds.predicates)
|
||||
let elaborated_predicates = util::elaborate_predicates(self.tcx(), bounds.predicates);
|
||||
let matching_bound = elaborated_predicates
|
||||
.filter_to_traits()
|
||||
.find(|bound| {
|
||||
self.infcx.probe(|_| {
|
||||
|
@ -1,3 +1,7 @@
|
||||
use errors::DiagnosticBuilder;
|
||||
use smallvec::SmallVec;
|
||||
use syntax_pos::Span;
|
||||
|
||||
use crate::hir;
|
||||
use crate::hir::def_id::DefId;
|
||||
use crate::traits::specialize::specialization_graph::NodeItem;
|
||||
@ -41,15 +45,14 @@ fn anonymize_predicate<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
struct PredicateSet<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
|
||||
struct PredicateSet<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
|
||||
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
set: FxHashSet<ty::Predicate<'tcx>>,
|
||||
}
|
||||
|
||||
impl<'a, 'gcx, 'tcx> PredicateSet<'a, 'gcx, 'tcx> {
|
||||
fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>) -> PredicateSet<'a, 'gcx, 'tcx> {
|
||||
PredicateSet { tcx: tcx, set: Default::default() }
|
||||
fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Self {
|
||||
Self { tcx: tcx, set: Default::default() }
|
||||
}
|
||||
|
||||
fn insert(&mut self, pred: &ty::Predicate<'tcx>) -> bool {
|
||||
@ -67,18 +70,25 @@ impl<'a, 'gcx, 'tcx> PredicateSet<'a, 'gcx, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'gcx, 'tcx, T: AsRef<ty::Predicate<'tcx>>> Extend<T> for PredicateSet<'a, 'gcx, 'tcx> {
|
||||
fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
|
||||
for pred in iter {
|
||||
self.insert(pred.as_ref());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// `Elaboration` iterator
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/// "Elaboration" is the process of identifying all the predicates that
|
||||
/// are implied by a source predicate. Currently this basically means
|
||||
/// walking the "supertraits" and other similar assumptions. For
|
||||
/// example, if we know that `T : Ord`, the elaborator would deduce
|
||||
/// that `T : PartialOrd` holds as well. Similarly, if we have `trait
|
||||
/// Foo : 'static`, and we know that `T : Foo`, then we know that `T :
|
||||
/// 'static`.
|
||||
pub struct Elaborator<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
|
||||
/// walking the "supertraits" and other similar assumptions. For example,
|
||||
/// if we know that `T: Ord`, the elaborator would deduce that `T: PartialOrd`
|
||||
/// holds as well. Similarly, if we have `trait Foo: 'static`, and we know that
|
||||
/// `T: Foo`, then we know that `T: 'static`.
|
||||
pub struct Elaborator<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
|
||||
stack: Vec<ty::Predicate<'tcx>>,
|
||||
visited: PredicateSet<'a, 'gcx, 'tcx>,
|
||||
}
|
||||
@ -96,8 +106,7 @@ pub fn elaborate_trait_refs<'cx, 'gcx, 'tcx>(
|
||||
trait_refs: impl Iterator<Item = ty::PolyTraitRef<'tcx>>)
|
||||
-> Elaborator<'cx, 'gcx, 'tcx>
|
||||
{
|
||||
let predicates = trait_refs.map(|trait_ref| trait_ref.to_predicate())
|
||||
.collect();
|
||||
let predicates = trait_refs.map(|trait_ref| trait_ref.to_predicate()).collect();
|
||||
elaborate_predicates(tcx, predicates)
|
||||
}
|
||||
|
||||
@ -108,7 +117,7 @@ pub fn elaborate_predicates<'cx, 'gcx, 'tcx>(
|
||||
{
|
||||
let mut visited = PredicateSet::new(tcx);
|
||||
predicates.retain(|pred| visited.insert(pred));
|
||||
Elaborator { stack: predicates, visited: visited }
|
||||
Elaborator { stack: predicates, visited }
|
||||
}
|
||||
|
||||
impl<'cx, 'gcx, 'tcx> Elaborator<'cx, 'gcx, 'tcx> {
|
||||
@ -116,28 +125,25 @@ impl<'cx, 'gcx, 'tcx> Elaborator<'cx, 'gcx, 'tcx> {
|
||||
FilterToTraits::new(self)
|
||||
}
|
||||
|
||||
fn push(&mut self, predicate: &ty::Predicate<'tcx>) {
|
||||
fn elaborate(&mut self, predicate: &ty::Predicate<'tcx>) {
|
||||
let tcx = self.visited.tcx;
|
||||
match *predicate {
|
||||
ty::Predicate::Trait(ref data) => {
|
||||
// Predicates declared on the trait.
|
||||
// Get predicates declared on the trait.
|
||||
let predicates = tcx.super_predicates_of(data.def_id());
|
||||
|
||||
let mut predicates: Vec<_> =
|
||||
predicates.predicates
|
||||
.iter()
|
||||
.map(|(p, _)| p.subst_supertrait(tcx, &data.to_poly_trait_ref()))
|
||||
.collect();
|
||||
|
||||
let predicates = predicates.predicates
|
||||
.iter()
|
||||
.map(|(pred, _)| pred.subst_supertrait(tcx, &data.to_poly_trait_ref()));
|
||||
debug!("super_predicates: data={:?} predicates={:?}",
|
||||
data, predicates);
|
||||
data, predicates.clone());
|
||||
|
||||
// Only keep those bounds that we haven't already
|
||||
// seen. This is necessary to prevent infinite
|
||||
// recursion in some cases. One common case is when
|
||||
// people define `trait Sized: Sized { }` rather than `trait
|
||||
// Sized { }`.
|
||||
predicates.retain(|r| self.visited.insert(r));
|
||||
// Only keep those bounds that we haven't already seen.
|
||||
// This is necessary to prevent infinite recursion in some
|
||||
// cases. One common case is when people define
|
||||
// `trait Sized: Sized { }` rather than `trait Sized { }`.
|
||||
let visited = &mut self.visited;
|
||||
let predicates = predicates.filter(|pred| visited.insert(pred));
|
||||
|
||||
self.stack.extend(predicates);
|
||||
}
|
||||
@ -150,8 +156,8 @@ impl<'cx, 'gcx, 'tcx> Elaborator<'cx, 'gcx, 'tcx> {
|
||||
// predicates.
|
||||
}
|
||||
ty::Predicate::Subtype(..) => {
|
||||
// Currently, we do not "elaborate" predicates like `X
|
||||
// <: Y`, though conceivably we might.
|
||||
// Currently, we do not "elaborate" predicates like `X <: Y`,
|
||||
// though conceivably we might.
|
||||
}
|
||||
ty::Predicate::Projection(..) => {
|
||||
// Nothing to elaborate in a projection predicate.
|
||||
@ -163,11 +169,9 @@ impl<'cx, 'gcx, 'tcx> Elaborator<'cx, 'gcx, 'tcx> {
|
||||
// Currently, we do not elaborate const-evaluatable
|
||||
// predicates.
|
||||
}
|
||||
|
||||
ty::Predicate::RegionOutlives(..) => {
|
||||
// Nothing to elaborate from `'a: 'b`.
|
||||
}
|
||||
|
||||
ty::Predicate::TypeOutlives(ref data) => {
|
||||
// We know that `T: 'a` for some type `T`. We can
|
||||
// often elaborate this. For example, if we know that
|
||||
@ -194,34 +198,35 @@ impl<'cx, 'gcx, 'tcx> Elaborator<'cx, 'gcx, 'tcx> {
|
||||
tcx.push_outlives_components(ty_max, &mut components);
|
||||
self.stack.extend(
|
||||
components
|
||||
.into_iter()
|
||||
.filter_map(|component| match component {
|
||||
Component::Region(r) => if r.is_late_bound() {
|
||||
None
|
||||
} else {
|
||||
Some(ty::Predicate::RegionOutlives(
|
||||
ty::Binder::dummy(ty::OutlivesPredicate(r, r_min))))
|
||||
},
|
||||
.into_iter()
|
||||
.filter_map(|component| match component {
|
||||
Component::Region(r) => if r.is_late_bound() {
|
||||
None
|
||||
} else {
|
||||
Some(ty::Predicate::RegionOutlives(
|
||||
ty::Binder::dummy(ty::OutlivesPredicate(r, r_min))))
|
||||
}
|
||||
|
||||
Component::Param(p) => {
|
||||
let ty = tcx.mk_ty_param(p.index, p.name);
|
||||
Some(ty::Predicate::TypeOutlives(
|
||||
ty::Binder::dummy(ty::OutlivesPredicate(ty, r_min))))
|
||||
},
|
||||
Component::Param(p) => {
|
||||
let ty = tcx.mk_ty_param(p.index, p.name);
|
||||
Some(ty::Predicate::TypeOutlives(
|
||||
ty::Binder::dummy(ty::OutlivesPredicate(ty, r_min))))
|
||||
}
|
||||
|
||||
Component::UnresolvedInferenceVariable(_) => {
|
||||
None
|
||||
},
|
||||
Component::UnresolvedInferenceVariable(_) => {
|
||||
None
|
||||
}
|
||||
|
||||
Component::Projection(_) |
|
||||
Component::EscapingProjection(_) => {
|
||||
// We can probably do more here. This
|
||||
// corresponds to a case like `<T as
|
||||
// Foo<'a>>::U: 'b`.
|
||||
None
|
||||
},
|
||||
})
|
||||
.filter(|p| visited.insert(p)));
|
||||
Component::Projection(_) |
|
||||
Component::EscapingProjection(_) => {
|
||||
// We can probably do more here. This
|
||||
// corresponds to a case like `<T as
|
||||
// Foo<'a>>::U: 'b`.
|
||||
None
|
||||
}
|
||||
})
|
||||
.filter(|p| visited.insert(p))
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -236,15 +241,12 @@ impl<'cx, 'gcx, 'tcx> Iterator for Elaborator<'cx, 'gcx, 'tcx> {
|
||||
|
||||
fn next(&mut self) -> Option<ty::Predicate<'tcx>> {
|
||||
// Extract next item from top-most stack frame, if any.
|
||||
let next_predicate = match self.stack.pop() {
|
||||
Some(predicate) => predicate,
|
||||
None => {
|
||||
// No more stack frames. Done.
|
||||
return None;
|
||||
}
|
||||
};
|
||||
self.push(&next_predicate);
|
||||
return Some(next_predicate);
|
||||
if let Some(pred) = self.stack.pop() {
|
||||
self.elaborate(&pred);
|
||||
Some(pred)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -256,20 +258,161 @@ pub type Supertraits<'cx, 'gcx, 'tcx> = FilterToTraits<Elaborator<'cx, 'gcx, 'tc
|
||||
|
||||
pub fn supertraits<'cx, 'gcx, 'tcx>(tcx: TyCtxt<'cx, 'gcx, 'tcx>,
|
||||
trait_ref: ty::PolyTraitRef<'tcx>)
|
||||
-> Supertraits<'cx, 'gcx, 'tcx>
|
||||
{
|
||||
-> Supertraits<'cx, 'gcx, 'tcx> {
|
||||
elaborate_trait_ref(tcx, trait_ref).filter_to_traits()
|
||||
}
|
||||
|
||||
pub fn transitive_bounds<'cx, 'gcx, 'tcx>(tcx: TyCtxt<'cx, 'gcx, 'tcx>,
|
||||
bounds: impl Iterator<Item = ty::PolyTraitRef<'tcx>>)
|
||||
-> Supertraits<'cx, 'gcx, 'tcx>
|
||||
{
|
||||
-> Supertraits<'cx, 'gcx, 'tcx> {
|
||||
elaborate_trait_refs(tcx, bounds).filter_to_traits()
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Iterator over def-ids of supertraits
|
||||
// `TraitAliasExpander` iterator
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/// "Trait alias expansion" is the process of expanding a sequence of trait
|
||||
/// references into another sequence by transitively following all trait
|
||||
/// aliases. e.g. If you have bounds like `Foo + Send`, a trait alias
|
||||
/// `trait Foo = Bar + Sync;`, and another trait alias
|
||||
/// `trait Bar = Read + Write`, then the bounds would expand to
|
||||
/// `Read + Write + Sync + Send`.
|
||||
/// Expansion is done via a DFS (depth-first search), and the `visited` field
|
||||
/// is used to avoid cycles.
|
||||
pub struct TraitAliasExpander<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
|
||||
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
stack: Vec<TraitAliasExpansionInfo<'tcx>>,
|
||||
}
|
||||
|
||||
/// Stores information about the expansion of a trait via a path of zero or more trait aliases.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct TraitAliasExpansionInfo<'tcx> {
|
||||
pub path: SmallVec<[(ty::PolyTraitRef<'tcx>, Span); 4]>,
|
||||
}
|
||||
|
||||
impl<'tcx> TraitAliasExpansionInfo<'tcx> {
|
||||
fn new(trait_ref: ty::PolyTraitRef<'tcx>, span: Span) -> Self {
|
||||
Self {
|
||||
path: smallvec![(trait_ref, span)]
|
||||
}
|
||||
}
|
||||
|
||||
/// Adds diagnostic labels to `diag` for the expansion path of a trait through all intermediate
|
||||
/// trait aliases.
|
||||
pub fn label_with_exp_info(&self,
|
||||
diag: &mut DiagnosticBuilder<'_>,
|
||||
top_label: &str,
|
||||
use_desc: &str
|
||||
) {
|
||||
diag.span_label(self.top().1, top_label);
|
||||
if self.path.len() > 1 {
|
||||
for (_, sp) in self.path.iter().rev().skip(1).take(self.path.len() - 2) {
|
||||
diag.span_label(*sp, format!("referenced here ({})", use_desc));
|
||||
}
|
||||
}
|
||||
diag.span_label(self.bottom().1,
|
||||
format!("trait alias used in trait object type ({})", use_desc));
|
||||
}
|
||||
|
||||
pub fn trait_ref(&self) -> &ty::PolyTraitRef<'tcx> {
|
||||
&self.top().0
|
||||
}
|
||||
|
||||
pub fn top(&self) -> &(ty::PolyTraitRef<'tcx>, Span) {
|
||||
self.path.last().unwrap()
|
||||
}
|
||||
|
||||
pub fn bottom(&self) -> &(ty::PolyTraitRef<'tcx>, Span) {
|
||||
self.path.first().unwrap()
|
||||
}
|
||||
|
||||
fn clone_and_push(&self, trait_ref: ty::PolyTraitRef<'tcx>, span: Span) -> Self {
|
||||
let mut path = self.path.clone();
|
||||
path.push((trait_ref, span));
|
||||
|
||||
Self {
|
||||
path
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn expand_trait_aliases<'cx, 'gcx, 'tcx>(
|
||||
tcx: TyCtxt<'cx, 'gcx, 'tcx>,
|
||||
trait_refs: impl IntoIterator<Item = (ty::PolyTraitRef<'tcx>, Span)>
|
||||
) -> TraitAliasExpander<'cx, 'gcx, 'tcx> {
|
||||
let items: Vec<_> = trait_refs
|
||||
.into_iter()
|
||||
.map(|(trait_ref, span)| TraitAliasExpansionInfo::new(trait_ref, span))
|
||||
.collect();
|
||||
TraitAliasExpander { tcx, stack: items }
|
||||
}
|
||||
|
||||
impl<'cx, 'gcx, 'tcx> TraitAliasExpander<'cx, 'gcx, 'tcx> {
|
||||
/// If `item` is a trait alias and its predicate has not yet been visited, then expands `item`
|
||||
/// to the definition, pushes the resulting expansion onto `self.stack`, and returns `false`.
|
||||
/// Otherwise, immediately returns `true` if `item` is a regular trait, or `false` if it is a
|
||||
/// trait alias.
|
||||
/// The return value indicates whether `item` should be yielded to the user.
|
||||
fn expand(&mut self, item: &TraitAliasExpansionInfo<'tcx>) -> bool {
|
||||
let tcx = self.tcx;
|
||||
let trait_ref = item.trait_ref();
|
||||
let pred = trait_ref.to_predicate();
|
||||
|
||||
debug!("expand_trait_aliases: trait_ref={:?}", trait_ref);
|
||||
|
||||
// Don't recurse if this bound is not a trait alias.
|
||||
let is_alias = tcx.is_trait_alias(trait_ref.def_id());
|
||||
if !is_alias {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Don't recurse if this trait alias is already on the stack for the DFS search.
|
||||
let anon_pred = anonymize_predicate(tcx, &pred);
|
||||
if item.path.iter().rev().skip(1)
|
||||
.any(|(tr, _)| anonymize_predicate(tcx, &tr.to_predicate()) == anon_pred) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get components of trait alias.
|
||||
let predicates = tcx.super_predicates_of(trait_ref.def_id());
|
||||
|
||||
let items = predicates.predicates
|
||||
.iter()
|
||||
.rev()
|
||||
.filter_map(|(pred, span)| {
|
||||
pred.subst_supertrait(tcx, &trait_ref)
|
||||
.to_opt_poly_trait_ref()
|
||||
.map(|trait_ref| item.clone_and_push(trait_ref, *span))
|
||||
});
|
||||
debug!("expand_trait_aliases: items={:?}", items.clone());
|
||||
|
||||
self.stack.extend(items);
|
||||
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
impl<'cx, 'gcx, 'tcx> Iterator for TraitAliasExpander<'cx, 'gcx, 'tcx> {
|
||||
type Item = TraitAliasExpansionInfo<'tcx>;
|
||||
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
(self.stack.len(), None)
|
||||
}
|
||||
|
||||
fn next(&mut self) -> Option<TraitAliasExpansionInfo<'tcx>> {
|
||||
while let Some(item) = self.stack.pop() {
|
||||
if self.expand(&item) {
|
||||
return Some(item);
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Iterator over def-IDs of supertraits
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
pub struct SupertraitDefIds<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
|
||||
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
@ -298,8 +441,8 @@ impl<'cx, 'gcx, 'tcx> Iterator for SupertraitDefIds<'cx, 'gcx, 'tcx> {
|
||||
self.stack.extend(
|
||||
predicates.predicates
|
||||
.iter()
|
||||
.filter_map(|(p, _)| p.to_opt_poly_trait_ref())
|
||||
.map(|t| t.def_id())
|
||||
.filter_map(|(pred, _)| pred.to_opt_poly_trait_ref())
|
||||
.map(|trait_ref| trait_ref.def_id())
|
||||
.filter(|&super_def_id| visited.insert(super_def_id)));
|
||||
Some(def_id)
|
||||
}
|
||||
@ -325,17 +468,12 @@ impl<'tcx, I: Iterator<Item = ty::Predicate<'tcx>>> Iterator for FilterToTraits<
|
||||
type Item = ty::PolyTraitRef<'tcx>;
|
||||
|
||||
fn next(&mut self) -> Option<ty::PolyTraitRef<'tcx>> {
|
||||
loop {
|
||||
match self.base_iterator.next() {
|
||||
None => {
|
||||
return None;
|
||||
}
|
||||
Some(ty::Predicate::Trait(data)) => {
|
||||
return Some(data.to_poly_trait_ref());
|
||||
}
|
||||
Some(_) => {}
|
||||
while let Some(pred) = self.base_iterator.next() {
|
||||
if let ty::Predicate::Trait(data) = pred {
|
||||
return Some(data.to_poly_trait_ref());
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
|
@ -1075,25 +1075,25 @@ impl<'a, 'gcx, 'tcx> GenericPredicates<'tcx> {
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, HashStable)]
|
||||
pub enum Predicate<'tcx> {
|
||||
/// Corresponds to `where Foo: Bar<A,B,C>`. `Foo` here would be
|
||||
/// Corresponds to `where Foo: Bar<A, B, C>`. `Foo` here would be
|
||||
/// the `Self` type of the trait reference and `A`, `B`, and `C`
|
||||
/// would be the type parameters.
|
||||
Trait(PolyTraitPredicate<'tcx>),
|
||||
|
||||
/// where `'a: 'b`
|
||||
/// `where 'a: 'b`
|
||||
RegionOutlives(PolyRegionOutlivesPredicate<'tcx>),
|
||||
|
||||
/// where `T: 'a`
|
||||
/// `where T: 'a`
|
||||
TypeOutlives(PolyTypeOutlivesPredicate<'tcx>),
|
||||
|
||||
/// where `<T as TraitRef>::Name == X`, approximately.
|
||||
/// `where <T as TraitRef>::Name == X`, approximately.
|
||||
/// See the `ProjectionPredicate` struct for details.
|
||||
Projection(PolyProjectionPredicate<'tcx>),
|
||||
|
||||
/// no syntax: `T` well-formed
|
||||
WellFormed(Ty<'tcx>),
|
||||
|
||||
/// trait must be object-safe
|
||||
/// Trait must be object-safe.
|
||||
ObjectSafe(DefId),
|
||||
|
||||
/// No direct syntax. May be thought of as `where T: FnFoo<...>`
|
||||
@ -1234,7 +1234,7 @@ impl<'tcx> TraitPredicate<'tcx> {
|
||||
self.trait_ref.def_id
|
||||
}
|
||||
|
||||
pub fn input_types<'a>(&'a self) -> impl DoubleEndedIterator<Item=Ty<'tcx>> + 'a {
|
||||
pub fn input_types<'a>(&'a self) -> impl DoubleEndedIterator<Item = Ty<'tcx>> + 'a {
|
||||
self.trait_ref.input_types()
|
||||
}
|
||||
|
||||
@ -2400,7 +2400,7 @@ impl<'a, 'gcx, 'tcx> AdtDef {
|
||||
pub fn discriminants(
|
||||
&'a self,
|
||||
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
) -> impl Iterator<Item=(VariantIdx, Discr<'tcx>)> + Captures<'gcx> + 'a {
|
||||
) -> impl Iterator<Item = (VariantIdx, Discr<'tcx>)> + Captures<'gcx> + 'a {
|
||||
let repr_type = self.repr.discr_type();
|
||||
let initial = repr_type.initial_discriminant(tcx.global_tcx());
|
||||
let mut prev_discr = None::<Discr<'tcx>>;
|
||||
|
@ -100,8 +100,7 @@ pub use self::on_disk_cache::OnDiskCache;
|
||||
|
||||
rustc_query_append! { [define_queries!][ <'tcx>
|
||||
Other {
|
||||
/// Run analysis passes on the crate
|
||||
/// Runs analysis passes on the crate.
|
||||
[] fn analysis: Analysis(CrateNum) -> Result<(), ErrorReported>,
|
||||
|
||||
},
|
||||
]}
|
||||
|
@ -1502,7 +1502,6 @@ enum StorageDeadOrDrop<'tcx> {
|
||||
}
|
||||
|
||||
impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
||||
|
||||
/// Adds a suggestion when a closure is invoked twice with a moved variable or when a closure
|
||||
/// is moved after being invoked.
|
||||
///
|
||||
|
@ -1177,13 +1177,13 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
|
||||
);
|
||||
}
|
||||
ast::ImplItemKind::Type(ref ty) => {
|
||||
// FIXME uses of the assoc type should ideally point to this
|
||||
// FIXME: uses of the assoc type should ideally point to this
|
||||
// 'def' and the name here should be a ref to the def in the
|
||||
// trait.
|
||||
self.visit_ty(ty)
|
||||
}
|
||||
ast::ImplItemKind::Existential(ref bounds) => {
|
||||
// FIXME uses of the assoc type should ideally point to this
|
||||
// FIXME: uses of the assoc type should ideally point to this
|
||||
// 'def' and the name here should be a ref to the def in the
|
||||
// trait.
|
||||
for bound in bounds.iter() {
|
||||
@ -1216,7 +1216,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
|
||||
let hir_id = self.tcx.hir().node_to_hir_id(id);
|
||||
let access = access_from!(self.save_ctxt, root_item, hir_id);
|
||||
|
||||
// The parent def id of a given use tree is always the enclosing item.
|
||||
// The parent `DefId` of a given use tree is always the enclosing item.
|
||||
let parent = self.save_ctxt.tcx.hir().opt_local_def_id(id)
|
||||
.and_then(|id| self.save_ctxt.tcx.parent(id))
|
||||
.map(id_from_def_id);
|
||||
|
@ -648,14 +648,14 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
|
||||
// careful!
|
||||
if default_needs_object_self(param) {
|
||||
struct_span_err!(tcx.sess, span, E0393,
|
||||
"the type parameter `{}` must be explicitly \
|
||||
specified",
|
||||
param.name)
|
||||
.span_label(span,
|
||||
format!("missing reference to `{}`", param.name))
|
||||
.note(&format!("because of the default `Self` reference, \
|
||||
type parameters must be specified on object \
|
||||
types"))
|
||||
"the type parameter `{}` must be explicitly specified",
|
||||
param.name
|
||||
)
|
||||
.span_label(span, format!(
|
||||
"missing reference to `{}`", param.name))
|
||||
.note(&format!(
|
||||
"because of the default `Self` reference, type parameters \
|
||||
must be specified on object types"))
|
||||
.emit();
|
||||
tcx.types.err.into()
|
||||
} else {
|
||||
@ -702,7 +702,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
|
||||
}
|
||||
|
||||
/// Instantiates the path for the given trait reference, assuming that it's
|
||||
/// bound to a valid trait type. Returns the def_id for the defining trait.
|
||||
/// bound to a valid trait type. Returns the `DefId` of the defining trait.
|
||||
/// The type _cannot_ be a type other than a trait type.
|
||||
///
|
||||
/// If the `projections` argument is `None`, then assoc type bindings like `Foo<T = X>`
|
||||
@ -973,60 +973,81 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
|
||||
{
|
||||
let tcx = self.tcx();
|
||||
|
||||
if trait_bounds.is_empty() {
|
||||
span_err!(tcx.sess, span, E0224,
|
||||
"at least one non-builtin trait is required for an object type");
|
||||
return tcx.types.err;
|
||||
}
|
||||
|
||||
let mut projection_bounds = Vec::new();
|
||||
let mut potential_assoc_types = Vec::new();
|
||||
let dummy_self = self.tcx().types.trait_object_dummy_self;
|
||||
let (principal, potential_assoc_types) = self.instantiate_poly_trait_ref(
|
||||
&trait_bounds[0],
|
||||
dummy_self,
|
||||
&mut projection_bounds,
|
||||
);
|
||||
debug!("principal: {:?}", principal);
|
||||
// FIXME: we want to avoid collecting into a `Vec` here, but simply cloning the iterator is
|
||||
// not straightforward due to the borrow checker.
|
||||
let bound_trait_refs: Vec<_> = trait_bounds
|
||||
.iter()
|
||||
.rev()
|
||||
.map(|trait_bound| {
|
||||
let (trait_ref, cur_potential_assoc_types) = self.instantiate_poly_trait_ref(
|
||||
trait_bound,
|
||||
dummy_self,
|
||||
&mut projection_bounds
|
||||
);
|
||||
potential_assoc_types.extend(cur_potential_assoc_types.into_iter().flatten());
|
||||
(trait_ref, trait_bound.span)
|
||||
})
|
||||
.collect();
|
||||
|
||||
for trait_bound in trait_bounds[1..].iter() {
|
||||
// sanity check for non-principal trait bounds
|
||||
self.instantiate_poly_trait_ref(trait_bound,
|
||||
dummy_self,
|
||||
&mut vec![]);
|
||||
// Expand trait aliases recursively and check that only one regular (non-auto) trait
|
||||
// is used and no 'maybe' bounds are used.
|
||||
let expanded_traits = traits::expand_trait_aliases(tcx, bound_trait_refs.iter().cloned());
|
||||
let (mut auto_traits, regular_traits): (Vec<_>, Vec<_>) =
|
||||
expanded_traits.partition(|i| tcx.trait_is_auto(i.trait_ref().def_id()));
|
||||
if regular_traits.len() > 1 {
|
||||
let first_trait = ®ular_traits[0];
|
||||
let additional_trait = ®ular_traits[1];
|
||||
let mut err = struct_span_err!(tcx.sess, additional_trait.bottom().1, E0225,
|
||||
"only auto traits can be used as additional traits in a trait object"
|
||||
);
|
||||
additional_trait.label_with_exp_info(&mut err,
|
||||
"additional non-auto trait", "additional use");
|
||||
first_trait.label_with_exp_info(&mut err,
|
||||
"first non-auto trait", "first use");
|
||||
err.emit();
|
||||
}
|
||||
|
||||
let (mut auto_traits, trait_bounds) = split_auto_traits(tcx, &trait_bounds[1..]);
|
||||
|
||||
if !trait_bounds.is_empty() {
|
||||
let b = &trait_bounds[0];
|
||||
let span = b.trait_ref.path.span;
|
||||
struct_span_err!(self.tcx().sess, span, E0225,
|
||||
"only auto traits can be used as additional traits in a trait object")
|
||||
.span_label(span, "non-auto additional trait")
|
||||
.emit();
|
||||
if regular_traits.is_empty() && auto_traits.is_empty() {
|
||||
span_err!(tcx.sess, span, E0224,
|
||||
"at least one non-builtin trait is required for an object type");
|
||||
return tcx.types.err;
|
||||
}
|
||||
|
||||
// Check that there are no gross object safety violations;
|
||||
// most importantly, that the supertraits don't contain `Self`,
|
||||
// to avoid ICEs.
|
||||
let object_safety_violations =
|
||||
tcx.global_tcx().astconv_object_safety_violations(principal.def_id());
|
||||
if !object_safety_violations.is_empty() {
|
||||
tcx.report_object_safety_error(span, principal.def_id(), object_safety_violations)
|
||||
.map(|mut err| err.emit());
|
||||
return tcx.types.err;
|
||||
for item in ®ular_traits {
|
||||
let object_safety_violations =
|
||||
tcx.global_tcx().astconv_object_safety_violations(item.trait_ref().def_id());
|
||||
if !object_safety_violations.is_empty() {
|
||||
tcx.report_object_safety_error(
|
||||
span,
|
||||
item.trait_ref().def_id(),
|
||||
object_safety_violations
|
||||
)
|
||||
.map(|mut err| err.emit());
|
||||
return tcx.types.err;
|
||||
}
|
||||
}
|
||||
|
||||
// Use a `BTreeSet` to keep output in a more consistent order.
|
||||
let mut associated_types = BTreeSet::default();
|
||||
|
||||
for tr in traits::elaborate_trait_ref(tcx, principal) {
|
||||
debug!("conv_object_ty_poly_trait_ref: observing object predicate `{:?}`", tr);
|
||||
match tr {
|
||||
let regular_traits_refs = bound_trait_refs
|
||||
.into_iter()
|
||||
.filter(|(trait_ref, _)| !tcx.trait_is_auto(trait_ref.def_id()))
|
||||
.map(|(trait_ref, _)| trait_ref);
|
||||
for trait_ref in traits::elaborate_trait_refs(tcx, regular_traits_refs) {
|
||||
debug!("conv_object_ty_poly_trait_ref: observing object predicate `{:?}`", trait_ref);
|
||||
match trait_ref {
|
||||
ty::Predicate::Trait(pred) => {
|
||||
associated_types.extend(tcx.associated_items(pred.def_id())
|
||||
.filter(|item| item.kind == ty::AssociatedKind::Type)
|
||||
.map(|item| item.def_id));
|
||||
associated_types
|
||||
.extend(tcx.associated_items(pred.def_id())
|
||||
.filter(|item| item.kind == ty::AssociatedKind::Type)
|
||||
.map(|item| item.def_id));
|
||||
}
|
||||
ty::Predicate::Projection(pred) => {
|
||||
// A `Self` within the original bound will be substituted with a
|
||||
@ -1035,7 +1056,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
|
||||
pred.skip_binder().ty.walk().any(|t| t == dummy_self);
|
||||
|
||||
// If the projection output contains `Self`, force the user to
|
||||
// elaborate it explicitly to avoid a bunch of complexity.
|
||||
// elaborate it explicitly to avoid a lot of complexity.
|
||||
//
|
||||
// The "classicaly useful" case is the following:
|
||||
// ```
|
||||
@ -1044,14 +1065,14 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
|
||||
// }
|
||||
// ```
|
||||
//
|
||||
// Here, the user could theoretically write `dyn MyTrait<Output=X>`,
|
||||
// Here, the user could theoretically write `dyn MyTrait<Output = X>`,
|
||||
// but actually supporting that would "expand" to an infinitely-long type
|
||||
// `fix $ τ → dyn MyTrait<MyOutput=X, Output=<τ as MyTrait>::MyOutput`.
|
||||
// `fix $ τ → dyn MyTrait<MyOutput = X, Output = <τ as MyTrait>::MyOutput`.
|
||||
//
|
||||
// Instead, we force the user to write `dyn MyTrait<MyOutput=X, Output=X>`,
|
||||
// Instead, we force the user to write `dyn MyTrait<MyOutput = X, Output = X>`,
|
||||
// which is uglier but works. See the discussion in #56288 for alternatives.
|
||||
if !references_self {
|
||||
// Include projections defined on supertraits,
|
||||
// Include projections defined on supertraits.
|
||||
projection_bounds.push((pred, DUMMY_SP))
|
||||
}
|
||||
}
|
||||
@ -1081,20 +1102,18 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
|
||||
if associated_types.len() == 1 { "" } else { "s" },
|
||||
names,
|
||||
);
|
||||
let mut suggest = false;
|
||||
let mut potential_assoc_types_spans = vec![];
|
||||
if let Some(potential_assoc_types) = potential_assoc_types {
|
||||
let (suggest, potential_assoc_types_spans) =
|
||||
if potential_assoc_types.len() == associated_types.len() {
|
||||
// Only suggest when the amount of missing associated types is equals to the
|
||||
// Only suggest when the amount of missing associated types equals the number of
|
||||
// extra type arguments present, as that gives us a relatively high confidence
|
||||
// that the user forgot to give the associtated type's name. The canonical
|
||||
// example would be trying to use `Iterator<isize>` instead of
|
||||
// `Iterator<Item=isize>`.
|
||||
suggest = true;
|
||||
potential_assoc_types_spans = potential_assoc_types;
|
||||
}
|
||||
}
|
||||
let mut suggestions = vec![];
|
||||
// `Iterator<Item = isize>`.
|
||||
(true, potential_assoc_types)
|
||||
} else {
|
||||
(false, Vec::new())
|
||||
};
|
||||
let mut suggestions = Vec::new();
|
||||
for (i, item_def_id) in associated_types.iter().enumerate() {
|
||||
let assoc_item = tcx.associated_item(*item_def_id);
|
||||
err.span_label(
|
||||
@ -1130,9 +1149,16 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
|
||||
err.emit();
|
||||
}
|
||||
|
||||
// De-duplicate auto traits so that, e.g., `dyn Trait + Send + Send` is the same as
|
||||
// `dyn Trait + Send`.
|
||||
auto_traits.sort_by_key(|i| i.trait_ref().def_id());
|
||||
auto_traits.dedup_by_key(|i| i.trait_ref().def_id());
|
||||
debug!("regular_traits: {:?}", regular_traits);
|
||||
debug!("auto_traits: {:?}", auto_traits);
|
||||
|
||||
// Erase the `dummy_self` (`trait_object_dummy_self`) used above.
|
||||
let existential_principal = principal.map_bound(|trait_ref| {
|
||||
self.trait_ref_to_existential(trait_ref)
|
||||
let existential_trait_refs = regular_traits.iter().map(|i| {
|
||||
i.trait_ref().map_bound(|trait_ref| self.trait_ref_to_existential(trait_ref))
|
||||
});
|
||||
let existential_projections = projection_bounds.iter().map(|(bound, _)| {
|
||||
bound.map_bound(|b| {
|
||||
@ -1145,19 +1171,14 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
|
||||
})
|
||||
});
|
||||
|
||||
// Dedup auto traits so that `dyn Trait + Send + Send` is the same as `dyn Trait + Send`.
|
||||
auto_traits.sort();
|
||||
auto_traits.dedup();
|
||||
|
||||
// Calling `skip_binder` is okay, because the predicates are re-bound.
|
||||
let principal = if tcx.trait_is_auto(existential_principal.def_id()) {
|
||||
ty::ExistentialPredicate::AutoTrait(existential_principal.def_id())
|
||||
} else {
|
||||
ty::ExistentialPredicate::Trait(*existential_principal.skip_binder())
|
||||
};
|
||||
// Calling `skip_binder` is okay because the predicates are re-bound.
|
||||
let regular_trait_predicates = existential_trait_refs.map(
|
||||
|trait_ref| ty::ExistentialPredicate::Trait(*trait_ref.skip_binder()));
|
||||
let auto_trait_predicates = auto_traits.into_iter().map(
|
||||
|trait_ref| ty::ExistentialPredicate::AutoTrait(trait_ref.trait_ref().def_id()));
|
||||
let mut v =
|
||||
iter::once(principal)
|
||||
.chain(auto_traits.into_iter().map(ty::ExistentialPredicate::AutoTrait))
|
||||
regular_trait_predicates
|
||||
.chain(auto_trait_predicates)
|
||||
.chain(existential_projections
|
||||
.map(|x| ty::ExistentialPredicate::Projection(*x.skip_binder())))
|
||||
.collect::<SmallVec<[_; 8]>>();
|
||||
@ -1175,14 +1196,13 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
|
||||
} else {
|
||||
self.re_infer(span, None).unwrap_or_else(|| {
|
||||
span_err!(tcx.sess, span, E0228,
|
||||
"the lifetime bound for this object type cannot be deduced \
|
||||
from context; please supply an explicit bound");
|
||||
"the lifetime bound for this object type cannot be deduced \
|
||||
from context; please supply an explicit bound");
|
||||
tcx.lifetimes.re_static
|
||||
})
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
debug!("region_bound: {:?}", region_bound);
|
||||
|
||||
let ty = tcx.mk_dynamic(existential_predicates, region_bound);
|
||||
@ -1220,7 +1240,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
|
||||
}
|
||||
|
||||
// Search for a bound on a type parameter which includes the associated item
|
||||
// given by `assoc_name`. `ty_param_def_id` is the `DefId` for the type parameter
|
||||
// given by `assoc_name`. `ty_param_def_id` is the `DefId` of the type parameter
|
||||
// This function will fail if there are no suitable bounds or there is
|
||||
// any ambiguity.
|
||||
fn find_bound_for_assoc_item(&self,
|
||||
@ -2097,33 +2117,6 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
|
||||
}
|
||||
}
|
||||
|
||||
/// Divides a list of general trait bounds into two groups: auto traits (e.g., Sync and Send) and
|
||||
/// the remaining general trait bounds.
|
||||
fn split_auto_traits<'a, 'b, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
trait_bounds: &'b [hir::PolyTraitRef])
|
||||
-> (Vec<DefId>, Vec<&'b hir::PolyTraitRef>)
|
||||
{
|
||||
let (auto_traits, trait_bounds): (Vec<_>, _) = trait_bounds.iter().partition(|bound| {
|
||||
// Checks whether `trait_did` is an auto trait and adds it to `auto_traits` if so.
|
||||
match bound.trait_ref.path.res {
|
||||
Res::Def(DefKind::Trait, trait_did) if tcx.trait_is_auto(trait_did) => {
|
||||
true
|
||||
}
|
||||
_ => false
|
||||
}
|
||||
});
|
||||
|
||||
let auto_traits = auto_traits.into_iter().map(|tr| {
|
||||
if let Res::Def(DefKind::Trait, trait_did) = tr.trait_ref.path.res {
|
||||
trait_did
|
||||
} else {
|
||||
unreachable!()
|
||||
}
|
||||
}).collect::<Vec<_>>();
|
||||
|
||||
(auto_traits, trait_bounds)
|
||||
}
|
||||
|
||||
// A helper struct for conveniently grouping a set of bounds which we pass to
|
||||
// and return from functions in multiple places.
|
||||
#[derive(PartialEq, Eq, Clone, Debug)]
|
||||
@ -2138,7 +2131,7 @@ impl<'a, 'gcx, 'tcx> Bounds<'tcx> {
|
||||
pub fn predicates(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, param_ty: Ty<'tcx>)
|
||||
-> Vec<(ty::Predicate<'tcx>, Span)>
|
||||
{
|
||||
// If it could be sized, and is, add the sized predicate.
|
||||
// If it could be sized, and is, add the `Sized` predicate.
|
||||
let sized_predicate = self.implicitly_sized.and_then(|span| {
|
||||
tcx.lang_items().sized_trait().map(|sized| {
|
||||
let trait_ref = ty::TraitRef {
|
||||
|
@ -758,7 +758,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
|
||||
}
|
||||
|
||||
fn assemble_inherent_candidates_from_param(&mut self, param_ty: ty::ParamTy) {
|
||||
// FIXME -- Do we want to commit to this behavior for param bounds?
|
||||
// FIXME: do we want to commit to this behavior for param bounds?
|
||||
|
||||
let bounds = self.param_env
|
||||
.caller_bounds
|
||||
|
@ -1019,7 +1019,7 @@ fn check_false_global_bounds<'a, 'gcx, 'tcx>(
|
||||
.iter()
|
||||
.map(|(p, _)| *p)
|
||||
.collect();
|
||||
// Check elaborated bounds
|
||||
// Check elaborated bounds.
|
||||
let implied_obligations = traits::elaborate_predicates(fcx.tcx, predicates);
|
||||
|
||||
for pred in implied_obligations {
|
||||
|
@ -684,9 +684,9 @@ fn adt_def<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx ty::Ad
|
||||
tcx.alloc_adt_def(def_id, kind, variants, repr)
|
||||
}
|
||||
|
||||
/// Ensures that the super-predicates of the trait with `DefId`
|
||||
/// trait_def_id are converted and stored. This also ensures that
|
||||
/// the transitive super-predicates are converted;
|
||||
/// Ensures that the super-predicates of the trait with a `DefId`
|
||||
/// of `trait_def_id` are converted and stored. This also ensures that
|
||||
/// the transitive super-predicates are converted.
|
||||
fn super_predicates_of<'a, 'tcx>(
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
trait_def_id: DefId,
|
||||
@ -707,15 +707,15 @@ fn super_predicates_of<'a, 'tcx>(
|
||||
|
||||
let icx = ItemCtxt::new(tcx, trait_def_id);
|
||||
|
||||
// Convert the bounds that follow the colon, e.g., `Bar + Zed` in `trait Foo : Bar + Zed`.
|
||||
// Convert the bounds that follow the colon, e.g., `Bar + Zed` in `trait Foo: Bar + Zed`.
|
||||
let self_param_ty = tcx.mk_self_type();
|
||||
let superbounds1 = compute_bounds(&icx, self_param_ty, bounds, SizedByDefault::No, item.span);
|
||||
|
||||
let superbounds1 = superbounds1.predicates(tcx, self_param_ty);
|
||||
|
||||
// Convert any explicit superbounds in the where clause,
|
||||
// e.g., `trait Foo where Self : Bar`.
|
||||
// In the case of trait aliases, however, we include all bounds in the where clause,
|
||||
// Convert any explicit superbounds in the where-clause,
|
||||
// e.g., `trait Foo where Self: Bar`.
|
||||
// In the case of trait aliases, however, we include all bounds in the where-clause,
|
||||
// so e.g., `trait Foo = where u32: PartialEq<Self>` would include `u32: PartialEq<Self>`
|
||||
// as one of its "superpredicates".
|
||||
let is_trait_alias = tcx.is_trait_alias(trait_def_id);
|
||||
|
@ -2129,10 +2129,10 @@ pub struct TraitRef {
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
||||
pub struct PolyTraitRef {
|
||||
/// The `'a` in `<'a> Foo<&'a T>`
|
||||
/// The `'a` in `<'a> Foo<&'a T>`.
|
||||
pub bound_generic_params: Vec<GenericParam>,
|
||||
|
||||
/// The `Foo<&'a T>` in `<'a> Foo<&'a T>`
|
||||
/// The `Foo<&'a T>` in `<'a> Foo<&'a T>`.
|
||||
pub trait_ref: TraitRef,
|
||||
|
||||
pub span: Span,
|
||||
|
@ -6,7 +6,7 @@ LL | let _: &I32Iterator<Item = u32> = &vec![42].into_iter();
|
||||
|
|
||||
= note: expected type `u32`
|
||||
found type `i32`
|
||||
= note: required for the cast to the object type `dyn I32Iterator<Item = u32, Item = i32>`
|
||||
= note: required for the cast to the object type `dyn std::iter::Iterator<Item = u32, Item = i32>`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -2,7 +2,12 @@ error[E0225]: only auto traits can be used as additional traits in a trait objec
|
||||
--> $DIR/bad-sized.rs:4:24
|
||||
|
|
||||
LL | let x: Vec<Trait + Sized> = Vec::new();
|
||||
| ^^^^^ non-auto additional trait
|
||||
| ----- ^^^^^
|
||||
| | |
|
||||
| | additional non-auto trait
|
||||
| | trait alias used in trait object type (additional use)
|
||||
| first non-auto trait
|
||||
| trait alias used in trait object type (first use)
|
||||
|
||||
error[E0277]: the size for values of type `dyn Trait` cannot be known at compilation time
|
||||
--> $DIR/bad-sized.rs:4:12
|
||||
|
@ -1,4 +1,10 @@
|
||||
#![feature(trait_alias)]
|
||||
|
||||
trait Foo = std::io::Read + std::io::Write;
|
||||
|
||||
fn main() {
|
||||
let _: Box<std::io::Read + std::io::Write>;
|
||||
let _: Box<dyn std::io::Read + std::io::Write>;
|
||||
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
|
||||
let _: Box<dyn Foo>;
|
||||
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
|
||||
}
|
||||
|
@ -1,9 +1,28 @@
|
||||
error[E0225]: only auto traits can be used as additional traits in a trait object
|
||||
--> $DIR/E0225.rs:2:32
|
||||
--> $DIR/E0225.rs:6:36
|
||||
|
|
||||
LL | let _: Box<std::io::Read + std::io::Write>;
|
||||
| ^^^^^^^^^^^^^^ non-auto additional trait
|
||||
LL | let _: Box<dyn std::io::Read + std::io::Write>;
|
||||
| ------------- ^^^^^^^^^^^^^^
|
||||
| | |
|
||||
| | additional non-auto trait
|
||||
| | trait alias used in trait object type (additional use)
|
||||
| first non-auto trait
|
||||
| trait alias used in trait object type (first use)
|
||||
|
||||
error: aborting due to previous error
|
||||
error[E0225]: only auto traits can be used as additional traits in a trait object
|
||||
--> $DIR/E0225.rs:8:20
|
||||
|
|
||||
LL | trait Foo = std::io::Read + std::io::Write;
|
||||
| ------------- -------------- additional non-auto trait
|
||||
| |
|
||||
| first non-auto trait
|
||||
...
|
||||
LL | let _: Box<dyn Foo>;
|
||||
| ^^^
|
||||
| |
|
||||
| trait alias used in trait object type (additional use)
|
||||
| trait alias used in trait object type (first use)
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0225`.
|
||||
|
@ -1,3 +1,11 @@
|
||||
error[E0393]: the type parameter `Rhs` must be explicitly specified
|
||||
--> $DIR/issue-22560.rs:6:13
|
||||
|
|
||||
LL | Sub;
|
||||
| ^^^ missing reference to `Rhs`
|
||||
|
|
||||
= note: because of the default `Self` reference, type parameters must be specified on object types
|
||||
|
||||
error[E0393]: the type parameter `Rhs` must be explicitly specified
|
||||
--> $DIR/issue-22560.rs:3:13
|
||||
|
|
||||
@ -6,29 +14,35 @@ LL | type Test = Add +
|
||||
|
|
||||
= note: because of the default `Self` reference, type parameters must be specified on object types
|
||||
|
||||
error[E0393]: the type parameter `Rhs` must be explicitly specified
|
||||
--> $DIR/issue-22560.rs:6:13
|
||||
|
|
||||
LL | Sub;
|
||||
| ^^^ missing reference to `Rhs`
|
||||
|
|
||||
= note: because of the default `Self` reference, type parameters must be specified on object types
|
||||
|
||||
error[E0225]: only auto traits can be used as additional traits in a trait object
|
||||
--> $DIR/issue-22560.rs:6:13
|
||||
|
|
||||
LL | type Test = Add +
|
||||
| ---
|
||||
| |
|
||||
| first non-auto trait
|
||||
| trait alias used in trait object type (first use)
|
||||
...
|
||||
LL | Sub;
|
||||
| ^^^ non-auto additional trait
|
||||
| ^^^
|
||||
| |
|
||||
| additional non-auto trait
|
||||
| trait alias used in trait object type (additional use)
|
||||
|
||||
error[E0191]: the value of the associated type `Output` (from the trait `std::ops::Add`) must be specified
|
||||
error[E0191]: the value of the associated types `Output` (from the trait `std::ops::Add`), `Output` (from the trait `std::ops::Sub`) must be specified
|
||||
--> $DIR/issue-22560.rs:3:13
|
||||
|
|
||||
LL | type Test = Add +
|
||||
| _____________^
|
||||
| |_____________|
|
||||
| |
|
||||
LL | |
|
||||
LL | |
|
||||
LL | | Sub;
|
||||
| |_______________^ associated type `Output` must be specified
|
||||
| | ^
|
||||
| |_______________|
|
||||
| |_______________associated type `Output` must be specified
|
||||
| associated type `Output` must be specified
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
|
@ -2,7 +2,12 @@ error[E0225]: only auto traits can be used as additional traits in a trait objec
|
||||
--> $DIR/issue-32963.rs:8:25
|
||||
|
|
||||
LL | size_of_copy::<Misc+Copy>();
|
||||
| ^^^^ non-auto additional trait
|
||||
| ---- ^^^^
|
||||
| | |
|
||||
| | additional non-auto trait
|
||||
| | trait alias used in trait object type (additional use)
|
||||
| first non-auto trait
|
||||
| trait alias used in trait object type (first use)
|
||||
|
||||
error[E0277]: the trait bound `dyn Misc: std::marker::Copy` is not satisfied
|
||||
--> $DIR/issue-32963.rs:8:5
|
||||
|
@ -1,6 +1,9 @@
|
||||
trait Tr: ?Sized {} //~ ERROR `?Trait` is not permitted in supertraits
|
||||
trait Tr: ?Sized {}
|
||||
//~^ ERROR `?Trait` is not permitted in supertraits
|
||||
|
||||
type A1 = Tr + (?Sized); //~ ERROR `?Trait` is not permitted in trait object types
|
||||
type A2 = for<'a> Tr + (?Sized); //~ ERROR `?Trait` is not permitted in trait object types
|
||||
type A1 = dyn Tr + (?Sized);
|
||||
//~^ ERROR `?Trait` is not permitted in trait object types
|
||||
type A2 = dyn for<'a> Tr + (?Sized);
|
||||
//~^ ERROR `?Trait` is not permitted in trait object types
|
||||
|
||||
fn main() {}
|
||||
|
@ -7,16 +7,16 @@ LL | trait Tr: ?Sized {}
|
||||
= note: traits are `?Sized` by default
|
||||
|
||||
error: `?Trait` is not permitted in trait object types
|
||||
--> $DIR/maybe-bounds.rs:3:16
|
||||
--> $DIR/maybe-bounds.rs:4:20
|
||||
|
|
||||
LL | type A1 = Tr + (?Sized);
|
||||
| ^^^^^^^^
|
||||
LL | type A1 = dyn Tr + (?Sized);
|
||||
| ^^^^^^^^
|
||||
|
||||
error: `?Trait` is not permitted in trait object types
|
||||
--> $DIR/maybe-bounds.rs:4:24
|
||||
--> $DIR/maybe-bounds.rs:6:28
|
||||
|
|
||||
LL | type A2 = for<'a> Tr + (?Sized);
|
||||
| ^^^^^^^^
|
||||
LL | type A2 = dyn for<'a> Tr + (?Sized);
|
||||
| ^^^^^^^^
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
|
@ -7,6 +7,6 @@ fn main() {
|
||||
//~^ ERROR `?Trait` is not permitted in trait object types
|
||||
let _: Box<(?Sized) + (for<'a> Trait<'a>) + (Copy)>;
|
||||
let _: Box<(for<'a> Trait<'a>) + (Copy) + (?Sized)>;
|
||||
//~^ ERROR `?Trait` is not permitted in trait object types
|
||||
//~| ERROR use of undeclared lifetime name `'a`
|
||||
//~^ ERROR use of undeclared lifetime name `'a`
|
||||
//~| ERROR `?Trait` is not permitted in trait object types
|
||||
}
|
||||
|
@ -1,9 +0,0 @@
|
||||
#![feature(trait_alias)]
|
||||
|
||||
trait EqAlias = Eq;
|
||||
trait IteratorAlias = Iterator;
|
||||
|
||||
fn main() {
|
||||
let _: &dyn EqAlias = &123; //~ ERROR `EqAlias` cannot be made into an object
|
||||
let _: &dyn IteratorAlias = &vec![123].into_iter(); //~ ERROR must be specified
|
||||
}
|
@ -1,3 +1,5 @@
|
||||
// run-pass
|
||||
|
||||
#![feature(trait_alias)]
|
||||
|
||||
use std::marker::PhantomData;
|
29
src/test/ui/traits/trait-alias/trait-alias-maybe-bound.rs
Normal file
29
src/test/ui/traits/trait-alias/trait-alias-maybe-bound.rs
Normal file
@ -0,0 +1,29 @@
|
||||
// compile-pass
|
||||
|
||||
// Test that `dyn ... + ?Sized + ...` resulting from the expansion of trait aliases is okay.
|
||||
|
||||
#![feature(trait_alias)]
|
||||
|
||||
trait Foo {}
|
||||
|
||||
trait S = ?Sized;
|
||||
|
||||
// Nest a couple of levels deep:
|
||||
trait _0 = S;
|
||||
trait _1 = _0;
|
||||
|
||||
// Straight list expansion:
|
||||
type _T0 = dyn _1 + Foo;
|
||||
|
||||
// In second position:
|
||||
type _T1 = dyn Foo + _1;
|
||||
|
||||
// ... and with an auto trait:
|
||||
type _T2 = dyn Foo + Send + _1;
|
||||
|
||||
// Twice:
|
||||
trait _2 = _1 + _1;
|
||||
|
||||
type _T3 = dyn _2 + Foo;
|
||||
|
||||
fn main() {}
|
126
src/test/ui/traits/trait-alias/trait-alias-no-duplicates.rs
Normal file
126
src/test/ui/traits/trait-alias/trait-alias-no-duplicates.rs
Normal file
@ -0,0 +1,126 @@
|
||||
// The purpose of this test is to demonstrate that duplicating object safe traits
|
||||
// that are not auto traits is rejected with trait aliases even though one could
|
||||
// reasonably accept this.
|
||||
|
||||
#![feature(trait_alias)]
|
||||
|
||||
use std::marker::Unpin;
|
||||
|
||||
// Some arbitrary object-safe trait:
|
||||
trait Obj {}
|
||||
|
||||
// Nest a few levels deep:
|
||||
trait _0 = Obj;
|
||||
trait _1 = _0;
|
||||
|
||||
type _T00 = dyn _0 + _0;
|
||||
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
|
||||
|
||||
type _T01 = dyn _1 + _0;
|
||||
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
|
||||
|
||||
type _T02 = dyn _1 + _1;
|
||||
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
|
||||
|
||||
type _T03 = dyn Obj + _1;
|
||||
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
|
||||
|
||||
type _T04 = dyn _1 + Obj;
|
||||
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
|
||||
|
||||
// Nest some more and in weird ways:
|
||||
|
||||
trait _2 = _0 + _1;
|
||||
trait _3 = Obj;
|
||||
trait _4 = _3;
|
||||
|
||||
type _T10 = dyn _2 + _3;
|
||||
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
|
||||
|
||||
type _T11 = dyn _3 + _2;
|
||||
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
|
||||
|
||||
type _T12 = dyn Obj + _2;
|
||||
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
|
||||
|
||||
type _T13 = dyn _2 + Obj;
|
||||
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
|
||||
|
||||
type _T14 = dyn _1 + _3;
|
||||
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
|
||||
|
||||
type _T15 = dyn _3 + _1;
|
||||
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
|
||||
|
||||
type _T16 = dyn _1 + _4;
|
||||
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
|
||||
|
||||
type _T17 = dyn _4 + _1;
|
||||
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
|
||||
|
||||
// Include auto traits:
|
||||
|
||||
trait _5 = Obj + Send;
|
||||
|
||||
type _T20 = dyn _5 + _5;
|
||||
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
|
||||
|
||||
type _T21 = dyn Obj + _5;
|
||||
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
|
||||
|
||||
type _T22 = dyn _5 + Obj;
|
||||
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
|
||||
|
||||
type _T23 = dyn _5 + Send + Sync + Obj;
|
||||
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
|
||||
|
||||
// Also nest:
|
||||
|
||||
trait _6 = _5 + _5; // ==> Obj + Send + Obj + Send
|
||||
|
||||
type _T30 = dyn _6;
|
||||
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
|
||||
|
||||
type _T31 = dyn _6 + Send;
|
||||
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
|
||||
|
||||
type _T32 = dyn Send + _6;
|
||||
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
|
||||
|
||||
// Nest some more:
|
||||
|
||||
trait _7 = _5 + Sync;
|
||||
trait _8 = Unpin + _7;
|
||||
|
||||
type _T40 = dyn _8 + Obj;
|
||||
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
|
||||
|
||||
type _T41 = dyn Obj + _8;
|
||||
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
|
||||
|
||||
type _T42 = dyn _8 + _4;
|
||||
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
|
||||
|
||||
type _T43 = dyn _4 + _8;
|
||||
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
|
||||
|
||||
type _T44 = dyn _4 + Send + Sync + _8;
|
||||
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
|
||||
|
||||
// Take higher ranked types into account.
|
||||
|
||||
// Note that `'a` and `'b` are intentionally different to make sure we consider
|
||||
// them semantically the same.
|
||||
trait ObjL<'l> {}
|
||||
trait _9 = for<'a> ObjL<'a>;
|
||||
trait _10 = for<'b> ObjL<'b>;
|
||||
type _T50 = _9 + _10;
|
||||
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
|
||||
|
||||
trait ObjT<T> {}
|
||||
trait _11 = ObjT<for<'a> fn(&'a u8)>;
|
||||
trait _12 = ObjT<for<'b> fn(&'b u8)>;
|
||||
type _T60 = _11 + _12;
|
||||
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
|
||||
|
||||
fn main() {}
|
458
src/test/ui/traits/trait-alias/trait-alias-no-duplicates.stderr
Normal file
458
src/test/ui/traits/trait-alias/trait-alias-no-duplicates.stderr
Normal file
@ -0,0 +1,458 @@
|
||||
error[E0225]: only auto traits can be used as additional traits in a trait object
|
||||
--> $DIR/trait-alias-no-duplicates.rs:16:22
|
||||
|
|
||||
LL | trait _0 = Obj;
|
||||
| ---
|
||||
| |
|
||||
| additional non-auto trait
|
||||
| first non-auto trait
|
||||
...
|
||||
LL | type _T00 = dyn _0 + _0;
|
||||
| -- ^^ trait alias used in trait object type (additional use)
|
||||
| |
|
||||
| trait alias used in trait object type (first use)
|
||||
|
||||
error[E0225]: only auto traits can be used as additional traits in a trait object
|
||||
--> $DIR/trait-alias-no-duplicates.rs:19:22
|
||||
|
|
||||
LL | trait _0 = Obj;
|
||||
| ---
|
||||
| |
|
||||
| additional non-auto trait
|
||||
| first non-auto trait
|
||||
LL | trait _1 = _0;
|
||||
| -- referenced here (first use)
|
||||
...
|
||||
LL | type _T01 = dyn _1 + _0;
|
||||
| -- ^^ trait alias used in trait object type (additional use)
|
||||
| |
|
||||
| trait alias used in trait object type (first use)
|
||||
|
||||
error[E0225]: only auto traits can be used as additional traits in a trait object
|
||||
--> $DIR/trait-alias-no-duplicates.rs:22:22
|
||||
|
|
||||
LL | trait _0 = Obj;
|
||||
| ---
|
||||
| |
|
||||
| additional non-auto trait
|
||||
| first non-auto trait
|
||||
LL | trait _1 = _0;
|
||||
| --
|
||||
| |
|
||||
| referenced here (additional use)
|
||||
| referenced here (first use)
|
||||
...
|
||||
LL | type _T02 = dyn _1 + _1;
|
||||
| -- ^^ trait alias used in trait object type (additional use)
|
||||
| |
|
||||
| trait alias used in trait object type (first use)
|
||||
|
||||
error[E0225]: only auto traits can be used as additional traits in a trait object
|
||||
--> $DIR/trait-alias-no-duplicates.rs:25:23
|
||||
|
|
||||
LL | trait _0 = Obj;
|
||||
| --- additional non-auto trait
|
||||
LL | trait _1 = _0;
|
||||
| -- referenced here (additional use)
|
||||
...
|
||||
LL | type _T03 = dyn Obj + _1;
|
||||
| --- ^^ trait alias used in trait object type (additional use)
|
||||
| |
|
||||
| first non-auto trait
|
||||
| trait alias used in trait object type (first use)
|
||||
|
||||
error[E0225]: only auto traits can be used as additional traits in a trait object
|
||||
--> $DIR/trait-alias-no-duplicates.rs:28:22
|
||||
|
|
||||
LL | trait _0 = Obj;
|
||||
| --- first non-auto trait
|
||||
LL | trait _1 = _0;
|
||||
| -- referenced here (first use)
|
||||
...
|
||||
LL | type _T04 = dyn _1 + Obj;
|
||||
| -- ^^^
|
||||
| | |
|
||||
| | additional non-auto trait
|
||||
| | trait alias used in trait object type (additional use)
|
||||
| trait alias used in trait object type (first use)
|
||||
|
||||
error[E0225]: only auto traits can be used as additional traits in a trait object
|
||||
--> $DIR/trait-alias-no-duplicates.rs:37:17
|
||||
|
|
||||
LL | trait _0 = Obj;
|
||||
| ---
|
||||
| |
|
||||
| additional non-auto trait
|
||||
| first non-auto trait
|
||||
LL | trait _1 = _0;
|
||||
| -- referenced here (additional use)
|
||||
...
|
||||
LL | trait _2 = _0 + _1;
|
||||
| -- -- referenced here (additional use)
|
||||
| |
|
||||
| referenced here (first use)
|
||||
...
|
||||
LL | type _T10 = dyn _2 + _3;
|
||||
| ^^
|
||||
| |
|
||||
| trait alias used in trait object type (additional use)
|
||||
| trait alias used in trait object type (first use)
|
||||
|
||||
error[E0225]: only auto traits can be used as additional traits in a trait object
|
||||
--> $DIR/trait-alias-no-duplicates.rs:40:22
|
||||
|
|
||||
LL | trait _0 = Obj;
|
||||
| --- additional non-auto trait
|
||||
...
|
||||
LL | trait _2 = _0 + _1;
|
||||
| -- referenced here (additional use)
|
||||
LL | trait _3 = Obj;
|
||||
| --- first non-auto trait
|
||||
...
|
||||
LL | type _T11 = dyn _3 + _2;
|
||||
| -- ^^ trait alias used in trait object type (additional use)
|
||||
| |
|
||||
| trait alias used in trait object type (first use)
|
||||
|
||||
error[E0225]: only auto traits can be used as additional traits in a trait object
|
||||
--> $DIR/trait-alias-no-duplicates.rs:43:23
|
||||
|
|
||||
LL | trait _0 = Obj;
|
||||
| --- additional non-auto trait
|
||||
...
|
||||
LL | trait _2 = _0 + _1;
|
||||
| -- referenced here (additional use)
|
||||
...
|
||||
LL | type _T12 = dyn Obj + _2;
|
||||
| --- ^^ trait alias used in trait object type (additional use)
|
||||
| |
|
||||
| first non-auto trait
|
||||
| trait alias used in trait object type (first use)
|
||||
|
||||
error[E0225]: only auto traits can be used as additional traits in a trait object
|
||||
--> $DIR/trait-alias-no-duplicates.rs:46:17
|
||||
|
|
||||
LL | trait _0 = Obj;
|
||||
| ---
|
||||
| |
|
||||
| additional non-auto trait
|
||||
| first non-auto trait
|
||||
LL | trait _1 = _0;
|
||||
| -- referenced here (additional use)
|
||||
...
|
||||
LL | trait _2 = _0 + _1;
|
||||
| -- -- referenced here (additional use)
|
||||
| |
|
||||
| referenced here (first use)
|
||||
...
|
||||
LL | type _T13 = dyn _2 + Obj;
|
||||
| ^^
|
||||
| |
|
||||
| trait alias used in trait object type (additional use)
|
||||
| trait alias used in trait object type (first use)
|
||||
|
||||
error[E0225]: only auto traits can be used as additional traits in a trait object
|
||||
--> $DIR/trait-alias-no-duplicates.rs:49:22
|
||||
|
|
||||
LL | trait _0 = Obj;
|
||||
| --- first non-auto trait
|
||||
LL | trait _1 = _0;
|
||||
| -- referenced here (first use)
|
||||
...
|
||||
LL | trait _3 = Obj;
|
||||
| --- additional non-auto trait
|
||||
...
|
||||
LL | type _T14 = dyn _1 + _3;
|
||||
| -- ^^ trait alias used in trait object type (additional use)
|
||||
| |
|
||||
| trait alias used in trait object type (first use)
|
||||
|
||||
error[E0225]: only auto traits can be used as additional traits in a trait object
|
||||
--> $DIR/trait-alias-no-duplicates.rs:52:22
|
||||
|
|
||||
LL | trait _0 = Obj;
|
||||
| --- additional non-auto trait
|
||||
LL | trait _1 = _0;
|
||||
| -- referenced here (additional use)
|
||||
...
|
||||
LL | trait _3 = Obj;
|
||||
| --- first non-auto trait
|
||||
...
|
||||
LL | type _T15 = dyn _3 + _1;
|
||||
| -- ^^ trait alias used in trait object type (additional use)
|
||||
| |
|
||||
| trait alias used in trait object type (first use)
|
||||
|
||||
error[E0225]: only auto traits can be used as additional traits in a trait object
|
||||
--> $DIR/trait-alias-no-duplicates.rs:55:22
|
||||
|
|
||||
LL | trait _0 = Obj;
|
||||
| --- first non-auto trait
|
||||
LL | trait _1 = _0;
|
||||
| -- referenced here (first use)
|
||||
...
|
||||
LL | trait _3 = Obj;
|
||||
| --- additional non-auto trait
|
||||
LL | trait _4 = _3;
|
||||
| -- referenced here (additional use)
|
||||
...
|
||||
LL | type _T16 = dyn _1 + _4;
|
||||
| -- ^^ trait alias used in trait object type (additional use)
|
||||
| |
|
||||
| trait alias used in trait object type (first use)
|
||||
|
||||
error[E0225]: only auto traits can be used as additional traits in a trait object
|
||||
--> $DIR/trait-alias-no-duplicates.rs:58:22
|
||||
|
|
||||
LL | trait _0 = Obj;
|
||||
| --- additional non-auto trait
|
||||
LL | trait _1 = _0;
|
||||
| -- referenced here (additional use)
|
||||
...
|
||||
LL | trait _3 = Obj;
|
||||
| --- first non-auto trait
|
||||
LL | trait _4 = _3;
|
||||
| -- referenced here (first use)
|
||||
...
|
||||
LL | type _T17 = dyn _4 + _1;
|
||||
| -- ^^ trait alias used in trait object type (additional use)
|
||||
| |
|
||||
| trait alias used in trait object type (first use)
|
||||
|
||||
error[E0225]: only auto traits can be used as additional traits in a trait object
|
||||
--> $DIR/trait-alias-no-duplicates.rs:65:22
|
||||
|
|
||||
LL | trait _5 = Obj + Send;
|
||||
| ---
|
||||
| |
|
||||
| additional non-auto trait
|
||||
| first non-auto trait
|
||||
LL |
|
||||
LL | type _T20 = dyn _5 + _5;
|
||||
| -- ^^ trait alias used in trait object type (additional use)
|
||||
| |
|
||||
| trait alias used in trait object type (first use)
|
||||
|
||||
error[E0225]: only auto traits can be used as additional traits in a trait object
|
||||
--> $DIR/trait-alias-no-duplicates.rs:68:23
|
||||
|
|
||||
LL | trait _5 = Obj + Send;
|
||||
| --- additional non-auto trait
|
||||
...
|
||||
LL | type _T21 = dyn Obj + _5;
|
||||
| --- ^^ trait alias used in trait object type (additional use)
|
||||
| |
|
||||
| first non-auto trait
|
||||
| trait alias used in trait object type (first use)
|
||||
|
||||
error[E0225]: only auto traits can be used as additional traits in a trait object
|
||||
--> $DIR/trait-alias-no-duplicates.rs:71:22
|
||||
|
|
||||
LL | trait _5 = Obj + Send;
|
||||
| --- first non-auto trait
|
||||
...
|
||||
LL | type _T22 = dyn _5 + Obj;
|
||||
| -- ^^^
|
||||
| | |
|
||||
| | additional non-auto trait
|
||||
| | trait alias used in trait object type (additional use)
|
||||
| trait alias used in trait object type (first use)
|
||||
|
||||
error[E0225]: only auto traits can be used as additional traits in a trait object
|
||||
--> $DIR/trait-alias-no-duplicates.rs:74:36
|
||||
|
|
||||
LL | trait _5 = Obj + Send;
|
||||
| --- first non-auto trait
|
||||
...
|
||||
LL | type _T23 = dyn _5 + Send + Sync + Obj;
|
||||
| -- ^^^
|
||||
| | |
|
||||
| | additional non-auto trait
|
||||
| | trait alias used in trait object type (additional use)
|
||||
| trait alias used in trait object type (first use)
|
||||
|
||||
error[E0225]: only auto traits can be used as additional traits in a trait object
|
||||
--> $DIR/trait-alias-no-duplicates.rs:81:17
|
||||
|
|
||||
LL | trait _5 = Obj + Send;
|
||||
| ---
|
||||
| |
|
||||
| additional non-auto trait
|
||||
| first non-auto trait
|
||||
...
|
||||
LL | trait _6 = _5 + _5; // ==> Obj + Send + Obj + Send
|
||||
| -- -- referenced here (additional use)
|
||||
| |
|
||||
| referenced here (first use)
|
||||
LL |
|
||||
LL | type _T30 = dyn _6;
|
||||
| ^^
|
||||
| |
|
||||
| trait alias used in trait object type (additional use)
|
||||
| trait alias used in trait object type (first use)
|
||||
|
||||
error[E0225]: only auto traits can be used as additional traits in a trait object
|
||||
--> $DIR/trait-alias-no-duplicates.rs:84:17
|
||||
|
|
||||
LL | trait _5 = Obj + Send;
|
||||
| ---
|
||||
| |
|
||||
| additional non-auto trait
|
||||
| first non-auto trait
|
||||
...
|
||||
LL | trait _6 = _5 + _5; // ==> Obj + Send + Obj + Send
|
||||
| -- -- referenced here (additional use)
|
||||
| |
|
||||
| referenced here (first use)
|
||||
...
|
||||
LL | type _T31 = dyn _6 + Send;
|
||||
| ^^
|
||||
| |
|
||||
| trait alias used in trait object type (additional use)
|
||||
| trait alias used in trait object type (first use)
|
||||
|
||||
error[E0225]: only auto traits can be used as additional traits in a trait object
|
||||
--> $DIR/trait-alias-no-duplicates.rs:87:24
|
||||
|
|
||||
LL | trait _5 = Obj + Send;
|
||||
| ---
|
||||
| |
|
||||
| additional non-auto trait
|
||||
| first non-auto trait
|
||||
...
|
||||
LL | trait _6 = _5 + _5; // ==> Obj + Send + Obj + Send
|
||||
| -- -- referenced here (additional use)
|
||||
| |
|
||||
| referenced here (first use)
|
||||
...
|
||||
LL | type _T32 = dyn Send + _6;
|
||||
| ^^
|
||||
| |
|
||||
| trait alias used in trait object type (additional use)
|
||||
| trait alias used in trait object type (first use)
|
||||
|
||||
error[E0225]: only auto traits can be used as additional traits in a trait object
|
||||
--> $DIR/trait-alias-no-duplicates.rs:95:22
|
||||
|
|
||||
LL | trait _5 = Obj + Send;
|
||||
| --- first non-auto trait
|
||||
...
|
||||
LL | trait _7 = _5 + Sync;
|
||||
| -- referenced here (first use)
|
||||
LL | trait _8 = Unpin + _7;
|
||||
| -- referenced here (first use)
|
||||
LL |
|
||||
LL | type _T40 = dyn _8 + Obj;
|
||||
| -- ^^^
|
||||
| | |
|
||||
| | additional non-auto trait
|
||||
| | trait alias used in trait object type (additional use)
|
||||
| trait alias used in trait object type (first use)
|
||||
|
||||
error[E0225]: only auto traits can be used as additional traits in a trait object
|
||||
--> $DIR/trait-alias-no-duplicates.rs:98:23
|
||||
|
|
||||
LL | trait _5 = Obj + Send;
|
||||
| --- additional non-auto trait
|
||||
...
|
||||
LL | trait _7 = _5 + Sync;
|
||||
| -- referenced here (additional use)
|
||||
LL | trait _8 = Unpin + _7;
|
||||
| -- referenced here (additional use)
|
||||
...
|
||||
LL | type _T41 = dyn Obj + _8;
|
||||
| --- ^^ trait alias used in trait object type (additional use)
|
||||
| |
|
||||
| first non-auto trait
|
||||
| trait alias used in trait object type (first use)
|
||||
|
||||
error[E0225]: only auto traits can be used as additional traits in a trait object
|
||||
--> $DIR/trait-alias-no-duplicates.rs:101:22
|
||||
|
|
||||
LL | trait _3 = Obj;
|
||||
| --- additional non-auto trait
|
||||
LL | trait _4 = _3;
|
||||
| -- referenced here (additional use)
|
||||
...
|
||||
LL | trait _5 = Obj + Send;
|
||||
| --- first non-auto trait
|
||||
...
|
||||
LL | trait _7 = _5 + Sync;
|
||||
| -- referenced here (first use)
|
||||
LL | trait _8 = Unpin + _7;
|
||||
| -- referenced here (first use)
|
||||
...
|
||||
LL | type _T42 = dyn _8 + _4;
|
||||
| -- ^^ trait alias used in trait object type (additional use)
|
||||
| |
|
||||
| trait alias used in trait object type (first use)
|
||||
|
||||
error[E0225]: only auto traits can be used as additional traits in a trait object
|
||||
--> $DIR/trait-alias-no-duplicates.rs:104:22
|
||||
|
|
||||
LL | trait _3 = Obj;
|
||||
| --- first non-auto trait
|
||||
LL | trait _4 = _3;
|
||||
| -- referenced here (first use)
|
||||
...
|
||||
LL | trait _5 = Obj + Send;
|
||||
| --- additional non-auto trait
|
||||
...
|
||||
LL | trait _7 = _5 + Sync;
|
||||
| -- referenced here (additional use)
|
||||
LL | trait _8 = Unpin + _7;
|
||||
| -- referenced here (additional use)
|
||||
...
|
||||
LL | type _T43 = dyn _4 + _8;
|
||||
| -- ^^ trait alias used in trait object type (additional use)
|
||||
| |
|
||||
| trait alias used in trait object type (first use)
|
||||
|
||||
error[E0225]: only auto traits can be used as additional traits in a trait object
|
||||
--> $DIR/trait-alias-no-duplicates.rs:107:36
|
||||
|
|
||||
LL | trait _3 = Obj;
|
||||
| --- first non-auto trait
|
||||
LL | trait _4 = _3;
|
||||
| -- referenced here (first use)
|
||||
...
|
||||
LL | trait _5 = Obj + Send;
|
||||
| --- additional non-auto trait
|
||||
...
|
||||
LL | trait _7 = _5 + Sync;
|
||||
| -- referenced here (additional use)
|
||||
LL | trait _8 = Unpin + _7;
|
||||
| -- referenced here (additional use)
|
||||
...
|
||||
LL | type _T44 = dyn _4 + Send + Sync + _8;
|
||||
| -- ^^ trait alias used in trait object type (additional use)
|
||||
| |
|
||||
| trait alias used in trait object type (first use)
|
||||
|
||||
error[E0225]: only auto traits can be used as additional traits in a trait object
|
||||
--> $DIR/trait-alias-no-duplicates.rs:117:18
|
||||
|
|
||||
LL | trait _9 = for<'a> ObjL<'a>;
|
||||
| ---------------- first non-auto trait
|
||||
LL | trait _10 = for<'b> ObjL<'b>;
|
||||
| ---------------- additional non-auto trait
|
||||
LL | type _T50 = _9 + _10;
|
||||
| -- ^^^ trait alias used in trait object type (additional use)
|
||||
| |
|
||||
| trait alias used in trait object type (first use)
|
||||
|
||||
error[E0225]: only auto traits can be used as additional traits in a trait object
|
||||
--> $DIR/trait-alias-no-duplicates.rs:123:19
|
||||
|
|
||||
LL | trait _11 = ObjT<for<'a> fn(&'a u8)>;
|
||||
| ------------------------ first non-auto trait
|
||||
LL | trait _12 = ObjT<for<'b> fn(&'b u8)>;
|
||||
| ------------------------ additional non-auto trait
|
||||
LL | type _T60 = _11 + _12;
|
||||
| --- ^^^ trait alias used in trait object type (additional use)
|
||||
| |
|
||||
| trait alias used in trait object type (first use)
|
||||
|
||||
error: aborting due to 27 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0225`.
|
121
src/test/ui/traits/trait-alias/trait-alias-no-extra-traits.rs
Normal file
121
src/test/ui/traits/trait-alias/trait-alias-no-extra-traits.rs
Normal file
@ -0,0 +1,121 @@
|
||||
// The purpose of this test is to demonstrate that trait alias expansion
|
||||
// preserves the rule that `dyn Trait` may only reference one non-auto trait.
|
||||
|
||||
#![feature(trait_alias)]
|
||||
|
||||
use std::marker::Unpin;
|
||||
|
||||
// Some arbitrary object-safe traits:
|
||||
trait ObjA {}
|
||||
trait ObjB {}
|
||||
|
||||
// Nest a few levels deep:
|
||||
trait _0 = ObjA;
|
||||
trait _1 = _0;
|
||||
|
||||
type _T00 = dyn _0 + ObjB;
|
||||
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
|
||||
|
||||
type _T01 = dyn ObjB + _0;
|
||||
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
|
||||
|
||||
type _T02 = dyn ObjB + _1;
|
||||
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
|
||||
|
||||
type _T03 = dyn _1 + ObjB;
|
||||
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
|
||||
|
||||
// Nest some more and in weird ways:
|
||||
|
||||
trait _2 = ObjB;
|
||||
trait _3 = _2;
|
||||
trait _4 = _3;
|
||||
|
||||
type _T10 = dyn _2 + _3;
|
||||
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
|
||||
|
||||
type _T11 = dyn _3 + _2;
|
||||
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
|
||||
|
||||
type _T12 = dyn _2 + _4;
|
||||
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
|
||||
|
||||
type _T13 = dyn _4 + _2;
|
||||
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
|
||||
|
||||
// Include auto traits:
|
||||
|
||||
trait _5 = Sync + ObjB + Send;
|
||||
|
||||
type _T20 = dyn _5 + _1;
|
||||
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
|
||||
|
||||
type _T21 = dyn _1 + _5;
|
||||
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
|
||||
|
||||
type _T22 = dyn _5 + ObjA;
|
||||
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
|
||||
|
||||
type _T23 = dyn ObjA + _5;
|
||||
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
|
||||
|
||||
type _T24 = dyn Send + _5 + _1 + Sync;
|
||||
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
|
||||
|
||||
type _T25 = dyn _1 + Sync + _5 + Send;
|
||||
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
|
||||
|
||||
type _T26 = dyn Sync + Send + _5 + ObjA;
|
||||
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
|
||||
|
||||
type _T27 = dyn Send + Sync + ObjA + _5;
|
||||
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
|
||||
|
||||
// Also nest:
|
||||
|
||||
trait _6 = _1 + _5;
|
||||
trait _7 = _6;
|
||||
trait _8 = _7;
|
||||
|
||||
type _T30 = dyn _6;
|
||||
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
|
||||
|
||||
type _T31 = dyn _6 + Send;
|
||||
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
|
||||
|
||||
type _T32 = dyn Send + _6;
|
||||
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
|
||||
|
||||
type _T33 = dyn _8;
|
||||
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
|
||||
|
||||
type _T34 = dyn _8 + Send;
|
||||
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
|
||||
|
||||
type _T35 = dyn Send + _8;
|
||||
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
|
||||
|
||||
// Nest some more:
|
||||
|
||||
trait _9 = _5 + Sync;
|
||||
trait _10 = Unpin + _9;
|
||||
|
||||
type _T40 = dyn _10 + ObjA;
|
||||
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
|
||||
|
||||
type _T41 = dyn ObjA + _10;
|
||||
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
|
||||
|
||||
type _T42 = dyn _10 + _1;
|
||||
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
|
||||
|
||||
type _T43 = dyn Send + _10 + Sync + ObjA;
|
||||
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
|
||||
|
||||
type _T44 = dyn ObjA + _10 + Send + Sync;
|
||||
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
|
||||
|
||||
type _T45 = dyn Sync + Send + _10 + _1;
|
||||
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
|
||||
|
||||
fn main() {}
|
@ -0,0 +1,513 @@
|
||||
error[E0225]: only auto traits can be used as additional traits in a trait object
|
||||
--> $DIR/trait-alias-no-extra-traits.rs:16:22
|
||||
|
|
||||
LL | trait _0 = ObjA;
|
||||
| ---- first non-auto trait
|
||||
...
|
||||
LL | type _T00 = dyn _0 + ObjB;
|
||||
| -- ^^^^
|
||||
| | |
|
||||
| | additional non-auto trait
|
||||
| | trait alias used in trait object type (additional use)
|
||||
| trait alias used in trait object type (first use)
|
||||
|
||||
error[E0225]: only auto traits can be used as additional traits in a trait object
|
||||
--> $DIR/trait-alias-no-extra-traits.rs:19:24
|
||||
|
|
||||
LL | trait _0 = ObjA;
|
||||
| ---- additional non-auto trait
|
||||
...
|
||||
LL | type _T01 = dyn ObjB + _0;
|
||||
| ---- ^^ trait alias used in trait object type (additional use)
|
||||
| |
|
||||
| first non-auto trait
|
||||
| trait alias used in trait object type (first use)
|
||||
|
||||
error[E0225]: only auto traits can be used as additional traits in a trait object
|
||||
--> $DIR/trait-alias-no-extra-traits.rs:22:24
|
||||
|
|
||||
LL | trait _0 = ObjA;
|
||||
| ---- additional non-auto trait
|
||||
LL | trait _1 = _0;
|
||||
| -- referenced here (additional use)
|
||||
...
|
||||
LL | type _T02 = dyn ObjB + _1;
|
||||
| ---- ^^ trait alias used in trait object type (additional use)
|
||||
| |
|
||||
| first non-auto trait
|
||||
| trait alias used in trait object type (first use)
|
||||
|
||||
error[E0225]: only auto traits can be used as additional traits in a trait object
|
||||
--> $DIR/trait-alias-no-extra-traits.rs:25:22
|
||||
|
|
||||
LL | trait _0 = ObjA;
|
||||
| ---- first non-auto trait
|
||||
LL | trait _1 = _0;
|
||||
| -- referenced here (first use)
|
||||
...
|
||||
LL | type _T03 = dyn _1 + ObjB;
|
||||
| -- ^^^^
|
||||
| | |
|
||||
| | additional non-auto trait
|
||||
| | trait alias used in trait object type (additional use)
|
||||
| trait alias used in trait object type (first use)
|
||||
|
||||
error[E0225]: only auto traits can be used as additional traits in a trait object
|
||||
--> $DIR/trait-alias-no-extra-traits.rs:34:22
|
||||
|
|
||||
LL | trait _2 = ObjB;
|
||||
| ----
|
||||
| |
|
||||
| additional non-auto trait
|
||||
| first non-auto trait
|
||||
LL | trait _3 = _2;
|
||||
| -- referenced here (additional use)
|
||||
...
|
||||
LL | type _T10 = dyn _2 + _3;
|
||||
| -- ^^ trait alias used in trait object type (additional use)
|
||||
| |
|
||||
| trait alias used in trait object type (first use)
|
||||
|
||||
error[E0225]: only auto traits can be used as additional traits in a trait object
|
||||
--> $DIR/trait-alias-no-extra-traits.rs:37:22
|
||||
|
|
||||
LL | trait _2 = ObjB;
|
||||
| ----
|
||||
| |
|
||||
| additional non-auto trait
|
||||
| first non-auto trait
|
||||
LL | trait _3 = _2;
|
||||
| -- referenced here (first use)
|
||||
...
|
||||
LL | type _T11 = dyn _3 + _2;
|
||||
| -- ^^ trait alias used in trait object type (additional use)
|
||||
| |
|
||||
| trait alias used in trait object type (first use)
|
||||
|
||||
error[E0225]: only auto traits can be used as additional traits in a trait object
|
||||
--> $DIR/trait-alias-no-extra-traits.rs:40:22
|
||||
|
|
||||
LL | trait _2 = ObjB;
|
||||
| ----
|
||||
| |
|
||||
| additional non-auto trait
|
||||
| first non-auto trait
|
||||
LL | trait _3 = _2;
|
||||
| -- referenced here (additional use)
|
||||
LL | trait _4 = _3;
|
||||
| -- referenced here (additional use)
|
||||
...
|
||||
LL | type _T12 = dyn _2 + _4;
|
||||
| -- ^^ trait alias used in trait object type (additional use)
|
||||
| |
|
||||
| trait alias used in trait object type (first use)
|
||||
|
||||
error[E0225]: only auto traits can be used as additional traits in a trait object
|
||||
--> $DIR/trait-alias-no-extra-traits.rs:43:22
|
||||
|
|
||||
LL | trait _2 = ObjB;
|
||||
| ----
|
||||
| |
|
||||
| additional non-auto trait
|
||||
| first non-auto trait
|
||||
LL | trait _3 = _2;
|
||||
| -- referenced here (first use)
|
||||
LL | trait _4 = _3;
|
||||
| -- referenced here (first use)
|
||||
...
|
||||
LL | type _T13 = dyn _4 + _2;
|
||||
| -- ^^ trait alias used in trait object type (additional use)
|
||||
| |
|
||||
| trait alias used in trait object type (first use)
|
||||
|
||||
error[E0225]: only auto traits can be used as additional traits in a trait object
|
||||
--> $DIR/trait-alias-no-extra-traits.rs:50:22
|
||||
|
|
||||
LL | trait _0 = ObjA;
|
||||
| ---- additional non-auto trait
|
||||
LL | trait _1 = _0;
|
||||
| -- referenced here (additional use)
|
||||
...
|
||||
LL | trait _5 = Sync + ObjB + Send;
|
||||
| ---- first non-auto trait
|
||||
LL |
|
||||
LL | type _T20 = dyn _5 + _1;
|
||||
| -- ^^ trait alias used in trait object type (additional use)
|
||||
| |
|
||||
| trait alias used in trait object type (first use)
|
||||
|
||||
error[E0225]: only auto traits can be used as additional traits in a trait object
|
||||
--> $DIR/trait-alias-no-extra-traits.rs:53:22
|
||||
|
|
||||
LL | trait _0 = ObjA;
|
||||
| ---- first non-auto trait
|
||||
LL | trait _1 = _0;
|
||||
| -- referenced here (first use)
|
||||
...
|
||||
LL | trait _5 = Sync + ObjB + Send;
|
||||
| ---- additional non-auto trait
|
||||
...
|
||||
LL | type _T21 = dyn _1 + _5;
|
||||
| -- ^^ trait alias used in trait object type (additional use)
|
||||
| |
|
||||
| trait alias used in trait object type (first use)
|
||||
|
||||
error[E0225]: only auto traits can be used as additional traits in a trait object
|
||||
--> $DIR/trait-alias-no-extra-traits.rs:56:22
|
||||
|
|
||||
LL | trait _5 = Sync + ObjB + Send;
|
||||
| ---- first non-auto trait
|
||||
...
|
||||
LL | type _T22 = dyn _5 + ObjA;
|
||||
| -- ^^^^
|
||||
| | |
|
||||
| | additional non-auto trait
|
||||
| | trait alias used in trait object type (additional use)
|
||||
| trait alias used in trait object type (first use)
|
||||
|
||||
error[E0225]: only auto traits can be used as additional traits in a trait object
|
||||
--> $DIR/trait-alias-no-extra-traits.rs:59:24
|
||||
|
|
||||
LL | trait _5 = Sync + ObjB + Send;
|
||||
| ---- additional non-auto trait
|
||||
...
|
||||
LL | type _T23 = dyn ObjA + _5;
|
||||
| ---- ^^ trait alias used in trait object type (additional use)
|
||||
| |
|
||||
| first non-auto trait
|
||||
| trait alias used in trait object type (first use)
|
||||
|
||||
error[E0225]: only auto traits can be used as additional traits in a trait object
|
||||
--> $DIR/trait-alias-no-extra-traits.rs:62:29
|
||||
|
|
||||
LL | trait _0 = ObjA;
|
||||
| ---- additional non-auto trait
|
||||
LL | trait _1 = _0;
|
||||
| -- referenced here (additional use)
|
||||
...
|
||||
LL | trait _5 = Sync + ObjB + Send;
|
||||
| ---- first non-auto trait
|
||||
...
|
||||
LL | type _T24 = dyn Send + _5 + _1 + Sync;
|
||||
| -- ^^ trait alias used in trait object type (additional use)
|
||||
| |
|
||||
| trait alias used in trait object type (first use)
|
||||
|
||||
error[E0225]: only auto traits can be used as additional traits in a trait object
|
||||
--> $DIR/trait-alias-no-extra-traits.rs:65:29
|
||||
|
|
||||
LL | trait _0 = ObjA;
|
||||
| ---- first non-auto trait
|
||||
LL | trait _1 = _0;
|
||||
| -- referenced here (first use)
|
||||
...
|
||||
LL | trait _5 = Sync + ObjB + Send;
|
||||
| ---- additional non-auto trait
|
||||
...
|
||||
LL | type _T25 = dyn _1 + Sync + _5 + Send;
|
||||
| -- ^^ trait alias used in trait object type (additional use)
|
||||
| |
|
||||
| trait alias used in trait object type (first use)
|
||||
|
||||
error[E0225]: only auto traits can be used as additional traits in a trait object
|
||||
--> $DIR/trait-alias-no-extra-traits.rs:68:36
|
||||
|
|
||||
LL | trait _5 = Sync + ObjB + Send;
|
||||
| ---- first non-auto trait
|
||||
...
|
||||
LL | type _T26 = dyn Sync + Send + _5 + ObjA;
|
||||
| -- ^^^^
|
||||
| | |
|
||||
| | additional non-auto trait
|
||||
| | trait alias used in trait object type (additional use)
|
||||
| trait alias used in trait object type (first use)
|
||||
|
||||
error[E0225]: only auto traits can be used as additional traits in a trait object
|
||||
--> $DIR/trait-alias-no-extra-traits.rs:71:38
|
||||
|
|
||||
LL | trait _5 = Sync + ObjB + Send;
|
||||
| ---- additional non-auto trait
|
||||
...
|
||||
LL | type _T27 = dyn Send + Sync + ObjA + _5;
|
||||
| ---- ^^ trait alias used in trait object type (additional use)
|
||||
| |
|
||||
| first non-auto trait
|
||||
| trait alias used in trait object type (first use)
|
||||
|
||||
error[E0225]: only auto traits can be used as additional traits in a trait object
|
||||
--> $DIR/trait-alias-no-extra-traits.rs:80:17
|
||||
|
|
||||
LL | trait _0 = ObjA;
|
||||
| ---- first non-auto trait
|
||||
LL | trait _1 = _0;
|
||||
| -- referenced here (first use)
|
||||
...
|
||||
LL | trait _5 = Sync + ObjB + Send;
|
||||
| ---- additional non-auto trait
|
||||
...
|
||||
LL | trait _6 = _1 + _5;
|
||||
| -- -- referenced here (additional use)
|
||||
| |
|
||||
| referenced here (first use)
|
||||
...
|
||||
LL | type _T30 = dyn _6;
|
||||
| ^^
|
||||
| |
|
||||
| trait alias used in trait object type (additional use)
|
||||
| trait alias used in trait object type (first use)
|
||||
|
||||
error[E0225]: only auto traits can be used as additional traits in a trait object
|
||||
--> $DIR/trait-alias-no-extra-traits.rs:83:17
|
||||
|
|
||||
LL | trait _0 = ObjA;
|
||||
| ---- first non-auto trait
|
||||
LL | trait _1 = _0;
|
||||
| -- referenced here (first use)
|
||||
...
|
||||
LL | trait _5 = Sync + ObjB + Send;
|
||||
| ---- additional non-auto trait
|
||||
...
|
||||
LL | trait _6 = _1 + _5;
|
||||
| -- -- referenced here (additional use)
|
||||
| |
|
||||
| referenced here (first use)
|
||||
...
|
||||
LL | type _T31 = dyn _6 + Send;
|
||||
| ^^
|
||||
| |
|
||||
| trait alias used in trait object type (additional use)
|
||||
| trait alias used in trait object type (first use)
|
||||
|
||||
error[E0225]: only auto traits can be used as additional traits in a trait object
|
||||
--> $DIR/trait-alias-no-extra-traits.rs:86:24
|
||||
|
|
||||
LL | trait _0 = ObjA;
|
||||
| ---- first non-auto trait
|
||||
LL | trait _1 = _0;
|
||||
| -- referenced here (first use)
|
||||
...
|
||||
LL | trait _5 = Sync + ObjB + Send;
|
||||
| ---- additional non-auto trait
|
||||
...
|
||||
LL | trait _6 = _1 + _5;
|
||||
| -- -- referenced here (additional use)
|
||||
| |
|
||||
| referenced here (first use)
|
||||
...
|
||||
LL | type _T32 = dyn Send + _6;
|
||||
| ^^
|
||||
| |
|
||||
| trait alias used in trait object type (additional use)
|
||||
| trait alias used in trait object type (first use)
|
||||
|
||||
error[E0225]: only auto traits can be used as additional traits in a trait object
|
||||
--> $DIR/trait-alias-no-extra-traits.rs:89:17
|
||||
|
|
||||
LL | trait _0 = ObjA;
|
||||
| ---- first non-auto trait
|
||||
LL | trait _1 = _0;
|
||||
| -- referenced here (first use)
|
||||
...
|
||||
LL | trait _5 = Sync + ObjB + Send;
|
||||
| ---- additional non-auto trait
|
||||
...
|
||||
LL | trait _6 = _1 + _5;
|
||||
| -- -- referenced here (additional use)
|
||||
| |
|
||||
| referenced here (first use)
|
||||
LL | trait _7 = _6;
|
||||
| --
|
||||
| |
|
||||
| referenced here (additional use)
|
||||
| referenced here (first use)
|
||||
LL | trait _8 = _7;
|
||||
| --
|
||||
| |
|
||||
| referenced here (additional use)
|
||||
| referenced here (first use)
|
||||
...
|
||||
LL | type _T33 = dyn _8;
|
||||
| ^^
|
||||
| |
|
||||
| trait alias used in trait object type (additional use)
|
||||
| trait alias used in trait object type (first use)
|
||||
|
||||
error[E0225]: only auto traits can be used as additional traits in a trait object
|
||||
--> $DIR/trait-alias-no-extra-traits.rs:92:17
|
||||
|
|
||||
LL | trait _0 = ObjA;
|
||||
| ---- first non-auto trait
|
||||
LL | trait _1 = _0;
|
||||
| -- referenced here (first use)
|
||||
...
|
||||
LL | trait _5 = Sync + ObjB + Send;
|
||||
| ---- additional non-auto trait
|
||||
...
|
||||
LL | trait _6 = _1 + _5;
|
||||
| -- -- referenced here (additional use)
|
||||
| |
|
||||
| referenced here (first use)
|
||||
LL | trait _7 = _6;
|
||||
| --
|
||||
| |
|
||||
| referenced here (additional use)
|
||||
| referenced here (first use)
|
||||
LL | trait _8 = _7;
|
||||
| --
|
||||
| |
|
||||
| referenced here (additional use)
|
||||
| referenced here (first use)
|
||||
...
|
||||
LL | type _T34 = dyn _8 + Send;
|
||||
| ^^
|
||||
| |
|
||||
| trait alias used in trait object type (additional use)
|
||||
| trait alias used in trait object type (first use)
|
||||
|
||||
error[E0225]: only auto traits can be used as additional traits in a trait object
|
||||
--> $DIR/trait-alias-no-extra-traits.rs:95:24
|
||||
|
|
||||
LL | trait _0 = ObjA;
|
||||
| ---- first non-auto trait
|
||||
LL | trait _1 = _0;
|
||||
| -- referenced here (first use)
|
||||
...
|
||||
LL | trait _5 = Sync + ObjB + Send;
|
||||
| ---- additional non-auto trait
|
||||
...
|
||||
LL | trait _6 = _1 + _5;
|
||||
| -- -- referenced here (additional use)
|
||||
| |
|
||||
| referenced here (first use)
|
||||
LL | trait _7 = _6;
|
||||
| --
|
||||
| |
|
||||
| referenced here (additional use)
|
||||
| referenced here (first use)
|
||||
LL | trait _8 = _7;
|
||||
| --
|
||||
| |
|
||||
| referenced here (additional use)
|
||||
| referenced here (first use)
|
||||
...
|
||||
LL | type _T35 = dyn Send + _8;
|
||||
| ^^
|
||||
| |
|
||||
| trait alias used in trait object type (additional use)
|
||||
| trait alias used in trait object type (first use)
|
||||
|
||||
error[E0225]: only auto traits can be used as additional traits in a trait object
|
||||
--> $DIR/trait-alias-no-extra-traits.rs:103:23
|
||||
|
|
||||
LL | trait _5 = Sync + ObjB + Send;
|
||||
| ---- first non-auto trait
|
||||
...
|
||||
LL | trait _9 = _5 + Sync;
|
||||
| -- referenced here (first use)
|
||||
LL | trait _10 = Unpin + _9;
|
||||
| -- referenced here (first use)
|
||||
LL |
|
||||
LL | type _T40 = dyn _10 + ObjA;
|
||||
| --- ^^^^
|
||||
| | |
|
||||
| | additional non-auto trait
|
||||
| | trait alias used in trait object type (additional use)
|
||||
| trait alias used in trait object type (first use)
|
||||
|
||||
error[E0225]: only auto traits can be used as additional traits in a trait object
|
||||
--> $DIR/trait-alias-no-extra-traits.rs:106:24
|
||||
|
|
||||
LL | trait _5 = Sync + ObjB + Send;
|
||||
| ---- additional non-auto trait
|
||||
...
|
||||
LL | trait _9 = _5 + Sync;
|
||||
| -- referenced here (additional use)
|
||||
LL | trait _10 = Unpin + _9;
|
||||
| -- referenced here (additional use)
|
||||
...
|
||||
LL | type _T41 = dyn ObjA + _10;
|
||||
| ---- ^^^ trait alias used in trait object type (additional use)
|
||||
| |
|
||||
| first non-auto trait
|
||||
| trait alias used in trait object type (first use)
|
||||
|
||||
error[E0225]: only auto traits can be used as additional traits in a trait object
|
||||
--> $DIR/trait-alias-no-extra-traits.rs:109:23
|
||||
|
|
||||
LL | trait _0 = ObjA;
|
||||
| ---- additional non-auto trait
|
||||
LL | trait _1 = _0;
|
||||
| -- referenced here (additional use)
|
||||
...
|
||||
LL | trait _5 = Sync + ObjB + Send;
|
||||
| ---- first non-auto trait
|
||||
...
|
||||
LL | trait _9 = _5 + Sync;
|
||||
| -- referenced here (first use)
|
||||
LL | trait _10 = Unpin + _9;
|
||||
| -- referenced here (first use)
|
||||
...
|
||||
LL | type _T42 = dyn _10 + _1;
|
||||
| --- ^^ trait alias used in trait object type (additional use)
|
||||
| |
|
||||
| trait alias used in trait object type (first use)
|
||||
|
||||
error[E0225]: only auto traits can be used as additional traits in a trait object
|
||||
--> $DIR/trait-alias-no-extra-traits.rs:112:37
|
||||
|
|
||||
LL | trait _5 = Sync + ObjB + Send;
|
||||
| ---- first non-auto trait
|
||||
...
|
||||
LL | trait _9 = _5 + Sync;
|
||||
| -- referenced here (first use)
|
||||
LL | trait _10 = Unpin + _9;
|
||||
| -- referenced here (first use)
|
||||
...
|
||||
LL | type _T43 = dyn Send + _10 + Sync + ObjA;
|
||||
| --- ^^^^
|
||||
| | |
|
||||
| | additional non-auto trait
|
||||
| | trait alias used in trait object type (additional use)
|
||||
| trait alias used in trait object type (first use)
|
||||
|
||||
error[E0225]: only auto traits can be used as additional traits in a trait object
|
||||
--> $DIR/trait-alias-no-extra-traits.rs:115:24
|
||||
|
|
||||
LL | trait _5 = Sync + ObjB + Send;
|
||||
| ---- additional non-auto trait
|
||||
...
|
||||
LL | trait _9 = _5 + Sync;
|
||||
| -- referenced here (additional use)
|
||||
LL | trait _10 = Unpin + _9;
|
||||
| -- referenced here (additional use)
|
||||
...
|
||||
LL | type _T44 = dyn ObjA + _10 + Send + Sync;
|
||||
| ---- ^^^ trait alias used in trait object type (additional use)
|
||||
| |
|
||||
| first non-auto trait
|
||||
| trait alias used in trait object type (first use)
|
||||
|
||||
error[E0225]: only auto traits can be used as additional traits in a trait object
|
||||
--> $DIR/trait-alias-no-extra-traits.rs:118:37
|
||||
|
|
||||
LL | trait _0 = ObjA;
|
||||
| ---- additional non-auto trait
|
||||
LL | trait _1 = _0;
|
||||
| -- referenced here (additional use)
|
||||
...
|
||||
LL | trait _5 = Sync + ObjB + Send;
|
||||
| ---- first non-auto trait
|
||||
...
|
||||
LL | trait _9 = _5 + Sync;
|
||||
| -- referenced here (first use)
|
||||
LL | trait _10 = Unpin + _9;
|
||||
| -- referenced here (first use)
|
||||
...
|
||||
LL | type _T45 = dyn Sync + Send + _10 + _1;
|
||||
| --- ^^ trait alias used in trait object type (additional use)
|
||||
| |
|
||||
| trait alias used in trait object type (first use)
|
||||
|
||||
error: aborting due to 28 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0225`.
|
11
src/test/ui/traits/trait-alias/trait-alias-object-fail.rs
Normal file
11
src/test/ui/traits/trait-alias/trait-alias-object-fail.rs
Normal file
@ -0,0 +1,11 @@
|
||||
#![feature(trait_alias)]
|
||||
|
||||
trait EqAlias = Eq;
|
||||
trait IteratorAlias = Iterator;
|
||||
|
||||
fn main() {
|
||||
let _: &dyn EqAlias = &123;
|
||||
//~^ ERROR the trait `std::cmp::Eq` cannot be made into an object [E0038]
|
||||
let _: &dyn IteratorAlias = &vec![123].into_iter();
|
||||
//~^ ERROR must be specified
|
||||
}
|
@ -1,13 +1,13 @@
|
||||
error[E0038]: the trait `EqAlias` cannot be made into an object
|
||||
--> $DIR/trait-alias-object.rs:7:13
|
||||
error[E0038]: the trait `std::cmp::Eq` cannot be made into an object
|
||||
--> $DIR/trait-alias-object-fail.rs:7:13
|
||||
|
|
||||
LL | let _: &dyn EqAlias = &123;
|
||||
| ^^^^^^^^^^^ the trait `EqAlias` cannot be made into an object
|
||||
| ^^^^^^^^^^^ the trait `std::cmp::Eq` cannot be made into an object
|
||||
|
|
||||
= note: the trait cannot use `Self` as a type parameter in the supertraits or where-clauses
|
||||
|
||||
error[E0191]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) must be specified
|
||||
--> $DIR/trait-alias-object.rs:8:13
|
||||
--> $DIR/trait-alias-object-fail.rs:9:13
|
||||
|
|
||||
LL | let _: &dyn IteratorAlias = &vec![123].into_iter();
|
||||
| ^^^^^^^^^^^^^^^^^ associated type `Item` must be specified
|
85
src/test/ui/traits/trait-alias/trait-alias-object-wf.rs
Normal file
85
src/test/ui/traits/trait-alias/trait-alias-object-wf.rs
Normal file
@ -0,0 +1,85 @@
|
||||
// run-pass
|
||||
|
||||
// This test checks that trait objects involving trait aliases are well-formed.
|
||||
|
||||
#![feature(trait_alias)]
|
||||
|
||||
trait Obj {}
|
||||
|
||||
trait _0 = Send + Sync;
|
||||
|
||||
// Just auto traits:
|
||||
|
||||
trait _1 = _0 + Send + Sync;
|
||||
|
||||
use std::marker::Unpin;
|
||||
|
||||
fn _f0() {
|
||||
let _: Box<dyn _0>;
|
||||
let _: Box<dyn _1>;
|
||||
let _: Box<dyn Unpin + _1 + Send + Sync>;
|
||||
}
|
||||
|
||||
// Include object safe traits:
|
||||
|
||||
fn _f1() {
|
||||
let _: Box<dyn Obj + _0>;
|
||||
let _: Box<dyn Obj + _1>;
|
||||
let _: Box<dyn Obj + _1 + _0>;
|
||||
}
|
||||
|
||||
// And when the object safe trait is in a trait alias:
|
||||
|
||||
trait _2 = Obj;
|
||||
|
||||
fn _f2() {
|
||||
let _: Box<dyn _2 + _0>;
|
||||
let _: Box<dyn _2 + _1>;
|
||||
let _: Box<dyn _2 + _1 + _0>;
|
||||
}
|
||||
|
||||
// And it should also work when that trait is has auto traits to the right of it.
|
||||
|
||||
trait _3 = Obj + Unpin;
|
||||
|
||||
fn _f3() {
|
||||
let _: Box<dyn _3 + _0>;
|
||||
let _: Box<dyn _3 + _1>;
|
||||
let _: Box<dyn _3 + _1 + _0>;
|
||||
}
|
||||
|
||||
// Nest the trait deeply:
|
||||
|
||||
trait _4 = _3;
|
||||
trait _5 = _4 + Sync + _0 + Send;
|
||||
trait _6 = _5 + Send + _1 + Sync;
|
||||
|
||||
fn _f4() {
|
||||
let _: Box<dyn _6 + _0>;
|
||||
let _: Box<dyn _6 + _1>;
|
||||
let _: Box<dyn _6 + _1 + _0>;
|
||||
}
|
||||
|
||||
// Just nest the trait alone:
|
||||
|
||||
trait _7 = _2;
|
||||
trait _8 = _7;
|
||||
trait _9 = _8;
|
||||
|
||||
fn _f5() {
|
||||
let _: Box<dyn _9>;
|
||||
}
|
||||
|
||||
// First bound is auto trait:
|
||||
|
||||
trait _10 = Send + Obj;
|
||||
trait _11 = Obj + Send;
|
||||
trait _12 = Sync + _11;
|
||||
trait _13 = Send + _12;
|
||||
|
||||
fn f6() {
|
||||
let _: Box<dyn _10>;
|
||||
let _: Box<dyn _13>;
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -1,3 +1,5 @@
|
||||
// run-pass
|
||||
|
||||
#![feature(trait_alias)]
|
||||
|
||||
trait Foo = PartialEq<i32> + Send;
|
@ -0,0 +1,22 @@
|
||||
// Test that `dyn ?Sized` (i.e., a trait object with only a maybe buond) is not allowed, when just
|
||||
// `?Sized` results from trait alias expansion.
|
||||
|
||||
#![feature(trait_alias)]
|
||||
|
||||
trait S = ?Sized;
|
||||
|
||||
// Nest a couple of levels deep:
|
||||
trait _0 = S;
|
||||
trait _1 = _0;
|
||||
|
||||
// Straight list expansion:
|
||||
type _T0 = dyn _1;
|
||||
//~^ ERROR at least one non-builtin trait is required for an object type [E0224]
|
||||
|
||||
// Twice:
|
||||
trait _2 = _1 + _1;
|
||||
|
||||
type _T1 = dyn _2;
|
||||
//~^ ERROR at least one non-builtin trait is required for an object type [E0224]
|
||||
|
||||
fn main() {}
|
@ -0,0 +1,14 @@
|
||||
error[E0224]: at least one non-builtin trait is required for an object type
|
||||
--> $DIR/trait-alias-only-maybe-bound.rs:13:12
|
||||
|
|
||||
LL | type _T0 = dyn _1;
|
||||
| ^^^^^^
|
||||
|
||||
error[E0224]: at least one non-builtin trait is required for an object type
|
||||
--> $DIR/trait-alias-only-maybe-bound.rs:19:12
|
||||
|
|
||||
LL | type _T1 = dyn _2;
|
||||
| ^^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
@ -1,11 +1,11 @@
|
||||
error: trait aliases cannot be `auto`
|
||||
--> $DIR/trait-alias-syntax.rs:4:19
|
||||
--> $DIR/trait-alias-syntax-fail.rs:4:19
|
||||
|
|
||||
LL | auto trait A = Foo;
|
||||
| ^ trait aliases cannot be `auto`
|
||||
|
||||
error: trait aliases cannot be `unsafe`
|
||||
--> $DIR/trait-alias-syntax.rs:5:21
|
||||
--> $DIR/trait-alias-syntax-fail.rs:5:21
|
||||
|
|
||||
LL | unsafe trait B = Foo;
|
||||
| ^ trait aliases cannot be `unsafe`
|
@ -1,3 +1,5 @@
|
||||
// run-pass
|
||||
|
||||
#![feature(trait_alias)]
|
||||
|
||||
trait SimpleAlias = Default;
|
@ -1,4 +1,5 @@
|
||||
// run-pass
|
||||
|
||||
#![feature(trait_alias)]
|
||||
|
||||
pub trait Foo {}
|
20
src/test/ui/traits/wf-trait-object-maybe-bound.rs
Normal file
20
src/test/ui/traits/wf-trait-object-maybe-bound.rs
Normal file
@ -0,0 +1,20 @@
|
||||
// compile-fail
|
||||
|
||||
// Test that `dyn ... + ?Sized + ...` is okay (though `?Sized` has no effect in trait objects).
|
||||
|
||||
trait Foo {}
|
||||
|
||||
type _0 = dyn ?Sized + Foo;
|
||||
//~^ ERROR `?Trait` is not permitted in trait object types
|
||||
|
||||
type _1 = dyn Foo + ?Sized;
|
||||
//~^ ERROR `?Trait` is not permitted in trait object types
|
||||
|
||||
type _2 = dyn Foo + ?Sized + ?Sized;
|
||||
//~^ ERROR `?Trait` is not permitted in trait object types
|
||||
//~| ERROR `?Trait` is not permitted in trait object types
|
||||
|
||||
type _3 = dyn ?Sized + Foo;
|
||||
//~^ ERROR `?Trait` is not permitted in trait object types
|
||||
|
||||
fn main() {}
|
32
src/test/ui/traits/wf-trait-object-maybe-bound.stderr
Normal file
32
src/test/ui/traits/wf-trait-object-maybe-bound.stderr
Normal file
@ -0,0 +1,32 @@
|
||||
error: `?Trait` is not permitted in trait object types
|
||||
--> $DIR/wf-trait-object-maybe-bound.rs:7:15
|
||||
|
|
||||
LL | type _0 = dyn ?Sized + Foo;
|
||||
| ^^^^^^
|
||||
|
||||
error: `?Trait` is not permitted in trait object types
|
||||
--> $DIR/wf-trait-object-maybe-bound.rs:10:21
|
||||
|
|
||||
LL | type _1 = dyn Foo + ?Sized;
|
||||
| ^^^^^^
|
||||
|
||||
error: `?Trait` is not permitted in trait object types
|
||||
--> $DIR/wf-trait-object-maybe-bound.rs:13:21
|
||||
|
|
||||
LL | type _2 = dyn Foo + ?Sized + ?Sized;
|
||||
| ^^^^^^
|
||||
|
||||
error: `?Trait` is not permitted in trait object types
|
||||
--> $DIR/wf-trait-object-maybe-bound.rs:13:30
|
||||
|
|
||||
LL | type _2 = dyn Foo + ?Sized + ?Sized;
|
||||
| ^^^^^^
|
||||
|
||||
error: `?Trait` is not permitted in trait object types
|
||||
--> $DIR/wf-trait-object-maybe-bound.rs:17:15
|
||||
|
|
||||
LL | type _3 = dyn ?Sized + Foo;
|
||||
| ^^^^^^
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
|
33
src/test/ui/traits/wf-trait-object-no-duplicates.rs
Normal file
33
src/test/ui/traits/wf-trait-object-no-duplicates.rs
Normal file
@ -0,0 +1,33 @@
|
||||
// The purpose of this test is to demonstrate that duplicating object safe traits
|
||||
// that are not auto-traits is rejected even though one could reasonably accept this.
|
||||
|
||||
// Some arbitrary object-safe trait:
|
||||
trait Obj {}
|
||||
|
||||
// Demonstrate that recursive expansion of trait aliases doesn't affect stable behavior:
|
||||
type _0 = dyn Obj + Obj;
|
||||
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
|
||||
|
||||
// Some variations:
|
||||
|
||||
type _1 = dyn Send + Obj + Obj;
|
||||
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
|
||||
|
||||
type _2 = dyn Obj + Send + Obj;
|
||||
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
|
||||
|
||||
type _3 = dyn Obj + Send + Send; // But it is OK to duplicate auto traits.
|
||||
|
||||
// Take higher ranked types into account.
|
||||
|
||||
// Note that `'a` and `'b` are intentionally different to make sure we consider
|
||||
// them semantically the same.
|
||||
trait ObjL<'l> {}
|
||||
type _4 = dyn for<'a> ObjL<'a> + for<'b> ObjL<'b>;
|
||||
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
|
||||
|
||||
trait ObjT<T> {}
|
||||
type _5 = dyn ObjT<for<'a> fn(&'a u8)> + ObjT<for<'b> fn(&'b u8)>;
|
||||
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
|
||||
|
||||
fn main() {}
|
58
src/test/ui/traits/wf-trait-object-no-duplicates.stderr
Normal file
58
src/test/ui/traits/wf-trait-object-no-duplicates.stderr
Normal file
@ -0,0 +1,58 @@
|
||||
error[E0225]: only auto traits can be used as additional traits in a trait object
|
||||
--> $DIR/wf-trait-object-no-duplicates.rs:8:21
|
||||
|
|
||||
LL | type _0 = dyn Obj + Obj;
|
||||
| --- ^^^
|
||||
| | |
|
||||
| | additional non-auto trait
|
||||
| | trait alias used in trait object type (additional use)
|
||||
| first non-auto trait
|
||||
| trait alias used in trait object type (first use)
|
||||
|
||||
error[E0225]: only auto traits can be used as additional traits in a trait object
|
||||
--> $DIR/wf-trait-object-no-duplicates.rs:13:28
|
||||
|
|
||||
LL | type _1 = dyn Send + Obj + Obj;
|
||||
| --- ^^^
|
||||
| | |
|
||||
| | additional non-auto trait
|
||||
| | trait alias used in trait object type (additional use)
|
||||
| first non-auto trait
|
||||
| trait alias used in trait object type (first use)
|
||||
|
||||
error[E0225]: only auto traits can be used as additional traits in a trait object
|
||||
--> $DIR/wf-trait-object-no-duplicates.rs:16:28
|
||||
|
|
||||
LL | type _2 = dyn Obj + Send + Obj;
|
||||
| --- ^^^
|
||||
| | |
|
||||
| | additional non-auto trait
|
||||
| | trait alias used in trait object type (additional use)
|
||||
| first non-auto trait
|
||||
| trait alias used in trait object type (first use)
|
||||
|
||||
error[E0225]: only auto traits can be used as additional traits in a trait object
|
||||
--> $DIR/wf-trait-object-no-duplicates.rs:26:34
|
||||
|
|
||||
LL | type _4 = dyn for<'a> ObjL<'a> + for<'b> ObjL<'b>;
|
||||
| ---------------- ^^^^^^^^^^^^^^^^
|
||||
| | |
|
||||
| | additional non-auto trait
|
||||
| | trait alias used in trait object type (additional use)
|
||||
| first non-auto trait
|
||||
| trait alias used in trait object type (first use)
|
||||
|
||||
error[E0225]: only auto traits can be used as additional traits in a trait object
|
||||
--> $DIR/wf-trait-object-no-duplicates.rs:30:42
|
||||
|
|
||||
LL | type _5 = dyn ObjT<for<'a> fn(&'a u8)> + ObjT<for<'b> fn(&'b u8)>;
|
||||
| ------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
| | |
|
||||
| | additional non-auto trait
|
||||
| | trait alias used in trait object type (additional use)
|
||||
| first non-auto trait
|
||||
| trait alias used in trait object type (first use)
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0225`.
|
7
src/test/ui/traits/wf-trait-object-only-maybe-bound.rs
Normal file
7
src/test/ui/traits/wf-trait-object-only-maybe-bound.rs
Normal file
@ -0,0 +1,7 @@
|
||||
// Test that `dyn ?Sized` (i.e., a trait object with only a maybe buond) is not allowed.
|
||||
|
||||
type _0 = dyn ?Sized;
|
||||
//~^ ERROR at least one non-builtin trait is required for an object type [E0224]
|
||||
//~| ERROR ?Trait` is not permitted in trait object types
|
||||
|
||||
fn main() {}
|
14
src/test/ui/traits/wf-trait-object-only-maybe-bound.stderr
Normal file
14
src/test/ui/traits/wf-trait-object-only-maybe-bound.stderr
Normal file
@ -0,0 +1,14 @@
|
||||
error: `?Trait` is not permitted in trait object types
|
||||
--> $DIR/wf-trait-object-only-maybe-bound.rs:3:15
|
||||
|
|
||||
LL | type _0 = dyn ?Sized;
|
||||
| ^^^^^^
|
||||
|
||||
error[E0224]: at least one non-builtin trait is required for an object type
|
||||
--> $DIR/wf-trait-object-only-maybe-bound.rs:3:11
|
||||
|
|
||||
LL | type _0 = dyn ?Sized;
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
15
src/test/ui/traits/wf-trait-object-reverse-order.rs
Normal file
15
src/test/ui/traits/wf-trait-object-reverse-order.rs
Normal file
@ -0,0 +1,15 @@
|
||||
// run-pass
|
||||
|
||||
// Ensure that `dyn $($AutoTrait)+ ObjSafe` is well-formed.
|
||||
|
||||
use std::marker::Unpin;
|
||||
|
||||
// Some arbitrary object-safe trait:
|
||||
trait Obj {}
|
||||
|
||||
type _0 = dyn Unpin;
|
||||
type _1 = dyn Send + Obj;
|
||||
type _2 = dyn Send + Unpin + Obj;
|
||||
type _3 = dyn Send + Unpin + Sync + Obj;
|
||||
|
||||
fn main() {}
|
Loading…
Reference in New Issue
Block a user