Skip to content

Commit 3c56616

Browse files
committed
Address feedback, and remove invalid tests
1 parent 36cdb8f commit 3c56616

11 files changed

+108
-214
lines changed

src/librustc/ty/mod.rs

-10
Original file line numberDiff line numberDiff line change
@@ -762,16 +762,6 @@ pub struct GenericPredicates<'tcx> {
762762
}
763763

764764
impl<'a, 'gcx, 'tcx> GenericPredicates<'tcx> {
765-
pub fn empty() -> GenericPredicates<'tcx> {
766-
GenericPredicates {
767-
predicates: VecPerParamSpace::empty(),
768-
}
769-
}
770-
771-
pub fn is_empty(&self) -> bool {
772-
self.predicates.is_empty()
773-
}
774-
775765
pub fn instantiate(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, substs: &Substs<'tcx>)
776766
-> InstantiatedPredicates<'tcx> {
777767
let mut instantiated = InstantiatedPredicates::empty();

src/librustc_typeck/check/wfcheck.rs

+55-40
Original file line numberDiff line numberDiff line change
@@ -252,33 +252,71 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> {
252252
}
253253

254254
fn check_auto_trait(&mut self,
255-
trait_def_id: DefId,
256-
span: Span)
255+
trait_def_id: DefId,
256+
items: &[hir::TraitItem],
257+
span: Span)
257258
{
259+
// We want to ensure:
260+
//
261+
// 1) that there are no items contained within
262+
// the trait defintion
263+
//
264+
// 2) that the definition doesn't violate the no-super trait rule
265+
// for auto traits.
266+
//
267+
// 3) that the trait definition does not have any type parameters
268+
258269
let predicates = self.tcx().lookup_predicates(trait_def_id);
259270

260-
// If we must exclude the Self : Trait predicate contained by all
271+
// We must exclude the Self : Trait predicate contained by all
261272
// traits.
262-
let no_refl_predicates : Vec<_> =
263-
predicates.predicates.iter().filter(|predicate| {
264-
match *predicate {
265-
&ty::Predicate::Trait(ref poly_trait_ref) =>
266-
poly_trait_ref.def_id() != trait_def_id,
273+
let has_predicates =
274+
predicates.predicates.iter().any(|predicate| {
275+
match predicate {
276+
&ty::Predicate::Trait(ref poly_trait_ref) => {
277+
let self_ty = poly_trait_ref.0.self_ty();
278+
!(self_ty.is_self() && poly_trait_ref.def_id() == trait_def_id)
279+
},
267280
_ => true,
268-
}
269-
}).collect();
281+
}
282+
});
270283

271284
let trait_def = self.tcx().lookup_trait_def(trait_def_id);
272285

286+
let has_ty_params =
287+
trait_def.generics
288+
.types
289+
.len() > 1;
290+
273291
// We use an if-else here, since the generics will also trigger
274292
// an extraneous error message when we find predicates like
275293
// `T : Sized` for a trait like: `trait Magic<T>`.
276-
if !trait_def.generics.types.get_slice(ParamSpace::TypeSpace).is_empty() {
277-
error_566(self.ccx, span);
278-
} else if !no_refl_predicates.is_empty() {
279-
error_565(self.ccx, span);
294+
//
295+
// We also put the check on the number of items here,
296+
// as it seems confusing to report an error about
297+
// extraneous predicates created by things like
298+
// an associated type inside the trait.
299+
300+
if !items.is_empty() {
301+
error_380(self.ccx, span);
302+
} else if has_ty_params {
303+
span_err!(self.tcx().sess, span, E0566,
304+
"traits with auto impls (`e.g. unsafe impl \
305+
Trait for ..`) can not have type parameters")
306+
} else if has_predicates {
307+
span_err!(self.tcx().sess, span, E0565,
308+
"traits with auto impls (`e.g. unsafe impl \
309+
Trait for ..`) can not have predicates")
280310
}
281311

312+
// Finally if either of the above conditions apply we should add a note
313+
// indicating that this error is the result of a recent soundness fix.
314+
if has_ty_params || has_predicates {
315+
self.tcx().sess.span_note_without_error(
316+
span,
317+
"the new auto trait rules are the result of a \
318+
recent soundness fix; see #29859 for more details")
319+
}
282320
}
283321

284322
fn check_trait(&mut self,
@@ -287,19 +325,10 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> {
287325
{
288326
let trait_def_id = self.tcx().map.local_def_id(item.id);
289327

328+
// TODO: in a second pass, globally rename to auto_trait,
329+
// from default_impl.
290330
if self.tcx().trait_has_default_impl(trait_def_id) {
291-
// We want to both ensure:
292-
// 1) that there are no items contained within
293-
// the trait defintion
294-
//
295-
// 2) that the definition doesn't violate the no-super trait rule
296-
// for auto traits.
297-
298-
if !items.is_empty() {
299-
error_380(self.ccx, item.span);
300-
}
301-
302-
self.check_auto_trait(trait_def_id, item.span);
331+
self.check_auto_trait(trait_def_id, items, item.span);
303332
}
304333

305334
self.for_item(item).with_fcx(|fcx, this| {
@@ -311,8 +340,6 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> {
311340
});
312341
}
313342

314-
315-
316343
fn check_item_fn(&mut self,
317344
item: &hir::Item,
318345
body: &hir::Block)
@@ -663,18 +690,6 @@ fn error_380(ccx: &CrateCtxt, span: Span) {
663690
Trait for ..`) must have no methods or associated items")
664691
}
665692

666-
fn error_565(ccx: &CrateCtxt, span: Span) {
667-
span_err!(ccx.tcx.sess, span, E0565,
668-
"traits with default impls (`e.g. unsafe impl \
669-
Trait for ..`) can not have predicates")
670-
}
671-
672-
fn error_566(ccx: &CrateCtxt, span: Span) {
673-
span_err!(ccx.tcx.sess, span, E0566,
674-
"traits with default impls (`e.g. unsafe impl \
675-
Trait for ..`) can not have type parameters")
676-
}
677-
678693
fn error_392<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, span: Span, param_name: ast::Name)
679694
-> DiagnosticBuilder<'tcx> {
680695
let mut err = struct_span_err!(ccx.tcx.sess, span, E0392,

src/test/compile-fail/traits-inductive-overflow-auto-normal-auto.rs

-32
This file was deleted.

src/test/compile-fail/traits-inductive-overflow-supertrait-oibit.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
#![feature(optin_builtin_traits)]
1616

17-
trait Magic: Copy {}
17+
trait Magic: Copy {} //~ ERROR E0565
1818
impl Magic for .. {}
1919

2020
fn copy<T: Magic>(x: T) -> (T, T) { (x, x) }
@@ -23,6 +23,6 @@ fn copy<T: Magic>(x: T) -> (T, T) { (x, x) }
2323
struct NoClone;
2424

2525
fn main() {
26-
let (a, b) = copy(NoClone); //~ ERROR E0277
26+
let (a, b) = copy(NoClone);
2727
println!("{:?} {:?}", a, b);
2828
}

src/test/compile-fail/issue-29859.rs renamed to src/test/compile-fail/typeck-auto-trait-no-supertraits-2.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
#![feature(optin_builtin_traits)]
1212

13-
trait Magic: Copy {} //~ ERROR E0565
13+
trait Magic : Sized where Option<Self> : Magic {} //~ ERROR E0565
1414
impl Magic for .. {}
1515
impl<T:Magic> Magic for T {}
1616

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// This test is for #29859, we need to ensure auto traits,
12+
// (also known previously as default traits), do not have
13+
// supertraits. Since the compiler synthesizes these
14+
// instances on demand, we are essentially enabling
15+
// users to write axioms if we view trait selection,
16+
// as a proof system.
17+
//
18+
// For example the below test allows us to add the rule:
19+
// forall (T : Type), T : Copy
20+
//
21+
// Providing a copy instance for *any* type, which
22+
// is most definitely unsound. Imagine copying a
23+
// type that contains a mutable reference, enabling
24+
// mutable aliasing.
25+
//
26+
// You can imagine an even more dangerous test,
27+
// which currently compiles on nightly.
28+
//
29+
// fn main() {
30+
// let mut i = 10;
31+
// let (a, b) = copy(&mut i);
32+
// println!("{:?} {:?}", a, b);
33+
// }
34+
35+
#![feature(optin_builtin_traits)]
36+
37+
trait Magic: Copy {} //~ ERROR E0565
38+
impl Magic for .. {}
39+
impl<T:Magic> Magic for T {}
40+
41+
fn copy<T: Magic>(x: T) -> (T, T) { (x, x) }
42+
43+
#[derive(Debug)]
44+
struct NoClone;
45+
46+
fn main() {
47+
let (a, b) = copy(NoClone);
48+
println!("{:?} {:?}", a, b);
49+
}

src/test/compile-fail/issue-29859-2.rs renamed to src/test/compile-fail/typeck-auto-trait-no-typeparams.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,5 @@
1010

1111
#![feature(optin_builtin_traits)]
1212

13-
trait Magic<T> {} //~ E0566
13+
trait Magic<T> {} //~ ERROR E0566
1414
impl Magic<isize> for .. {}

src/test/compile-fail/typeck-default-trait-impl-superregion.rs

-27
This file was deleted.

src/test/compile-fail/typeck-default-trait-impl-supertrait.rs

-29
This file was deleted.

src/test/compile-fail/typeck-default-trait-impl-trait-where-clause-2.rs

-36
This file was deleted.

0 commit comments

Comments
 (0)