about summary refs log tree commit diff
diff options
context:
space:
mode:
authorkadmin <julianknodt@gmail.com>2020-08-31 17:12:53 +0000
committerkadmin <julianknodt@gmail.com>2020-09-03 17:46:27 +0000
commit96bb2c86f2cfe03ad870d12b3b838e8b75eb1978 (patch)
treec68f17103ae8503e6352dd644bc44de79ed43436
parent8d9187597a5e8ebcf17acba6b234884252b1a543 (diff)
downloadrust-96bb2c86f2cfe03ad870d12b3b838e8b75eb1978.tar.gz
rust-96bb2c86f2cfe03ad870d12b3b838e8b75eb1978.zip
Add further tests and liberalize type checking
-rw-r--r--compiler/rustc_typeck/src/astconv/generics.rs61
-rw-r--r--src/test/ui/const-generics/invalid-enum.rs26
-rw-r--r--src/test/ui/const-generics/invalid-enum.stderr99
3 files changed, 139 insertions, 47 deletions
diff --git a/compiler/rustc_typeck/src/astconv/generics.rs b/compiler/rustc_typeck/src/astconv/generics.rs
index b7336fcd369..eb2207a0d67 100644
--- a/compiler/rustc_typeck/src/astconv/generics.rs
+++ b/compiler/rustc_typeck/src/astconv/generics.rs
@@ -445,15 +445,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
             assert_ne!(bound, provided);
             Err((bound as i32 - provided as i32, Some(err)))
         };
-        let emit_correct =
-            |correct: Result<(), (_, Option<rustc_errors::DiagnosticBuilder<'_>>)>| match correct {
-                Ok(()) => Ok(()),
-                Err((_, None)) => Err(()),
-                Err((_, Some(mut err))) => {
-                    err.emit();
-                    Err(())
-                }
-            };
 
         let mut unexpected_spans = vec![];
 
@@ -501,31 +492,41 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
 
         // Emit a help message if it's possible that a type could be surrounded in braces
         if let Err((c_mismatch, Some(ref mut _const_err))) = const_count_correct {
-            if let Err((t_mismatch, Some(ref mut type_err))) = type_count_correct {
-                if c_mismatch == -t_mismatch && t_mismatch < 0 {
-                    for i in 0..c_mismatch as usize {
-                        let arg = &args.args[arg_counts.lifetimes + i];
-                        match arg {
-                            GenericArg::Type(hir::Ty {
-                                kind: hir::TyKind::Path { .. }, ..
-                            }) => {}
-                            _ => continue,
-                        }
-                        let suggestions = vec![
-                            (arg.span().shrink_to_lo(), String::from("{ ")),
-                            (arg.span().shrink_to_hi(), String::from(" }")),
-                        ];
-                        type_err.multipart_suggestion(
-                            "If this generic argument was intended as a const parameter, \
-                            try surrounding it with braces:",
-                            suggestions,
-                            Applicability::MaybeIncorrect,
-                        );
-                    }
+            if let Err((_, Some(ref mut type_err))) = type_count_correct {
+                let possible_matches = args.args[arg_counts.lifetimes..]
+                    .iter()
+                    .filter(|arg| {
+                        matches!(
+                            arg,
+                            GenericArg::Type(hir::Ty { kind: hir::TyKind::Path { .. }, .. })
+                        )
+                    })
+                    .take(c_mismatch.max(0) as usize);
+                for arg in possible_matches {
+                    let suggestions = vec![
+                        (arg.span().shrink_to_lo(), String::from("{ ")),
+                        (arg.span().shrink_to_hi(), String::from(" }")),
+                    ];
+                    type_err.multipart_suggestion(
+                        "If this generic argument was intended as a const parameter, \
+                        try surrounding it with braces:",
+                        suggestions,
+                        Applicability::MaybeIncorrect,
+                    );
                 }
             }
         }
 
+        let emit_correct =
+            |correct: Result<(), (_, Option<rustc_errors::DiagnosticBuilder<'_>>)>| match correct {
+                Ok(()) => Ok(()),
+                Err((_, None)) => Err(()),
+                Err((_, Some(mut err))) => {
+                    err.emit();
+                    Err(())
+                }
+            };
+
         let arg_count_correct = emit_correct(lifetime_count_correct)
             .and(emit_correct(const_count_correct))
             .and(emit_correct(type_count_correct));
diff --git a/src/test/ui/const-generics/invalid-enum.rs b/src/test/ui/const-generics/invalid-enum.rs
index 05c13e8fe0c..ceb188a0d3d 100644
--- a/src/test/ui/const-generics/invalid-enum.rs
+++ b/src/test/ui/const-generics/invalid-enum.rs
@@ -7,11 +7,33 @@ enum CompileFlag {
   B,
 }
 
-pub fn test<const CF: CompileFlag>() {}
+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,
+}
+
+impl<const CF: CompileFlag, T> Example<CF, T> {
+  const ASSOC_FLAG: CompileFlag = CompileFlag::A;
+}
 
 pub fn main() {
-  test::<CompileFlag::A>();
+  test_1::<CompileFlag::A>();
+  //~^ ERROR: expected type, found variant
+  //~| ERROR: wrong number of const arguments
+  //~| ERROR: wrong number of type arguments
+
+  test_2::<_, CompileFlag::A>(0);
   //~^ ERROR: expected type, found variant
   //~| ERROR: wrong number of const arguments
   //~| ERROR: wrong number of type arguments
+
+  let _: Example<CompileFlag::A, _> = Example { x: 0 };
+  //~^ ERROR: expected type, found variant
+  //~| ERROR: wrong number of const arguments
+  //~| ERROR: wrong number of type arguments
+
+  let _: Example<Example::ASSOC_FLAG, _> = Example { x: 0 };
+  //~^ ERROR: wrong number of const arguments
+  //~| ERROR: wrong number of type arguments
 }
diff --git a/src/test/ui/const-generics/invalid-enum.stderr b/src/test/ui/const-generics/invalid-enum.stderr
index 3291b62ea9f..965abbc9cb7 100644
--- a/src/test/ui/const-generics/invalid-enum.stderr
+++ b/src/test/ui/const-generics/invalid-enum.stderr
@@ -1,30 +1,99 @@
 error[E0573]: expected type, found variant `CompileFlag::A`
-  --> $DIR/invalid-enum.rs:13:10
+  --> $DIR/invalid-enum.rs:21:12
    |
-LL |   test::<CompileFlag::A>();
-   |          ^^^^^^^^^^^^^^
-   |          |
-   |          not a type
-   |          help: try using the variant's enum: `CompileFlag`
+LL |   test_1::<CompileFlag::A>();
+   |            ^^^^^^^^^^^^^^
+   |            |
+   |            not a type
+   |            help: try using the variant's enum: `CompileFlag`
+
+error[E0573]: expected type, found variant `CompileFlag::A`
+  --> $DIR/invalid-enum.rs:26:15
+   |
+LL |   test_2::<_, CompileFlag::A>(0);
+   |               ^^^^^^^^^^^^^^
+   |               |
+   |               not a type
+   |               help: try using the variant's enum: `CompileFlag`
+
+error[E0573]: expected type, found variant `CompileFlag::A`
+  --> $DIR/invalid-enum.rs:31:18
+   |
+LL |   let _: Example<CompileFlag::A, _> = Example { x: 0 };
+   |                  ^^^^^^^^^^^^^^
+   |                  |
+   |                  not a type
+   |                  help: try using the variant's enum: `CompileFlag`
+
+error[E0107]: wrong number of const arguments: expected 1, found 0
+  --> $DIR/invalid-enum.rs:31:10
+   |
+LL |   let _: Example<CompileFlag::A, _> = Example { x: 0 };
+   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected 1 const argument
+
+error[E0107]: wrong number of type arguments: expected at most 1, found 2
+  --> $DIR/invalid-enum.rs:31:10
+   |
+LL |   let _: Example<CompileFlag::A, _> = Example { x: 0 };
+   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected at most 1 type argument
+   |
+help: If this generic argument was intended as a const parameter, try surrounding it with braces:
+   |
+LL |   let _: Example<{ CompileFlag::A }, _> = Example { x: 0 };
+   |                  ^                ^
+
+error[E0107]: wrong number of const arguments: expected 1, found 0
+  --> $DIR/invalid-enum.rs:36:10
+   |
+LL |   let _: Example<Example::ASSOC_FLAG, _> = Example { x: 0 };
+   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected 1 const argument
+
+error[E0107]: wrong number of type arguments: expected at most 1, found 2
+  --> $DIR/invalid-enum.rs:36:10
+   |
+LL |   let _: Example<Example::ASSOC_FLAG, _> = Example { x: 0 };
+   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected at most 1 type argument
+   |
+help: If this generic argument was intended as a const parameter, try surrounding it with braces:
+   |
+LL |   let _: Example<{ Example::ASSOC_FLAG }, _> = Example { x: 0 };
+   |                  ^                     ^
 
 error[E0107]: wrong number of const arguments: expected 1, found 0
-  --> $DIR/invalid-enum.rs:13:3
+  --> $DIR/invalid-enum.rs:21:3
    |
-LL |   test::<CompileFlag::A>();
-   |   ^^^^^^^^^^^^^^^^^^^^^^ expected 1 const argument
+LL |   test_1::<CompileFlag::A>();
+   |   ^^^^^^^^^^^^^^^^^^^^^^^^ expected 1 const argument
 
 error[E0107]: wrong number of type arguments: expected 0, found 1
-  --> $DIR/invalid-enum.rs:13:10
+  --> $DIR/invalid-enum.rs:21:12
+   |
+LL |   test_1::<CompileFlag::A>();
+   |            ^^^^^^^^^^^^^^ unexpected type argument
+   |
+help: If this generic argument was intended as a const parameter, try surrounding it with braces:
+   |
+LL |   test_1::<{ CompileFlag::A }>();
+   |            ^                ^
+
+error[E0107]: wrong number of const arguments: expected 1, found 0
+  --> $DIR/invalid-enum.rs:26:3
+   |
+LL |   test_2::<_, CompileFlag::A>(0);
+   |   ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected 1 const argument
+
+error[E0107]: wrong number of type arguments: expected 1, found 2
+  --> $DIR/invalid-enum.rs:26:15
    |
-LL |   test::<CompileFlag::A>();
-   |          ^^^^^^^^^^^^^^ unexpected type argument
+LL |   test_2::<_, CompileFlag::A>(0);
+   |               ^^^^^^^^^^^^^^ unexpected type argument
    |
 help: If this generic argument was intended as a const parameter, try surrounding it with braces:
    |
-LL |   test::<{ CompileFlag::A }>();
-   |          ^                ^
+LL |   test_2::<_, { CompileFlag::A }>(0);
+   |               ^                ^
 
-error: aborting due to 3 previous errors
+error: aborting due to 11 previous errors
 
 Some errors have detailed explanations: E0107, E0573.
 For more information about an error, try `rustc --explain E0107`.