From bb6b433958cf1471f7df02f824a7112c2ef81792 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Wed, 4 May 2022 22:46:24 +0200 Subject: [PATCH 1/4] Add debug statements. --- compiler/rustc_trait_selection/src/traits/util.rs | 3 ++- compiler/rustc_typeck/src/astconv/mod.rs | 1 + compiler/rustc_typeck/src/collect.rs | 4 ++++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs index 7543d1f9a7b55..d101f69096fe8 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::>()); self.stack.extend(items); diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs index fd1b7bfa0b1b0..673a2c2fcaf40 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -1070,6 +1070,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 } diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index c1c63c460664c..7a7e4a2f2b02b 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, ) -> 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() @@ -1140,6 +1143,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. From cca981661ab474f9bfe4a86b868e76d406b2a4e1 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Wed, 4 May 2022 22:47:09 +0200 Subject: [PATCH 2/4] Only keep predicates on `Self` when checking `dyn TraitAlias`. --- compiler/rustc_typeck/src/astconv/mod.rs | 5 +++-- src/test/ui/traits/issue-65673.rs | 2 +- src/test/ui/traits/issue-65673.stderr | 13 +++---------- src/test/ui/traits/issue-96664.rs | 16 ++++++++++++++++ 4 files changed, 23 insertions(+), 13 deletions(-) create mode 100644 src/test/ui/traits/issue-96664.rs diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs index 673a2c2fcaf40..a21e9f4a0a510 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -1334,8 +1334,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 = ®ular_traits[0]; let additional_trait = ®ular_traits[1]; diff --git a/src/test/ui/traits/issue-65673.rs b/src/test/ui/traits/issue-65673.rs index 4b47bd493a568..e5c2fccb2b5db 100644 --- a/src/test/ui/traits/issue-65673.rs +++ b/src/test/ui/traits/issue-65673.rs @@ -7,6 +7,6 @@ trait Alias = where T: Trait; impl WithType for T { type Ctx = dyn Alias; -//~^ 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 245c4ee525eab..79f071ba30279 100644 --- a/src/test/ui/traits/issue-65673.stderr +++ b/src/test/ui/traits/issue-65673.stderr @@ -1,16 +1,9 @@ -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 | type Ctx = dyn Alias; - | ^^^^^^^^^^^^ 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 0000000000000..3c5314af73e2d --- /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 = FnMut() -> S + Send; + +pub trait Evaluator { + type State; +} + +pub struct Evolver { + rand_state: Box>, +} + +fn main() {} From 1d43b4d59cad44e73110383ce650c72ac6fe3731 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Wed, 4 May 2022 22:51:34 +0200 Subject: [PATCH 3/4] Exit before fetching bounds on associated items. --- compiler/rustc_typeck/src/collect.rs | 9 ++++----- src/test/ui/traits/issue-96665.rs | 16 ++++++++++++++++ 2 files changed, 20 insertions(+), 5 deletions(-) create mode 100644 src/test/ui/traits/issue-96665.rs diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index 7a7e4a2f2b02b..af7ef2ace3c8a 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -679,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() diff --git a/src/test/ui/traits/issue-96665.rs b/src/test/ui/traits/issue-96665.rs new file mode 100644 index 0000000000000..a571d48d97a22 --- /dev/null +++ b/src/test/ui/traits/issue-96665.rs @@ -0,0 +1,16 @@ +// check-pass + +pub trait Sequence> {} + +pub trait NodeWalk>: + Sequence +{ +} + +pub trait GraphBase { + type NodeIndex; +} + +pub trait WalkableGraph: GraphBase {} + +fn main() {} From e947fad68cc7dce9285364984931dc1f286b9fa3 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Mon, 9 May 2022 19:03:37 +0200 Subject: [PATCH 4/4] Point to the empty trait alias. --- compiler/rustc_error_messages/locales/en-US/typeck.ftl | 1 + compiler/rustc_typeck/src/astconv/mod.rs | 8 +++++++- compiler/rustc_typeck/src/errors.rs | 2 ++ src/test/ui/traits/alias/only-maybe-bound.stderr | 6 ++++++ src/test/ui/traits/issue-65673.stderr | 3 +++ 5 files changed, 19 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_error_messages/locales/en-US/typeck.ftl b/compiler/rustc_error_messages/locales/en-US/typeck.ftl index 6a3235fc7728c..e279b39a69002 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_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs index a21e9f4a0a510..b0244a44ffe19 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -1370,7 +1370,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/errors.rs b/compiler/rustc_typeck/src/errors.rs index 3d2f93537e4e8..d99ae35bb9a8b 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, } #[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 99589edb535ff..e9e846c2ff39a 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.stderr b/src/test/ui/traits/issue-65673.stderr index 79f071ba30279..71f3a0e7c7caa 100644 --- a/src/test/ui/traits/issue-65673.stderr +++ b/src/test/ui/traits/issue-65673.stderr @@ -1,6 +1,9 @@ error[E0224]: at least one trait is required for an object type --> $DIR/issue-65673.rs:9:16 | +LL | trait Alias = where T: Trait; + | -------------------------------- this alias does not contain a trait +... LL | type Ctx = dyn Alias; | ^^^^^^^^^^^^