From 7de81fbe703787123df64a1f762b90cdbcaa8019 Mon Sep 17 00:00:00 2001 From: Jared Roesch Date: Tue, 16 Aug 2016 18:41:27 -0700 Subject: [PATCH 1/6] Add tests for #29859 --- src/test/compile-fail/issue-29859-2.rs | 25 +++++++++++++++++++++++++ src/test/compile-fail/issue-29859.rs | 25 +++++++++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 src/test/compile-fail/issue-29859-2.rs create mode 100644 src/test/compile-fail/issue-29859.rs diff --git a/src/test/compile-fail/issue-29859-2.rs b/src/test/compile-fail/issue-29859-2.rs new file mode 100644 index 0000000000000..c0e50185f939d --- /dev/null +++ b/src/test/compile-fail/issue-29859-2.rs @@ -0,0 +1,25 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(optin_builtin_traits)] + +trait Magic: Copy {} +impl Magic for .. {} +impl Magic for T {} + +fn copy(x: T) -> (T, T) { (x, x) } + +#[derive(Debug)] +struct NoClone; + +fn main() { + let (a, b) = copy(NoClone); //~ ERROR E0277 + println!("{:?} {:?}", a, b); +} diff --git a/src/test/compile-fail/issue-29859.rs b/src/test/compile-fail/issue-29859.rs new file mode 100644 index 0000000000000..c0e50185f939d --- /dev/null +++ b/src/test/compile-fail/issue-29859.rs @@ -0,0 +1,25 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(optin_builtin_traits)] + +trait Magic: Copy {} +impl Magic for .. {} +impl Magic for T {} + +fn copy(x: T) -> (T, T) { (x, x) } + +#[derive(Debug)] +struct NoClone; + +fn main() { + let (a, b) = copy(NoClone); //~ ERROR E0277 + println!("{:?} {:?}", a, b); +} From 36cdb8f48e600cd4785f162004fec98a5f3a21ac Mon Sep 17 00:00:00 2001 From: Jared Roesch Date: Tue, 16 Aug 2016 22:48:09 -0700 Subject: [PATCH 2/6] Reject certain auto trait declarations Fixes #29859 --- src/librustc/ty/mod.rs | 10 +++++ src/librustc_typeck/check/wfcheck.rs | 53 ++++++++++++++++++++++++++ src/librustc_typeck/diagnostics.rs | 2 + src/test/compile-fail/issue-29859-2.rs | 15 +------- src/test/compile-fail/issue-29859.rs | 6 +-- 5 files changed, 70 insertions(+), 16 deletions(-) diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 759dc30037210..c5edee4019065 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -762,6 +762,16 @@ pub struct GenericPredicates<'tcx> { } impl<'a, 'gcx, 'tcx> GenericPredicates<'tcx> { + pub fn empty() -> GenericPredicates<'tcx> { + GenericPredicates { + predicates: VecPerParamSpace::empty(), + } + } + + pub fn is_empty(&self) -> bool { + self.predicates.is_empty() + } + pub fn instantiate(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, substs: &Substs<'tcx>) -> InstantiatedPredicates<'tcx> { let mut instantiated = InstantiatedPredicates::empty(); diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index 6b6a688bf1d18..1d8d01324faff 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -251,6 +251,36 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> { }); } + fn check_auto_trait(&mut self, + trait_def_id: DefId, + span: Span) + { + let predicates = self.tcx().lookup_predicates(trait_def_id); + + // If we must exclude the Self : Trait predicate contained by all + // traits. + let no_refl_predicates : Vec<_> = + predicates.predicates.iter().filter(|predicate| { + match *predicate { + &ty::Predicate::Trait(ref poly_trait_ref) => + poly_trait_ref.def_id() != trait_def_id, + _ => true, + } + }).collect(); + + let trait_def = self.tcx().lookup_trait_def(trait_def_id); + + // We use an if-else here, since the generics will also trigger + // an extraneous error message when we find predicates like + // `T : Sized` for a trait like: `trait Magic`. + if !trait_def.generics.types.get_slice(ParamSpace::TypeSpace).is_empty() { + error_566(self.ccx, span); + } else if !no_refl_predicates.is_empty() { + error_565(self.ccx, span); + } + + } + fn check_trait(&mut self, item: &hir::Item, items: &[hir::TraitItem]) @@ -258,9 +288,18 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> { let trait_def_id = self.tcx().map.local_def_id(item.id); if self.tcx().trait_has_default_impl(trait_def_id) { + // We want to both ensure: + // 1) that there are no items contained within + // the trait defintion + // + // 2) that the definition doesn't violate the no-super trait rule + // for auto traits. + if !items.is_empty() { error_380(self.ccx, item.span); } + + self.check_auto_trait(trait_def_id, item.span); } self.for_item(item).with_fcx(|fcx, this| { @@ -272,6 +311,8 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> { }); } + + fn check_item_fn(&mut self, item: &hir::Item, body: &hir::Block) @@ -622,6 +663,18 @@ fn error_380(ccx: &CrateCtxt, span: Span) { Trait for ..`) must have no methods or associated items") } +fn error_565(ccx: &CrateCtxt, span: Span) { + span_err!(ccx.tcx.sess, span, E0565, + "traits with default impls (`e.g. unsafe impl \ + Trait for ..`) can not have predicates") +} + +fn error_566(ccx: &CrateCtxt, span: Span) { + span_err!(ccx.tcx.sess, span, E0566, + "traits with default impls (`e.g. unsafe impl \ + Trait for ..`) can not have type parameters") +} + fn error_392<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, span: Span, param_name: ast::Name) -> DiagnosticBuilder<'tcx> { let mut err = struct_span_err!(ccx.tcx.sess, span, E0392, diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index 8bb5efdcad2c3..a188cebde6cc7 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -4079,4 +4079,6 @@ register_diagnostics! { E0563, // cannot determine a type for this `impl Trait`: {} E0564, // only named lifetimes are allowed in `impl Trait`, // but `{}` was found in the type `{}` + E0565, // auto-traits can not have predicates, + E0566, // auto traits can not have type parameters } diff --git a/src/test/compile-fail/issue-29859-2.rs b/src/test/compile-fail/issue-29859-2.rs index c0e50185f939d..258aafb15baf4 100644 --- a/src/test/compile-fail/issue-29859-2.rs +++ b/src/test/compile-fail/issue-29859-2.rs @@ -10,16 +10,5 @@ #![feature(optin_builtin_traits)] -trait Magic: Copy {} -impl Magic for .. {} -impl Magic for T {} - -fn copy(x: T) -> (T, T) { (x, x) } - -#[derive(Debug)] -struct NoClone; - -fn main() { - let (a, b) = copy(NoClone); //~ ERROR E0277 - println!("{:?} {:?}", a, b); -} +trait Magic {} //~ E0566 +impl Magic for .. {} diff --git a/src/test/compile-fail/issue-29859.rs b/src/test/compile-fail/issue-29859.rs index c0e50185f939d..3419e66af1393 100644 --- a/src/test/compile-fail/issue-29859.rs +++ b/src/test/compile-fail/issue-29859.rs @@ -10,8 +10,8 @@ #![feature(optin_builtin_traits)] -trait Magic: Copy {} -impl Magic for .. {} +trait Magic: Copy {} //~ ERROR E0565 +impl Magic for .. {} impl Magic for T {} fn copy(x: T) -> (T, T) { (x, x) } @@ -20,6 +20,6 @@ fn copy(x: T) -> (T, T) { (x, x) } struct NoClone; fn main() { - let (a, b) = copy(NoClone); //~ ERROR E0277 + let (a, b) = copy(NoClone); println!("{:?} {:?}", a, b); } From 3c56616b4556221271d106ee6d8ebf58b6512804 Mon Sep 17 00:00:00 2001 From: Jared Roesch Date: Thu, 18 Aug 2016 11:29:35 -0700 Subject: [PATCH 3/6] Address feedback, and remove invalid tests --- src/librustc/ty/mod.rs | 10 -- src/librustc_typeck/check/wfcheck.rs | 95 +++++++++++-------- ...its-inductive-overflow-auto-normal-auto.rs | 32 ------- ...its-inductive-overflow-supertrait-oibit.rs | 4 +- ... => typeck-auto-trait-no-supertraits-2.rs} | 2 +- .../typeck-auto-trait-no-supertraits.rs | 49 ++++++++++ ....rs => typeck-auto-trait-no-typeparams.rs} | 2 +- .../typeck-default-trait-impl-superregion.rs | 27 ------ .../typeck-default-trait-impl-supertrait.rs | 29 ------ ...default-trait-impl-trait-where-clause-2.rs | 36 ------- ...k-default-trait-impl-trait-where-clause.rs | 36 ------- 11 files changed, 108 insertions(+), 214 deletions(-) delete mode 100644 src/test/compile-fail/traits-inductive-overflow-auto-normal-auto.rs rename src/test/compile-fail/{issue-29859.rs => typeck-auto-trait-no-supertraits-2.rs} (91%) create mode 100644 src/test/compile-fail/typeck-auto-trait-no-supertraits.rs rename src/test/compile-fail/{issue-29859-2.rs => typeck-auto-trait-no-typeparams.rs} (93%) delete mode 100644 src/test/compile-fail/typeck-default-trait-impl-superregion.rs delete mode 100644 src/test/compile-fail/typeck-default-trait-impl-supertrait.rs delete mode 100644 src/test/compile-fail/typeck-default-trait-impl-trait-where-clause-2.rs delete mode 100644 src/test/compile-fail/typeck-default-trait-impl-trait-where-clause.rs diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index c5edee4019065..759dc30037210 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -762,16 +762,6 @@ pub struct GenericPredicates<'tcx> { } impl<'a, 'gcx, 'tcx> GenericPredicates<'tcx> { - pub fn empty() -> GenericPredicates<'tcx> { - GenericPredicates { - predicates: VecPerParamSpace::empty(), - } - } - - pub fn is_empty(&self) -> bool { - self.predicates.is_empty() - } - pub fn instantiate(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, substs: &Substs<'tcx>) -> InstantiatedPredicates<'tcx> { let mut instantiated = InstantiatedPredicates::empty(); diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index 1d8d01324faff..b2942765547ba 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -252,33 +252,71 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> { } fn check_auto_trait(&mut self, - trait_def_id: DefId, - span: Span) + trait_def_id: DefId, + items: &[hir::TraitItem], + span: Span) { + // We want to ensure: + // + // 1) that there are no items contained within + // the trait defintion + // + // 2) that the definition doesn't violate the no-super trait rule + // for auto traits. + // + // 3) that the trait definition does not have any type parameters + let predicates = self.tcx().lookup_predicates(trait_def_id); - // If we must exclude the Self : Trait predicate contained by all + // We must exclude the Self : Trait predicate contained by all // traits. - let no_refl_predicates : Vec<_> = - predicates.predicates.iter().filter(|predicate| { - match *predicate { - &ty::Predicate::Trait(ref poly_trait_ref) => - poly_trait_ref.def_id() != trait_def_id, + let has_predicates = + predicates.predicates.iter().any(|predicate| { + match predicate { + &ty::Predicate::Trait(ref poly_trait_ref) => { + let self_ty = poly_trait_ref.0.self_ty(); + !(self_ty.is_self() && poly_trait_ref.def_id() == trait_def_id) + }, _ => true, - } - }).collect(); + } + }); let trait_def = self.tcx().lookup_trait_def(trait_def_id); + let has_ty_params = + trait_def.generics + .types + .len() > 1; + // We use an if-else here, since the generics will also trigger // an extraneous error message when we find predicates like // `T : Sized` for a trait like: `trait Magic`. - if !trait_def.generics.types.get_slice(ParamSpace::TypeSpace).is_empty() { - error_566(self.ccx, span); - } else if !no_refl_predicates.is_empty() { - error_565(self.ccx, span); + // + // We also put the check on the number of items here, + // as it seems confusing to report an error about + // extraneous predicates created by things like + // an associated type inside the trait. + + if !items.is_empty() { + error_380(self.ccx, span); + } else if has_ty_params { + span_err!(self.tcx().sess, span, E0566, + "traits with auto impls (`e.g. unsafe impl \ + Trait for ..`) can not have type parameters") + } else if has_predicates { + span_err!(self.tcx().sess, span, E0565, + "traits with auto impls (`e.g. unsafe impl \ + Trait for ..`) can not have predicates") } + // Finally if either of the above conditions apply we should add a note + // indicating that this error is the result of a recent soundness fix. + if has_ty_params || has_predicates { + self.tcx().sess.span_note_without_error( + span, + "the new auto trait rules are the result of a \ + recent soundness fix; see #29859 for more details") + } } fn check_trait(&mut self, @@ -287,19 +325,10 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> { { let trait_def_id = self.tcx().map.local_def_id(item.id); + // TODO: in a second pass, globally rename to auto_trait, + // from default_impl. if self.tcx().trait_has_default_impl(trait_def_id) { - // We want to both ensure: - // 1) that there are no items contained within - // the trait defintion - // - // 2) that the definition doesn't violate the no-super trait rule - // for auto traits. - - if !items.is_empty() { - error_380(self.ccx, item.span); - } - - self.check_auto_trait(trait_def_id, item.span); + self.check_auto_trait(trait_def_id, items, item.span); } self.for_item(item).with_fcx(|fcx, this| { @@ -311,8 +340,6 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> { }); } - - fn check_item_fn(&mut self, item: &hir::Item, body: &hir::Block) @@ -663,18 +690,6 @@ fn error_380(ccx: &CrateCtxt, span: Span) { Trait for ..`) must have no methods or associated items") } -fn error_565(ccx: &CrateCtxt, span: Span) { - span_err!(ccx.tcx.sess, span, E0565, - "traits with default impls (`e.g. unsafe impl \ - Trait for ..`) can not have predicates") -} - -fn error_566(ccx: &CrateCtxt, span: Span) { - span_err!(ccx.tcx.sess, span, E0566, - "traits with default impls (`e.g. unsafe impl \ - Trait for ..`) can not have type parameters") -} - fn error_392<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, span: Span, param_name: ast::Name) -> DiagnosticBuilder<'tcx> { let mut err = struct_span_err!(ccx.tcx.sess, span, E0392, diff --git a/src/test/compile-fail/traits-inductive-overflow-auto-normal-auto.rs b/src/test/compile-fail/traits-inductive-overflow-auto-normal-auto.rs deleted file mode 100644 index cdf4b405fd83e..0000000000000 --- a/src/test/compile-fail/traits-inductive-overflow-auto-normal-auto.rs +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright 2015 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// Test for a potential corner case in current impl where you have an -// auto trait (Magic1) that depends on a normal trait (Magic2) which -// in turn depends on the auto trait (Magic1). This was incorrectly -// being considered coinductive, but because of the normal trait -// interfering, it should not be. - -#![feature(optin_builtin_traits)] - -trait Magic1: Magic2 { } -impl Magic1 for .. {} - -trait Magic2 { } -impl Magic2 for T { } - -fn is_magic1() { } - -#[derive(Debug)] -struct NoClone; - -fn main() { - is_magic1::(); //~ ERROR E0275 -} diff --git a/src/test/compile-fail/traits-inductive-overflow-supertrait-oibit.rs b/src/test/compile-fail/traits-inductive-overflow-supertrait-oibit.rs index ec8db996600d1..168148b92fe44 100644 --- a/src/test/compile-fail/traits-inductive-overflow-supertrait-oibit.rs +++ b/src/test/compile-fail/traits-inductive-overflow-supertrait-oibit.rs @@ -14,7 +14,7 @@ #![feature(optin_builtin_traits)] -trait Magic: Copy {} +trait Magic: Copy {} //~ ERROR E0565 impl Magic for .. {} fn copy(x: T) -> (T, T) { (x, x) } @@ -23,6 +23,6 @@ fn copy(x: T) -> (T, T) { (x, x) } struct NoClone; fn main() { - let (a, b) = copy(NoClone); //~ ERROR E0277 + let (a, b) = copy(NoClone); println!("{:?} {:?}", a, b); } diff --git a/src/test/compile-fail/issue-29859.rs b/src/test/compile-fail/typeck-auto-trait-no-supertraits-2.rs similarity index 91% rename from src/test/compile-fail/issue-29859.rs rename to src/test/compile-fail/typeck-auto-trait-no-supertraits-2.rs index 3419e66af1393..60da647f68240 100644 --- a/src/test/compile-fail/issue-29859.rs +++ b/src/test/compile-fail/typeck-auto-trait-no-supertraits-2.rs @@ -10,7 +10,7 @@ #![feature(optin_builtin_traits)] -trait Magic: Copy {} //~ ERROR E0565 +trait Magic : Sized where Option : Magic {} //~ ERROR E0565 impl Magic for .. {} impl Magic for T {} diff --git a/src/test/compile-fail/typeck-auto-trait-no-supertraits.rs b/src/test/compile-fail/typeck-auto-trait-no-supertraits.rs new file mode 100644 index 0000000000000..177d594da18a0 --- /dev/null +++ b/src/test/compile-fail/typeck-auto-trait-no-supertraits.rs @@ -0,0 +1,49 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// This test is for #29859, we need to ensure auto traits, +// (also known previously as default traits), do not have +// supertraits. Since the compiler synthesizes these +// instances on demand, we are essentially enabling +// users to write axioms if we view trait selection, +// as a proof system. +// +// For example the below test allows us to add the rule: +// forall (T : Type), T : Copy +// +// Providing a copy instance for *any* type, which +// is most definitely unsound. Imagine copying a +// type that contains a mutable reference, enabling +// mutable aliasing. +// +// You can imagine an even more dangerous test, +// which currently compiles on nightly. +// +// fn main() { +// let mut i = 10; +// let (a, b) = copy(&mut i); +// println!("{:?} {:?}", a, b); +// } + +#![feature(optin_builtin_traits)] + +trait Magic: Copy {} //~ ERROR E0565 +impl Magic for .. {} +impl Magic for T {} + +fn copy(x: T) -> (T, T) { (x, x) } + +#[derive(Debug)] +struct NoClone; + +fn main() { + let (a, b) = copy(NoClone); + println!("{:?} {:?}", a, b); +} diff --git a/src/test/compile-fail/issue-29859-2.rs b/src/test/compile-fail/typeck-auto-trait-no-typeparams.rs similarity index 93% rename from src/test/compile-fail/issue-29859-2.rs rename to src/test/compile-fail/typeck-auto-trait-no-typeparams.rs index 258aafb15baf4..f2841a413db9e 100644 --- a/src/test/compile-fail/issue-29859-2.rs +++ b/src/test/compile-fail/typeck-auto-trait-no-typeparams.rs @@ -10,5 +10,5 @@ #![feature(optin_builtin_traits)] -trait Magic {} //~ E0566 +trait Magic {} //~ ERROR E0566 impl Magic for .. {} diff --git a/src/test/compile-fail/typeck-default-trait-impl-superregion.rs b/src/test/compile-fail/typeck-default-trait-impl-superregion.rs deleted file mode 100644 index aa918119fbcee..0000000000000 --- a/src/test/compile-fail/typeck-default-trait-impl-superregion.rs +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright 2015 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// Test that when a `..` impl applies, we also check that any -// supertrait conditions are met. - -#![feature(optin_builtin_traits)] - -trait MyTrait : 'static {} - -impl MyTrait for .. {} - -fn foo() { } - -fn bar<'a>() { - foo::<&'a ()>(); //~ ERROR does not fulfill the required lifetime -} - -fn main() { -} diff --git a/src/test/compile-fail/typeck-default-trait-impl-supertrait.rs b/src/test/compile-fail/typeck-default-trait-impl-supertrait.rs deleted file mode 100644 index 0b071a9acd092..0000000000000 --- a/src/test/compile-fail/typeck-default-trait-impl-supertrait.rs +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2015 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// Test that when a `..` impl applies, we also check that any -// supertrait conditions are met. - -#![feature(optin_builtin_traits)] - -trait NotImplemented { } - -trait MyTrait : NotImplemented {} - -impl MyTrait for .. {} - -fn foo() { bar::() } - -fn bar() { } - -fn main() { - foo::(); //~ ERROR `i32: NotImplemented` is not satisfied - bar::(); //~ ERROR `i64: NotImplemented` is not satisfied -} diff --git a/src/test/compile-fail/typeck-default-trait-impl-trait-where-clause-2.rs b/src/test/compile-fail/typeck-default-trait-impl-trait-where-clause-2.rs deleted file mode 100644 index 3085f45a83dd1..0000000000000 --- a/src/test/compile-fail/typeck-default-trait-impl-trait-where-clause-2.rs +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright 2015 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// ignore-tidy-linelength - -// Test that when a `..` impl applies, we also check that any -// supertrait conditions are met. - -#![feature(optin_builtin_traits)] - -trait NotImplemented { } - -trait MyTrait: Sized - where Option : NotImplemented -{} - -impl NotImplemented for i32 {} - -impl MyTrait for .. {} - -fn bar() { } - -fn test() { - bar::>(); - //~^ ERROR `std::option::Option: NotImplemented` is not satisfied -} - -fn main() { -} diff --git a/src/test/compile-fail/typeck-default-trait-impl-trait-where-clause.rs b/src/test/compile-fail/typeck-default-trait-impl-trait-where-clause.rs deleted file mode 100644 index 47e87c09d12b1..0000000000000 --- a/src/test/compile-fail/typeck-default-trait-impl-trait-where-clause.rs +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright 2015 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// ignore-tidy-linelength - -// Test that when a `..` impl applies, we also check that any -// supertrait conditions are met. - -#![feature(optin_builtin_traits)] - -trait NotImplemented { } - -trait MyTrait: Sized - where Option : NotImplemented -{} - -impl NotImplemented for i32 {} - -impl MyTrait for .. {} - -fn foo() { - //~^ ERROR `std::option::Option: NotImplemented` is not satisfied - // This should probably typecheck. This is #20671. -} - -fn bar() { } - -fn main() { -} From 19c328ac37bfff30e4fe88fbcfeb90691b5063e6 Mon Sep 17 00:00:00 2001 From: Jared Roesch Date: Thu, 18 Aug 2016 11:47:33 -0700 Subject: [PATCH 4/6] Address feedback on secondary changes --- src/librustc_typeck/check/wfcheck.rs | 30 ++++++++++++++-------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index b2942765547ba..6b7934731099a 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -296,26 +296,28 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> { // as it seems confusing to report an error about // extraneous predicates created by things like // an associated type inside the trait. - + let mut err = None; if !items.is_empty() { error_380(self.ccx, span); } else if has_ty_params { - span_err!(self.tcx().sess, span, E0566, - "traits with auto impls (`e.g. unsafe impl \ - Trait for ..`) can not have type parameters") + err = Some(struct_span_err!(self.tcx().sess, span, E0566, + "traits with auto impls (`e.g. impl \ + Trait for ..`) can not have type parameters")); } else if has_predicates { - span_err!(self.tcx().sess, span, E0565, - "traits with auto impls (`e.g. unsafe impl \ - Trait for ..`) can not have predicates") + err = Some(struct_span_err!(self.tcx().sess, span, E0565, + "traits with auto impls (`e.g. impl \ + Trait for ..`) cannot have predicates")); } // Finally if either of the above conditions apply we should add a note // indicating that this error is the result of a recent soundness fix. - if has_ty_params || has_predicates { - self.tcx().sess.span_note_without_error( - span, - "the new auto trait rules are the result of a \ - recent soundness fix; see #29859 for more details") + match err { + None => {}, + Some(mut e) => { + e.note("the new auto trait rules are the result of a \ + recent soundness fix; see #29859 for more details"); + e.emit(); + } } } @@ -325,8 +327,6 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> { { let trait_def_id = self.tcx().map.local_def_id(item.id); - // TODO: in a second pass, globally rename to auto_trait, - // from default_impl. if self.tcx().trait_has_default_impl(trait_def_id) { self.check_auto_trait(trait_def_id, items, item.span); } @@ -686,7 +686,7 @@ fn error_192(ccx: &CrateCtxt, span: Span) { fn error_380(ccx: &CrateCtxt, span: Span) { span_err!(ccx.tcx.sess, span, E0380, - "traits with default impls (`e.g. unsafe impl \ + "traits with default impls (`e.g. impl \ Trait for ..`) must have no methods or associated items") } From c4504fdc5ad87571f337496297a138ce91038874 Mon Sep 17 00:00:00 2001 From: Jared Roesch Date: Thu, 18 Aug 2016 12:46:20 -0700 Subject: [PATCH 5/6] Forget to update tests to use new error message --- src/test/compile-fail/issue-23080-2.rs | 2 +- src/test/compile-fail/issue-23080.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/compile-fail/issue-23080-2.rs b/src/test/compile-fail/issue-23080-2.rs index b77230a8b340d..9d20c17674bc3 100644 --- a/src/test/compile-fail/issue-23080-2.rs +++ b/src/test/compile-fail/issue-23080-2.rs @@ -13,7 +13,7 @@ #![feature(optin_builtin_traits)] unsafe trait Trait { -//~^ error: traits with default impls (`e.g. unsafe impl Trait for ..`) must have no methods or associated items +//~^ ERROR E0380 type Output; } diff --git a/src/test/compile-fail/issue-23080.rs b/src/test/compile-fail/issue-23080.rs index 99373a69697ae..2e8cba87be515 100644 --- a/src/test/compile-fail/issue-23080.rs +++ b/src/test/compile-fail/issue-23080.rs @@ -13,7 +13,7 @@ #![feature(optin_builtin_traits)] unsafe trait Trait { -//~^ error: traits with default impls (`e.g. unsafe impl Trait for ..`) must have no methods or associated items +//~^ ERROR E0380 fn method(&self) { println!("Hello"); } From dba5cbebcd737112c55f03248f6eaa16b36b0936 Mon Sep 17 00:00:00 2001 From: Jared Roesch Date: Mon, 29 Aug 2016 01:54:10 -0700 Subject: [PATCH 6/6] Remove illegal bound from doc test --- src/test/compile-fail/typeck-auto-trait-no-supertraits-2.rs | 2 +- src/test/compile-fail/typeck-auto-trait-no-supertraits.rs | 4 ++-- src/test/rustdoc/auxiliary/rustdoc-default-impl.rs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/test/compile-fail/typeck-auto-trait-no-supertraits-2.rs b/src/test/compile-fail/typeck-auto-trait-no-supertraits-2.rs index 60da647f68240..333cb569ee895 100644 --- a/src/test/compile-fail/typeck-auto-trait-no-supertraits-2.rs +++ b/src/test/compile-fail/typeck-auto-trait-no-supertraits-2.rs @@ -11,7 +11,7 @@ #![feature(optin_builtin_traits)] trait Magic : Sized where Option : Magic {} //~ ERROR E0565 -impl Magic for .. {} +impl Magic for .. {} impl Magic for T {} fn copy(x: T) -> (T, T) { (x, x) } diff --git a/src/test/compile-fail/typeck-auto-trait-no-supertraits.rs b/src/test/compile-fail/typeck-auto-trait-no-supertraits.rs index 177d594da18a0..713f26f82079e 100644 --- a/src/test/compile-fail/typeck-auto-trait-no-supertraits.rs +++ b/src/test/compile-fail/typeck-auto-trait-no-supertraits.rs @@ -23,7 +23,7 @@ // type that contains a mutable reference, enabling // mutable aliasing. // -// You can imagine an even more dangerous test, +// You can imagine an even more dangerous test, // which currently compiles on nightly. // // fn main() { @@ -35,7 +35,7 @@ #![feature(optin_builtin_traits)] trait Magic: Copy {} //~ ERROR E0565 -impl Magic for .. {} +impl Magic for .. {} impl Magic for T {} fn copy(x: T) -> (T, T) { (x, x) } diff --git a/src/test/rustdoc/auxiliary/rustdoc-default-impl.rs b/src/test/rustdoc/auxiliary/rustdoc-default-impl.rs index c2ff7a0054f19..52bd386ba595b 100644 --- a/src/test/rustdoc/auxiliary/rustdoc-default-impl.rs +++ b/src/test/rustdoc/auxiliary/rustdoc-default-impl.rs @@ -14,7 +14,7 @@ pub mod bar { use std::marker; - pub trait Bar: 'static {} + pub trait Bar {} impl Bar for .. {}