From 73cc2fc79172084f10590f6ad434bf0a480e7773 Mon Sep 17 00:00:00 2001 From: alecmocatta Date: Tue, 5 Nov 2019 13:12:28 +0000 Subject: [PATCH] allow auto trait predicates in where clauses --- src/librustc/traits/object_safety.rs | 31 ++++++++++++++++++---------- src/test/ui/issues/issue-50781-1.rs | 15 ++++++++++++++ 2 files changed, 35 insertions(+), 11 deletions(-) create mode 100644 src/test/ui/issues/issue-50781-1.rs diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs index 8ded1417ee570..eb55730d276b7 100644 --- a/src/librustc/traits/object_safety.rs +++ b/src/librustc/traits/object_safety.rs @@ -331,17 +331,26 @@ impl<'tcx> TyCtxt<'tcx> { return Some(MethodViolationCode::Generic); } - if self.predicates_of(method.def_id).predicates.iter() - // A trait object can't claim to live more than the concrete type, - // so outlives predicates will always hold. - .cloned() - .filter(|(p, _)| p.to_opt_type_outlives().is_none()) - .collect::>() - // Do a shallow visit so that `contains_illegal_self_type_reference` - // may apply it's custom visiting. - .visit_tys_shallow(|t| { - self.contains_illegal_self_type_reference(trait_def_id, t) - }) { + if self + .predicates_of(method.def_id) + .predicates + .iter() + .cloned() + // A trait object can't claim to live more than the concrete type, + // so outlives predicates will always hold. Auto trait predicates + // are allowed as they don't affect vtables thus can't introduce + // unsoundness. + .filter(|(p, _)| { + p.to_opt_type_outlives().is_none() + && p.to_opt_poly_trait_ref() + .map_or(true, |trait_ref| !self.trait_is_auto(trait_ref.def_id())) + }) + .collect::>() + // Do a shallow visit so that `contains_illegal_self_type_reference` + // may apply it's custom visiting. + .visit_tys_shallow(|t| { + self.contains_illegal_self_type_reference(trait_def_id, t) + }) { return Some(MethodViolationCode::WhereClauseReferencesSelf); } diff --git a/src/test/ui/issues/issue-50781-1.rs b/src/test/ui/issues/issue-50781-1.rs new file mode 100644 index 0000000000000..538a343493cdb --- /dev/null +++ b/src/test/ui/issues/issue-50781-1.rs @@ -0,0 +1,15 @@ +// run-pass + +#![deny(where_clauses_object_safety)] + +trait Y { + fn foo(&self) where Self: Send {} + fn bar(&self) where Self: Send + Sync {} +} + +impl Y for () {} + +fn main() { + ::foo(&()); + ::bar(&()); +}