-
Notifications
You must be signed in to change notification settings - Fork 13.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Suggest how to fix with unconstrained type parameters #134270
base: master
Are you sure you want to change the base?
Conversation
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
☔ The latest upstream changes (presumably #135057) made this pull request unmergeable. Please resolve the merge conflicts. |
This comment has been minimized.
This comment has been minimized.
☔ The latest upstream changes (presumably #135151) made this pull request unmergeable. Please resolve the merge conflicts. |
let node = tcx.hir().get_if_local(impl_def_id.into()).expect("cannot get `Node`"); | ||
let hir_impl = if let rustc_hir::Node::Item(item) = node { | ||
if let rustc_hir::ItemKind::Impl(imp) = item.kind { Some(imp) } else { None } | ||
} else { | ||
None | ||
} | ||
.expect("cannot take `Impl` in a impl block"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let node = tcx.hir().get_if_local(impl_def_id.into()).expect("cannot get `Node`"); | |
let hir_impl = if let rustc_hir::Node::Item(item) = node { | |
if let rustc_hir::ItemKind::Impl(imp) = item.kind { Some(imp) } else { None } | |
} else { | |
None | |
} | |
.expect("cannot take `Impl` in a impl block"); | |
let node = tcx.hir_node_by_def_id(impl_def_id); | |
let hir_impl = node.expect_item().expect_impl(); |
.iter() | ||
.enumerate() | ||
.find(|(_, par)| par.name.ident().name == param.name) | ||
.unwrap(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you avoid unwrapping here? We may get very weird stuff in diagnostic code.
.params | ||
.iter() | ||
.enumerate() | ||
.find(|(_, par)| par.name.ident().name == param.name) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This identifies by parameter name, which is ambiguous due to hygiene. This should perhaps identify using par.def_id
and param.def_id
.
if let Some(prev) = hir_impl.generics.params[..index].iter().rfind(is_impl_generic) { | ||
let mut span = prev.span; | ||
|
||
// Consider the span of the bounds with the generic parameter when there is. | ||
if let Some(predicate) = hir_impl.generics.predicates.iter().find(|pred| { | ||
if let WherePredicateKind::BoundPredicate(WhereBoundPredicate { | ||
origin: PredicateOrigin::GenericParam, | ||
bounded_ty, | ||
.. | ||
}) = pred.kind | ||
{ | ||
bounded_ty.span == prev.span | ||
} else { | ||
false | ||
} | ||
}) { | ||
span = span.to(predicate.span) | ||
}; | ||
|
||
span.shrink_to_hi().to(hir_param.span) | ||
} else if let Some(next) = | ||
hir_impl.generics.params[index + 1..].iter().find(is_impl_generic) | ||
{ | ||
hir_param.span.until(next.span) | ||
} else { | ||
// Remove also angle brackets <> when there is just ONE generic parameter. | ||
hir_impl.generics.span | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you mind making all this a method on Generics
? For instance fn span_for_param_removal(&self, param: usize) -> Span
.
LL | unsafe impl<Q: Trait> Send for Inner<Q> {} | ||
| +++ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not really convinced that suggesting to use Q
in some path is the right solution. Inner
takes no generic params, so the suggestion is wrong.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To do this, we must know the ty::Ty
for self_ty
(e.g. Inner
here). Is there any way to get it?
help: either remove the type parameter T, or make use of it, for example | ||
| | ||
LL - impl<T: Tr> S<T::Assoc> { | ||
LL + impl S<T::Assoc> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This case is more subtle. We should not suggest to remove T
if it appears somewhere.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like avoidable, but only we can do is to compare symbols of generics parameters and, bounds of them and generics of the type. Is it acceptable, or do you know better ways?
Unconstrained type parameters made no suggestion and it makes difficult to know how to fix (rust-lang#107295). To make fixing easier, we output suggestions how to fix.
The job Click to see the possible cause of the failure (guessed by this bot)
|
Unconstrained type parameters made no suggestion and it makes difficult to know how to fix (#107295).
To make fixing easier, we output suggestions how to fix.
close #107295