diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index ab9db159038af..f1dc7e5390629 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -8,6 +8,7 @@ use crate::collect::PlaceholderHirTyCollector; use crate::middle::resolve_lifetime as rl; use crate::require_c_abi_if_c_variadic; +use rustc_ast::ast::ParamKindOrd; use rustc_ast::util::lev_distance::find_best_match_for_name; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_errors::ErrorReported; @@ -483,8 +484,25 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { arg.descr(), kind, ); + + let kind_ord = match kind { + "lifetime" => ParamKindOrd::Lifetime, + "type" => ParamKindOrd::Type, + "constant" => ParamKindOrd::Const, + // It's more concise to match on the string representation, though it means + // the match is non-exhaustive. + _ => bug!("invalid generic parameter kind {}", kind), + }; + let arg_ord = match arg { + GenericArg::Lifetime(_) => ParamKindOrd::Lifetime, + GenericArg::Type(_) => ParamKindOrd::Type, + GenericArg::Const(_) => ParamKindOrd::Const, + }; + // This note will be true as long as generic parameters are strictly ordered by their kind. - err.note(&format!("{} arguments must be provided before {} arguments", kind, arg.descr())); + let (first, last) = + if kind_ord < arg_ord { (kind, arg.descr()) } else { (arg.descr(), kind) }; + err.note(&format!("{} arguments must be provided before {} arguments", first, last)); err.emit(); } diff --git a/src/test/ui/suggestions/suggest-move-types.stderr b/src/test/ui/suggestions/suggest-move-types.stderr index 3bb6fd6e4f423..96f1656bae4ac 100644 --- a/src/test/ui/suggestions/suggest-move-types.stderr +++ b/src/test/ui/suggestions/suggest-move-types.stderr @@ -124,7 +124,7 @@ error[E0747]: lifetime provided when a type was expected LL | struct Cl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime> { | ^^ | - = note: type arguments must be provided before lifetime arguments + = note: lifetime arguments must be provided before type arguments error[E0747]: lifetime provided when a type was expected --> $DIR/suggest-move-types.rs:82:56 @@ -132,7 +132,7 @@ error[E0747]: lifetime provided when a type was expected LL | struct Dl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime> { | ^^ | - = note: type arguments must be provided before lifetime arguments + = note: lifetime arguments must be provided before type arguments error: aborting due to 12 previous errors