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:
bors 2019-05-22 08:22:17 +00:00
commit 37ff5d388f
57 changed files with 2032 additions and 294 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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(|_| {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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 = &regular_traits[0];
let additional_trait = &regular_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 &regular_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 {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,3 +1,5 @@
// run-pass
#![feature(trait_alias)]
use std::marker::PhantomData;

View 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() {}

View 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() {}

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

View 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() {}

View File

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

View 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
}

View File

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

View 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() {}

View File

@ -1,3 +1,5 @@
// run-pass
#![feature(trait_alias)]
trait Foo = PartialEq<i32> + Send;

View File

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

View File

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

View File

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

View File

@ -1,3 +1,5 @@
// run-pass
#![feature(trait_alias)]
trait SimpleAlias = Default;

View File

@ -1,4 +1,5 @@
// run-pass
#![feature(trait_alias)]
pub trait Foo {}

View 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() {}

View 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

View 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() {}

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

View 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() {}

View 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

View 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() {}