From 91194f795c3ce323b50b5caa30c089ec026200f0 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sun, 22 Mar 2020 04:40:05 +0100 Subject: [PATCH] parse: move constraint/arg restriction to ast_validation. --- src/librustc_ast/ast.rs | 29 +++-- src/librustc_ast/mut_visit.rs | 8 +- src/librustc_ast/visit.rs | 8 +- src/librustc_ast_lowering/lib.rs | 1 + src/librustc_ast_lowering/path.rs | 35 ++--- src/librustc_ast_passes/ast_validation.rs | 54 ++++++-- src/librustc_ast_passes/lib.rs | 4 +- src/librustc_ast_pretty/pprust.rs | 41 +++--- src/librustc_expand/build.rs | 3 +- src/librustc_interface/util.rs | 16 ++- src/librustc_parse/parser/path.rs | 76 ++++------- src/librustc_save_analysis/dump_visitor.rs | 4 +- ...ints-before-generic-args-syntactic-pass.rs | 9 ++ src/test/ui/parser/issue-32214.rs | 2 +- src/test/ui/parser/issue-32214.stderr | 11 +- src/test/ui/suggestions/suggest-move-types.rs | 22 ++-- .../ui/suggestions/suggest-move-types.stderr | 122 ++++++++++-------- 17 files changed, 246 insertions(+), 199 deletions(-) create mode 100644 src/test/ui/parser/constraints-before-generic-args-syntactic-pass.rs diff --git a/src/librustc_ast/ast.rs b/src/librustc_ast/ast.rs index 646294a7cca7..6586280d2145 100644 --- a/src/librustc_ast/ast.rs +++ b/src/librustc_ast/ast.rs @@ -214,11 +214,18 @@ impl GenericArg { pub struct AngleBracketedArgs { /// The overall span. pub span: Span, - /// The arguments for this path segment. - pub args: Vec, - /// Constraints on associated types, if any. - /// E.g., `Foo`. - pub constraints: Vec, + /// The comma separated parts in the `<...>`. + pub args: Vec, +} + +/// Either an argument for a parameter e.g., `'a`, `Vec`, `0`, +/// or a constraint on an associated item, e.g., `Item = String` or `Item: Bound`. +#[derive(Clone, RustcEncodable, RustcDecodable, Debug)] +pub enum AngleBracketedArg { + /// Argument for a generic parameter. + Arg(GenericArg), + /// Constraint for an associated item. + Constraint(AssocTyConstraint), } impl Into>> for AngleBracketedArgs { @@ -248,11 +255,13 @@ pub struct ParenthesizedArgs { impl ParenthesizedArgs { pub fn as_angle_bracketed_args(&self) -> AngleBracketedArgs { - AngleBracketedArgs { - span: self.span, - args: self.inputs.iter().cloned().map(GenericArg::Type).collect(), - constraints: vec![], - } + let args = self + .inputs + .iter() + .cloned() + .map(|input| AngleBracketedArg::Arg(GenericArg::Type(input))) + .collect(); + AngleBracketedArgs { span: self.span, args } } } diff --git a/src/librustc_ast/mut_visit.rs b/src/librustc_ast/mut_visit.rs index 67f7764d5bb2..a72a60c30b28 100644 --- a/src/librustc_ast/mut_visit.rs +++ b/src/librustc_ast/mut_visit.rs @@ -546,9 +546,11 @@ pub fn noop_visit_angle_bracketed_parameter_data( data: &mut AngleBracketedArgs, vis: &mut T, ) { - let AngleBracketedArgs { args, constraints, span } = data; - visit_vec(args, |arg| vis.visit_generic_arg(arg)); - visit_vec(constraints, |constraint| vis.visit_ty_constraint(constraint)); + let AngleBracketedArgs { args, span } = data; + visit_vec(args, |arg| match arg { + AngleBracketedArg::Arg(arg) => vis.visit_generic_arg(arg), + AngleBracketedArg::Constraint(constraint) => vis.visit_ty_constraint(constraint), + }); vis.visit_span(span); } diff --git a/src/librustc_ast/visit.rs b/src/librustc_ast/visit.rs index cc2b1c48b51a..51863350a8cf 100644 --- a/src/librustc_ast/visit.rs +++ b/src/librustc_ast/visit.rs @@ -464,8 +464,12 @@ where { match *generic_args { GenericArgs::AngleBracketed(ref data) => { - walk_list!(visitor, visit_generic_arg, &data.args); - walk_list!(visitor, visit_assoc_ty_constraint, &data.constraints); + for arg in &data.args { + match arg { + AngleBracketedArg::Arg(a) => visitor.visit_generic_arg(a), + AngleBracketedArg::Constraint(c) => visitor.visit_assoc_ty_constraint(c), + } + } } GenericArgs::Parenthesized(ref data) => { walk_list!(visitor, visit_ty, &data.inputs); diff --git a/src/librustc_ast_lowering/lib.rs b/src/librustc_ast_lowering/lib.rs index 68cb1f8585fc..45ee7265c15f 100644 --- a/src/librustc_ast_lowering/lib.rs +++ b/src/librustc_ast_lowering/lib.rs @@ -34,6 +34,7 @@ #![feature(crate_visibility_modifier)] #![feature(marker_trait_attr)] #![feature(specialization)] +#![feature(or_patterns)] #![recursion_limit = "256"] use rustc_ast::ast; diff --git a/src/librustc_ast_lowering/path.rs b/src/librustc_ast_lowering/path.rs index e996bdac7cb3..f15a4555e5f1 100644 --- a/src/librustc_ast_lowering/path.rs +++ b/src/librustc_ast_lowering/path.rs @@ -366,22 +366,27 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { param_mode: ParamMode, mut itctx: ImplTraitContext<'_, 'hir>, ) -> (GenericArgsCtor<'hir>, bool) { - let &AngleBracketedArgs { ref args, ref constraints, .. } = data; - let has_non_lt_args = args.iter().any(|arg| match arg { - ast::GenericArg::Lifetime(_) => false, - ast::GenericArg::Type(_) => true, - ast::GenericArg::Const(_) => true, + let has_non_lt_args = data.args.iter().any(|arg| match arg { + AngleBracketedArg::Arg(ast::GenericArg::Lifetime(_)) => false, + AngleBracketedArg::Arg(ast::GenericArg::Type(_) | ast::GenericArg::Const(_)) + | AngleBracketedArg::Constraint(_) => true, }); - ( - GenericArgsCtor { - args: args.iter().map(|a| self.lower_generic_arg(a, itctx.reborrow())).collect(), - bindings: self.arena.alloc_from_iter( - constraints.iter().map(|b| self.lower_assoc_ty_constraint(b, itctx.reborrow())), - ), - parenthesized: false, - }, - !has_non_lt_args && param_mode == ParamMode::Optional, - ) + let args = data + .args + .iter() + .filter_map(|arg| match arg { + AngleBracketedArg::Arg(arg) => Some(self.lower_generic_arg(arg, itctx.reborrow())), + AngleBracketedArg::Constraint(_) => None, + }) + .collect(); + let bindings = self.arena.alloc_from_iter(data.args.iter().filter_map(|arg| match arg { + AngleBracketedArg::Constraint(c) => { + Some(self.lower_assoc_ty_constraint(c, itctx.reborrow())) + } + AngleBracketedArg::Arg(_) => None, + })); + let ctor = GenericArgsCtor { args, bindings, parenthesized: false }; + (ctor, !has_non_lt_args && param_mode == ParamMode::Optional) } fn lower_parenthesized_parameter_data( diff --git a/src/librustc_ast_passes/ast_validation.rs b/src/librustc_ast_passes/ast_validation.rs index 885f2f939a65..e6f09a3a6cba 100644 --- a/src/librustc_ast_passes/ast_validation.rs +++ b/src/librustc_ast_passes/ast_validation.rs @@ -639,6 +639,37 @@ impl<'a> AstValidator<'a> { .emit(); } } + + /// Enforce generic args coming before constraints in `<...>` of a path segment. + fn check_generic_args_before_constraints(&self, data: &AngleBracketedArgs) { + // Early exit in case it's partitioned as it should be. + if data.args.iter().is_partitioned(|arg| matches!(arg, AngleBracketedArg::Arg(_))) { + return; + } + // Find all generic argument coming after the first constraint... + let mut misplaced_args = Vec::new(); + let mut first = None; + for arg in &data.args { + match (arg, first) { + (AngleBracketedArg::Arg(a), Some(_)) => misplaced_args.push(a.span()), + (AngleBracketedArg::Constraint(c), None) => first = Some(c.span), + (AngleBracketedArg::Arg(_), None) | (AngleBracketedArg::Constraint(_), Some(_)) => { + } + } + } + // ...and then error: + self.err_handler() + .struct_span_err( + data.span, + "constraints in a path segment must come after generic arguments", + ) + .span_labels( + misplaced_args, + "this generic argument must come before the first constraint", + ) + .span_label(first.unwrap(), "the first constraint is provided here") + .emit(); + } } /// Checks that generic parameters are in the correct order, @@ -1008,17 +1039,20 @@ impl<'a> Visitor<'a> for AstValidator<'a> { fn visit_generic_args(&mut self, _: Span, generic_args: &'a GenericArgs) { match *generic_args { GenericArgs::AngleBracketed(ref data) => { - walk_list!(self, visit_generic_arg, &data.args); + self.check_generic_args_before_constraints(data); - // Type bindings such as `Item = impl Debug` in `Iterator` - // are allowed to contain nested `impl Trait`. - self.with_impl_trait(None, |this| { - walk_list!( - this, - visit_assoc_ty_constraint_from_generic_args, - &data.constraints - ); - }); + for arg in &data.args { + match arg { + AngleBracketedArg::Arg(arg) => self.visit_generic_arg(arg), + // Type bindings such as `Item = impl Debug` in `Iterator` + // are allowed to contain nested `impl Trait`. + AngleBracketedArg::Constraint(constraint) => { + self.with_impl_trait(None, |this| { + this.visit_assoc_ty_constraint_from_generic_args(constraint); + }); + } + } + } } GenericArgs::Parenthesized(ref data) => { walk_list!(self, visit_ty, &data.inputs); diff --git a/src/librustc_ast_passes/lib.rs b/src/librustc_ast_passes/lib.rs index 10081d36754b..bfe304419801 100644 --- a/src/librustc_ast_passes/lib.rs +++ b/src/librustc_ast_passes/lib.rs @@ -1,10 +1,12 @@ -#![feature(bindings_after_at)] //! The `rustc_ast_passes` crate contains passes which validate the AST in `syntax` //! parsed by `rustc_parse` and then lowered, after the passes in this crate, //! by `rustc_ast_lowering`. //! //! The crate also contains other misc AST visitors, e.g. `node_count` and `show_span`. +#![feature(bindings_after_at)] +#![feature(iter_is_partitioned)] + pub mod ast_validation; pub mod feature_gate; pub mod node_count; diff --git a/src/librustc_ast_pretty/pprust.rs b/src/librustc_ast_pretty/pprust.rs index 2d6932ffbeed..4aabbe7efbef 100644 --- a/src/librustc_ast_pretty/pprust.rs +++ b/src/librustc_ast_pretty/pprust.rs @@ -796,31 +796,10 @@ impl<'a> PrintState<'a> for State<'a> { match *args { ast::GenericArgs::AngleBracketed(ref data) => { self.s.word("<"); - - self.commasep(Inconsistent, &data.args, |s, generic_arg| { - s.print_generic_arg(generic_arg) + self.commasep(Inconsistent, &data.args, |s, arg| match arg { + ast::AngleBracketedArg::Arg(a) => s.print_generic_arg(a), + ast::AngleBracketedArg::Constraint(c) => s.print_assoc_constraint(c), }); - - let mut comma = !data.args.is_empty(); - - for constraint in data.constraints.iter() { - if comma { - self.word_space(",") - } - self.print_ident(constraint.ident); - self.s.space(); - match constraint.kind { - ast::AssocTyConstraintKind::Equality { ref ty } => { - self.word_space("="); - self.print_type(ty); - } - ast::AssocTyConstraintKind::Bound { ref bounds } => { - self.print_type_bounds(":", &*bounds); - } - } - comma = true; - } - self.s.word(">") } @@ -891,6 +870,20 @@ impl<'a> State<'a> { } } + fn print_assoc_constraint(&mut self, constraint: &ast::AssocTyConstraint) { + self.print_ident(constraint.ident); + self.s.space(); + match &constraint.kind { + ast::AssocTyConstraintKind::Equality { ty } => { + self.word_space("="); + self.print_type(ty); + } + ast::AssocTyConstraintKind::Bound { bounds } => { + self.print_type_bounds(":", &*bounds); + } + } + } + crate fn print_generic_arg(&mut self, generic_arg: &GenericArg) { match generic_arg { GenericArg::Lifetime(lt) => self.print_lifetime(*lt), diff --git a/src/librustc_expand/build.rs b/src/librustc_expand/build.rs index 48ceaf5fccd8..4d89bf79e7c6 100644 --- a/src/librustc_expand/build.rs +++ b/src/librustc_expand/build.rs @@ -36,7 +36,8 @@ impl<'a> ExtCtxt<'a> { idents.into_iter().map(|ident| ast::PathSegment::from_ident(ident.with_span_pos(span))), ); let args = if !args.is_empty() { - ast::AngleBracketedArgs { args, constraints: Vec::new(), span }.into() + let args = args.into_iter().map(ast::AngleBracketedArg::Arg).collect(); + ast::AngleBracketedArgs { args, span }.into() } else { None }; diff --git a/src/librustc_interface/util.rs b/src/librustc_interface/util.rs index c6f2d1b82fcf..eff7dacef795 100644 --- a/src/librustc_interface/util.rs +++ b/src/librustc_interface/util.rs @@ -634,17 +634,19 @@ impl<'a, 'b> ReplaceBodyWithLoop<'a, 'b> { match seg.args.as_ref().map(|generic_arg| &**generic_arg) { None => false, Some(&ast::GenericArgs::AngleBracketed(ref data)) => { - let types = data.args.iter().filter_map(|arg| match arg { - ast::GenericArg::Type(ty) => Some(ty), - _ => None, - }); - any_involves_impl_trait(types) - || data.constraints.iter().any(|c| match c.kind { + data.args.iter().any(|arg| match arg { + ast::AngleBracketedArg::Arg(arg) => match arg { + ast::GenericArg::Type(ty) => involves_impl_trait(ty), + ast::GenericArg::Lifetime(_) + | ast::GenericArg::Const(_) => false, + }, + ast::AngleBracketedArg::Constraint(c) => match c.kind { ast::AssocTyConstraintKind::Bound { .. } => true, ast::AssocTyConstraintKind::Equality { ref ty } => { involves_impl_trait(ty) } - }) + }, + }) } Some(&ast::GenericArgs::Parenthesized(ref data)) => { any_involves_impl_trait(data.inputs.iter()) diff --git a/src/librustc_parse/parser/path.rs b/src/librustc_parse/parser/path.rs index f88b4fe6ff0a..2320dcba33c9 100644 --- a/src/librustc_parse/parser/path.rs +++ b/src/librustc_parse/parser/path.rs @@ -1,12 +1,9 @@ use super::ty::{AllowPlus, RecoverQPath}; use super::{Parser, TokenType}; use crate::maybe_whole; -use rustc_ast::ast::{ - self, AngleBracketedArgs, Ident, ParenthesizedArgs, Path, PathSegment, QSelf, -}; -use rustc_ast::ast::{ - AnonConst, AssocTyConstraint, AssocTyConstraintKind, BlockCheckMode, GenericArg, -}; +use rustc_ast::ast::{self, AngleBracketedArg, AngleBracketedArgs, GenericArg, ParenthesizedArgs}; +use rustc_ast::ast::{AnonConst, AssocTyConstraint, AssocTyConstraintKind, BlockCheckMode}; +use rustc_ast::ast::{Ident, Path, PathSegment, QSelf}; use rustc_ast::token::{self, Token}; use rustc_errors::{pluralize, Applicability, PResult}; use rustc_span::source_map::{BytePos, Span}; @@ -218,11 +215,11 @@ impl<'a> Parser<'a> { let lo = self.token.span; let args = if self.eat_lt() { // `<'a, T, A = U>` - let (args, constraints) = - self.parse_generic_args_with_leading_angle_bracket_recovery(style, lo)?; + let args = + self.parse_angle_args_with_leading_angle_bracket_recovery(style, lo)?; self.expect_gt()?; let span = lo.to(self.prev_token.span); - AngleBracketedArgs { args, constraints, span }.into() + AngleBracketedArgs { args, span }.into() } else { // `(T, U) -> R` let (inputs, _) = self.parse_paren_comma_seq(|p| p.parse_ty())?; @@ -251,18 +248,18 @@ impl<'a> Parser<'a> { /// Parses generic args (within a path segment) with recovery for extra leading angle brackets. /// For the purposes of understanding the parsing logic of generic arguments, this function - /// can be thought of being the same as just calling `self.parse_generic_args()` if the source + /// can be thought of being the same as just calling `self.parse_angle_args()` if the source /// had the correct amount of leading angle brackets. /// /// ```ignore (diagnostics) /// bar::<<<::Output>(); /// ^^ help: remove extra angle brackets /// ``` - fn parse_generic_args_with_leading_angle_bracket_recovery( + fn parse_angle_args_with_leading_angle_bracket_recovery( &mut self, style: PathStyle, lo: Span, - ) -> PResult<'a, (Vec, Vec)> { + ) -> PResult<'a, Vec> { // We need to detect whether there are extra leading left angle brackets and produce an // appropriate error and suggestion. This cannot be implemented by looking ahead at // upcoming tokens for a matching `>` character - if there are unmatched `<` tokens @@ -337,8 +334,8 @@ impl<'a> Parser<'a> { let snapshot = if is_first_invocation { Some(self.clone()) } else { None }; debug!("parse_generic_args_with_leading_angle_bracket_recovery: (snapshotting)"); - match self.parse_generic_args() { - Ok(value) => Ok(value), + match self.parse_angle_args() { + Ok(args) => Ok(args), Err(ref mut e) if is_first_invocation && self.unmatched_angle_bracket_count > 0 => { // Cancel error from being unable to find `>`. We know the error // must have been this due to a non-zero unmatched angle bracket @@ -381,29 +378,22 @@ impl<'a> Parser<'a> { .emit(); // Try again without unmatched angle bracket characters. - self.parse_generic_args() + self.parse_angle_args() } Err(e) => Err(e), } } - /// Parses (possibly empty) list of lifetime and type arguments and associated type bindings, + /// Parses (possibly empty) list of generic arguments / associated item constraints, /// possibly including trailing comma. - fn parse_generic_args(&mut self) -> PResult<'a, (Vec, Vec)> { + fn parse_angle_args(&mut self) -> PResult<'a, Vec> { let mut args = Vec::new(); - let mut constraints = Vec::new(); - let mut misplaced_assoc_ty_constraints: Vec = Vec::new(); - let mut assoc_ty_constraints: Vec = Vec::new(); - - let args_lo = self.token.span; - loop { if self.check_lifetime() && self.look_ahead(1, |t| !t.is_like_plus()) { // Parse lifetime argument. - args.push(GenericArg::Lifetime(self.expect_lifetime())); - misplaced_assoc_ty_constraints.append(&mut assoc_ty_constraints); + args.push(AngleBracketedArg::Arg(GenericArg::Lifetime(self.expect_lifetime()))); } else if self.check_ident() - && self.look_ahead(1, |t| t == &token::Eq || t == &token::Colon) + && self.look_ahead(1, |t| matches!(t.kind, token::Eq | token::Colon)) { // Parse associated type constraint. let lo = self.token.span; @@ -411,9 +401,8 @@ impl<'a> Parser<'a> { let kind = if self.eat(&token::Eq) { AssocTyConstraintKind::Equality { ty: self.parse_ty()? } } else if self.eat(&token::Colon) { - AssocTyConstraintKind::Bound { - bounds: self.parse_generic_bounds(Some(self.prev_token.span))?, - } + let bounds = self.parse_generic_bounds(Some(self.prev_token.span))?; + AssocTyConstraintKind::Bound { bounds } } else { unreachable!(); }; @@ -425,8 +414,8 @@ impl<'a> Parser<'a> { self.sess.gated_spans.gate(sym::associated_type_bounds, span); } - constraints.push(AssocTyConstraint { id: ast::DUMMY_NODE_ID, ident, kind, span }); - assoc_ty_constraints.push(span); + let constraint = AssocTyConstraint { id: ast::DUMMY_NODE_ID, ident, kind, span }; + args.push(AngleBracketedArg::Constraint(constraint)); } else if self.check_const_arg() { // Parse const argument. let expr = if let token::OpenDelim(token::Brace) = self.token.kind { @@ -453,12 +442,10 @@ impl<'a> Parser<'a> { self.parse_literal_maybe_minus()? }; let value = AnonConst { id: ast::DUMMY_NODE_ID, value: expr }; - args.push(GenericArg::Const(value)); - misplaced_assoc_ty_constraints.append(&mut assoc_ty_constraints); + args.push(AngleBracketedArg::Arg(GenericArg::Const(value))); } else if self.check_type() { // Parse type argument. - args.push(GenericArg::Type(self.parse_ty()?)); - misplaced_assoc_ty_constraints.append(&mut assoc_ty_constraints); + args.push(AngleBracketedArg::Arg(GenericArg::Type(self.parse_ty()?))); } else { break; } @@ -468,23 +455,6 @@ impl<'a> Parser<'a> { } } - // FIXME: we would like to report this in ast_validation instead, but we currently do not - // preserve ordering of generic parameters with respect to associated type binding, so we - // lose that information after parsing. - if !misplaced_assoc_ty_constraints.is_empty() { - let mut err = self.struct_span_err( - args_lo.to(self.prev_token.span), - "associated type bindings must be declared after generic parameters", - ); - for span in misplaced_assoc_ty_constraints { - err.span_label( - span, - "this associated type binding should be moved after the generic parameters", - ); - } - err.emit(); - } - - Ok((args, constraints)) + Ok(args) } } diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs index a80c3b72044e..0829a82b932c 100644 --- a/src/librustc_save_analysis/dump_visitor.rs +++ b/src/librustc_save_analysis/dump_visitor.rs @@ -783,7 +783,7 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> { match **generic_args { ast::GenericArgs::AngleBracketed(ref data) => { for arg in &data.args { - if let ast::GenericArg::Type(ty) = arg { + if let ast::AngleBracketedArg::Arg(ast::GenericArg::Type(ty)) = arg { self.visit_ty(ty); } } @@ -849,7 +849,7 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> { if let ast::GenericArgs::AngleBracketed(ref data) = **generic_args { for arg in &data.args { match arg { - ast::GenericArg::Type(ty) => self.visit_ty(ty), + ast::AngleBracketedArg::Arg(ast::GenericArg::Type(ty)) => self.visit_ty(ty), _ => {} } } diff --git a/src/test/ui/parser/constraints-before-generic-args-syntactic-pass.rs b/src/test/ui/parser/constraints-before-generic-args-syntactic-pass.rs new file mode 100644 index 000000000000..afbd13e6fd9a --- /dev/null +++ b/src/test/ui/parser/constraints-before-generic-args-syntactic-pass.rs @@ -0,0 +1,9 @@ +// check-pass + +#[cfg(FALSE)] +fn syntax() { + foo::(); + foo::(); +} + +fn main() {} diff --git a/src/test/ui/parser/issue-32214.rs b/src/test/ui/parser/issue-32214.rs index 82f7ce62b945..ca30f5f1329d 100644 --- a/src/test/ui/parser/issue-32214.rs +++ b/src/test/ui/parser/issue-32214.rs @@ -1,6 +1,6 @@ trait Trait { type Item; } pub fn test >() {} -//~^ ERROR associated type bindings must be declared after generic parameters +//~^ ERROR constraints in a path segment must come after generic arguments fn main() { } diff --git a/src/test/ui/parser/issue-32214.stderr b/src/test/ui/parser/issue-32214.stderr index 08b230a14f50..ee99fe70811d 100644 --- a/src/test/ui/parser/issue-32214.stderr +++ b/src/test/ui/parser/issue-32214.stderr @@ -1,10 +1,11 @@ -error: associated type bindings must be declared after generic parameters - --> $DIR/issue-32214.rs:3:25 +error: constraints in a path segment must come after generic arguments + --> $DIR/issue-32214.rs:3:24 | LL | pub fn test >() {} - | -------^^^ - | | - | this associated type binding should be moved after the generic parameters + | ^-------^^-^ + | | | + | | this generic argument must come before the first constraint + | the first constraint is provided here error: aborting due to previous error diff --git a/src/test/ui/suggestions/suggest-move-types.rs b/src/test/ui/suggestions/suggest-move-types.rs index 6505a97de6e4..d9d5351b5c2d 100644 --- a/src/test/ui/suggestions/suggest-move-types.rs +++ b/src/test/ui/suggestions/suggest-move-types.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - #![allow(warnings)] // This test verifies that the suggestion to move types before associated type bindings @@ -25,20 +23,22 @@ trait ThreeWithLifetime<'a, 'b, 'c, T, U, V> { type C; } -struct A> { //~ ERROR associated type bindings must be declared after generic parameters +struct A> { +//~^ ERROR constraints in a path segment must come after generic arguments m: M, t: T, } struct Al<'a, T, M: OneWithLifetime> { -//~^ ERROR associated type bindings must be declared after generic parameters +//~^ ERROR constraints in a path segment must come after generic arguments //~^^ ERROR type provided when a lifetime was expected m: M, t: &'a T, } -struct B> { //~ ERROR associated type bindings must be declared after generic parameters +struct B> { +//~^ ERROR constraints in a path segment must come after generic arguments m: M, t: T, u: U, @@ -46,7 +46,7 @@ struct B> { //~ ERROR associated ty } struct Bl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime> { -//~^ ERROR associated type bindings must be declared after generic parameters +//~^ ERROR constraints in a path segment must come after generic arguments //~^^ ERROR type provided when a lifetime was expected m: M, t: &'a T, @@ -54,7 +54,8 @@ struct Bl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime> { //~ ERROR associated type bindings must be declared after generic parameters +struct C> { +//~^ ERROR constraints in a path segment must come after generic arguments m: M, t: T, u: U, @@ -62,7 +63,7 @@ struct C> { //~ ERROR associated ty } struct Cl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime> { -//~^ ERROR associated type bindings must be declared after generic parameters +//~^ ERROR constraints in a path segment must come after generic arguments //~^^ ERROR lifetime provided when a type was expected m: M, t: &'a T, @@ -70,7 +71,8 @@ struct Cl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime> { //~ ERROR associated type bindings must be declared after generic parameters +struct D> { +//~^ ERROR constraints in a path segment must come after generic arguments m: M, t: T, u: U, @@ -78,7 +80,7 @@ struct D> { //~ ERROR associated ty } struct Dl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime> { -//~^ ERROR associated type bindings must be declared after generic parameters +//~^ ERROR constraints in a path segment must come after generic arguments //~^^ ERROR lifetime provided when a type was expected m: M, t: &'a T, diff --git a/src/test/ui/suggestions/suggest-move-types.stderr b/src/test/ui/suggestions/suggest-move-types.stderr index ac91813f9283..0225546b9e37 100644 --- a/src/test/ui/suggestions/suggest-move-types.stderr +++ b/src/test/ui/suggestions/suggest-move-types.stderr @@ -1,81 +1,93 @@ -error: associated type bindings must be declared after generic parameters - --> $DIR/suggest-move-types.rs:28:20 +error: constraints in a path segment must come after generic arguments + --> $DIR/suggest-move-types.rs:26:19 | LL | struct A> { - | ----^^^ - | | - | this associated type binding should be moved after the generic parameters + | ^----^^-^ + | | | + | | this generic argument must come before the first constraint + | the first constraint is provided here -error: associated type bindings must be declared after generic parameters - --> $DIR/suggest-move-types.rs:34:37 +error: constraints in a path segment must come after generic arguments + --> $DIR/suggest-move-types.rs:33:36 | LL | struct Al<'a, T, M: OneWithLifetime> { - | ----^^^^^^^ - | | - | this associated type binding should be moved after the generic parameters + | ^----^^-^^--^ + | | | | + | | | this generic argument must come before the first constraint + | | this generic argument must come before the first constraint + | the first constraint is provided here -error: associated type bindings must be declared after generic parameters - --> $DIR/suggest-move-types.rs:41:28 +error: constraints in a path segment must come after generic arguments + --> $DIR/suggest-move-types.rs:40:27 | LL | struct B> { - | ----^^----^^----^^^^^^^^^ - | | | | - | | | this associated type binding should be moved after the generic parameters - | | this associated type binding should be moved after the generic parameters - | this associated type binding should be moved after the generic parameters + | ^----^^^^^^^^^^^^^^-^^-^^-^ + | | | | | + | | | | this generic argument must come before the first constraint + | | | this generic argument must come before the first constraint + | | this generic argument must come before the first constraint + | the first constraint is provided here -error: associated type bindings must be declared after generic parameters - --> $DIR/suggest-move-types.rs:48:53 +error: constraints in a path segment must come after generic arguments + --> $DIR/suggest-move-types.rs:48:52 | LL | struct Bl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime> { - | ----^^----^^----^^^^^^^^^^^^^^^^^^^^^ - | | | | - | | | this associated type binding should be moved after the generic parameters - | | this associated type binding should be moved after the generic parameters - | this associated type binding should be moved after the generic parameters + | ^----^^^^^^^^^^^^^^-^^-^^-^^--^^--^^--^ + | | | | | | | | + | | | | | | | this generic argument must come before the first constraint + | | | | | | this generic argument must come before the first constraint + | | | | | this generic argument must come before the first constraint + | | | | this generic argument must come before the first constraint + | | | this generic argument must come before the first constraint + | | this generic argument must come before the first constraint + | the first constraint is provided here -error: associated type bindings must be declared after generic parameters - --> $DIR/suggest-move-types.rs:57:28 +error: constraints in a path segment must come after generic arguments + --> $DIR/suggest-move-types.rs:57:27 | LL | struct C> { - | ^^^----^^----^^----^^^^^^ - | | | | - | | | this associated type binding should be moved after the generic parameters - | | this associated type binding should be moved after the generic parameters - | this associated type binding should be moved after the generic parameters + | ^^^^----^^^^^^^^^^^^^^-^^-^ + | | | | + | | | this generic argument must come before the first constraint + | | this generic argument must come before the first constraint + | the first constraint is provided here -error: associated type bindings must be declared after generic parameters - --> $DIR/suggest-move-types.rs:64:53 +error: constraints in a path segment must come after generic arguments + --> $DIR/suggest-move-types.rs:65:52 | LL | struct Cl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime> { - | ^^^^^^^----^^----^^----^^^^^^^^^^^^^^ - | | | | - | | | this associated type binding should be moved after the generic parameters - | | this associated type binding should be moved after the generic parameters - | this associated type binding should be moved after the generic parameters + | ^^^^^^^^----^^^^^^^^^^^^^^-^^--^^-^^--^ + | | | | | | + | | | | | this generic argument must come before the first constraint + | | | | this generic argument must come before the first constraint + | | | this generic argument must come before the first constraint + | | this generic argument must come before the first constraint + | the first constraint is provided here -error: associated type bindings must be declared after generic parameters - --> $DIR/suggest-move-types.rs:73:28 +error: constraints in a path segment must come after generic arguments + --> $DIR/suggest-move-types.rs:74:27 | LL | struct D> { - | ^^^----^^----^^^^^----^^^ - | | | | - | | | this associated type binding should be moved after the generic parameters - | | this associated type binding should be moved after the generic parameters - | this associated type binding should be moved after the generic parameters + | ^^^^----^^^^^^^^-^^^^^^^^-^ + | | | | + | | | this generic argument must come before the first constraint + | | this generic argument must come before the first constraint + | the first constraint is provided here -error: associated type bindings must be declared after generic parameters - --> $DIR/suggest-move-types.rs:80:53 +error: constraints in a path segment must come after generic arguments + --> $DIR/suggest-move-types.rs:82:52 | LL | struct Dl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime> { - | ^^^^^^^----^^----^^^^^^^^^----^^^^^^^ - | | | | - | | | this associated type binding should be moved after the generic parameters - | | this associated type binding should be moved after the generic parameters - | this associated type binding should be moved after the generic parameters + | ^^^^^^^^----^^^^^^^^-^^--^^^^^^^^-^^--^ + | | | | | | + | | | | | this generic argument must come before the first constraint + | | | | this generic argument must come before the first constraint + | | | this generic argument must come before the first constraint + | | this generic argument must come before the first constraint + | the first constraint is provided here error[E0747]: type provided when a lifetime was expected - --> $DIR/suggest-move-types.rs:34:43 + --> $DIR/suggest-move-types.rs:33:43 | LL | struct Al<'a, T, M: OneWithLifetime> { | ^ @@ -91,7 +103,7 @@ LL | struct Bl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime $DIR/suggest-move-types.rs:64:56 + --> $DIR/suggest-move-types.rs:65:56 | LL | struct Cl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime> { | ^^ @@ -99,7 +111,7 @@ LL | struct Cl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime $DIR/suggest-move-types.rs:80:56 + --> $DIR/suggest-move-types.rs:82:56 | LL | struct Dl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime> { | ^^