diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index de158a15d54..49bb3d03621 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -959,7 +959,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { fn coinductive_predicate(&self, predicate: ty::Predicate<'tcx>) -> bool { let result = match predicate.kind().skip_binder() { - ty::PredicateKind::Trait(ref data) => self.tcx().trait_is_auto(data.def_id()), + ty::PredicateKind::Trait(ref data) => { + self.tcx().trait_is_auto(data.def_id()) + || self.tcx().lang_items().sized_trait() == Some(data.def_id()) + } ty::PredicateKind::WellFormed(_) => true, _ => false, }; diff --git a/src/test/ui/sized/coinductive-1.rs b/src/test/ui/sized/coinductive-1.rs new file mode 100644 index 00000000000..7bcd0f1fdaf --- /dev/null +++ b/src/test/ui/sized/coinductive-1.rs @@ -0,0 +1,14 @@ +// check-pass +struct Node>(C::Assoc); + +trait Trait { + type Assoc; +} + +impl Trait for Vec<()> { + type Assoc = Vec; +} + +fn main() { + let _ = Node::>(Vec::new()); +} diff --git a/src/test/ui/sized/coinductive-2.rs b/src/test/ui/sized/coinductive-2.rs new file mode 100644 index 00000000000..212274d2e4b --- /dev/null +++ b/src/test/ui/sized/coinductive-2.rs @@ -0,0 +1,28 @@ +// run-pass +struct Node> { + _children: C::Collection, +} + +trait CollectionFactory { + type Collection; +} + +impl CollectionFactory for Vec<()> { + type Collection = Vec; +} + +trait Collection: Sized { + fn push(&mut self, v: T); +} + +impl Collection for Vec { + fn push(&mut self, v: T) { + self.push(v) + } +} + +fn main() { + let _ = Node::> { + _children: Vec::new(), + }; +}