mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-23 12:23:22 +00:00
Parse and suggest moving where clauses after equals for type aliases
This commit is contained in:
parent
e95e084a14
commit
4391a11537
@ -2780,34 +2780,34 @@ impl<'a> State<'a> {
|
||||
self.word_space(",");
|
||||
}
|
||||
|
||||
match *predicate {
|
||||
ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate {
|
||||
ref bound_generic_params,
|
||||
ref bounded_ty,
|
||||
ref bounds,
|
||||
..
|
||||
}) => {
|
||||
self.print_formal_generic_params(bound_generic_params);
|
||||
self.print_type(bounded_ty);
|
||||
self.print_type_bounds(":", bounds);
|
||||
}
|
||||
ast::WherePredicate::RegionPredicate(ast::WhereRegionPredicate {
|
||||
ref lifetime,
|
||||
ref bounds,
|
||||
..
|
||||
}) => {
|
||||
self.print_lifetime_bounds(*lifetime, bounds);
|
||||
}
|
||||
ast::WherePredicate::EqPredicate(ast::WhereEqPredicate {
|
||||
ref lhs_ty,
|
||||
ref rhs_ty,
|
||||
..
|
||||
}) => {
|
||||
self.print_type(lhs_ty);
|
||||
self.space();
|
||||
self.word_space("=");
|
||||
self.print_type(rhs_ty);
|
||||
}
|
||||
self.print_where_predicate(predicate);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn print_where_predicate(&mut self, predicate: &ast::WherePredicate) {
|
||||
match predicate {
|
||||
ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate {
|
||||
bound_generic_params,
|
||||
bounded_ty,
|
||||
bounds,
|
||||
..
|
||||
}) => {
|
||||
self.print_formal_generic_params(bound_generic_params);
|
||||
self.print_type(bounded_ty);
|
||||
self.print_type_bounds(":", bounds);
|
||||
}
|
||||
ast::WherePredicate::RegionPredicate(ast::WhereRegionPredicate {
|
||||
lifetime,
|
||||
bounds,
|
||||
..
|
||||
}) => {
|
||||
self.print_lifetime_bounds(*lifetime, bounds);
|
||||
}
|
||||
ast::WherePredicate::EqPredicate(ast::WhereEqPredicate { lhs_ty, rhs_ty, .. }) => {
|
||||
self.print_type(lhs_ty);
|
||||
self.space();
|
||||
self.word_space("=");
|
||||
self.print_type(rhs_ty);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -794,6 +794,44 @@ impl<'a> Parser<'a> {
|
||||
))
|
||||
}
|
||||
|
||||
/// Emits an error that the where clause at the end of a type alias is not
|
||||
/// allowed and suggests moving it.
|
||||
fn error_ty_alias_where(
|
||||
&self,
|
||||
before_where_clause_present: bool,
|
||||
before_where_clause_span: Span,
|
||||
after_predicates: &[WherePredicate],
|
||||
after_where_clause_span: Span,
|
||||
) {
|
||||
let mut err =
|
||||
self.struct_span_err(after_where_clause_span, "where clause not allowed here");
|
||||
if !after_predicates.is_empty() {
|
||||
let mut state = crate::pprust::State::new();
|
||||
if !before_where_clause_present {
|
||||
state.space();
|
||||
state.word_space("where");
|
||||
} else {
|
||||
state.word_space(",");
|
||||
}
|
||||
let mut first = true;
|
||||
for p in after_predicates.iter() {
|
||||
if !first {
|
||||
state.word_space(",");
|
||||
}
|
||||
first = false;
|
||||
state.print_where_predicate(p);
|
||||
}
|
||||
let suggestion = state.s.eof();
|
||||
err.span_suggestion(
|
||||
before_where_clause_span.shrink_to_hi(),
|
||||
"move it here",
|
||||
suggestion,
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
}
|
||||
err.emit()
|
||||
}
|
||||
|
||||
/// Parses a `type` alias with the following grammar:
|
||||
/// ```
|
||||
/// TypeAlias = "type" Ident Generics {":" GenericBounds}? {"=" Ty}? ";" ;
|
||||
@ -806,9 +844,24 @@ impl<'a> Parser<'a> {
|
||||
// Parse optional colon and param bounds.
|
||||
let bounds =
|
||||
if self.eat(&token::Colon) { self.parse_generic_bounds(None)? } else { Vec::new() };
|
||||
|
||||
generics.where_clause = self.parse_where_clause()?;
|
||||
|
||||
let ty = if self.eat(&token::Eq) { Some(self.parse_ty()?) } else { None };
|
||||
|
||||
if self.token.is_keyword(kw::Where) {
|
||||
let after_where_clause = self.parse_where_clause()?;
|
||||
|
||||
self.error_ty_alias_where(
|
||||
generics.where_clause.has_where_token,
|
||||
generics.where_clause.span,
|
||||
&after_where_clause.predicates,
|
||||
after_where_clause.span,
|
||||
);
|
||||
|
||||
generics.where_clause.predicates.extend(after_where_clause.predicates.into_iter());
|
||||
}
|
||||
|
||||
self.expect_semi()?;
|
||||
|
||||
Ok((ident, ItemKind::TyAlias(Box::new(TyAlias { defaultness, generics, bounds, ty }))))
|
||||
|
37
src/test/ui/parser/type-alias-where.rs
Normal file
37
src/test/ui/parser/type-alias-where.rs
Normal file
@ -0,0 +1,37 @@
|
||||
// check-fail
|
||||
|
||||
#![feature(generic_associated_types)]
|
||||
|
||||
// Fine, but lints as unused
|
||||
type Foo where u32: Copy = ();
|
||||
// Not fine.
|
||||
type Bar = () where u32: Copy;
|
||||
//~^ ERROR where clause not allowed here
|
||||
type Baz = () where;
|
||||
//~^ ERROR where clause not allowed here
|
||||
|
||||
trait Trait {
|
||||
// Fine.
|
||||
type Assoc where u32: Copy;
|
||||
// Fine.
|
||||
type Assoc2 where u32: Copy, i32: Copy;
|
||||
}
|
||||
|
||||
impl Trait for u32 {
|
||||
// Fine.
|
||||
type Assoc where u32: Copy = ();
|
||||
// Not fine, suggests moving `i32: Copy`
|
||||
type Assoc2 where u32: Copy = () where i32: Copy;
|
||||
//~^ ERROR where clause not allowed here
|
||||
}
|
||||
|
||||
impl Trait for i32 {
|
||||
// Not fine, suggests moving `u32: Copy`
|
||||
type Assoc = () where u32: Copy;
|
||||
//~^ ERROR where clause not allowed here
|
||||
// Not fine, suggests moving both.
|
||||
type Assoc2 = () where u32: Copy, i32: Copy;
|
||||
//~^ ERROR where clause not allowed here
|
||||
}
|
||||
|
||||
fn main() {}
|
40
src/test/ui/parser/type-alias-where.stderr
Normal file
40
src/test/ui/parser/type-alias-where.stderr
Normal file
@ -0,0 +1,40 @@
|
||||
error: where clause not allowed here
|
||||
--> $DIR/type-alias-where.rs:8:15
|
||||
|
|
||||
LL | type Bar = () where u32: Copy;
|
||||
| - ^^^^^^^^^^^^^^^
|
||||
| |
|
||||
| help: move it here: `where u32: Copy`
|
||||
|
||||
error: where clause not allowed here
|
||||
--> $DIR/type-alias-where.rs:10:15
|
||||
|
|
||||
LL | type Baz = () where;
|
||||
| ^^^^^
|
||||
|
||||
error: where clause not allowed here
|
||||
--> $DIR/type-alias-where.rs:24:38
|
||||
|
|
||||
LL | type Assoc2 where u32: Copy = () where i32: Copy;
|
||||
| - ^^^^^^^^^^^^^^^
|
||||
| |
|
||||
| help: move it here: `, i32: Copy`
|
||||
|
||||
error: where clause not allowed here
|
||||
--> $DIR/type-alias-where.rs:30:21
|
||||
|
|
||||
LL | type Assoc = () where u32: Copy;
|
||||
| - ^^^^^^^^^^^^^^^
|
||||
| |
|
||||
| help: move it here: `where u32: Copy`
|
||||
|
||||
error: where clause not allowed here
|
||||
--> $DIR/type-alias-where.rs:33:22
|
||||
|
|
||||
LL | type Assoc2 = () where u32: Copy, i32: Copy;
|
||||
| - ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
| |
|
||||
| help: move it here: `where u32: Copy, i32: Copy`
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
|
Loading…
Reference in New Issue
Block a user