about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_error_messages/locales/en-US/typeck.ftl1
-rw-r--r--compiler/rustc_trait_selection/src/traits/util.rs3
-rw-r--r--compiler/rustc_typeck/src/astconv/mod.rs14
-rw-r--r--compiler/rustc_typeck/src/collect.rs13
-rw-r--r--compiler/rustc_typeck/src/errors.rs2
-rw-r--r--src/test/ui/traits/alias/only-maybe-bound.stderr6
-rw-r--r--src/test/ui/traits/issue-65673.rs2
-rw-r--r--src/test/ui/traits/issue-65673.stderr16
-rw-r--r--src/test/ui/traits/issue-96664.rs16
-rw-r--r--src/test/ui/traits/issue-96665.rs16
10 files changed, 69 insertions, 20 deletions
diff --git a/compiler/rustc_error_messages/locales/en-US/typeck.ftl b/compiler/rustc_error_messages/locales/en-US/typeck.ftl
index aef18fcafaa..9195d7a2b8f 100644
--- a/compiler/rustc_error_messages/locales/en-US/typeck.ftl
+++ b/compiler/rustc_error_messages/locales/en-US/typeck.ftl
@@ -45,6 +45,7 @@ typeck-copy-impl-on-non-adt =
 
 typeck-trait-object-declared-with-no-traits =
     at least one trait is required for an object type
+    .alias-span = this alias does not contain a trait
 
 typeck-ambiguous-lifetime-bound =
     ambiguous lifetime bound, explicit lifetime bound required
diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs
index 7543d1f9a7b..d101f69096f 100644
--- a/compiler/rustc_trait_selection/src/traits/util.rs
+++ b/compiler/rustc_trait_selection/src/traits/util.rs
@@ -118,13 +118,14 @@ impl<'tcx> TraitAliasExpander<'tcx> {
 
         // Get components of trait alias.
         let predicates = tcx.super_predicates_of(trait_ref.def_id());
+        debug!(?predicates);
 
         let items = predicates.predicates.iter().rev().filter_map(|(pred, span)| {
             pred.subst_supertrait(tcx, &trait_ref)
                 .to_opt_poly_trait_pred()
                 .map(|trait_ref| item.clone_and_push(trait_ref.map_bound(|t| t.trait_ref), *span))
         });
-        debug!("expand_trait_aliases: items={:?}", items.clone());
+        debug!("expand_trait_aliases: items={:?}", items.clone().collect::<Vec<_>>());
 
         self.stack.extend(items);
 
diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs
index 3c1676b1aac..e940d065a99 100644
--- a/compiler/rustc_typeck/src/astconv/mod.rs
+++ b/compiler/rustc_typeck/src/astconv/mod.rs
@@ -1064,6 +1064,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         let mut bounds = Bounds::default();
 
         self.add_bounds(param_ty, ast_bounds.iter(), &mut bounds, ty::List::empty());
+        debug!(?bounds);
 
         bounds
     }
@@ -1327,8 +1328,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         // is used and no 'maybe' bounds are used.
         let expanded_traits =
             traits::expand_trait_aliases(tcx, bounds.trait_bounds.iter().map(|&(a, b, _)| (a, b)));
-        let (mut auto_traits, regular_traits): (Vec<_>, Vec<_>) =
-            expanded_traits.partition(|i| tcx.trait_is_auto(i.trait_ref().def_id()));
+        let (mut auto_traits, regular_traits): (Vec<_>, Vec<_>) = expanded_traits
+            .filter(|i| i.trait_ref().self_ty().skip_binder() == dummy_self)
+            .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];
@@ -1362,7 +1364,13 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         }
 
         if regular_traits.is_empty() && auto_traits.is_empty() {
-            tcx.sess.emit_err(TraitObjectDeclaredWithNoTraits { span });
+            let trait_alias_span = bounds
+                .trait_bounds
+                .iter()
+                .map(|&(trait_ref, _, _)| trait_ref.def_id())
+                .find(|&trait_ref| tcx.is_trait_alias(trait_ref))
+                .map(|trait_ref| tcx.def_span(trait_ref));
+            tcx.sess.emit_err(TraitObjectDeclaredWithNoTraits { span, trait_alias_span });
             return tcx.ty_error();
         }
 
diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs
index 74714d75fa0..2e0e026631b 100644
--- a/compiler/rustc_typeck/src/collect.rs
+++ b/compiler/rustc_typeck/src/collect.rs
@@ -52,6 +52,7 @@ use std::iter;
 mod item_bounds;
 mod type_of;
 
+#[derive(Debug)]
 struct OnlySelfBounds(bool);
 
 ///////////////////////////////////////////////////////////////////////////
@@ -650,6 +651,7 @@ impl<'tcx> ItemCtxt<'tcx> {
     /// AST. We do this to avoid having to convert *all* the bounds, which
     /// would create artificial cycles. Instead, we can only convert the
     /// bounds for a type parameter `X` if `X::Foo` is used.
+    #[instrument(level = "trace", skip(self, ast_generics))]
     fn type_parameter_bounds_in_generics(
         &self,
         ast_generics: &'tcx hir::Generics<'tcx>,
@@ -659,6 +661,7 @@ impl<'tcx> ItemCtxt<'tcx> {
         assoc_name: Option<Ident>,
     ) -> Vec<(ty::Predicate<'tcx>, Span)> {
         let param_def_id = self.tcx.hir().local_def_id(param_id).to_def_id();
+        debug!(?param_def_id);
         ast_generics
             .predicates
             .iter()
@@ -676,13 +679,12 @@ impl<'tcx> ItemCtxt<'tcx> {
                 };
                 let bvars = self.tcx.late_bound_vars(bp.bounded_ty.hir_id);
 
-                bp.bounds
-                    .iter()
-                    .filter(|b| match assoc_name {
+                bp.bounds.iter().filter_map(move |b| bt.map(|bt| (bt, b, bvars))).filter(
+                    |(_, b, _)| match assoc_name {
                         Some(assoc_name) => self.bound_defines_assoc_item(b, assoc_name),
                         None => true,
-                    })
-                    .filter_map(move |b| bt.map(|bt| (bt, b, bvars)))
+                    },
+                )
             })
             .flat_map(|(bt, b, bvars)| predicates_from_bound(self, bt, b, bvars))
             .collect()
@@ -1140,6 +1142,7 @@ fn super_predicates_that_define_assoc_type(
 
         // Combine the two lists to form the complete set of superbounds:
         let superbounds = &*tcx.arena.alloc_from_iter(superbounds1.into_iter().chain(superbounds2));
+        debug!(?superbounds);
 
         // Now require that immediate supertraits are converted,
         // which will, in turn, reach indirect supertraits.
diff --git a/compiler/rustc_typeck/src/errors.rs b/compiler/rustc_typeck/src/errors.rs
index a3e7108caae..81d4c9135ef 100644
--- a/compiler/rustc_typeck/src/errors.rs
+++ b/compiler/rustc_typeck/src/errors.rs
@@ -103,6 +103,8 @@ pub struct CopyImplOnNonAdt {
 pub struct TraitObjectDeclaredWithNoTraits {
     #[primary_span]
     pub span: Span,
+    #[label = "alias-span"]
+    pub trait_alias_span: Option<Span>,
 }
 
 #[derive(SessionDiagnostic)]
diff --git a/src/test/ui/traits/alias/only-maybe-bound.stderr b/src/test/ui/traits/alias/only-maybe-bound.stderr
index 99589edb535..e9e846c2ff3 100644
--- a/src/test/ui/traits/alias/only-maybe-bound.stderr
+++ b/src/test/ui/traits/alias/only-maybe-bound.stderr
@@ -1,12 +1,18 @@
 error[E0224]: at least one trait is required for an object type
   --> $DIR/only-maybe-bound.rs:13:12
    |
+LL | trait _1 = _0;
+   | -------------- this alias does not contain a trait
+...
 LL | type _T0 = dyn _1;
    |            ^^^^^^
 
 error[E0224]: at least one trait is required for an object type
   --> $DIR/only-maybe-bound.rs:19:12
    |
+LL | trait _2 = _1 + _1;
+   | ------------------- this alias does not contain a trait
+LL | 
 LL | type _T1 = dyn _2;
    |            ^^^^^^
 
diff --git a/src/test/ui/traits/issue-65673.rs b/src/test/ui/traits/issue-65673.rs
index 4b47bd493a5..e5c2fccb2b5 100644
--- a/src/test/ui/traits/issue-65673.rs
+++ b/src/test/ui/traits/issue-65673.rs
@@ -7,6 +7,6 @@ trait Alias<T> = where T: Trait;
 
 impl<T> WithType for T {
     type Ctx = dyn Alias<T>;
-//~^ ERROR the size for values of type `(dyn Trait + 'static)` cannot be known at compilation time
+    //~^ ERROR at least one trait is required for an object type [E0224]
 }
 fn main() {}
diff --git a/src/test/ui/traits/issue-65673.stderr b/src/test/ui/traits/issue-65673.stderr
index 245c4ee525e..71f3a0e7c7c 100644
--- a/src/test/ui/traits/issue-65673.stderr
+++ b/src/test/ui/traits/issue-65673.stderr
@@ -1,16 +1,12 @@
-error[E0277]: the size for values of type `(dyn Trait + 'static)` cannot be known at compilation time
+error[E0224]: at least one trait is required for an object type
   --> $DIR/issue-65673.rs:9:16
    |
+LL | trait Alias<T> = where T: Trait;
+   | -------------------------------- this alias does not contain a trait
+...
 LL |     type Ctx = dyn Alias<T>;
-   |                ^^^^^^^^^^^^ doesn't have a size known at compile-time
-   |
-   = help: the trait `Sized` is not implemented for `(dyn Trait + 'static)`
-note: required by a bound in `WithType::Ctx`
-  --> $DIR/issue-65673.rs:4:5
-   |
-LL |     type Ctx;
-   |     ^^^^^^^^^ required by this bound in `WithType::Ctx`
+   |                ^^^^^^^^^^^^
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0277`.
+For more information about this error, try `rustc --explain E0224`.
diff --git a/src/test/ui/traits/issue-96664.rs b/src/test/ui/traits/issue-96664.rs
new file mode 100644
index 00000000000..3c5314af73e
--- /dev/null
+++ b/src/test/ui/traits/issue-96664.rs
@@ -0,0 +1,16 @@
+// check-pass
+
+#![feature(trait_alias)]
+
+pub trait State = Clone + Send + Sync + PartialOrd + PartialEq + std::fmt::Display;
+pub trait RandState<S: State> = FnMut() -> S + Send;
+
+pub trait Evaluator {
+    type State;
+}
+
+pub struct Evolver<E: Evaluator> {
+    rand_state: Box<dyn RandState<E::State>>,
+}
+
+fn main() {}
diff --git a/src/test/ui/traits/issue-96665.rs b/src/test/ui/traits/issue-96665.rs
new file mode 100644
index 00000000000..a571d48d97a
--- /dev/null
+++ b/src/test/ui/traits/issue-96665.rs
@@ -0,0 +1,16 @@
+// check-pass
+
+pub trait Sequence<Item, Subsequence: Sequence<Item, Subsequence>> {}
+
+pub trait NodeWalk<Graph: GraphBase, NodeSubwalk: NodeWalk<Graph, NodeSubwalk>>:
+    Sequence<Graph::NodeIndex, NodeSubwalk>
+{
+}
+
+pub trait GraphBase {
+    type NodeIndex;
+}
+
+pub trait WalkableGraph: GraphBase {}
+
+fn main() {}