From f46f388cb20962cdf08747132c17448cf9602b5e Mon Sep 17 00:00:00 2001 From: "leonardo.yvens" Date: Sat, 4 Nov 2017 19:44:19 -0200 Subject: [PATCH] Fix checking of auto trait bounds in trait objects. Any auto trait is allowed in trait object bounds. Fix duplicate check of type and lifetime parameter count. --- src/librustc_typeck/astconv.rs | 27 +++++---------------------- src/librustc_typeck/diagnostics.rs | 6 +++--- src/test/compile-fail/E0225.rs | 4 ++-- src/test/compile-fail/bad-sized.rs | 2 +- src/test/compile-fail/issue-22560.rs | 2 +- src/test/compile-fail/issue-32963.rs | 2 +- src/test/run-pass/auto-traits.rs | 3 +++ 7 files changed, 16 insertions(+), 30 deletions(-) diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index c7f7e62fd61e..77ead1d50330 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -572,8 +572,8 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { let b = &trait_bounds[0]; let span = b.trait_ref.path.span; struct_span_err!(self.tcx().sess, span, E0225, - "only Send/Sync traits can be used as additional traits in a trait object") - .span_label(span, "non-Send/Sync additional trait") + "only auto traits can be used as additional traits in a trait object") + .span_label(span, "non-auto additional trait") .emit(); } @@ -1311,27 +1311,10 @@ fn split_auto_traits<'a, 'b, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, -> (Vec, 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.def { - Def::Trait(trait_did) => { - // Checks whether `trait_did` refers to one of the builtin - // traits, like `Send`, and adds it to `auto_traits` if so. - if Some(trait_did) == tcx.lang_items().send_trait() || - Some(trait_did) == tcx.lang_items().sync_trait() { - let segments = &bound.trait_ref.path.segments; - segments[segments.len() - 1].with_parameters(|parameters| { - if !parameters.types.is_empty() { - check_type_argument_count(tcx, bound.trait_ref.path.span, - parameters.types.len(), &[]); - } - if !parameters.lifetimes.is_empty() { - report_lifetime_number_error(tcx, bound.trait_ref.path.span, - parameters.lifetimes.len(), 0); - } - }); - true - } else { - false - } + Def::Trait(trait_did) if tcx.trait_is_auto(trait_did) => { + true } _ => false } diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index 075367cbbb7c..76ac372b29f1 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -2455,9 +2455,9 @@ fn main() { } ``` -Send and Sync are an exception to this rule: it's possible to have bounds of -one non-builtin trait, plus either or both of Send and Sync. For example, the -following compiles correctly: +Auto traits such as Send and Sync are an exception to this rule: +It's possible to have bounds of one non-builtin trait, plus any number of +auto traits. For example, the following compiles correctly: ``` fn main() { diff --git a/src/test/compile-fail/E0225.rs b/src/test/compile-fail/E0225.rs index 8c79c15e3de5..c2f610ecd281 100644 --- a/src/test/compile-fail/E0225.rs +++ b/src/test/compile-fail/E0225.rs @@ -10,6 +10,6 @@ fn main() { let _: Box; - //~^ ERROR only Send/Sync traits can be used as additional traits in a trait object [E0225] - //~| NOTE non-Send/Sync additional trait + //~^ ERROR only auto traits can be used as additional traits in a trait object [E0225] + //~| NOTE non-auto additional trait } diff --git a/src/test/compile-fail/bad-sized.rs b/src/test/compile-fail/bad-sized.rs index a2e2e5caafe6..df3da5096bf5 100644 --- a/src/test/compile-fail/bad-sized.rs +++ b/src/test/compile-fail/bad-sized.rs @@ -12,7 +12,7 @@ trait Trait {} pub fn main() { let x: Vec = Vec::new(); - //~^ ERROR only Send/Sync traits can be used as additional traits in a trait object + //~^ ERROR only auto traits can be used as additional traits in a trait object //~| ERROR the trait bound `Trait: std::marker::Sized` is not satisfied //~| ERROR the trait bound `Trait: std::marker::Sized` is not satisfied } diff --git a/src/test/compile-fail/issue-22560.rs b/src/test/compile-fail/issue-22560.rs index eb5c6076440e..914a3bd79d46 100644 --- a/src/test/compile-fail/issue-22560.rs +++ b/src/test/compile-fail/issue-22560.rs @@ -23,6 +23,6 @@ type Test = Add + //~| NOTE missing reference to `RHS` //~| NOTE because of the default `Self` reference, type parameters must be specified on object types //~| ERROR E0225 - //~| NOTE non-Send/Sync additional trait + //~| NOTE non-auto additional trait fn main() { } diff --git a/src/test/compile-fail/issue-32963.rs b/src/test/compile-fail/issue-32963.rs index f146cfbe68b9..e97e5a86a9d7 100644 --- a/src/test/compile-fail/issue-32963.rs +++ b/src/test/compile-fail/issue-32963.rs @@ -16,6 +16,6 @@ fn size_of_copy() -> usize { mem::size_of::() } fn main() { size_of_copy::(); - //~^ ERROR only Send/Sync traits can be used as additional traits in a trait object + //~^ ERROR only auto traits can be used as additional traits in a trait object //~| ERROR the trait bound `Misc: std::marker::Copy` is not satisfied } diff --git a/src/test/run-pass/auto-traits.rs b/src/test/run-pass/auto-traits.rs index 752f5a11375a..e42aca9ccbd1 100644 --- a/src/test/run-pass/auto-traits.rs +++ b/src/test/run-pass/auto-traits.rs @@ -33,4 +33,7 @@ fn main() { take_auto(AutoBool(true)); take_auto_unsafe(0); take_auto_unsafe(AutoBool(true)); + + /// Auto traits are allowed in trait object bounds. + let _: &(Send + Auto) = &0; }