Skip to content

Commit 352fac9

Browse files
committed
Reject certain auto trait declarations
Fixes #29859
1 parent f18c990 commit 352fac9

File tree

5 files changed

+70
-16
lines changed

5 files changed

+70
-16
lines changed

src/librustc/ty/mod.rs

+10
Original file line numberDiff line numberDiff line change
@@ -762,6 +762,16 @@ 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+
765775
pub fn instantiate(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, substs: &Substs<'tcx>)
766776
-> InstantiatedPredicates<'tcx> {
767777
let mut instantiated = InstantiatedPredicates::empty();

src/librustc_typeck/check/wfcheck.rs

+53
Original file line numberDiff line numberDiff line change
@@ -251,16 +251,55 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> {
251251
});
252252
}
253253

254+
fn check_auto_trait(&mut self,
255+
trait_def_id: DefId,
256+
span: Span)
257+
{
258+
let predicates = self.tcx().lookup_predicates(trait_def_id);
259+
260+
// If we must exclude the Self : Trait predicate contained by all
261+
// 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,
267+
_ => true,
268+
}
269+
}).collect();
270+
271+
let trait_def = self.tcx().lookup_trait_def(trait_def_id);
272+
273+
// We use an if-else here, since the generics will also trigger
274+
// an extraneous error message when we find predicates like
275+
// `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);
280+
}
281+
282+
}
283+
254284
fn check_trait(&mut self,
255285
item: &hir::Item,
256286
items: &[hir::TraitItem])
257287
{
258288
let trait_def_id = self.tcx().map.local_def_id(item.id);
259289

260290
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+
261298
if !items.is_empty() {
262299
error_380(self.ccx, item.span);
263300
}
301+
302+
self.check_auto_trait(trait_def_id, item.span);
264303
}
265304

266305
self.for_item(item).with_fcx(|fcx, this| {
@@ -272,6 +311,8 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> {
272311
});
273312
}
274313

314+
315+
275316
fn check_item_fn(&mut self,
276317
item: &hir::Item,
277318
body: &hir::Block)
@@ -637,6 +678,18 @@ fn error_380(ccx: &CrateCtxt, span: Span) {
637678
Trait for ..`) must have no methods or associated items")
638679
}
639680

681+
fn error_565(ccx: &CrateCtxt, span: Span) {
682+
span_err!(ccx.tcx.sess, span, E0565,
683+
"traits with default impls (`e.g. unsafe impl \
684+
Trait for ..`) can not have predicates")
685+
}
686+
687+
fn error_566(ccx: &CrateCtxt, span: Span) {
688+
span_err!(ccx.tcx.sess, span, E0566,
689+
"traits with default impls (`e.g. unsafe impl \
690+
Trait for ..`) can not have type parameters")
691+
}
692+
640693
fn error_392<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, span: Span, param_name: ast::Name)
641694
-> DiagnosticBuilder<'tcx> {
642695
let mut err = struct_span_err!(ccx.tcx.sess, span, E0392,

src/librustc_typeck/diagnostics.rs

+2
Original file line numberDiff line numberDiff line change
@@ -4072,4 +4072,6 @@ register_diagnostics! {
40724072
E0563, // cannot determine a type for this `impl Trait`: {}
40734073
E0564, // only named lifetimes are allowed in `impl Trait`,
40744074
// but `{}` was found in the type `{}`
4075+
E0565, // auto-traits can not have predicates,
4076+
E0566, // auto traits can not have type parameters
40754077
}

src/test/compile-fail/issue-29859-2.rs

+2-13
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,5 @@
1010

1111
#![feature(optin_builtin_traits)]
1212

13-
trait Magic: Copy {}
14-
impl Magic for .. {}
15-
impl<T:Magic> Magic for T {}
16-
17-
fn copy<T: Magic>(x: T) -> (T, T) { (x, x) }
18-
19-
#[derive(Debug)]
20-
struct NoClone;
21-
22-
fn main() {
23-
let (a, b) = copy(NoClone); //~ ERROR E0277
24-
println!("{:?} {:?}", a, b);
25-
}
13+
trait Magic<T> {} //~ E0566
14+
impl Magic<isize> for .. {}

src/test/compile-fail/issue-29859.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010

1111
#![feature(optin_builtin_traits)]
1212

13-
trait Magic: Copy {}
14-
impl Magic for .. {}
13+
trait Magic: Copy {} //~ ERROR E0565
14+
impl Magic for .. {}
1515
impl<T:Magic> Magic for T {}
1616

1717
fn copy<T: Magic>(x: T) -> (T, T) { (x, x) }
@@ -20,6 +20,6 @@ fn copy<T: Magic>(x: T) -> (T, T) { (x, x) }
2020
struct NoClone;
2121

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

0 commit comments

Comments
 (0)