Change:
suggests type parameters should come before lifetime parameters, which is incorrect. The message is emitted here: <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --This issue has been assigned to via . <!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOT_END --
I want to try working on this. claim
I've been trying to fix this, but even reversing the arguments to the format didn't seem to do anything. Am I missing something? I also to the error note for testing: And here's the error diff: EDIT: I modified the expected stderr for the test so that it matches how it should look after this is fixed by the way.
I've looked into it a bit more, and it looks like this isn't as simple as I thought at first. I thought it might work if I just reversed the arguments to , but that messes up other things. I think I'll need to rethink this.
Note that I cherry-picked the examples that were incorrect. The diagnostic is correct in other cases. You'll need to investigate a little to work out how best to fix this; one simple solution would be to sort the two with , though I'm not sure if that's the cleanest approach.
Okay, thanks for the info! I'll look into sorting and see if that works :)
I think I've figured out a basic solution. Let me know if there are things I can improve!

Discussion:
use crate::collect::PlaceholderHirTyCollector; use crate::middle::resolve_lifetime as rl; use crate::require_c_abi_if_c_variadic; <ins> use rustc_ast::ast::ParamKindOrd; </ins> use rustc_ast::util::lev_distance::find_best_match_for_name; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_errors::ErrorReported;

arg.descr(), kind, ); <ins> 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, }; </ins> // This note will be true as long as generic parameters are strictly ordered by their kind. <del> err.note(&format!("{} arguments must be provided before {} arguments", kind, arg.descr())); </del> <ins> 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)); </ins> err.emit(); }

LL | struct Cl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime<T, 'a, A=(), B=(), C=(), U, 'b, V, 'c>> { |                                                        ^^ | <del> = note: type arguments must be provided before lifetime arguments </del> <ins> = note: lifetime arguments must be provided before type arguments </ins> error[E0747]: lifetime provided when a type was expected --> $DIR/suggest-move-types.rs:82:56

LL | struct Dl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime<T, 'a, A=(), B=(), U, 'b, C=(), V, 'c>> { |                                                        ^^ | <del> = note: type arguments must be provided before lifetime arguments </del> <ins> = note: lifetime arguments must be provided before type arguments </ins> error: aborting due to 12 previous errors