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