Skip to content

Commit 2e64bb2

Browse files
committed
syntax: reject trait Foo: Bar = Baz;.
Add test for rejecting `trait A: B1 = B2;`. Also test rejection of `trait A: = B;`.
1 parent 4a8c5b2 commit 2e64bb2

File tree

3 files changed

+40
-13
lines changed

3 files changed

+40
-13
lines changed

src/libsyntax/parse/parser/item.rs

+20-8
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ impl<'a> Parser<'a> {
211211
{
212212
// UNSAFE TRAIT ITEM
213213
self.bump(); // `unsafe`
214-
let info = self.parse_item_trait(Unsafety::Unsafe)?;
214+
let info = self.parse_item_trait(lo, Unsafety::Unsafe)?;
215215
return self.mk_item_with_info(attrs, lo, vis, info);
216216
}
217217

@@ -289,7 +289,7 @@ impl<'a> Parser<'a> {
289289
&& self.is_keyword_ahead(1, &[kw::Trait]))
290290
{
291291
// TRAIT ITEM
292-
let info = self.parse_item_trait(Unsafety::Normal)?;
292+
let info = self.parse_item_trait(lo, Unsafety::Normal)?;
293293
return self.mk_item_with_info(attrs, lo, vis, info);
294294
}
295295

@@ -780,7 +780,7 @@ impl<'a> Parser<'a> {
780780
}
781781

782782
/// Parses `auto? trait Foo { ... }` or `trait Foo = Bar;`.
783-
fn parse_item_trait(&mut self, unsafety: Unsafety) -> PResult<'a, ItemInfo> {
783+
fn parse_item_trait(&mut self, lo: Span, unsafety: Unsafety) -> PResult<'a, ItemInfo> {
784784
// Parse optional `auto` prefix.
785785
let is_auto = if self.eat_keyword(kw::Auto) {
786786
IsAuto::Yes
@@ -793,29 +793,41 @@ impl<'a> Parser<'a> {
793793
let mut tps = self.parse_generics()?;
794794

795795
// Parse optional colon and supertrait bounds.
796-
let bounds = if self.eat(&token::Colon) {
796+
let had_colon = self.eat(&token::Colon);
797+
let span_at_colon = self.prev_span;
798+
let bounds = if had_colon {
797799
self.parse_generic_bounds(Some(self.prev_span))?
798800
} else {
799801
Vec::new()
800802
};
801803

804+
let span_before_eq = self.prev_span;
802805
if self.eat(&token::Eq) {
803806
// It's a trait alias.
807+
if had_colon {
808+
let span = span_at_colon.to(span_before_eq);
809+
self.struct_span_err(span, "bounds are not allowed on trait aliases")
810+
.emit();
811+
}
812+
804813
let bounds = self.parse_generic_bounds(None)?;
805814
tps.where_clause = self.parse_where_clause()?;
806815
self.expect(&token::Semi)?;
816+
817+
let whole_span = lo.to(self.prev_span);
807818
if is_auto == IsAuto::Yes {
808819
let msg = "trait aliases cannot be `auto`";
809-
self.struct_span_err(self.prev_span, msg)
810-
.span_label(self.prev_span, msg)
820+
self.struct_span_err(whole_span, msg)
821+
.span_label(whole_span, msg)
811822
.emit();
812823
}
813824
if unsafety != Unsafety::Normal {
814825
let msg = "trait aliases cannot be `unsafe`";
815-
self.struct_span_err(self.prev_span, msg)
816-
.span_label(self.prev_span, msg)
826+
self.struct_span_err(whole_span, msg)
827+
.span_label(whole_span, msg)
817828
.emit();
818829
}
830+
819831
Ok((ident, ItemKind::TraitAlias(tps, bounds), None))
820832
} else {
821833
// It's a normal trait.

src/test/ui/traits/trait-alias/trait-alias-syntax-fail.rs

+3
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,7 @@ trait Foo {}
44
auto trait A = Foo; //~ ERROR trait aliases cannot be `auto`
55
unsafe trait B = Foo; //~ ERROR trait aliases cannot be `unsafe`
66

7+
trait C: Ord = Eq; //~ ERROR bounds are not allowed on trait aliases
8+
trait D: = Eq; //~ ERROR bounds are not allowed on trait aliases
9+
710
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,26 @@
11
error: trait aliases cannot be `auto`
2-
--> $DIR/trait-alias-syntax-fail.rs:4:19
2+
--> $DIR/trait-alias-syntax-fail.rs:4:1
33
|
44
LL | auto trait A = Foo;
5-
| ^ trait aliases cannot be `auto`
5+
| ^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `auto`
66

77
error: trait aliases cannot be `unsafe`
8-
--> $DIR/trait-alias-syntax-fail.rs:5:21
8+
--> $DIR/trait-alias-syntax-fail.rs:5:1
99
|
1010
LL | unsafe trait B = Foo;
11-
| ^ trait aliases cannot be `unsafe`
11+
| ^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `unsafe`
1212

13-
error: aborting due to 2 previous errors
13+
error: bounds are not allowed on trait aliases
14+
--> $DIR/trait-alias-syntax-fail.rs:7:8
15+
|
16+
LL | trait C: Ord = Eq;
17+
| ^^^^^
18+
19+
error: bounds are not allowed on trait aliases
20+
--> $DIR/trait-alias-syntax-fail.rs:8:8
21+
|
22+
LL | trait D: = Eq;
23+
| ^
24+
25+
error: aborting due to 4 previous errors
1426

0 commit comments

Comments
 (0)