about summary refs log tree commit diff
diff options
context:
space:
mode:
authorkadmin <julianknodt@gmail.com>2021-02-14 04:35:18 +0000
committerkadmin <julianknodt@gmail.com>2021-02-16 05:14:22 +0000
commitb97951b50f81862ccd997d48b20f50d05cd5157e (patch)
treeceb7e47134081be8574cc26d8719f2c4ab611571
parentbe1ed00712ce0b884e1fc9779f25b1758e994d0b (diff)
downloadrust-b97951b50f81862ccd997d48b20f50d05cd5157e.tar.gz
rust-b97951b50f81862ccd997d48b20f50d05cd5157e.zip
Update w/ comments
-rw-r--r--compiler/rustc_typeck/src/astconv/generics.rs60
-rw-r--r--src/test/ui/const-generics/const-param-shadowing.stderr2
-rw-r--r--src/test/ui/const-generics/diagnostics.rs11
-rw-r--r--src/test/ui/const-generics/diagnostics.stderr33
-rw-r--r--src/test/ui/const-generics/invalid-enum.rs12
-rw-r--r--src/test/ui/const-generics/invalid-enum.stderr26
6 files changed, 101 insertions, 43 deletions
diff --git a/compiler/rustc_typeck/src/astconv/generics.rs b/compiler/rustc_typeck/src/astconv/generics.rs
index 341f6fadba1..b421adbf9ea 100644
--- a/compiler/rustc_typeck/src/astconv/generics.rs
+++ b/compiler/rustc_typeck/src/astconv/generics.rs
@@ -6,8 +6,9 @@ use crate::astconv::{
 use crate::errors::AssocTypeBindingNotAllowed;
 use crate::structured_errors::{StructuredDiagnostic, WrongNumberOfGenericArgs};
 use rustc_ast::ast::ParamKindOrd;
-use rustc_errors::{struct_span_err, Applicability, ErrorReported};
+use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, ErrorReported};
 use rustc_hir as hir;
+use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::DefId;
 use rustc_hir::GenericArg;
 use rustc_middle::ty::{
@@ -24,8 +25,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         tcx: TyCtxt<'_>,
         arg: &GenericArg<'_>,
         param: &GenericParamDef,
-        // DefId of the function
-        //body_def_id: DefId,
         possible_ordering_error: bool,
         help: Option<&str>,
     ) {
@@ -45,6 +44,19 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
             }
         }
 
+        let add_braces_suggestion = |arg: &GenericArg<'_>, err: &mut DiagnosticBuilder<'_>| {
+            let suggestions = vec![
+                (arg.span().shrink_to_lo(), String::from("{ ")),
+                (arg.span().shrink_to_hi(), String::from(" }")),
+            ];
+            err.multipart_suggestion(
+                "if this generic argument was intended as a const parameter, \
+                 surround it with braces",
+                suggestions,
+                Applicability::MaybeIncorrect,
+            );
+        };
+
         // Specific suggestion set for diagnostics
         match (arg, &param.kind) {
             (
@@ -53,40 +65,34 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                     ..
                 }),
                 GenericParamDefKind::Const,
-            ) => {
-                use rustc_hir::def::{DefKind, Res};
-                match path.res {
-                    Res::Err => {}
-                    Res::Def(DefKind::TyParam, src_def_id) => (|| {
-                        let param_hir_id = match param.def_id.as_local() {
-                            Some(x) => tcx.hir().local_def_id_to_hir_id(x),
-                            None => return,
-                        };
+            ) => match path.res {
+                Res::Err => {
+                    add_braces_suggestion(arg, &mut err);
+                    err.set_primary_message(
+                        "unresolved item provided when a constant was expected",
+                    );
+                }
+                Res::Def(DefKind::TyParam, src_def_id) => {
+                    if let Some(param_local_id) = param.def_id.as_local() {
+                        let param_hir_id = tcx.hir().local_def_id_to_hir_id(param_local_id);
                         let param_name = tcx.hir().ty_param_name(param_hir_id);
                         let param_type = tcx.type_of(param.def_id);
                         if param_type.is_suggestable() {
                             err.span_suggestion(
                                 tcx.def_span(src_def_id),
-                                &format!("try changing to a const-generic parameter:"),
+                                "consider changing this type paramater to a `const`-generic",
                                 format!("const {}: {}", param_name, param_type),
                                 Applicability::MaybeIncorrect,
                             );
-                        }
-                    })(),
-                    _ => {
-                        let suggestions = vec![
-                            (arg.span().shrink_to_lo(), String::from("{ ")),
-                            (arg.span().shrink_to_hi(), String::from(" }")),
-                        ];
-                        err.multipart_suggestion(
-                            "if this generic argument was intended as a const parameter, \
-                  try surrounding it with braces:",
-                            suggestions,
-                            Applicability::MaybeIncorrect,
-                        );
+                        };
                     }
                 }
-            }
+                _ => add_braces_suggestion(arg, &mut err),
+            },
+            (
+                GenericArg::Type(hir::Ty { kind: hir::TyKind::Path(_), .. }),
+                GenericParamDefKind::Const,
+            ) => add_braces_suggestion(arg, &mut err),
             (
                 GenericArg::Type(hir::Ty { kind: hir::TyKind::Array(_, len), .. }),
                 GenericParamDefKind::Const { .. },
diff --git a/src/test/ui/const-generics/const-param-shadowing.stderr b/src/test/ui/const-generics/const-param-shadowing.stderr
index 7447ca3ff36..17ccd2f3527 100644
--- a/src/test/ui/const-generics/const-param-shadowing.stderr
+++ b/src/test/ui/const-generics/const-param-shadowing.stderr
@@ -4,7 +4,7 @@ error[E0747]: type provided when a constant was expected
 LL | fn test<const N: usize>() -> Foo<N> {
    |                                  ^
    |
-help: if this generic argument was intended as a const parameter, try surrounding it with braces:
+help: if this generic argument was intended as a const parameter, surround it with braces
    |
 LL | fn test<const N: usize>() -> Foo<{ N }> {
    |                                  ^   ^
diff --git a/src/test/ui/const-generics/diagnostics.rs b/src/test/ui/const-generics/diagnostics.rs
index c90e3d0e0eb..1581af5ab27 100644
--- a/src/test/ui/const-generics/diagnostics.rs
+++ b/src/test/ui/const-generics/diagnostics.rs
@@ -1,13 +1,18 @@
 #![crate_type="lib"]
-#![feature(const_generics)]
+#![feature(min_const_generics)]
 #![allow(incomplete_features)]
 
 struct A<const N: u8>;
 trait Foo {}
 impl Foo for A<N> {}
-//~^ ERROR type provided when a constant
-//~| ERROR cannot find type
+//~^ ERROR cannot find type
+//~| unresolved item provided when a constant
 
 struct B<const N: u8>;
 impl<N> Foo for B<N> {}
 //~^ ERROR type provided when a constant
+
+struct C<const C: u8, const N: u8>;
+impl<const N: u8> Foo for C<N, T> {}
+//~^ ERROR cannot find type
+//~| unresolved item provided when a constant
diff --git a/src/test/ui/const-generics/diagnostics.stderr b/src/test/ui/const-generics/diagnostics.stderr
index a66858a310c..33f5337eb80 100644
--- a/src/test/ui/const-generics/diagnostics.stderr
+++ b/src/test/ui/const-generics/diagnostics.stderr
@@ -7,11 +7,25 @@ LL | trait Foo {}
 LL | impl Foo for A<N> {}
    |                ^ help: a struct with a similar name exists: `A`
 
-error[E0747]: type provided when a constant was expected
+error[E0412]: cannot find type `T` in this scope
+  --> $DIR/diagnostics.rs:16:32
+   |
+LL | struct A<const N: u8>;
+   | ---------------------- similarly named struct `A` defined here
+...
+LL | impl<const N: u8> Foo for C<N, T> {}
+   |                                ^ help: a struct with a similar name exists: `A`
+
+error[E0747]: unresolved item provided when a constant was expected
   --> $DIR/diagnostics.rs:7:16
    |
 LL | impl Foo for A<N> {}
    |                ^
+   |
+help: if this generic argument was intended as a const parameter, surround it with braces
+   |
+LL | impl Foo for A<{ N }> {}
+   |                ^   ^
 
 error[E0747]: type provided when a constant was expected
   --> $DIR/diagnostics.rs:12:19
@@ -19,9 +33,22 @@ error[E0747]: type provided when a constant was expected
 LL | impl<N> Foo for B<N> {}
    |      -            ^
    |      |
-   |      help: try changing to a const-generic parameter:: `const N: u8`
+   |      help: consider changing this type paramater to a `const`-generic: `const N: u8`
+
+error[E0747]: unresolved item provided when a constant was expected
+  --> $DIR/diagnostics.rs:16:32
+   |
+LL | impl<const N: u8> Foo for C<N, T> {}
+   |                                ^
+   |
+   = note: type arguments must be provided before constant arguments
+   = help: reorder the arguments: consts: `<C, N>`
+help: if this generic argument was intended as a const parameter, surround it with braces
+   |
+LL | impl<const N: u8> Foo for C<N, { T }> {}
+   |                                ^   ^
 
-error: aborting due to 3 previous errors
+error: aborting due to 5 previous errors
 
 Some errors have detailed explanations: E0412, E0747.
 For more information about an error, try `rustc --explain E0412`.
diff --git a/src/test/ui/const-generics/invalid-enum.rs b/src/test/ui/const-generics/invalid-enum.rs
index 4ca10ed8b71..32939dcd286 100644
--- a/src/test/ui/const-generics/invalid-enum.rs
+++ b/src/test/ui/const-generics/invalid-enum.rs
@@ -3,14 +3,14 @@
 
 #[derive(PartialEq, Eq)]
 enum CompileFlag {
-  A,
-  B,
+    A,
+    B,
 }
 
 pub fn test_1<const CF: CompileFlag>() {}
 pub fn test_2<T, const CF: CompileFlag>(x: T) {}
 pub struct Example<const CF: CompileFlag, T=u32>{
-  x: T,
+    x: T,
 }
 
 impl<const CF: CompileFlag, T> Example<CF, T> {
@@ -20,15 +20,15 @@ impl<const CF: CompileFlag, T> Example<CF, T> {
 pub fn main() {
   test_1::<CompileFlag::A>();
   //~^ ERROR: expected type, found variant
-  //~| ERROR: type provided when a constant was expected
+  //~| ERROR: unresolved item provided when a constant was expected
 
   test_2::<_, CompileFlag::A>(0);
   //~^ ERROR: expected type, found variant
-  //~| ERROR: type provided when a constant was expected
+  //~| ERROR: unresolved item provided when a constant was expected
 
   let _: Example<CompileFlag::A, _> = Example { x: 0 };
   //~^ ERROR: expected type, found variant
-  //~| ERROR: type provided when a constant was expected
+  //~| ERROR: unresolved item provided when a constant was expected
 
   let _: Example<Example::ASSOC_FLAG, _> = Example { x: 0 };
   //~^ ERROR: type provided when a constant was expected
diff --git a/src/test/ui/const-generics/invalid-enum.stderr b/src/test/ui/const-generics/invalid-enum.stderr
index c062fc9ac88..cfbc61f0254 100644
--- a/src/test/ui/const-generics/invalid-enum.stderr
+++ b/src/test/ui/const-generics/invalid-enum.stderr
@@ -25,29 +25,49 @@ LL |   let _: Example<CompileFlag::A, _> = Example { x: 0 };
    |                  not a type
    |                  help: try using the variant's enum: `CompileFlag`
 
-error[E0747]: type provided when a constant was expected
+error[E0747]: unresolved item provided when a constant was expected
   --> $DIR/invalid-enum.rs:29:18
    |
 LL |   let _: Example<CompileFlag::A, _> = Example { x: 0 };
    |                  ^^^^^^^^^^^^^^
+   |
+help: if this generic argument was intended as a const parameter, surround it with braces
+   |
+LL |   let _: Example<{ CompileFlag::A }, _> = Example { x: 0 };
+   |                  ^                ^
 
 error[E0747]: type provided when a constant was expected
   --> $DIR/invalid-enum.rs:33:18
    |
 LL |   let _: Example<Example::ASSOC_FLAG, _> = Example { x: 0 };
    |                  ^^^^^^^^^^^^^^^^^^^
+   |
+help: if this generic argument was intended as a const parameter, surround it with braces
+   |
+LL |   let _: Example<{ Example::ASSOC_FLAG }, _> = Example { x: 0 };
+   |                  ^                     ^
 
-error[E0747]: type provided when a constant was expected
+error[E0747]: unresolved item provided when a constant was expected
   --> $DIR/invalid-enum.rs:21:12
    |
 LL |   test_1::<CompileFlag::A>();
    |            ^^^^^^^^^^^^^^
+   |
+help: if this generic argument was intended as a const parameter, surround it with braces
+   |
+LL |   test_1::<{ CompileFlag::A }>();
+   |            ^                ^
 
-error[E0747]: type provided when a constant was expected
+error[E0747]: unresolved item provided when a constant was expected
   --> $DIR/invalid-enum.rs:25:15
    |
 LL |   test_2::<_, CompileFlag::A>(0);
    |               ^^^^^^^^^^^^^^
+   |
+help: if this generic argument was intended as a const parameter, surround it with braces
+   |
+LL |   test_2::<_, { CompileFlag::A }>(0);
+   |               ^                ^
 
 error: aborting due to 7 previous errors