Skip to content

Commit 9b2117d

Browse files
Rollup merge of #77758 - Stupremee:turbofish-help-for-const, r=varkor
suggest turbofish syntax for uninferred const arguments When not providing a const generic value, and it can not be inferred, the following suggestion is suggested: ![image](https://user-images.githubusercontent.com/39732259/95616180-af127b80-0a69-11eb-8877-551c815f9627.png) Resolves #76737 r? ``@varkor``
2 parents 0d96516 + 4379a43 commit 9b2117d

12 files changed

+110
-8
lines changed

compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs

+27-5
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,11 @@ impl<'a, 'tcx> Visitor<'tcx> for FindHirNodeVisitor<'a, 'tcx> {
124124
return;
125125
}
126126
}
127+
128+
// FIXME(const_generics): Currently, any uninferred `const` generics arguments
129+
// are handled specially, but instead they should be handled in `annotate_method_call`,
130+
// which currently doesn't work because this evaluates to `false` for const arguments.
131+
// See https://github.com/rust-lang/rust/pull/77758 for more details.
127132
if self.node_ty_contains_target(expr.hir_id).is_some() {
128133
match expr.kind {
129134
ExprKind::Closure(..) => self.found_closure = Some(&expr),
@@ -345,11 +350,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
345350
) -> DiagnosticBuilder<'tcx> {
346351
let arg = self.resolve_vars_if_possible(arg);
347352
let arg_data = self.extract_inference_diagnostics_data(arg, None);
348-
let kind_str = match arg.unpack() {
349-
GenericArgKind::Type(_) => "type",
350-
GenericArgKind::Const(_) => "the value",
351-
GenericArgKind::Lifetime(_) => bug!("unexpected lifetime"),
352-
};
353353

354354
let mut local_visitor = FindHirNodeVisitor::new(&self, arg, span);
355355
let ty_to_string = |ty: Ty<'tcx>| -> String {
@@ -618,6 +618,28 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
618618
.any(|span_label| span_label.label.is_some() && span_label.span == span)
619619
&& local_visitor.found_arg_pattern.is_none()
620620
{
621+
let (kind_str, const_value) = match arg.unpack() {
622+
GenericArgKind::Type(_) => ("type", None),
623+
GenericArgKind::Const(_) => ("the value", Some(())),
624+
GenericArgKind::Lifetime(_) => bug!("unexpected lifetime"),
625+
};
626+
627+
// FIXME(const_generics): we would like to handle const arguments
628+
// as part of the normal diagnostics flow below, but there appear to
629+
// be subtleties in doing so, so for now we special-case const args
630+
// here.
631+
if let Some(suggestion) = const_value
632+
.and_then(|_| arg_data.parent_name.as_ref())
633+
.map(|parent| format!("{}::<{}>", parent, arg_data.name))
634+
{
635+
err.span_suggestion_verbose(
636+
span,
637+
"consider specifying the const argument",
638+
suggestion,
639+
Applicability::MaybeIncorrect,
640+
);
641+
}
642+
621643
// Avoid multiple labels pointing at `span`.
622644
err.span_label(
623645
span,

src/test/ui/const-generics/infer/cannot-infer-const-args.full.stderr

+5
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@ error[E0282]: type annotations needed
33
|
44
LL | foo();
55
| ^^^ cannot infer the value of const parameter `X` declared on the function `foo`
6+
|
7+
help: consider specifying the const argument
8+
|
9+
LL | foo::<X>();
10+
| ^^^^^^^^
611

712
error: aborting due to previous error
813

src/test/ui/const-generics/infer/cannot-infer-const-args.min.stderr

+5
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@ error[E0282]: type annotations needed
33
|
44
LL | foo();
55
| ^^^ cannot infer the value of const parameter `X` declared on the function `foo`
6+
|
7+
help: consider specifying the const argument
8+
|
9+
LL | foo::<X>();
10+
| ^^^^^^^^
611

712
error: aborting due to previous error
813

src/test/ui/const-generics/infer/issue-77092.stderr

+5
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@ error[E0282]: type annotations needed
33
|
44
LL | println!("{:?}", take_array_from_mut(&mut arr, i));
55
| ^^^^^^^^^^^^^^^^^^^ cannot infer the value of const parameter `N` declared on the function `take_array_from_mut`
6+
|
7+
help: consider specifying the const argument
8+
|
9+
LL | println!("{:?}", take_array_from_mut::<N>(&mut arr, i));
10+
| ^^^^^^^^^^^^^^^^^^^^^^^^
611

712
error: aborting due to previous error
813

src/test/ui/const-generics/infer/method-chain.full.stderr

+5
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@ error[E0282]: type annotations needed
33
|
44
LL | Foo.bar().bar().bar().bar().baz();
55
| ^^^ cannot infer the value of const parameter `N` declared on the associated function `baz`
6+
|
7+
help: consider specifying the const argument
8+
|
9+
LL | Foo.bar().bar().bar().bar().baz::<N>();
10+
| ^^^^^^^^
611

712
error: aborting due to previous error
813

src/test/ui/const-generics/infer/method-chain.min.stderr

+5
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@ error[E0282]: type annotations needed
33
|
44
LL | Foo.bar().bar().bar().bar().baz();
55
| ^^^ cannot infer the value of const parameter `N` declared on the associated function `baz`
6+
|
7+
help: consider specifying the const argument
8+
|
9+
LL | Foo.bar().bar().bar().bar().baz::<N>();
10+
| ^^^^^^^^
611

712
error: aborting due to previous error
813

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
error[E0282]: type annotations needed
2+
--> $DIR/one-param-uninferred.rs:15:23
3+
|
4+
LL | let _: [u8; 17] = foo();
5+
| ^^^ cannot infer the value of const parameter `M` declared on the function `foo`
6+
|
7+
help: consider specifying the const argument
8+
|
9+
LL | let _: [u8; 17] = foo::<M>();
10+
| ^^^^^^^^
11+
12+
error: aborting due to previous error
13+
14+
For more information about this error, try `rustc --explain E0282`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
error[E0282]: type annotations needed
2+
--> $DIR/one-param-uninferred.rs:15:23
3+
|
4+
LL | let _: [u8; 17] = foo();
5+
| ^^^ cannot infer the value of const parameter `M` declared on the function `foo`
6+
|
7+
help: consider specifying the const argument
8+
|
9+
LL | let _: [u8; 17] = foo::<M>();
10+
| ^^^^^^^^
11+
12+
error: aborting due to previous error
13+
14+
For more information about this error, try `rustc --explain E0282`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Test that we emit an error if we cannot properly infer a constant.
2+
// revisions: full min
3+
4+
#![cfg_attr(full, feature(const_generics))]
5+
#![cfg_attr(full, allow(incomplete_features))]
6+
#![cfg_attr(min, feature(min_const_generics))]
7+
8+
fn foo<const N: usize, const M: usize>() -> [u8; N] {
9+
todo!()
10+
}
11+
12+
fn main() {
13+
// FIXME(const_generics): Currently this only suggests one const parameter,
14+
// but instead it should suggest to provide all parameters.
15+
let _: [u8; 17] = foo();
16+
//~^ ERROR type annotations needed
17+
}

src/test/ui/const-generics/infer/uninferred-consts.full.stderr

+6-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,12 @@ error[E0282]: type annotations needed
22
--> $DIR/uninferred-consts.rs:14:9
33
|
44
LL | Foo.foo();
5-
| ^^^ cannot infer the value of const parameter `N` declared on the associated function `foo`
5+
| ^^^ cannot infer the value of const parameter `A` declared on the associated function `foo`
6+
|
7+
help: consider specifying the const argument
8+
|
9+
LL | Foo.foo::<A>();
10+
| ^^^^^^^^
611

712
error: aborting due to previous error
813

src/test/ui/const-generics/infer/uninferred-consts.min.stderr

+6-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,12 @@ error[E0282]: type annotations needed
22
--> $DIR/uninferred-consts.rs:14:9
33
|
44
LL | Foo.foo();
5-
| ^^^ cannot infer the value of const parameter `N` declared on the associated function `foo`
5+
| ^^^ cannot infer the value of const parameter `A` declared on the associated function `foo`
6+
|
7+
help: consider specifying the const argument
8+
|
9+
LL | Foo.foo::<A>();
10+
| ^^^^^^^^
611

712
error: aborting due to previous error
813

src/test/ui/const-generics/infer/uninferred-consts.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
// taken from https://github.com/rust-lang/rust/issues/70507#issuecomment-615268893
99
struct Foo;
1010
impl Foo {
11-
fn foo<const N: usize>(self) {}
11+
fn foo<const A: usize, const B: usize>(self) {}
1212
}
1313
fn main() {
1414
Foo.foo();

0 commit comments

Comments
 (0)