From 4f2d183af9294dd6944457b95def0f511b3c5f65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 27 May 2019 22:51:19 -0700 Subject: [PATCH] Rework how type params are parsed Separate lifetimes, type arguments, const params and type bindings as early as possible in the parser. When encountering bad ordering, suggest the correct order in a homogeneous way for all possible incorrect ordering. --- src/librustc/hir/intravisit.rs | 18 ++- src/librustc/hir/lowering.rs | 46 +++--- src/librustc/ty/subst.rs | 19 ++- src/librustc_interface/util.rs | 6 +- src/librustc_passes/ast_validation.rs | 146 ++++++------------ src/librustc_save_analysis/dump_visitor.rs | 14 +- src/libsyntax/ast.rs | 26 +--- src/libsyntax/ext/build.rs | 115 ++++++++------ src/libsyntax/mut_visit.rs | 24 +-- src/libsyntax/parse/diagnostics.rs | 44 +++++- src/libsyntax/parse/parser.rs | 55 ++++--- src/libsyntax/print/pprust.rs | 46 +++--- src/libsyntax/visit.rs | 11 +- src/libsyntax_ext/deriving/clone.rs | 35 +++-- src/libsyntax_ext/deriving/cmp/eq.rs | 14 +- src/libsyntax_ext/deriving/generic/mod.rs | 30 ++-- src/libsyntax_ext/deriving/generic/ty.rs | 52 ++++--- src/libsyntax_ext/env.rs | 33 ++-- .../const-param-before-other-params.rs | 9 +- .../const-param-before-other-params.stderr | 16 +- src/test/ui/issues/issue-59508-1.rs | 2 +- src/test/ui/issues/issue-59508-1.stderr | 6 +- src/test/ui/issues/issue-59508.fixed | 2 +- src/test/ui/issues/issue-59508.rs | 2 +- src/test/ui/issues/issue-59508.stderr | 6 +- src/test/ui/lifetime-before-type-params.fixed | 8 + src/test/ui/lifetime-before-type-params.rs | 17 +- .../ui/lifetime-before-type-params.stderr | 31 ++-- src/test/ui/parser/issue-14303-enum.fixed | 7 + src/test/ui/parser/issue-14303-enum.rs | 5 +- src/test/ui/parser/issue-14303-enum.stderr | 6 +- src/test/ui/parser/issue-14303-fn-def.fixed | 5 + src/test/ui/parser/issue-14303-fn-def.rs | 5 +- src/test/ui/parser/issue-14303-fn-def.stderr | 6 +- src/test/ui/parser/issue-14303-fncall.fixed | 18 +++ src/test/ui/parser/issue-14303-fncall.rs | 5 +- src/test/ui/parser/issue-14303-fncall.stderr | 6 +- src/test/ui/parser/issue-14303-impl.fixed | 7 + src/test/ui/parser/issue-14303-impl.rs | 5 +- src/test/ui/parser/issue-14303-impl.stderr | 6 +- src/test/ui/parser/issue-14303-path.fixed | 15 ++ src/test/ui/parser/issue-14303-path.rs | 4 +- src/test/ui/parser/issue-14303-path.stderr | 6 +- src/test/ui/parser/issue-14303-struct.fixed | 7 + src/test/ui/parser/issue-14303-struct.rs | 5 +- src/test/ui/parser/issue-14303-struct.stderr | 6 +- src/test/ui/parser/issue-14303-trait.fixed | 5 + src/test/ui/parser/issue-14303-trait.rs | 5 +- src/test/ui/parser/issue-14303-trait.stderr | 6 +- src/test/ui/parser/issue-32214.fixed | 7 + src/test/ui/parser/issue-32214.rs | 7 +- src/test/ui/parser/issue-32214.stderr | 8 +- .../ui/suggestions/suggest-move-lifetimes.rs | 8 +- .../suggestions/suggest-move-lifetimes.stderr | 24 +-- src/test/ui/suggestions/suggest-move-types.rs | 22 +-- .../ui/suggestions/suggest-move-types.stderr | 98 +++--------- .../ui/traits/trait-object-vs-lifetime.rs | 2 +- .../ui/traits/trait-object-vs-lifetime.stderr | 6 +- 58 files changed, 594 insertions(+), 561 deletions(-) create mode 100644 src/test/ui/lifetime-before-type-params.fixed create mode 100644 src/test/ui/parser/issue-14303-enum.fixed create mode 100644 src/test/ui/parser/issue-14303-fn-def.fixed create mode 100644 src/test/ui/parser/issue-14303-fncall.fixed create mode 100644 src/test/ui/parser/issue-14303-impl.fixed create mode 100644 src/test/ui/parser/issue-14303-path.fixed create mode 100644 src/test/ui/parser/issue-14303-struct.fixed create mode 100644 src/test/ui/parser/issue-14303-trait.fixed create mode 100644 src/test/ui/parser/issue-32214.fixed diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs index 517c99f99efea..6daf1e2406b21 100644 --- a/src/librustc/hir/intravisit.rs +++ b/src/librustc/hir/intravisit.rs @@ -661,9 +661,11 @@ pub fn walk_path<'v, V: Visitor<'v>>(visitor: &mut V, path: &'v Path) { } } -pub fn walk_path_segment<'v, V: Visitor<'v>>(visitor: &mut V, - path_span: Span, - segment: &'v PathSegment) { +pub fn walk_path_segment<'v, V: Visitor<'v>>( + visitor: &mut V, + path_span: Span, + segment: &'v PathSegment, +) { visitor.visit_ident(segment.ident); if let Some(id) = segment.hir_id { visitor.visit_id(id); @@ -673,10 +675,12 @@ pub fn walk_path_segment<'v, V: Visitor<'v>>(visitor: &mut V, } } -pub fn walk_generic_args<'v, V: Visitor<'v>>(visitor: &mut V, - _path_span: Span, - generic_args: &'v GenericArgs) { - walk_list!(visitor, visit_generic_arg, &generic_args.args); +pub fn walk_generic_args<'v, V: Visitor<'v>>( + visitor: &mut V, + _path_span: Span, + generic_args: &'v GenericArgs, +) { + walk_list!(visitor, visit_generic_arg, &generic_args.args); walk_list!(visitor, visit_assoc_type_binding, &generic_args.bindings); } diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 1d51e7cd74222..b787d04f3b0b2 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -1334,22 +1334,6 @@ impl<'a> LoweringContext<'a> { } } - fn lower_generic_arg(&mut self, - arg: &ast::GenericArg, - itctx: ImplTraitContext<'_>) - -> hir::GenericArg { - match arg { - ast::GenericArg::Lifetime(lt) => GenericArg::Lifetime(self.lower_lifetime(<)), - ast::GenericArg::Type(ty) => GenericArg::Type(self.lower_ty_direct(&ty, itctx)), - ast::GenericArg::Const(ct) => { - GenericArg::Const(ConstArg { - value: self.lower_anon_const(&ct), - span: ct.value.span, - }) - } - } - } - fn lower_ty(&mut self, t: &Ty, itctx: ImplTraitContext<'_>) -> P { P(self.lower_ty_direct(t, itctx)) } @@ -2175,17 +2159,25 @@ impl<'a> LoweringContext<'a> { param_mode: ParamMode, mut itctx: ImplTraitContext<'_>, ) -> (hir::GenericArgs, bool) { - let &AngleBracketedArgs { ref args, ref bindings, .. } = data; - let has_types = args.iter().any(|arg| match arg { - ast::GenericArg::Type(_) => true, - _ => false, - }); - (hir::GenericArgs { - args: args.iter().map(|a| self.lower_generic_arg(a, itctx.reborrow())).collect(), - bindings: bindings.iter().map(|b| self.lower_ty_binding(b, itctx.reborrow())).collect(), - parenthesized: false, - }, - !has_types && param_mode == ParamMode::Optional) + let AngleBracketedArgs { lifetimes, types, const_args, bindings, .. } = &data; + let mut args = vec![]; + for lt in lifetimes { + args.push(GenericArg::Lifetime(self.lower_lifetime(<))); + } + for ty in types { + args.push(GenericArg::Type(self.lower_ty_direct(&ty, itctx.reborrow()))); + } + for ct in const_args { + args.push(GenericArg::Const(ConstArg { + value: self.lower_anon_const(&ct), + span: ct.value.span, + })) + } + let args = hir::HirVec::from(args); + let bindings = bindings.iter().map(|b| self.lower_ty_binding(b, itctx.reborrow())) + .collect(); + (hir::GenericArgs { args, bindings, parenthesized: false }, + types.is_empty() && param_mode == ParamMode::Optional) } fn lower_parenthesized_parameter_data( diff --git a/src/librustc/ty/subst.rs b/src/librustc/ty/subst.rs index 75ba1dd46ca2a..7d880707844b5 100644 --- a/src/librustc/ty/subst.rs +++ b/src/librustc/ty/subst.rs @@ -549,21 +549,30 @@ impl<'a, 'gcx, 'tcx> SubstFolder<'a, 'gcx, 'tcx> { fn ty_for_param(&self, p: ty::ParamTy, source_ty: Ty<'tcx>) -> Ty<'tcx> { // Look up the type in the substitutions. It really should be in there. let opt_ty = self.substs.get(p.index as usize).map(|k| k.unpack()); + debug!( + "parameter `{:?}` ({:?}/{}), found {:?} when substituting (root type={:?}) substs={:?}", + p, + source_ty, + p.index, + opt_ty, + self.root_ty, + self.substs, + ); let ty = match opt_ty { Some(UnpackedKind::Type(ty)) => ty, Some(kind) => { let span = self.span.unwrap_or(DUMMY_SP); - span_bug!( - span, - "expected type for `{:?}` ({:?}/{}) but found {:?} \ - when substituting (root type={:?}) substs={:?}", + self.tcx.sess.delay_span_bug(span, &format!( + "expected type for `{:?}` ({:?}/{}) but found {:?} when substituting \ + (root type={:?}) substs={:?}", p, source_ty, p.index, kind, self.root_ty, self.substs, - ); + )); + self.tcx.types.err } None => { let span = self.span.unwrap_or(DUMMY_SP); diff --git a/src/librustc_interface/util.rs b/src/librustc_interface/util.rs index 4ff996d1f5707..3c3fbef92b44c 100644 --- a/src/librustc_interface/util.rs +++ b/src/librustc_interface/util.rs @@ -712,11 +712,7 @@ impl<'a> ReplaceBodyWithLoop<'a> { 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.into_iter()) || + any_involves_impl_trait(data.types.iter()) || any_involves_impl_trait(data.bindings.iter().map(|b| &b.ty)) }, Some(&ast::GenericArgs::Parenthesized(ref data)) => { diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_passes/ast_validation.rs index 2afcbe8a15137..e8e1da851d51a 100644 --- a/src/librustc_passes/ast_validation.rs +++ b/src/librustc_passes/ast_validation.rs @@ -11,7 +11,6 @@ use syntax::print::pprust; use rustc::lint; use rustc::lint::builtin::{BuiltinLintDiagnostics, NESTED_IMPL_TRAIT}; use rustc::session::Session; -use rustc_data_structures::fx::FxHashMap; use syntax::ast::*; use syntax::attr; use syntax::source_map::Spanned; @@ -21,7 +20,7 @@ use syntax::visit::{self, Visitor}; use syntax::{span_err, struct_span_err, walk_list}; use syntax_ext::proc_macro_decls::is_proc_macro_attr; use syntax_pos::{Span, MultiSpan}; -use errors::{Applicability, FatalError}; +use errors::Applicability; use log::debug; #[derive(Copy, Clone, Debug)] @@ -346,104 +345,65 @@ impl<'a> AstValidator<'a> { } } -enum GenericPosition { - Param, - Arg, -} - fn validate_generics_order<'a>( - sess: &Session, handler: &errors::Handler, generics: impl Iterator< - Item = ( - ParamKindOrd, - Option<&'a [GenericBound]>, - Span, - Option - ), + Item = (ParamKindOrd, Option<&'a [GenericBound]>, Span, Option), >, - pos: GenericPosition, span: Span, ) { - let mut max_param: Option = None; - let mut out_of_order = FxHashMap::default(); - let mut param_idents = vec![]; - let mut found_type = false; - let mut found_const = false; - - for (kind, bounds, span, ident) in generics { - if let Some(ident) = ident { - param_idents.push((kind, bounds, param_idents.len(), ident)); - } - let max_param = &mut max_param; - match max_param { - Some(max_param) if *max_param > kind => { - let entry = out_of_order.entry(kind).or_insert((*max_param, vec![])); - entry.1.push(span); - } - Some(_) | None => *max_param = Some(kind), + let mut lifetimes = vec![]; + let mut type_args = vec![]; + let mut const_args = vec![]; + let mut out_of_order = false; + + for (kind, bounds, _span, ident) in generics { + let ident = match ident { + Some(ident) => ident, + None => return, }; match kind { - ParamKindOrd::Type => found_type = true, - ParamKindOrd::Const => found_const = true, - _ => {} + ParamKindOrd::Lifetime => { + lifetimes.push((ident, bounds)); + out_of_order |= type_args.len() > 0 || const_args.len() > 0; + } + ParamKindOrd::Type => { + type_args.push((ident, bounds)); + out_of_order |= const_args.len() > 0; + } + ParamKindOrd::Const => { + const_args.push((ident, bounds)); + } } } + if !out_of_order { + return; + } let mut ordered_params = "<".to_string(); - if !out_of_order.is_empty() { - param_idents.sort_by_key(|&(po, _, i, _)| (po, i)); - let mut first = true; - for (_, bounds, _, ident) in param_idents { - if !first { - ordered_params += ", "; - } - ordered_params += &ident; - if let Some(bounds) = bounds { - if !bounds.is_empty() { - ordered_params += ": "; - ordered_params += &pprust::bounds_to_string(&bounds); - } + let mut first = true; + for (ident, bounds) in lifetimes.iter().chain(type_args.iter()).chain(const_args.iter()) { + if !first { + ordered_params += ", "; + } + ordered_params += &ident; + if let Some(bounds) = bounds { + if !bounds.is_empty() { + ordered_params += ": "; + ordered_params += &pprust::bounds_to_string(&bounds); } - first = false; } + first = false; } ordered_params += ">"; - let pos_str = match pos { - GenericPosition::Param => "parameter", - GenericPosition::Arg => "argument", - }; - - for (param_ord, (max_param, spans)) in &out_of_order { - let mut err = handler.struct_span_err(spans.clone(), - &format!( - "{} {pos}s must be declared prior to {} {pos}s", - param_ord, - max_param, - pos = pos_str, - )); - if let GenericPosition::Param = pos { - err.span_suggestion( - span, - &format!( - "reorder the {}s: lifetimes, then types{}", - pos_str, - if sess.features_untracked().const_generics { ", then consts" } else { "" }, - ), - ordered_params.clone(), - Applicability::MachineApplicable, - ); - } - err.emit(); - } - - // FIXME(const_generics): we shouldn't have to abort here at all, but we currently get ICEs - // if we don't. Const parameters and type parameters can currently conflict if they - // are out-of-order. - if !out_of_order.is_empty() && found_type && found_const { - FatalError.raise(); - } + handler.struct_span_err(span, "incorrect parameter order") + .span_suggestion( + span, + "reorder the parameters", + ordered_params.clone(), + Applicability::MachineApplicable, + ).emit(); } impl<'a> Visitor<'a> for AstValidator<'a> { @@ -703,21 +663,9 @@ 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); - validate_generics_order( - self.session, - self.err_handler(), - data.args.iter().map(|arg| { - (match arg { - GenericArg::Lifetime(..) => ParamKindOrd::Lifetime, - GenericArg::Type(..) => ParamKindOrd::Type, - GenericArg::Const(..) => ParamKindOrd::Const, - }, None, arg.span(), None) - }), - GenericPosition::Arg, - generic_args.span(), - ); - + walk_list!(self, visit_lifetime, &data.lifetimes); + walk_list!(self, visit_ty, &data.types); + walk_list!(self, visit_anon_const, &data.const_args); // Type bindings such as `Item=impl Debug` in `Iterator` // are allowed to contain nested `impl Trait`. self.with_impl_trait(None, |this| { @@ -750,7 +698,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> { } validate_generics_order( - self.session, self.err_handler(), generics.params.iter().map(|param| { let ident = Some(param.ident.to_string()); @@ -764,7 +711,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> { }; (kind, Some(&*param.bounds), param.ident.span, ident) }), - GenericPosition::Param, generics.span, ); diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs index 1fdfcc84926f6..45f057751f5ac 100644 --- a/src/librustc_save_analysis/dump_visitor.rs +++ b/src/librustc_save_analysis/dump_visitor.rs @@ -795,11 +795,8 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { if let Some(ref generic_args) = seg.args { match **generic_args { ast::GenericArgs::AngleBracketed(ref data) => { - for arg in &data.args { - match arg { - ast::GenericArg::Type(ty) => self.visit_ty(ty), - _ => {} - } + for ty in &data.types { + self.visit_ty(ty); } } ast::GenericArgs::Parenthesized(ref data) => { @@ -861,11 +858,8 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { // Explicit types in the turbo-fish. if let Some(ref generic_args) = seg.args { if let ast::GenericArgs::AngleBracketed(ref data) = **generic_args { - for arg in &data.args { - match arg { - ast::GenericArg::Type(ty) => self.visit_ty(ty), - _ => {} - } + for ty in &data.types { + self.visit_ty(ty); } } } diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 75e83bd9f9c74..00c438c9807b9 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -166,30 +166,14 @@ impl GenericArgs { } } -#[derive(Clone, RustcEncodable, RustcDecodable, Debug)] -pub enum GenericArg { - Lifetime(Lifetime), - Type(P), - Const(AnonConst), -} - -impl GenericArg { - pub fn span(&self) -> Span { - match self { - GenericArg::Lifetime(lt) => lt.ident.span, - GenericArg::Type(ty) => ty.span, - GenericArg::Const(ct) => ct.value.span, - } - } -} - /// A path like `Foo<'a, T>`. #[derive(Clone, RustcEncodable, RustcDecodable, Debug, Default)] pub struct AngleBracketedArgs { /// The overall span. pub span: Span, - /// The arguments for this path segment. - pub args: Vec, + pub lifetimes: Vec, + pub types: Vec>, + pub const_args: Vec, /// Bindings (equality constraints) on associated types, if present. /// E.g., `Foo`. pub bindings: Vec, @@ -224,7 +208,9 @@ impl ParenthesizedArgs { pub fn as_angle_bracketed_args(&self) -> AngleBracketedArgs { AngleBracketedArgs { span: self.span, - args: self.inputs.iter().cloned().map(|input| GenericArg::Type(input)).collect(), + lifetimes: vec![], + types: self.inputs.iter().cloned().collect(), + const_args: vec![], bindings: vec![], } } diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index 9c0ffc1f6e8cb..588a7ddf2602c 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -14,23 +14,33 @@ pub trait AstBuilder { fn path(&self, span: Span, strs: Vec ) -> ast::Path; fn path_ident(&self, span: Span, id: ast::Ident) -> ast::Path; fn path_global(&self, span: Span, strs: Vec ) -> ast::Path; - fn path_all(&self, sp: Span, - global: bool, - idents: Vec, - args: Vec, - bindings: Vec) - -> ast::Path; - - fn qpath(&self, self_type: P, - trait_path: ast::Path, - ident: ast::Ident) - -> (ast::QSelf, ast::Path); - fn qpath_all(&self, self_type: P, - trait_path: ast::Path, - ident: ast::Ident, - args: Vec, - bindings: Vec) - -> (ast::QSelf, ast::Path); + fn path_all( + &self, sp: Span, + global: bool, + idents: Vec, + lifetimes: Vec, + types: Vec>, + const_args: Vec, + bindings: Vec, + ) -> ast::Path; + + fn qpath( + &self, + self_type: P, + trait_path: ast::Path, + ident: ast::Ident, + ) -> (ast::QSelf, ast::Path); + + fn qpath_all( + &self, + self_type: P, + trait_path: ast::Path, + ident: ast::Ident, + lifetimes: Vec, + types: Vec>, + const_args: Vec, + bindings: Vec, + ) -> (ast::QSelf, ast::Path); // types and consts fn ty_mt(&self, ty: P, mutbl: ast::Mutability) -> ast::MutTy; @@ -289,21 +299,24 @@ pub trait AstBuilder { impl<'a> AstBuilder for ExtCtxt<'a> { fn path(&self, span: Span, strs: Vec ) -> ast::Path { - self.path_all(span, false, strs, vec![], vec![]) + self.path_all(span, false, strs, vec![], vec![], vec![], vec![]) } fn path_ident(&self, span: Span, id: ast::Ident) -> ast::Path { self.path(span, vec![id]) } fn path_global(&self, span: Span, strs: Vec ) -> ast::Path { - self.path_all(span, true, strs, vec![], vec![]) - } - fn path_all(&self, - span: Span, - global: bool, - mut idents: Vec , - args: Vec, - bindings: Vec ) - -> ast::Path { + self.path_all(span, true, strs, vec![], vec![], vec![], vec![]) + } + fn path_all( + &self, + span: Span, + global: bool, + mut idents: Vec , + lifetimes: Vec, + types: Vec>, + const_args: Vec, + bindings: Vec, + ) -> ast::Path { assert!(!idents.is_empty()); let add_root = global && !idents[0].is_path_segment_keyword(); let mut segments = Vec::with_capacity(idents.len() + add_root as usize); @@ -314,8 +327,12 @@ impl<'a> AstBuilder for ExtCtxt<'a> { segments.extend(idents.into_iter().map(|ident| { ast::PathSegment::from_ident(ident.with_span_pos(span)) })); - let args = if !args.is_empty() || !bindings.is_empty() { - ast::AngleBracketedArgs { args, bindings, span }.into() + let args = if !lifetimes.is_empty() || + !types.is_empty() || + !const_args.is_empty() || + !bindings.is_empty() + { + ast::AngleBracketedArgs { lifetimes, types, const_args, bindings, span }.into() } else { None }; @@ -330,27 +347,37 @@ impl<'a> AstBuilder for ExtCtxt<'a> { /// Constructs a qualified path. /// /// Constructs a path like `::ident`. - fn qpath(&self, - self_type: P, - trait_path: ast::Path, - ident: ast::Ident) - -> (ast::QSelf, ast::Path) { - self.qpath_all(self_type, trait_path, ident, vec![], vec![]) + fn qpath( + &self, + self_type: P, + trait_path: ast::Path, + ident: ast::Ident, + ) -> (ast::QSelf, ast::Path) { + self.qpath_all(self_type, trait_path, ident, vec![], vec![], vec![], vec![]) } /// Constructs a qualified path. /// /// Constructs a path like `::ident<'a, T, A = Bar>`. - fn qpath_all(&self, - self_type: P, - trait_path: ast::Path, - ident: ast::Ident, - args: Vec, - bindings: Vec) - -> (ast::QSelf, ast::Path) { + fn qpath_all( + &self, + self_type: P, + trait_path: ast::Path, + ident: ast::Ident, + lifetimes: Vec, + types: Vec>, + const_args: Vec, + bindings: Vec, + ) -> (ast::QSelf, ast::Path) { let mut path = trait_path; - let args = if !args.is_empty() || !bindings.is_empty() { - ast::AngleBracketedArgs { args, bindings, span: ident.span }.into() + let args = if !lifetimes.is_empty() || + !types.is_empty() || + !const_args.is_empty() || + !bindings.is_empty() + { + ast::AngleBracketedArgs { + lifetimes, types, const_args, bindings, span: ident.span, + }.into() } else { None }; diff --git a/src/libsyntax/mut_visit.rs b/src/libsyntax/mut_visit.rs index 0016c0d4d7e2b..6cde9eb97947c 100644 --- a/src/libsyntax/mut_visit.rs +++ b/src/libsyntax/mut_visit.rs @@ -151,10 +151,6 @@ pub trait MutVisitor: Sized { noop_filter_map_expr(e, self) } - fn visit_generic_arg(&mut self, arg: &mut GenericArg) { - noop_visit_generic_arg(arg, self); - } - fn visit_ty(&mut self, t: &mut P) { noop_visit_ty(t, self); } @@ -497,18 +493,14 @@ pub fn noop_visit_generic_args(generic_args: &mut GenericArgs, vi } } -pub fn noop_visit_generic_arg(arg: &mut GenericArg, vis: &mut T) { - match arg { - GenericArg::Lifetime(lt) => vis.visit_lifetime(lt), - GenericArg::Type(ty) => vis.visit_ty(ty), - GenericArg::Const(ct) => vis.visit_anon_const(ct), - } -} - -pub fn noop_visit_angle_bracketed_parameter_data(data: &mut AngleBracketedArgs, - vis: &mut T) { - let AngleBracketedArgs { args, bindings, span } = data; - visit_vec(args, |arg| vis.visit_generic_arg(arg)); +pub fn noop_visit_angle_bracketed_parameter_data( + data: &mut AngleBracketedArgs, + vis: &mut T, +) { + let AngleBracketedArgs { lifetimes, types, const_args, bindings, span } = data; + visit_vec(lifetimes, |lt| vis.visit_lifetime(lt)); + visit_vec(types, |ty| vis.visit_ty(ty)); + visit_vec(const_args, |arg| vis.visit_anon_const(arg)); visit_vec(bindings, |binding| vis.visit_ty_binding(binding)); vis.visit_span(span); } diff --git a/src/libsyntax/parse/diagnostics.rs b/src/libsyntax/parse/diagnostics.rs index b3d49524d7668..6877dc108a981 100644 --- a/src/libsyntax/parse/diagnostics.rs +++ b/src/libsyntax/parse/diagnostics.rs @@ -1,7 +1,7 @@ use crate::ast; use crate::ast::{ BlockCheckMode, BinOpKind, Expr, ExprKind, Item, ItemKind, Pat, PatKind, PathSegment, QSelf, - Ty, TyKind, VariantData, + Ty, TyKind, VariantData, Lifetime, TypeBinding, AnonConst, }; use crate::parse::{SeqSep, token, PResult, Parser}; use crate::parse::parser::{BlockMode, PathStyle, SemiColonMode, TokenType, TokenExpectType}; @@ -1206,3 +1206,45 @@ impl<'a> Parser<'a> { err } } + +pub fn generic_arg_list( + lifetimes: &[Lifetime], + types: &[P], + const_args: &[AnonConst], + bindings: &[TypeBinding], + +) -> String { + let mut ordered_params = String::new(); + let mut first = true; + for lt in lifetimes { + if !first { + ordered_params += ", "; + } + ordered_params += <.ident.as_str(); + first = false; + } + for ty in types { + if !first { + ordered_params += ", "; + } + ordered_params += &pprust::ty_to_string(ty); + first = false; + } + for const_arg in const_args { + if !first { + ordered_params += ", "; + } + ordered_params += &pprust::expr_to_string(&const_arg.value); + first = false; + } + for binding in bindings { + if !first { + ordered_params += ", "; + } + ordered_params += &binding.ident.as_str(); + ordered_params += " = "; + ordered_params += &pprust::ty_to_string(&binding.ty); + first = false; + } + ordered_params +} diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 07efeaa4cf264..716b689d87e0c 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -13,7 +13,6 @@ use crate::ast::{Expr, ExprKind, RangeLimits}; use crate::ast::{Field, FnDecl, FnHeader}; use crate::ast::{ForeignItem, ForeignItemKind, FunctionRetTy}; use crate::ast::{GenericParam, GenericParamKind}; -use crate::ast::GenericArg; use crate::ast::{Ident, ImplItem, IsAsync, IsAuto, Item, ItemKind}; use crate::ast::{Label, Lifetime}; use crate::ast::{Local, LocalSource}; @@ -40,6 +39,7 @@ use crate::parse::lexer::{TokenAndSpan, UnmatchedBrace}; use crate::parse::lexer::comments::{doc_comment_style, strip_doc_comment_decoration}; use crate::parse::token::DelimToken; use crate::parse::{new_sub_parser_from_file, ParseSess, Directory, DirectoryOwnership}; +use crate::parse::diagnostics::generic_arg_list; use crate::util::parser::{AssocOp, Fixity}; use crate::print::pprust; use crate::ptr::P; @@ -1796,11 +1796,11 @@ impl<'a> Parser<'a> { let lo = self.span; let args = if self.eat_lt() { // `<'a, T, A = U>` - let (args, bindings) = + let (lifetimes, types, const_args, bindings) = self.parse_generic_args_with_leaning_angle_bracket_recovery(style, lo)?; self.expect_gt()?; let span = lo.to(self.prev_span); - AngleBracketedArgs { args, bindings, span }.into() + AngleBracketedArgs { lifetimes, types, const_args, bindings, span }.into() } else { // `(T, U) -> R` self.bump(); // `(` @@ -5075,7 +5075,7 @@ impl<'a> Parser<'a> { &mut self, style: PathStyle, lo: Span, - ) -> PResult<'a, (Vec, Vec)> { + ) -> PResult<'a, (Vec, Vec>, Vec, 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 @@ -5210,19 +5210,22 @@ impl<'a> Parser<'a> { /// Parses (possibly empty) list of lifetime and type arguments and associated type bindings, /// possibly including trailing comma. - fn parse_generic_args(&mut self) -> PResult<'a, (Vec, Vec)> { - let mut args = Vec::new(); + fn parse_generic_args( + &mut self, + ) -> PResult<'a, (Vec, Vec>, Vec, Vec)> { + let mut lifetimes = Vec::new(); + let mut types = Vec::new(); + let mut const_args = Vec::new(); let mut bindings = Vec::new(); - let mut misplaced_assoc_ty_bindings: Vec = Vec::new(); - let mut assoc_ty_bindings: Vec = Vec::new(); + let mut bad_order = false; let args_lo = self.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_bindings.append(&mut assoc_ty_bindings); + lifetimes.push(self.expect_lifetime()); + bad_order |= !types.is_empty() || !const_args.is_empty() || !bindings.is_empty(); } else if self.check_ident() && self.look_ahead(1, |t| t == &token::Eq) { // Parse associated type binding. let lo = self.span; @@ -5236,7 +5239,6 @@ impl<'a> Parser<'a> { ty, span, }); - assoc_ty_bindings.push(span); } else if self.check_const_arg() { // Parse const argument. let expr = if let token::OpenDelim(token::Brace) = self.token { @@ -5255,12 +5257,12 @@ impl<'a> Parser<'a> { id: ast::DUMMY_NODE_ID, value: expr, }; - args.push(GenericArg::Const(value)); - misplaced_assoc_ty_bindings.append(&mut assoc_ty_bindings); + const_args.push(value); + bad_order |= !bindings.is_empty(); } else if self.check_type() { // Parse type argument. - args.push(GenericArg::Type(self.parse_ty()?)); - misplaced_assoc_ty_bindings.append(&mut assoc_ty_bindings); + types.push(self.parse_ty()?); + bad_order |= !const_args.is_empty() || !bindings.is_empty(); } else { break } @@ -5273,21 +5275,18 @@ 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_bindings.len() > 0 { - let mut err = self.struct_span_err( - args_lo.to(self.prev_span), - "associated type bindings must be declared after generic parameters", - ); - for span in misplaced_assoc_ty_bindings { - err.span_label( - span, - "this associated type binding should be moved after the generic parameters", - ); - } - err.emit(); + if bad_order { + let sp = args_lo.to(self.prev_span); + self.struct_span_err(sp, "incorrect parameter order") + .span_suggestion( + sp, + "reorder the arguments", + generic_arg_list(&lifetimes, &types, &const_args, &bindings), + Applicability::MachineApplicable, + ).emit(); } - Ok((args, bindings)) + Ok((lifetimes, types, const_args, bindings)) } /// Parses an optional where-clause and places it in `generics`. diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index cf546332c2c9d..fe85d5903e281 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -1,8 +1,9 @@ // ignore-tidy-filelength -use crate::ast::{self, BlockCheckMode, PatKind, RangeEnd, RangeSyntax}; -use crate::ast::{SelfKind, GenericBound, TraitBoundModifier}; -use crate::ast::{Attribute, MacDelimiter, GenericArg}; +use crate::ast::{ + self, BlockCheckMode, PatKind, RangeEnd, RangeSyntax, SelfKind, GenericBound, + TraitBoundModifier, Attribute, MacDelimiter, +}; use crate::util::parser::{self, AssocOp, Fixity}; use crate::attr; use crate::source_map::{self, SourceMap, Spanned}; @@ -473,7 +474,7 @@ pub trait PrintState<'a> { self.writer().end() } - fn commasep(&mut self, b: Breaks, elts: &[T], mut op: F) -> io::Result<()> + fn commasep(&mut self, b: Breaks, elts: &[T], mut op: F) -> io::Result where F: FnMut(&mut Self, &T) -> io::Result<()>, { self.rbox(0, b)?; @@ -482,7 +483,7 @@ pub trait PrintState<'a> { if first { first = false; } else { self.word_space(",")?; } op(self, elt)?; } - self.end() + self.end().map(|_| !elts.is_empty()) } fn maybe_print_comment(&mut self, pos: BytePos) -> io::Result<()> { @@ -932,14 +933,6 @@ impl<'a> State<'a> { Ok(()) } - pub fn print_generic_arg(&mut self, generic_arg: &GenericArg) -> io::Result<()> { - match generic_arg { - GenericArg::Lifetime(lt) => self.print_lifetime(*lt), - GenericArg::Type(ty) => self.print_type(ty), - GenericArg::Const(ct) => self.print_expr(&ct.value), - } - } - pub fn print_type(&mut self, ty: &ast::Ty) -> io::Result<()> { self.maybe_print_comment(ty.span.lo())?; self.ibox(0)?; @@ -2444,21 +2437,30 @@ impl<'a> State<'a> { ast::GenericArgs::AngleBracketed(ref data) => { self.s.word("<")?; - self.commasep(Inconsistent, &data.args, |s, generic_arg| { - s.print_generic_arg(generic_arg) + let mut comma = false; + comma |= self.commasep(Inconsistent, &data.lifetimes, |s, lt| { + s.print_lifetime(*lt) })?; - - let mut comma = data.args.len() != 0; - + if comma && ( + !data.types.is_empty() || + !data.const_args.is_empty() || + !data.bindings.is_empty() + ) { + self.word_space(",")? + } + comma |= self.commasep(Inconsistent, &data.types, |s, ty| s.print_type(ty))?; + if comma && (!data.const_args.is_empty() || !data.bindings.is_empty()) { + self.word_space(",")? + } + self.commasep(Inconsistent, &data.const_args, |s, c| s.print_expr(&c.value))?; + if comma && !data.bindings.is_empty() { + self.word_space(",")? + } for binding in data.bindings.iter() { - if comma { - self.word_space(",")? - } self.print_ident(binding.ident)?; self.s.space()?; self.word_space("=")?; self.print_type(&binding.ty)?; - comma = true; } self.s.word(">")? diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 4e096d68235b5..095dfd6c5cc99 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -132,13 +132,6 @@ pub trait Visitor<'ast>: Sized { fn visit_generic_args(&mut self, path_span: Span, generic_args: &'ast GenericArgs) { walk_generic_args(self, path_span, generic_args) } - fn visit_generic_arg(&mut self, generic_arg: &'ast GenericArg) { - match generic_arg { - GenericArg::Lifetime(lt) => self.visit_lifetime(lt), - GenericArg::Type(ty) => self.visit_ty(ty), - GenericArg::Const(ct) => self.visit_anon_const(ct), - } - } fn visit_assoc_type_binding(&mut self, type_binding: &'ast TypeBinding) { walk_assoc_type_binding(self, type_binding) } @@ -403,7 +396,9 @@ pub fn walk_generic_args<'a, V>(visitor: &mut V, { match *generic_args { GenericArgs::AngleBracketed(ref data) => { - walk_list!(visitor, visit_generic_arg, &data.args); + walk_list!(visitor, visit_lifetime, &data.lifetimes); + walk_list!(visitor, visit_ty, &data.types); + walk_list!(visitor, visit_anon_const, &data.const_args); walk_list!(visitor, visit_assoc_type_binding, &data.bindings); } GenericArgs::Parenthesized(ref data) => { diff --git a/src/libsyntax_ext/deriving/clone.rs b/src/libsyntax_ext/deriving/clone.rs index b3b6328e2ca73..8538107e6fa3f 100644 --- a/src/libsyntax_ext/deriving/clone.rs +++ b/src/libsyntax_ext/deriving/clone.rs @@ -2,7 +2,7 @@ use crate::deriving::path_std; use crate::deriving::generic::*; use crate::deriving::generic::ty::*; -use syntax::ast::{self, Expr, GenericArg, Generics, ItemKind, MetaItem, VariantData}; +use syntax::ast::{self, Expr, Generics, ItemKind, MetaItem, VariantData}; use syntax::attr; use syntax::ext::base::{Annotatable, ExtCtxt}; use syntax::ext::build::AstBuilder; @@ -10,11 +10,13 @@ use syntax::ptr::P; use syntax::symbol::{kw, sym, Symbol}; use syntax_pos::Span; -pub fn expand_deriving_clone(cx: &mut ExtCtxt<'_>, - span: Span, - mitem: &MetaItem, - item: &Annotatable, - push: &mut dyn FnMut(Annotatable)) { +pub fn expand_deriving_clone( + cx: &mut ExtCtxt<'_>, + span: Span, + mitem: &MetaItem, + item: &Annotatable, + push: &mut dyn FnMut(Annotatable), +) { // check if we can use a short form // // the short form is `fn clone(&self) -> Self { *self }` @@ -109,14 +111,25 @@ fn cs_clone_shallow(name: &str, substr: &Substructure<'_>, is_union: bool) -> P { - fn assert_ty_bounds(cx: &mut ExtCtxt<'_>, stmts: &mut Vec, - ty: P, span: Span, helper_name: &str) { + fn assert_ty_bounds( + cx: &mut ExtCtxt<'_>, + stmts: &mut Vec, + ty: P, + span: Span, + helper_name: &str, + ) { // Generate statement `let _: helper_name;`, // set the expn ID so we can use the unstable struct. let span = span.with_ctxt(cx.backtrace()); - let assert_path = cx.path_all(span, true, - cx.std_path(&[sym::clone, Symbol::intern(helper_name)]), - vec![GenericArg::Type(ty)], vec![]); + let assert_path = cx.path_all( + span, + true, + cx.std_path(&[sym::clone, Symbol::intern(helper_name)]), + vec![], + vec![ty], + vec![], + vec![], + ); stmts.push(cx.stmt_let_type_only(span, cx.ty_path(assert_path))); } fn process_variant(cx: &mut ExtCtxt<'_>, stmts: &mut Vec, variant: &VariantData) { diff --git a/src/libsyntax_ext/deriving/cmp/eq.rs b/src/libsyntax_ext/deriving/cmp/eq.rs index 1d981e0ff7906..5641f964d40d3 100644 --- a/src/libsyntax_ext/deriving/cmp/eq.rs +++ b/src/libsyntax_ext/deriving/cmp/eq.rs @@ -2,7 +2,7 @@ use crate::deriving::path_std; use crate::deriving::generic::*; use crate::deriving::generic::ty::*; -use syntax::ast::{self, Expr, MetaItem, GenericArg}; +use syntax::ast::{self, Expr, MetaItem}; use syntax::ext::base::{Annotatable, ExtCtxt}; use syntax::ext::build::AstBuilder; use syntax::ptr::P; @@ -53,9 +53,15 @@ fn cs_total_eq_assert(cx: &mut ExtCtxt<'_>, // Generate statement `let _: helper_name;`, // set the expn ID so we can use the unstable struct. let span = span.with_ctxt(cx.backtrace()); - let assert_path = cx.path_all(span, true, - cx.std_path(&[sym::cmp, Symbol::intern(helper_name)]), - vec![GenericArg::Type(ty)], vec![]); + let assert_path = cx.path_all( + span, + true, + cx.std_path(&[sym::cmp, Symbol::intern(helper_name)]), + vec![], + vec![ty], + vec![], + vec![], + ); stmts.push(cx.stmt_let_type_only(span, cx.ty_path(assert_path))); } fn process_variant(cx: &mut ExtCtxt<'_>, diff --git a/src/libsyntax_ext/deriving/generic/mod.rs b/src/libsyntax_ext/deriving/generic/mod.rs index 7e3082a87d992..ab3920a8df058 100644 --- a/src/libsyntax_ext/deriving/generic/mod.rs +++ b/src/libsyntax_ext/deriving/generic/mod.rs @@ -184,7 +184,7 @@ use std::vec; use rustc_data_structures::thin_vec::ThinVec; use rustc_target::spec::abi::Abi; use syntax::ast::{self, BinOpKind, EnumDef, Expr, Generics, Ident, PatKind}; -use syntax::ast::{VariantData, GenericParamKind, GenericArg}; +use syntax::ast::{VariantData, GenericParamKind}; use syntax::attr; use syntax::ext::base::{Annotatable, ExtCtxt}; use syntax::ext::build::AstBuilder; @@ -649,20 +649,26 @@ impl<'a> TraitDef<'a> { // Create the reference to the trait. let trait_ref = cx.trait_ref(trait_path); - let self_params: Vec<_> = generics.params.iter().map(|param| match param.kind { - GenericParamKind::Lifetime { .. } => { - GenericArg::Lifetime(cx.lifetime(self.span, param.ident)) - } - GenericParamKind::Type { .. } => { - GenericArg::Type(cx.ty_ident(self.span, param.ident)) - } - GenericParamKind::Const { .. } => { - GenericArg::Const(cx.const_ident(self.span, param.ident)) + let mut lifetimes = vec![]; + let mut types = vec![]; + let mut const_args = vec![]; + for param in &generics.params { + match param.kind { + GenericParamKind::Lifetime { .. } => { + lifetimes.push(cx.lifetime(self.span, param.ident)); + } + GenericParamKind::Type { .. } => { + types.push(cx.ty_ident(self.span, param.ident)); + } + GenericParamKind::Const { .. } => { + const_args.push(cx.const_ident(self.span, param.ident)); + } } - }).collect(); + } // Create the type of `self`. - let path = cx.path_all(self.span, false, vec![type_ident], self_params, vec![]); + let sp = self.span; + let path = cx.path_all(sp, false, vec![type_ident], lifetimes, types, const_args, vec![]); let self_type = cx.ty_path(path); let attr = cx.attribute(self.span, diff --git a/src/libsyntax_ext/deriving/generic/ty.rs b/src/libsyntax_ext/deriving/generic/ty.rs index 362ea9ed2291f..80c992d348412 100644 --- a/src/libsyntax_ext/deriving/generic/ty.rs +++ b/src/libsyntax_ext/deriving/generic/ty.rs @@ -4,7 +4,7 @@ pub use PtrTy::*; pub use Ty::*; -use syntax::ast::{self, Expr, GenericParamKind, Generics, Ident, SelfKind, GenericArg}; +use syntax::ast::{self, Expr, GenericParamKind, Generics, Ident, SelfKind}; use syntax::ext::base::ExtCtxt; use syntax::ext::build::AstBuilder; use syntax::source_map::{respan, DUMMY_SP}; @@ -76,18 +76,14 @@ impl<'a> Path<'a> { let lt = mk_lifetimes(cx, span, &self.lifetime); let tys: Vec> = self.params.iter().map(|t| t.to_ty(cx, span, self_ty, self_generics)).collect(); - let params = lt.into_iter() - .map(|lt| GenericArg::Lifetime(lt)) - .chain(tys.into_iter().map(|ty| GenericArg::Type(ty))) - .collect(); match self.kind { - PathKind::Global => cx.path_all(span, true, idents, params, Vec::new()), - PathKind::Local => cx.path_all(span, false, idents, params, Vec::new()), + PathKind::Global => cx.path_all(span, true, idents, lt, tys, vec![], vec![]), + PathKind::Local => cx.path_all(span, false, idents, lt, tys, vec![], vec![]), PathKind::Std => { let def_site = DUMMY_SP.apply_mark(cx.current_expansion.mark); idents.insert(0, Ident::new(kw::DollarCrate, def_site)); - cx.path_all(span, false, idents, params, Vec::new()) + cx.path_all(span, false, idents, lt, tys, vec![], Vec::new()) } } @@ -172,27 +168,33 @@ impl<'a> Ty<'a> { } } - pub fn to_path(&self, - cx: &ExtCtxt<'_>, - span: Span, - self_ty: Ident, - generics: &Generics) - -> ast::Path { + pub fn to_path( + &self, + cx: &ExtCtxt<'_>, + span: Span, + self_ty: Ident, + generics: &Generics, + ) -> ast::Path { match *self { Self_ => { - let params: Vec<_> = generics.params.iter().map(|param| match param.kind { - GenericParamKind::Lifetime { .. } => { - GenericArg::Lifetime(ast::Lifetime { id: param.id, ident: param.ident }) - } - GenericParamKind::Type { .. } => { - GenericArg::Type(cx.ty_ident(span, param.ident)) + let mut lifetimes = vec![]; + let mut types = vec![]; + let mut const_args = vec![]; + for param in &generics.params { + match param.kind { + GenericParamKind::Lifetime { .. } => { + lifetimes.push(ast::Lifetime { id: param.id, ident: param.ident }); + } + GenericParamKind::Type { .. } => { + types.push(cx.ty_ident(span, param.ident)); + } + GenericParamKind::Const { .. } => { + const_args.push(cx.const_ident(span, param.ident)); + } } - GenericParamKind::Const { .. } => { - GenericArg::Const(cx.const_ident(span, param.ident)) - } - }).collect(); + } - cx.path_all(span, false, vec![self_ty], params, vec![]) + cx.path_all(span, false, vec![self_ty], lifetimes, types, const_args, vec![]) } Literal(ref p) => p.to_path(cx, span, self_ty, generics), Ptr(..) => cx.span_bug(span, "pointer in a path in generic `derive`"), diff --git a/src/libsyntax_ext/env.rs b/src/libsyntax_ext/env.rs index b7f2ecf0f9137..8f38b9bc380f8 100644 --- a/src/libsyntax_ext/env.rs +++ b/src/libsyntax_ext/env.rs @@ -3,7 +3,7 @@ // interface. // -use syntax::ast::{self, Ident, GenericArg}; +use syntax::ast::{self, Ident}; use syntax::ext::base::{self, *}; use syntax::ext::build::AstBuilder; use syntax::symbol::{kw, sym, Symbol}; @@ -25,20 +25,27 @@ pub fn expand_option_env<'cx>(cx: &'cx mut ExtCtxt<'_>, let e = match env::var(&*var.as_str()) { Err(..) => { let lt = cx.lifetime(sp, Ident::with_empty_ctxt(kw::StaticLifetime)); - cx.expr_path(cx.path_all(sp, - true, - cx.std_path(&[sym::option, sym::Option, sym::None]), - vec![GenericArg::Type(cx.ty_rptr(sp, - cx.ty_ident(sp, - Ident::with_empty_ctxt(sym::str)), - Some(lt), - ast::Mutability::Immutable))], - vec![])) + cx.expr_path(cx.path_all( + sp, + true, + cx.std_path(&[sym::option, sym::Option, sym::None]), + vec![], + vec![cx.ty_rptr(sp, + cx.ty_ident(sp, + Ident::with_empty_ctxt(sym::str)), + Some(lt), + ast::Mutability::Immutable, + )], + vec![], + vec![], + )) } Ok(s) => { - cx.expr_call_global(sp, - cx.std_path(&[sym::option, sym::Option, sym::Some]), - vec![cx.expr_str(sp, Symbol::intern(&s))]) + cx.expr_call_global( + sp, + cx.std_path(&[sym::option, sym::Option, sym::Some]), + vec![cx.expr_str(sp, Symbol::intern(&s))], + ) } }; MacEager::expr(e) diff --git a/src/test/ui/const-generics/const-param-before-other-params.rs b/src/test/ui/const-generics/const-param-before-other-params.rs index 2c81681b85e7d..f25bf7cc6ec2c 100644 --- a/src/test/ui/const-generics/const-param-before-other-params.rs +++ b/src/test/ui/const-generics/const-param-before-other-params.rs @@ -1,12 +1,7 @@ #![feature(const_generics)] //~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash -fn bar(_: &'a ()) { - //~^ ERROR lifetime parameters must be declared prior to const parameters -} - -fn foo(_: &T) { - //~^ ERROR type parameters must be declared prior to const parameters -} +fn bar(_: &'a ()) {} //~ ERROR incorrect parameter order +fn foo(_: &T) {} //~ ERROR incorrect parameter order fn main() {} diff --git a/src/test/ui/const-generics/const-param-before-other-params.stderr b/src/test/ui/const-generics/const-param-before-other-params.stderr index 33f981d1eba9b..e6d70d399f6d9 100644 --- a/src/test/ui/const-generics/const-param-before-other-params.stderr +++ b/src/test/ui/const-generics/const-param-before-other-params.stderr @@ -4,17 +4,17 @@ warning: the feature `const_generics` is incomplete and may cause the compiler t LL | #![feature(const_generics)] | ^^^^^^^^^^^^^^ -error: lifetime parameters must be declared prior to const parameters - --> $DIR/const-param-before-other-params.rs:4:21 +error: incorrect parameter order + --> $DIR/const-param-before-other-params.rs:4:7 | -LL | fn bar(_: &'a ()) { - | --------------^^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, const X: ()>` +LL | fn bar(_: &'a ()) {} + | ^^^^^^^^^^^^^^^^^ help: reorder the parameters: `<'a, const X: ()>` -error: type parameters must be declared prior to const parameters - --> $DIR/const-param-before-other-params.rs:8:21 +error: incorrect parameter order + --> $DIR/const-param-before-other-params.rs:5:7 | -LL | fn foo(_: &T) { - | --------------^- help: reorder the parameters: lifetimes, then types, then consts: `` +LL | fn foo(_: &T) {} + | ^^^^^^^^^^^^^^^^ help: reorder the parameters: `` error: aborting due to 2 previous errors diff --git a/src/test/ui/issues/issue-59508-1.rs b/src/test/ui/issues/issue-59508-1.rs index 4fbed9b08f215..4ad1a3edbcf30 100644 --- a/src/test/ui/issues/issue-59508-1.rs +++ b/src/test/ui/issues/issue-59508-1.rs @@ -10,7 +10,7 @@ struct A; impl A { pub fn do_things() { - //~^ ERROR lifetime parameters must be declared prior to type parameters + //~^ ERROR incorrect parameter order println!("panic"); } } diff --git a/src/test/ui/issues/issue-59508-1.stderr b/src/test/ui/issues/issue-59508-1.stderr index 8fb7d7c3c84dc..fa8aaa3bf06ea 100644 --- a/src/test/ui/issues/issue-59508-1.stderr +++ b/src/test/ui/issues/issue-59508-1.stderr @@ -4,11 +4,11 @@ warning: the feature `const_generics` is incomplete and may cause the compiler t LL | #![feature(const_generics)] | ^^^^^^^^^^^^^^ -error: lifetime parameters must be declared prior to type parameters - --> $DIR/issue-59508-1.rs:12:25 +error: incorrect parameter order + --> $DIR/issue-59508-1.rs:12:21 | LL | pub fn do_things() { - | ----^^--^^----- help: reorder the parameters: lifetimes, then types, then consts: `<'a, 'b: 'a, T>` + | ^^^^^^^^^^^^^^^ help: reorder the parameters: `<'a, 'b: 'a, T>` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-59508.fixed b/src/test/ui/issues/issue-59508.fixed index b5c60a1626f53..d53c751dfa1e9 100644 --- a/src/test/ui/issues/issue-59508.fixed +++ b/src/test/ui/issues/issue-59508.fixed @@ -8,7 +8,7 @@ struct A; impl A { pub fn do_things<'a, 'b: 'a, T>() { - //~^ ERROR lifetime parameters must be declared prior to type parameters + //~^ ERROR incorrect parameter order println!("panic"); } } diff --git a/src/test/ui/issues/issue-59508.rs b/src/test/ui/issues/issue-59508.rs index 0b39c5d8f2aec..e9c924e1f3559 100644 --- a/src/test/ui/issues/issue-59508.rs +++ b/src/test/ui/issues/issue-59508.rs @@ -8,7 +8,7 @@ struct A; impl A { pub fn do_things() { - //~^ ERROR lifetime parameters must be declared prior to type parameters + //~^ ERROR incorrect parameter order println!("panic"); } } diff --git a/src/test/ui/issues/issue-59508.stderr b/src/test/ui/issues/issue-59508.stderr index c0fdb2ef34ac4..6b74a8c2df761 100644 --- a/src/test/ui/issues/issue-59508.stderr +++ b/src/test/ui/issues/issue-59508.stderr @@ -1,8 +1,8 @@ -error: lifetime parameters must be declared prior to type parameters - --> $DIR/issue-59508.rs:10:25 +error: incorrect parameter order + --> $DIR/issue-59508.rs:10:21 | LL | pub fn do_things() { - | ----^^--^^----- help: reorder the parameters: lifetimes, then types: `<'a, 'b: 'a, T>` + | ^^^^^^^^^^^^^^^ help: reorder the parameters: `<'a, 'b: 'a, T>` error: aborting due to previous error diff --git a/src/test/ui/lifetime-before-type-params.fixed b/src/test/ui/lifetime-before-type-params.fixed new file mode 100644 index 0000000000000..2130ea6285ae8 --- /dev/null +++ b/src/test/ui/lifetime-before-type-params.fixed @@ -0,0 +1,8 @@ +// run-rustfix +#![allow(unused, dead_code)] +fn first<'a, 'b, T>() {} //~ ERROR incorrect parameter order +fn second<'a, 'b, T>() {} //~ ERROR incorrect parameter order +fn third<'a, T, U>() {} //~ ERROR incorrect parameter order +fn fourth<'a, 'b, 'c, T, U, V>() {} //~ ERROR incorrect parameter order + +fn main() {} diff --git a/src/test/ui/lifetime-before-type-params.rs b/src/test/ui/lifetime-before-type-params.rs index 9b905d4883a16..5d95871112138 100644 --- a/src/test/ui/lifetime-before-type-params.rs +++ b/src/test/ui/lifetime-before-type-params.rs @@ -1,9 +1,8 @@ -#![allow(unused)] -fn first() {} -//~^ ERROR lifetime parameters must be declared prior to type parameters -fn second<'a, T, 'b>() {} -//~^ ERROR lifetime parameters must be declared prior to type parameters -fn third() {} -//~^ ERROR lifetime parameters must be declared prior to type parameters -fn fourth<'a, T, 'b, U, 'c, V>() {} -//~^ ERROR lifetime parameters must be declared prior to type parameters +// run-rustfix +#![allow(unused, dead_code)] +fn first() {} //~ ERROR incorrect parameter order +fn second<'a, T, 'b>() {} //~ ERROR incorrect parameter order +fn third() {} //~ ERROR incorrect parameter order +fn fourth<'a, T, 'b, U, 'c, V>() {} //~ ERROR incorrect parameter order + +fn main() {} diff --git a/src/test/ui/lifetime-before-type-params.stderr b/src/test/ui/lifetime-before-type-params.stderr index ffc6784bafed8..c9039c8073baa 100644 --- a/src/test/ui/lifetime-before-type-params.stderr +++ b/src/test/ui/lifetime-before-type-params.stderr @@ -1,31 +1,26 @@ -error: lifetime parameters must be declared prior to type parameters - --> $DIR/lifetime-before-type-params.rs:2:13 +error: incorrect parameter order + --> $DIR/lifetime-before-type-params.rs:3:9 | LL | fn first() {} - | ----^^--^^- help: reorder the parameters: lifetimes, then types: `<'a, 'b, T>` + | ^^^^^^^^^^^ help: reorder the parameters: `<'a, 'b, T>` -error: lifetime parameters must be declared prior to type parameters - --> $DIR/lifetime-before-type-params.rs:4:18 +error: incorrect parameter order + --> $DIR/lifetime-before-type-params.rs:4:10 | LL | fn second<'a, T, 'b>() {} - | --------^^- help: reorder the parameters: lifetimes, then types: `<'a, 'b, T>` + | ^^^^^^^^^^^ help: reorder the parameters: `<'a, 'b, T>` -error: lifetime parameters must be declared prior to type parameters - --> $DIR/lifetime-before-type-params.rs:6:16 +error: incorrect parameter order + --> $DIR/lifetime-before-type-params.rs:5:9 | LL | fn third() {} - | -------^^- help: reorder the parameters: lifetimes, then types: `<'a, T, U>` + | ^^^^^^^^^^ help: reorder the parameters: `<'a, T, U>` -error: lifetime parameters must be declared prior to type parameters - --> $DIR/lifetime-before-type-params.rs:8:18 +error: incorrect parameter order + --> $DIR/lifetime-before-type-params.rs:6:10 | LL | fn fourth<'a, T, 'b, U, 'c, V>() {} - | --------^^-----^^---- help: reorder the parameters: lifetimes, then types: `<'a, 'b, 'c, T, U, V>` + | ^^^^^^^^^^^^^^^^^^^^^ help: reorder the parameters: `<'a, 'b, 'c, T, U, V>` -error[E0601]: `main` function not found in crate `lifetime_before_type_params` - | - = note: consider adding a `main` function to `$DIR/lifetime-before-type-params.rs` - -error: aborting due to 5 previous errors +error: aborting due to 4 previous errors -For more information about this error, try `rustc --explain E0601`. diff --git a/src/test/ui/parser/issue-14303-enum.fixed b/src/test/ui/parser/issue-14303-enum.fixed new file mode 100644 index 0000000000000..18103cc47ab44 --- /dev/null +++ b/src/test/ui/parser/issue-14303-enum.fixed @@ -0,0 +1,7 @@ +// run-rustfix +#![allow(dead_code)] +enum X<'a, 'b, T> { //~ ERROR incorrect parameter order + A(&'a &'b T) +} + +fn main() {} diff --git a/src/test/ui/parser/issue-14303-enum.rs b/src/test/ui/parser/issue-14303-enum.rs index a6106159805b2..93b82f3ee2d46 100644 --- a/src/test/ui/parser/issue-14303-enum.rs +++ b/src/test/ui/parser/issue-14303-enum.rs @@ -1,5 +1,6 @@ -enum X<'a, T, 'b> { -//~^ ERROR lifetime parameters must be declared prior to type parameters +// run-rustfix +#![allow(dead_code)] +enum X<'a, T, 'b> { //~ ERROR incorrect parameter order A(&'a &'b T) } diff --git a/src/test/ui/parser/issue-14303-enum.stderr b/src/test/ui/parser/issue-14303-enum.stderr index 46f16ea0cc41c..eb5fd44fe1e48 100644 --- a/src/test/ui/parser/issue-14303-enum.stderr +++ b/src/test/ui/parser/issue-14303-enum.stderr @@ -1,8 +1,8 @@ -error: lifetime parameters must be declared prior to type parameters - --> $DIR/issue-14303-enum.rs:1:15 +error: incorrect parameter order + --> $DIR/issue-14303-enum.rs:3:7 | LL | enum X<'a, T, 'b> { - | --------^^- help: reorder the parameters: lifetimes, then types: `<'a, 'b, T>` + | ^^^^^^^^^^^ help: reorder the parameters: `<'a, 'b, T>` error: aborting due to previous error diff --git a/src/test/ui/parser/issue-14303-fn-def.fixed b/src/test/ui/parser/issue-14303-fn-def.fixed new file mode 100644 index 0000000000000..c062596c34c47 --- /dev/null +++ b/src/test/ui/parser/issue-14303-fn-def.fixed @@ -0,0 +1,5 @@ +// run-rustfix +#![allow(dead_code, unused_variables)] +fn foo<'a, 'b, T>(x: &'a T) {} //~ ERROR incorrect parameter order + +fn main() {} diff --git a/src/test/ui/parser/issue-14303-fn-def.rs b/src/test/ui/parser/issue-14303-fn-def.rs index 221bd311e7479..83517cca5f4fb 100644 --- a/src/test/ui/parser/issue-14303-fn-def.rs +++ b/src/test/ui/parser/issue-14303-fn-def.rs @@ -1,4 +1,5 @@ -fn foo<'a, T, 'b>(x: &'a T) {} -//~^ ERROR lifetime parameters must be declared prior to type parameters +// run-rustfix +#![allow(dead_code, unused_variables)] +fn foo<'a, T, 'b>(x: &'a T) {} //~ ERROR incorrect parameter order fn main() {} diff --git a/src/test/ui/parser/issue-14303-fn-def.stderr b/src/test/ui/parser/issue-14303-fn-def.stderr index 8cbab4b9653a0..2e8e1e3fa077d 100644 --- a/src/test/ui/parser/issue-14303-fn-def.stderr +++ b/src/test/ui/parser/issue-14303-fn-def.stderr @@ -1,8 +1,8 @@ -error: lifetime parameters must be declared prior to type parameters - --> $DIR/issue-14303-fn-def.rs:1:15 +error: incorrect parameter order + --> $DIR/issue-14303-fn-def.rs:3:7 | LL | fn foo<'a, T, 'b>(x: &'a T) {} - | --------^^- help: reorder the parameters: lifetimes, then types: `<'a, 'b, T>` + | ^^^^^^^^^^^ help: reorder the parameters: `<'a, 'b, T>` error: aborting due to previous error diff --git a/src/test/ui/parser/issue-14303-fncall.fixed b/src/test/ui/parser/issue-14303-fncall.fixed new file mode 100644 index 0000000000000..53cdf1cce08dc --- /dev/null +++ b/src/test/ui/parser/issue-14303-fncall.fixed @@ -0,0 +1,18 @@ +// run-rustfix +// compile-flags: -Zborrowck=mir +// we need the above to avoid ast borrowck failure in recovered code +#![allow(dead_code, unused_variables)] + +struct S<'a, T> { + a: &'a T, + b: &'a T, +} + +fn foo<'a, 'b>(start: &'a usize, end: &'a usize) { + let _x = (*start..*end) + .map(|x| S { a: start, b: end }) + .collect::>>(); + //~^ ERROR incorrect parameter order +} + +fn main() {} diff --git a/src/test/ui/parser/issue-14303-fncall.rs b/src/test/ui/parser/issue-14303-fncall.rs index 39694198cdb4d..96534a54ff7db 100644 --- a/src/test/ui/parser/issue-14303-fncall.rs +++ b/src/test/ui/parser/issue-14303-fncall.rs @@ -1,6 +1,7 @@ -// can't run rustfix because it doesn't handle multipart suggestions correctly +// run-rustfix // compile-flags: -Zborrowck=mir // we need the above to avoid ast borrowck failure in recovered code +#![allow(dead_code, unused_variables)] struct S<'a, T> { a: &'a T, @@ -11,7 +12,7 @@ fn foo<'a, 'b>(start: &'a usize, end: &'a usize) { let _x = (*start..*end) .map(|x| S { a: start, b: end }) .collect::>>(); - //~^ ERROR lifetime arguments must be declared prior to type arguments + //~^ ERROR incorrect parameter order } fn main() {} diff --git a/src/test/ui/parser/issue-14303-fncall.stderr b/src/test/ui/parser/issue-14303-fncall.stderr index 8ef9f1a1a6c79..31296fa301c61 100644 --- a/src/test/ui/parser/issue-14303-fncall.stderr +++ b/src/test/ui/parser/issue-14303-fncall.stderr @@ -1,8 +1,8 @@ -error: lifetime arguments must be declared prior to type arguments - --> $DIR/issue-14303-fncall.rs:13:29 +error: incorrect parameter order + --> $DIR/issue-14303-fncall.rs:14:26 | LL | .collect::>>(); - | ^^ + | ^^^^^ help: reorder the arguments: `'a, _` error: aborting due to previous error diff --git a/src/test/ui/parser/issue-14303-impl.fixed b/src/test/ui/parser/issue-14303-impl.fixed new file mode 100644 index 0000000000000..6e90814fb8d19 --- /dev/null +++ b/src/test/ui/parser/issue-14303-impl.fixed @@ -0,0 +1,7 @@ +// run-rustfix +#![allow(dead_code)] +struct X(T); + +impl<'a, 'b, T> X {} //~ ERROR incorrect parameter order + +fn main() {} diff --git a/src/test/ui/parser/issue-14303-impl.rs b/src/test/ui/parser/issue-14303-impl.rs index 4dc2c66601807..862d6425efa23 100644 --- a/src/test/ui/parser/issue-14303-impl.rs +++ b/src/test/ui/parser/issue-14303-impl.rs @@ -1,6 +1,7 @@ +// run-rustfix +#![allow(dead_code)] struct X(T); -impl<'a, T, 'b> X {} -//~^ ERROR lifetime parameters must be declared prior to type parameters +impl<'a, T, 'b> X {} //~ ERROR incorrect parameter order fn main() {} diff --git a/src/test/ui/parser/issue-14303-impl.stderr b/src/test/ui/parser/issue-14303-impl.stderr index 56cd4fb381038..b3ea56328664f 100644 --- a/src/test/ui/parser/issue-14303-impl.stderr +++ b/src/test/ui/parser/issue-14303-impl.stderr @@ -1,8 +1,8 @@ -error: lifetime parameters must be declared prior to type parameters - --> $DIR/issue-14303-impl.rs:3:13 +error: incorrect parameter order + --> $DIR/issue-14303-impl.rs:5:5 | LL | impl<'a, T, 'b> X {} - | --------^^- help: reorder the parameters: lifetimes, then types: `<'a, 'b, T>` + | ^^^^^^^^^^^ help: reorder the parameters: `<'a, 'b, T>` error: aborting due to previous error diff --git a/src/test/ui/parser/issue-14303-path.fixed b/src/test/ui/parser/issue-14303-path.fixed new file mode 100644 index 0000000000000..6b15edfe3ad60 --- /dev/null +++ b/src/test/ui/parser/issue-14303-path.fixed @@ -0,0 +1,15 @@ +// run-rustfix +#![allow(dead_code, unused_variables)] +mod foo { + pub struct X<'a, 'b, 'c, T> { + a: &'a str, + b: &'b str, + c: &'c str, + t: T, + } +} + +fn bar<'a, 'b, 'c, T>(x: foo::X<'a, 'b, 'c, T>) {} +//~^ ERROR incorrect parameter order + +fn main() {} diff --git a/src/test/ui/parser/issue-14303-path.rs b/src/test/ui/parser/issue-14303-path.rs index 386d19859e4a8..74a3071d565c5 100644 --- a/src/test/ui/parser/issue-14303-path.rs +++ b/src/test/ui/parser/issue-14303-path.rs @@ -1,3 +1,5 @@ +// run-rustfix +#![allow(dead_code, unused_variables)] mod foo { pub struct X<'a, 'b, 'c, T> { a: &'a str, @@ -8,6 +10,6 @@ mod foo { } fn bar<'a, 'b, 'c, T>(x: foo::X<'a, T, 'b, 'c>) {} -//~^ ERROR lifetime arguments must be declared prior to type arguments +//~^ ERROR incorrect parameter order fn main() {} diff --git a/src/test/ui/parser/issue-14303-path.stderr b/src/test/ui/parser/issue-14303-path.stderr index 19f2995ebee53..2719989e61e88 100644 --- a/src/test/ui/parser/issue-14303-path.stderr +++ b/src/test/ui/parser/issue-14303-path.stderr @@ -1,8 +1,8 @@ -error: lifetime arguments must be declared prior to type arguments - --> $DIR/issue-14303-path.rs:10:40 +error: incorrect parameter order + --> $DIR/issue-14303-path.rs:12:33 | LL | fn bar<'a, 'b, 'c, T>(x: foo::X<'a, T, 'b, 'c>) {} - | ^^ ^^ + | ^^^^^^^^^^^^^ help: reorder the arguments: `'a, 'b, 'c, T` error: aborting due to previous error diff --git a/src/test/ui/parser/issue-14303-struct.fixed b/src/test/ui/parser/issue-14303-struct.fixed new file mode 100644 index 0000000000000..02f93c70454ff --- /dev/null +++ b/src/test/ui/parser/issue-14303-struct.fixed @@ -0,0 +1,7 @@ +// run-rustfix +#![allow(dead_code)] +struct X<'a, 'b, T> { //~ ERROR incorrect parameter order + x: &'a &'b T +} + +fn main() {} diff --git a/src/test/ui/parser/issue-14303-struct.rs b/src/test/ui/parser/issue-14303-struct.rs index 0bd10b4d08516..a3b82c7fadb40 100644 --- a/src/test/ui/parser/issue-14303-struct.rs +++ b/src/test/ui/parser/issue-14303-struct.rs @@ -1,5 +1,6 @@ -struct X<'a, T, 'b> { -//~^ ERROR lifetime parameters must be declared prior to type parameters +// run-rustfix +#![allow(dead_code)] +struct X<'a, T, 'b> { //~ ERROR incorrect parameter order x: &'a &'b T } diff --git a/src/test/ui/parser/issue-14303-struct.stderr b/src/test/ui/parser/issue-14303-struct.stderr index f31cb92ad66ce..60edb7c830565 100644 --- a/src/test/ui/parser/issue-14303-struct.stderr +++ b/src/test/ui/parser/issue-14303-struct.stderr @@ -1,8 +1,8 @@ -error: lifetime parameters must be declared prior to type parameters - --> $DIR/issue-14303-struct.rs:1:17 +error: incorrect parameter order + --> $DIR/issue-14303-struct.rs:3:9 | LL | struct X<'a, T, 'b> { - | --------^^- help: reorder the parameters: lifetimes, then types: `<'a, 'b, T>` + | ^^^^^^^^^^^ help: reorder the parameters: `<'a, 'b, T>` error: aborting due to previous error diff --git a/src/test/ui/parser/issue-14303-trait.fixed b/src/test/ui/parser/issue-14303-trait.fixed new file mode 100644 index 0000000000000..566a031934cea --- /dev/null +++ b/src/test/ui/parser/issue-14303-trait.fixed @@ -0,0 +1,5 @@ +// run-rustfix +#![allow(dead_code)] +trait Foo<'a, 'b, T> {} //~ ERROR incorrect parameter order + +fn main() {} diff --git a/src/test/ui/parser/issue-14303-trait.rs b/src/test/ui/parser/issue-14303-trait.rs index f253de92d92de..9162197ec25c0 100644 --- a/src/test/ui/parser/issue-14303-trait.rs +++ b/src/test/ui/parser/issue-14303-trait.rs @@ -1,4 +1,5 @@ -trait Foo<'a, T, 'b> {} -//~^ ERROR lifetime parameters must be declared prior to type parameters +// run-rustfix +#![allow(dead_code)] +trait Foo<'a, T, 'b> {} //~ ERROR incorrect parameter order fn main() {} diff --git a/src/test/ui/parser/issue-14303-trait.stderr b/src/test/ui/parser/issue-14303-trait.stderr index 0e7399102bf17..86aedcba015de 100644 --- a/src/test/ui/parser/issue-14303-trait.stderr +++ b/src/test/ui/parser/issue-14303-trait.stderr @@ -1,8 +1,8 @@ -error: lifetime parameters must be declared prior to type parameters - --> $DIR/issue-14303-trait.rs:1:18 +error: incorrect parameter order + --> $DIR/issue-14303-trait.rs:3:10 | LL | trait Foo<'a, T, 'b> {} - | --------^^- help: reorder the parameters: lifetimes, then types: `<'a, 'b, T>` + | ^^^^^^^^^^^ help: reorder the parameters: `<'a, 'b, T>` error: aborting due to previous error diff --git a/src/test/ui/parser/issue-32214.fixed b/src/test/ui/parser/issue-32214.fixed new file mode 100644 index 0000000000000..cc348e57ffa51 --- /dev/null +++ b/src/test/ui/parser/issue-32214.fixed @@ -0,0 +1,7 @@ +// run-rustfix +pub trait Trait { type Item; } + +pub fn test >() {} +//~^ ERROR incorrect parameter order + +fn main() { } diff --git a/src/test/ui/parser/issue-32214.rs b/src/test/ui/parser/issue-32214.rs index 7191a3234c083..e03eaaeeb73b8 100644 --- a/src/test/ui/parser/issue-32214.rs +++ b/src/test/ui/parser/issue-32214.rs @@ -1,8 +1,7 @@ -// compile-flags: -Z continue-parse-after-error - -trait Trait { type Item; } +// run-rustfix +pub trait Trait { type Item; } pub fn test >() {} -//~^ ERROR associated type bindings must be declared after generic parameters +//~^ ERROR incorrect parameter order fn main() { } diff --git a/src/test/ui/parser/issue-32214.stderr b/src/test/ui/parser/issue-32214.stderr index 7022019a22f26..5d54451521e1e 100644 --- a/src/test/ui/parser/issue-32214.stderr +++ b/src/test/ui/parser/issue-32214.stderr @@ -1,10 +1,8 @@ -error: associated type bindings must be declared after generic parameters - --> $DIR/issue-32214.rs:5:25 +error: incorrect parameter order + --> $DIR/issue-32214.rs:4:25 | LL | pub fn test >() {} - | -------^^^ - | | - | this associated type binding should be moved after the generic parameters + | ^^^^^^^^^^ help: reorder the arguments: `W, Item = ()` error: aborting due to previous error diff --git a/src/test/ui/suggestions/suggest-move-lifetimes.rs b/src/test/ui/suggestions/suggest-move-lifetimes.rs index 6b26f1214368c..b2afaec49dffc 100644 --- a/src/test/ui/suggestions/suggest-move-lifetimes.rs +++ b/src/test/ui/suggestions/suggest-move-lifetimes.rs @@ -1,18 +1,18 @@ -struct A { //~ ERROR lifetime parameters must be declared +struct A { //~ ERROR incorrect parameter order t: &'a T, } -struct B { //~ ERROR lifetime parameters must be declared +struct B { //~ ERROR incorrect parameter order t: &'a T, u: U, } -struct C { //~ ERROR lifetime parameters must be declared +struct C { //~ ERROR incorrect parameter order t: &'a T, u: U, } -struct D { //~ ERROR lifetime parameters must be declared +struct D { //~ ERROR incorrect parameter order t: &'a T, u: &'b U, v: &'c V, diff --git a/src/test/ui/suggestions/suggest-move-lifetimes.stderr b/src/test/ui/suggestions/suggest-move-lifetimes.stderr index 1851c8deaa8b4..5641509d950ec 100644 --- a/src/test/ui/suggestions/suggest-move-lifetimes.stderr +++ b/src/test/ui/suggestions/suggest-move-lifetimes.stderr @@ -1,26 +1,26 @@ -error: lifetime parameters must be declared prior to type parameters - --> $DIR/suggest-move-lifetimes.rs:1:13 +error: incorrect parameter order + --> $DIR/suggest-move-lifetimes.rs:1:9 | LL | struct A { - | ----^^- help: reorder the parameters: lifetimes, then types: `<'a, T>` + | ^^^^^^^ help: reorder the parameters: `<'a, T>` -error: lifetime parameters must be declared prior to type parameters - --> $DIR/suggest-move-lifetimes.rs:5:13 +error: incorrect parameter order + --> $DIR/suggest-move-lifetimes.rs:5:9 | LL | struct B { - | ----^^---- help: reorder the parameters: lifetimes, then types: `<'a, T, U>` + | ^^^^^^^^^^ help: reorder the parameters: `<'a, T, U>` -error: lifetime parameters must be declared prior to type parameters - --> $DIR/suggest-move-lifetimes.rs:10:16 +error: incorrect parameter order + --> $DIR/suggest-move-lifetimes.rs:10:9 | LL | struct C { - | -------^^- help: reorder the parameters: lifetimes, then types: `<'a, T, U>` + | ^^^^^^^^^^ help: reorder the parameters: `<'a, T, U>` -error: lifetime parameters must be declared prior to type parameters - --> $DIR/suggest-move-lifetimes.rs:15:16 +error: incorrect parameter order + --> $DIR/suggest-move-lifetimes.rs:15:9 | LL | struct D { - | -------^^--^^-----^^- help: reorder the parameters: lifetimes, then types: `<'a, 'b, 'c, T, U, V>` + | ^^^^^^^^^^^^^^^^^^^^^ help: reorder the parameters: `<'a, 'b, 'c, T, U, V>` error: aborting due to 4 previous errors diff --git a/src/test/ui/suggestions/suggest-move-types.rs b/src/test/ui/suggestions/suggest-move-types.rs index 890950ea08c5d..1e0978ac28e60 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,19 @@ 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 incorrect parameter order m: M, t: T, } struct Al<'a, T, M: OneWithLifetime> { -//~^ ERROR associated type bindings must be declared after generic parameters -//~^^ ERROR lifetime arguments must be declared prior to type arguments +//~^ ERROR incorrect parameter order m: M, t: &'a T, } -struct B> { //~ ERROR associated type bindings must be declared after generic parameters +struct B> { //~ ERROR incorrect parameter order m: M, t: T, u: U, @@ -46,15 +43,14 @@ 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 lifetime arguments must be declared prior to type arguments +//~^ ERROR incorrect parameter order m: M, t: &'a T, u: &'b U, v: &'c V, } -struct C> { //~ ERROR associated type bindings must be declared after generic parameters +struct C> { //~ ERROR incorrect parameter order m: M, t: T, u: U, @@ -62,15 +58,14 @@ 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 lifetime arguments must be declared prior to type arguments +//~^ ERROR incorrect parameter order m: M, t: &'a T, u: &'b U, v: &'c V, } -struct D> { //~ ERROR associated type bindings must be declared after generic parameters +struct D> { //~ ERROR incorrect parameter order m: M, t: T, u: U, @@ -78,8 +73,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 lifetime arguments must be declared prior to type arguments +//~^ ERROR incorrect parameter order m: M, t: &'a T, u: &'b U, diff --git a/src/test/ui/suggestions/suggest-move-types.stderr b/src/test/ui/suggestions/suggest-move-types.stderr index 552fb78cd3fdd..e284205b9775f 100644 --- a/src/test/ui/suggestions/suggest-move-types.stderr +++ b/src/test/ui/suggestions/suggest-move-types.stderr @@ -1,102 +1,50 @@ -error: associated type bindings must be declared after generic parameters +error: incorrect parameter order --> $DIR/suggest-move-types.rs:28:20 | LL | struct A> { - | ----^^^ - | | - | this associated type binding should be moved after the generic parameters + | ^^^^^^^ help: reorder the arguments: `T, A = ()` -error: associated type bindings must be declared after generic parameters +error: incorrect parameter order --> $DIR/suggest-move-types.rs:34:37 | LL | struct Al<'a, T, M: OneWithLifetime> { - | ----^^^^^^^ - | | - | this associated type binding should be moved after the generic parameters + | ^^^^^^^^^^^ help: reorder the arguments: `'a, T, A = ()` -error: associated type bindings must be declared after generic parameters - --> $DIR/suggest-move-types.rs:41:28 +error: incorrect parameter order + --> $DIR/suggest-move-types.rs:40:28 | 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 + | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: reorder the arguments: `T, U, V, A = (), B = (), C = ()` -error: associated type bindings must be declared after generic parameters - --> $DIR/suggest-move-types.rs:48:53 +error: incorrect parameter order + --> $DIR/suggest-move-types.rs:47:53 | 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 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: reorder the arguments: `'a, 'b, 'c, T, U, V, A = (), B = (), C = ()` -error: associated type bindings must be declared after generic parameters - --> $DIR/suggest-move-types.rs:57:28 +error: incorrect parameter order + --> $DIR/suggest-move-types.rs:55:28 | 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 + | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: reorder the arguments: `T, U, V, A = (), B = (), C = ()` -error: associated type bindings must be declared after generic parameters - --> $DIR/suggest-move-types.rs:64:53 +error: incorrect parameter order + --> $DIR/suggest-move-types.rs:62:53 | 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 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: reorder the arguments: `'a, 'b, 'c, T, U, V, A = (), B = (), C = ()` -error: associated type bindings must be declared after generic parameters - --> $DIR/suggest-move-types.rs:73:28 +error: incorrect parameter order + --> $DIR/suggest-move-types.rs:70:28 | 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 + | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: reorder the arguments: `T, U, V, A = (), B = (), C = ()` -error: associated type bindings must be declared after generic parameters - --> $DIR/suggest-move-types.rs:80:53 +error: incorrect parameter order + --> $DIR/suggest-move-types.rs:77:53 | 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 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: reorder the arguments: `'a, 'b, 'c, T, U, V, A = (), B = (), C = ()` -error: lifetime arguments must be declared prior to type arguments - --> $DIR/suggest-move-types.rs:34:46 - | -LL | struct Al<'a, T, M: OneWithLifetime> { - | ^^ - -error: lifetime arguments must be declared prior to type arguments - --> $DIR/suggest-move-types.rs:48:80 - | -LL | struct Bl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime> { - | ^^ ^^ ^^ - -error: lifetime arguments must be declared prior to type arguments - --> $DIR/suggest-move-types.rs:64:56 - | -LL | struct Cl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime> { - | ^^ ^^ ^^ - -error: lifetime arguments must be declared prior to type arguments - --> $DIR/suggest-move-types.rs:80:56 - | -LL | struct Dl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime> { - | ^^ ^^ ^^ - -error: aborting due to 12 previous errors +error: aborting due to 8 previous errors diff --git a/src/test/ui/traits/trait-object-vs-lifetime.rs b/src/test/ui/traits/trait-object-vs-lifetime.rs index 36dec21be0520..25acbac9b11aa 100644 --- a/src/test/ui/traits/trait-object-vs-lifetime.rs +++ b/src/test/ui/traits/trait-object-vs-lifetime.rs @@ -12,6 +12,6 @@ fn main() { //~^ ERROR wrong number of lifetime arguments: expected 1, found 2 //~| ERROR wrong number of type arguments: expected 1, found 0 let _: S<'static +, 'static>; - //~^ ERROR lifetime arguments must be declared prior to type arguments + //~^ ERROR incorrect parameter order //~| ERROR at least one non-builtin trait is required for an object type } diff --git a/src/test/ui/traits/trait-object-vs-lifetime.stderr b/src/test/ui/traits/trait-object-vs-lifetime.stderr index c13d0e3f29373..dec0cfe4299b0 100644 --- a/src/test/ui/traits/trait-object-vs-lifetime.stderr +++ b/src/test/ui/traits/trait-object-vs-lifetime.stderr @@ -1,8 +1,8 @@ -error: lifetime arguments must be declared prior to type arguments - --> $DIR/trait-object-vs-lifetime.rs:14:25 +error: incorrect parameter order + --> $DIR/trait-object-vs-lifetime.rs:14:14 | LL | let _: S<'static +, 'static>; - | ^^^^^^^ + | ^^^^^^^^^^^^^^^^^^ help: reorder the arguments: `'static, 'static` error[E0224]: at least one non-builtin trait is required for an object type --> $DIR/trait-object-vs-lifetime.rs:9:23