Point turbofish inference errors at the uninferred generic arg#153795
Point turbofish inference errors at the uninferred generic arg#153795rust-bors[bot] merged 2 commits intorust-lang:mainfrom
Conversation
|
Some changes occurred in need_type_info.rs cc @lcnr |
This comment was marked as resolved.
This comment was marked as resolved.
This comment has been minimized.
This comment has been minimized.
3051885 to
d1648a1
Compare
This comment has been minimized.
This comment has been minimized.
d1648a1 to
b2573ab
Compare
|
What happens if there are multiple uninferred parameters? 🤔 |
|
It points at the first uninferred one. Compiler stops after the first inference failure, so the second gets flagged on the next compile. |
| generics.has_own_self() as usize + generics.own_counts().lifetimes, | ||
| ) | ||
| && let Some(arg) = | ||
| hir_args.args.iter().filter(|a| a.is_ty_or_const()).nth(idx) |
There was a problem hiding this comment.
Minor nit, which saves on performing the is_ty_or_const check on each parameter.
| hir_args.args.iter().filter(|a| a.is_ty_or_const()).nth(idx) | |
| hir_args.args.get(hir_args.num_lifetime_params() + idx) |
Even more minor, if one were to move the adjustment of argument_index from lines 1268-1270 to after this statement ends on 1290, it wouldn't need to be reversed in the checked_sub above.
| let span = match expr.kind { | ||
| ExprKind::MethodCall(path, ..) => path.ident.span, | ||
| ExprKind::MethodCall(segment, ..) => { | ||
| if have_turbofish | ||
| && let Some(hir_args) = segment.args | ||
| && let Some(idx) = argument_index.checked_sub( | ||
| generics.has_own_self() as usize + generics.own_counts().lifetimes, | ||
| ) | ||
| && let Some(arg) = | ||
| hir_args.args.iter().filter(|a| a.is_ty_or_const()).nth(idx) | ||
| { | ||
| arg.span() | ||
| } else { | ||
| segment.ident.span | ||
| } | ||
| } | ||
| _ => expr.span, | ||
| }; |
There was a problem hiding this comment.
| let span = match expr.kind { | |
| ExprKind::MethodCall(path, ..) => path.ident.span, | |
| ExprKind::MethodCall(segment, ..) => { | |
| if have_turbofish | |
| && let Some(hir_args) = segment.args | |
| && let Some(idx) = argument_index.checked_sub( | |
| generics.has_own_self() as usize + generics.own_counts().lifetimes, | |
| ) | |
| && let Some(arg) = | |
| hir_args.args.iter().filter(|a| a.is_ty_or_const()).nth(idx) | |
| { | |
| arg.span() | |
| } else { | |
| segment.ident.span | |
| } | |
| } | |
| _ => expr.span, | |
| }; | |
| let span = match expr.kind { | |
| ExprKind::MethodCall(segment, ..) | |
| if have_turbofish | |
| && let Some(hir_args) = segment.args | |
| && let Some(idx) = argument_index.checked_sub( | |
| generics.has_own_self() as usize + generics.own_counts().lifetimes, | |
| ) | |
| && let Some(arg) = hir_args.args.iter().filter(|a| a.is_ty_or_const()).nth(idx) => | |
| { | |
| arg.span() | |
| } | |
| ExprKind::MethodCall(segment, ..) => segment.ident.span, | |
| _ => expr.span, | |
| }; |
There was a problem hiding this comment.
isn't it better do do a find here/maybe even enumerate().find(..)
There was a problem hiding this comment.
if you don't use the actual argument, but still refer to all generic_args, then using position seems fine. enumerate.find() and then only using the index should just be worse than position.
I expected that being able to easily name the unconstrained arg would be helpful. If it is not, keeping position here is fine
b2573ab to
e485708
Compare
|
I'll likely take a look tomorrow r? me |
|
cool, thanks @bors r=Kivooeo,eggyal rollup |
…uwer Rollup of 6 pull requests Successful merges: - #152998 (std: make `OsString::truncate` a no-op when `len > current_len`) - #153682 (Tweak E0599 note) - #153795 (Point turbofish inference errors at the uninferred generic arg) - #153994 (move `tests/ui/invalid` tests to new folders) - #154006 (attrs: Ignore ExprKind::Err when converting path attr expr to lit) - #154012 (unstable impl of `From<{i64, u64}> for f128`)
Follow-up to #153751.
When a method call has a turbofish with an uninferred generic argument, point the diagnostic span at the specific
_that couldn't be inferred instead of the method name.Before:
After:
Path expressions (
None::<_>,foo::<_>()) are not handled yet, that's a separate code path.cc @eggyal