1
Fork 0

simplify validate_generic_param_order

This commit is contained in:
klensy 2021-06-10 00:09:12 +03:00
parent da7ada584a
commit 6a19867417

View file

@ -889,35 +889,32 @@ fn validate_generic_param_order(
) { ) {
let mut max_param: Option<ParamKindOrd> = None; let mut max_param: Option<ParamKindOrd> = None;
let mut out_of_order = FxHashMap::default(); let mut out_of_order = FxHashMap::default();
let mut param_idents = vec![]; let mut param_idents = Vec::with_capacity(generics.len());
for param in generics { for (idx, param) in generics.iter().enumerate() {
let ident = Some(param.ident.to_string()); let ident = param.ident;
let (kind, bounds, span) = (&param.kind, Some(&*param.bounds), param.ident.span); let (kind, bounds, span) = (&param.kind, &param.bounds, ident.span);
let (ord_kind, ident) = match &param.kind { let (ord_kind, ident) = match &param.kind {
GenericParamKind::Lifetime => (ParamKindOrd::Lifetime, ident), GenericParamKind::Lifetime => (ParamKindOrd::Lifetime, ident.to_string()),
GenericParamKind::Type { default: _ } => (ParamKindOrd::Type, ident), GenericParamKind::Type { default: _ } => (ParamKindOrd::Type, ident.to_string()),
GenericParamKind::Const { ref ty, kw_span: _, default: _ } => { GenericParamKind::Const { ref ty, kw_span: _, default: _ } => {
let ty = pprust::ty_to_string(ty); let ty = pprust::ty_to_string(ty);
let unordered = sess.features_untracked().unordered_const_ty_params(); let unordered = sess.features_untracked().unordered_const_ty_params();
(ParamKindOrd::Const { unordered }, Some(format!("const {}: {}", param.ident, ty))) (ParamKindOrd::Const { unordered }, format!("const {}: {}", ident, ty))
} }
}; };
if let Some(ident) = ident { param_idents.push((kind, ord_kind, bounds, idx, ident));
param_idents.push((kind, ord_kind, bounds, param_idents.len(), ident));
}
let max_param = &mut max_param;
match max_param { match max_param {
Some(max_param) if *max_param > ord_kind => { Some(max_param) if max_param > ord_kind => {
let entry = out_of_order.entry(ord_kind).or_insert((*max_param, vec![])); let entry = out_of_order.entry(ord_kind).or_insert((max_param, vec![]));
entry.1.push(span); entry.1.push(span);
} }
Some(_) | None => *max_param = Some(ord_kind), Some(_) | None => max_param = Some(ord_kind),
}; };
} }
let mut ordered_params = "<".to_string();
if !out_of_order.is_empty() { if !out_of_order.is_empty() {
let mut ordered_params = "<".to_string();
param_idents.sort_by_key(|&(_, po, _, i, _)| (po, i)); param_idents.sort_by_key(|&(_, po, _, i, _)| (po, i));
let mut first = true; let mut first = true;
for (kind, _, bounds, _, ident) in param_idents { for (kind, _, bounds, _, ident) in param_idents {
@ -925,12 +922,12 @@ fn validate_generic_param_order(
ordered_params += ", "; ordered_params += ", ";
} }
ordered_params += &ident; ordered_params += &ident;
if let Some(bounds) = bounds {
if !bounds.is_empty() { if !bounds.is_empty() {
ordered_params += ": "; ordered_params += ": ";
ordered_params += &pprust::bounds_to_string(&bounds); ordered_params += &pprust::bounds_to_string(&bounds);
}
} }
match kind { match kind {
GenericParamKind::Type { default: Some(default) } => { GenericParamKind::Type { default: Some(default) } => {
ordered_params += " = "; ordered_params += " = ";
@ -946,32 +943,32 @@ fn validate_generic_param_order(
} }
first = false; first = false;
} }
}
ordered_params += ">";
for (param_ord, (max_param, spans)) in &out_of_order { ordered_params += ">";
let mut err =
handler.struct_span_err( for (param_ord, (max_param, spans)) in &out_of_order {
let mut err = handler.struct_span_err(
spans.clone(), spans.clone(),
&format!( &format!(
"{} parameters must be declared prior to {} parameters", "{} parameters must be declared prior to {} parameters",
param_ord, max_param, param_ord, max_param,
), ),
); );
err.span_suggestion( err.span_suggestion(
span, span,
&format!( &format!(
"reorder the parameters: lifetimes, {}", "reorder the parameters: lifetimes, {}",
if sess.features_untracked().unordered_const_ty_params() { if sess.features_untracked().unordered_const_ty_params() {
"then consts and types" "then consts and types"
} else { } else {
"then types, then consts" "then types, then consts"
} }
), ),
ordered_params.clone(), ordered_params.clone(),
Applicability::MachineApplicable, Applicability::MachineApplicable,
); );
err.emit(); err.emit();
}
} }
} }