about summary refs log tree commit diff
diff options
context:
space:
mode:
authorkadmin <julianknodt@gmail.com>2020-08-06 08:22:32 +0000
committerkadmin <julianknodt@gmail.com>2020-08-09 07:41:26 +0000
commitbe0d6f1c0636b2c7c3c8df819d8c2066669c8024 (patch)
tree5c38c608f74f76a1511f26fe0fc9fec0e6fc915a
parent4f461f5d1282ac58892b8985f1df7ea26df6613f (diff)
downloadrust-be0d6f1c0636b2c7c3c8df819d8c2066669c8024.tar.gz
rust-be0d6f1c0636b2c7c3c8df819d8c2066669c8024.zip
Change Ord impl for ParamKindOrd
Updated tests and error msgs

Update stderr from test

Update w/ lcnr comments

Change some tests around, and also updated Ord implementation for ParamKindOrd

Update w/ nits from lcnr
-rw-r--r--src/librustc_ast/ast.rs27
-rw-r--r--src/librustc_ast_passes/ast_validation.rs1
-rw-r--r--src/librustc_typeck/astconv.rs16
-rw-r--r--src/test/ui/const-generics/argument_order.stderr4
-rw-r--r--src/test/ui/const-generics/const-arg-type-arg-misordered.rs2
-rw-r--r--src/test/ui/const-generics/const-arg-type-arg-misordered.stderr14
-rw-r--r--src/test/ui/const-generics/defaults/complex-unord-param.rs8
-rw-r--r--src/test/ui/const-generics/defaults/intermixed-lifetime.rs2
-rw-r--r--src/test/ui/const-generics/defaults/intermixed-lifetime.stderr6
-rw-r--r--src/test/ui/const-generics/defaults/needs-feature.min.stderr8
-rw-r--r--src/test/ui/const-generics/defaults/needs-feature.none.stderr (renamed from src/test/ui/const-generics/defaults/needs-feature.stderr)8
-rw-r--r--src/test/ui/const-generics/defaults/needs-feature.rs15
-rw-r--r--src/test/ui/const-generics/defaults/right-order.rs11
-rw-r--r--src/test/ui/const-generics/defaults/simple-defaults.rs15
-rw-r--r--src/test/ui/const-generics/type-after-const-ok.rs (renamed from src/test/ui/const-generics/defaults/type-after-const-requires-default.rs)0
15 files changed, 82 insertions, 55 deletions
diff --git a/src/librustc_ast/ast.rs b/src/librustc_ast/ast.rs
index 5e8066dd960..2f11596c22c 100644
--- a/src/librustc_ast/ast.rs
+++ b/src/librustc_ast/ast.rs
@@ -35,6 +35,7 @@ use rustc_span::source_map::{respan, Spanned};
 use rustc_span::symbol::{kw, sym, Ident, Symbol};
 use rustc_span::{Span, DUMMY_SP};
 
+use std::cmp::Ordering;
 use std::convert::TryFrom;
 use std::fmt;
 use std::iter;
@@ -309,13 +310,37 @@ pub type GenericBounds = Vec<GenericBound>;
 /// Specifies the enforced ordering for generic parameters. In the future,
 /// if we wanted to relax this order, we could override `PartialEq` and
 /// `PartialOrd`, to allow the kinds to be unordered.
-#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)]
+#[derive(PartialEq, Eq, Hash, Clone, Copy)]
 pub enum ParamKindOrd {
     Lifetime,
     Type,
+    // `unordered` is only `true` if `sess.has_features().const_generics`
+    // is active. Specifically, if it's only `min_const_generics`, it will still require
+    // ordering consts after types.
     Const { unordered: bool },
 }
 
+impl Ord for ParamKindOrd {
+    fn cmp(&self, other: &Self) -> Ordering {
+        use ParamKindOrd::*;
+        let to_int = |v| match v {
+            Lifetime => 0,
+            Type | Const { unordered: true } => 1,
+            // technically both consts should be ordered equally,
+            // but only one is ever encountered at a time, so this is
+            // fine.
+            Const { unordered: false } => 2,
+        };
+
+        to_int(*self).cmp(&to_int(*other))
+    }
+}
+impl PartialOrd for ParamKindOrd {
+    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+        Some(self.cmp(other))
+    }
+}
+
 impl fmt::Display for ParamKindOrd {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         match self {
diff --git a/src/librustc_ast_passes/ast_validation.rs b/src/librustc_ast_passes/ast_validation.rs
index a229987da76..83f64793833 100644
--- a/src/librustc_ast_passes/ast_validation.rs
+++ b/src/librustc_ast_passes/ast_validation.rs
@@ -735,7 +735,6 @@ fn validate_generic_param_order<'a>(
         }
         let max_param = &mut max_param;
         match max_param {
-            Some(ParamKindOrd::Const { unordered: true }) if kind != ParamKindOrd::Lifetime => (),
             Some(max_param) if *max_param > kind => {
                 let entry = out_of_order.entry(kind).or_insert((*max_param, vec![]));
                 entry.1.push(span);
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index becabe9c3b9..2be100ae336 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -504,14 +504,16 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
             GenericArg::Const(_) => ParamKindOrd::Const { unordered },
         };
 
-        // This note will be true as long as generic parameters are strictly ordered by their kind.
-        let (first, last) =
-            if kind_ord < arg_ord { (kind, arg.descr()) } else { (arg.descr(), kind) };
-        err.note(&format!("{} arguments must be provided before {} arguments", first, last));
-
-        if let Some(help) = help {
-            err.help(help);
+        // This note is only true when generic parameters are strictly ordered by their kind.
+        if kind_ord.cmp(&arg_ord) != core::cmp::Ordering::Equal {
+            let (first, last) =
+                if kind_ord < arg_ord { (kind, arg.descr()) } else { (arg.descr(), kind) };
+            err.note(&format!("{} arguments must be provided before {} arguments", first, last));
+            if let Some(help) = help {
+                err.help(help);
+            }
         }
+
         err.emit();
     }
 
diff --git a/src/test/ui/const-generics/argument_order.stderr b/src/test/ui/const-generics/argument_order.stderr
index 87dff170b2a..687e8589bf0 100644
--- a/src/test/ui/const-generics/argument_order.stderr
+++ b/src/test/ui/const-generics/argument_order.stderr
@@ -2,7 +2,7 @@ error: lifetime parameters must be declared prior to const parameters
   --> $DIR/argument_order.rs:9:32
    |
 LL | struct AlsoBad<const N: usize, 'a, T, 'b, const M: usize, U> {
-   |               -----------------^^-----^^-------------------- help: reorder the parameters: lifetimes, then consts and types: `<'a, 'b, T, U, const N: usize, const M: usize>`
+   |               -----------------^^-----^^-------------------- help: reorder the parameters: lifetimes, then consts and types: `<'a, 'b, const N: usize, T, const M: usize, U>`
 
 error[E0747]: lifetime provided when a type was expected
   --> $DIR/argument_order.rs:16:23
@@ -11,7 +11,7 @@ LL |     let _: AlsoBad<7, 'static, u32, 'static, 17, u16>;
    |                       ^^^^^^^
    |
    = note: lifetime arguments must be provided before type arguments
-   = help: reorder the arguments: lifetimes, then types, then consts: `<'a, 'b, T, U, N, M>`
+   = help: reorder the arguments: lifetimes, then consts, then types, then consts, then types: `<'a, 'b, N, T, M, U>`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/const-generics/const-arg-type-arg-misordered.rs b/src/test/ui/const-generics/const-arg-type-arg-misordered.rs
index 9f989ee20a5..13ca56ad3e6 100644
--- a/src/test/ui/const-generics/const-arg-type-arg-misordered.rs
+++ b/src/test/ui/const-generics/const-arg-type-arg-misordered.rs
@@ -1,5 +1,5 @@
 #![feature(const_generics)]
-//~^ WARN the feature `const_generics` is incomplete
+#![allow(incomplete_features)]
 
 type Array<T, const N: usize> = [T; N];
 
diff --git a/src/test/ui/const-generics/const-arg-type-arg-misordered.stderr b/src/test/ui/const-generics/const-arg-type-arg-misordered.stderr
index 4a6241de1b4..2e2bfed51fb 100644
--- a/src/test/ui/const-generics/const-arg-type-arg-misordered.stderr
+++ b/src/test/ui/const-generics/const-arg-type-arg-misordered.stderr
@@ -1,21 +1,9 @@
-warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/const-arg-type-arg-misordered.rs:1:12
-   |
-LL | #![feature(const_generics)]
-   |            ^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
-
 error[E0747]: constant provided when a type was expected
   --> $DIR/const-arg-type-arg-misordered.rs:6:35
    |
 LL | fn foo<const N: usize>() -> Array<N, ()> {
    |                                   ^
-   |
-   = note: type arguments must be provided before constant arguments
-   = help: reorder the arguments: types, then consts: `<T, N>`
 
-error: aborting due to previous error; 1 warning emitted
+error: aborting due to previous error
 
 For more information about this error, try `rustc --explain E0747`.
diff --git a/src/test/ui/const-generics/defaults/complex-unord-param.rs b/src/test/ui/const-generics/defaults/complex-unord-param.rs
index 8ee5604633e..72967640a8e 100644
--- a/src/test/ui/const-generics/defaults/complex-unord-param.rs
+++ b/src/test/ui/const-generics/defaults/complex-unord-param.rs
@@ -5,14 +5,6 @@
 #![allow(incomplete_features)]
 #![allow(dead_code)]
 
-struct FixedOutput<'a, const N: usize, T=u32> {
-  out: &'a [T; N],
-}
-
-trait FixedOutputter {
-  fn out(&self) -> FixedOutput<'_, 10>;
-}
-
 struct NestedArrays<'a, const N: usize, A: 'a, const M: usize, T:'a =u32> {
   args: &'a [&'a [T; M]; N],
   specifier: A,
diff --git a/src/test/ui/const-generics/defaults/intermixed-lifetime.rs b/src/test/ui/const-generics/defaults/intermixed-lifetime.rs
index d53958c9573..ea3a8c14b98 100644
--- a/src/test/ui/const-generics/defaults/intermixed-lifetime.rs
+++ b/src/test/ui/const-generics/defaults/intermixed-lifetime.rs
@@ -7,6 +7,6 @@ struct Foo<const N: usize, 'a, T = u32>(&'a (), T);
 //~^ Error lifetime parameters must be declared prior to const parameters
 
 struct Bar<const N: usize, T = u32, 'a>(&'a (), T);
-//~^ Error lifetime parameters must be declared prior to const parameters
+//~^ Error lifetime parameters must be declared prior to type parameters
 
 fn main() {}
diff --git a/src/test/ui/const-generics/defaults/intermixed-lifetime.stderr b/src/test/ui/const-generics/defaults/intermixed-lifetime.stderr
index d8450ba442d..0f6d7f1065a 100644
--- a/src/test/ui/const-generics/defaults/intermixed-lifetime.stderr
+++ b/src/test/ui/const-generics/defaults/intermixed-lifetime.stderr
@@ -2,13 +2,13 @@ error: lifetime parameters must be declared prior to const parameters
   --> $DIR/intermixed-lifetime.rs:6:28
    |
 LL | struct Foo<const N: usize, 'a, T = u32>(&'a (), T);
-   |           -----------------^^---------- help: reorder the parameters: lifetimes, then consts and types: `<'a, T, const N: usize>`
+   |           -----------------^^---------- help: reorder the parameters: lifetimes, then consts and types: `<'a, const N: usize, T>`
 
-error: lifetime parameters must be declared prior to const parameters
+error: lifetime parameters must be declared prior to type parameters
   --> $DIR/intermixed-lifetime.rs:9:37
    |
 LL | struct Bar<const N: usize, T = u32, 'a>(&'a (), T);
-   |           --------------------------^^- help: reorder the parameters: lifetimes, then consts and types: `<'a, T, const N: usize>`
+   |           --------------------------^^- help: reorder the parameters: lifetimes, then consts and types: `<'a, const N: usize, T>`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/const-generics/defaults/needs-feature.min.stderr b/src/test/ui/const-generics/defaults/needs-feature.min.stderr
new file mode 100644
index 00000000000..d57190ea3bb
--- /dev/null
+++ b/src/test/ui/const-generics/defaults/needs-feature.min.stderr
@@ -0,0 +1,8 @@
+error: type parameters must be declared prior to const parameters
+  --> $DIR/needs-feature.rs:10:26
+   |
+LL | struct A<const N: usize, T=u32>(T);
+   |         -----------------^----- help: reorder the parameters: lifetimes, then consts, then types: `<T, const N: usize>`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/const-generics/defaults/needs-feature.stderr b/src/test/ui/const-generics/defaults/needs-feature.none.stderr
index 30604feab1b..3b6f63a8efe 100644
--- a/src/test/ui/const-generics/defaults/needs-feature.stderr
+++ b/src/test/ui/const-generics/defaults/needs-feature.none.stderr
@@ -1,17 +1,17 @@
 error: type parameters must be declared prior to const parameters
-  --> $DIR/needs-feature.rs:4:26
+  --> $DIR/needs-feature.rs:10:26
    |
 LL | struct A<const N: usize, T=u32>(T);
    |         -----------------^----- help: reorder the parameters: lifetimes, then types: `<T, const N: usize>`
 
 error[E0658]: const generics are unstable
-  --> $DIR/needs-feature.rs:4:16
+  --> $DIR/needs-feature.rs:10:16
    |
 LL | struct A<const N: usize, T=u32>(T);
    |                ^
    |
-   = note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
-   = help: add `#![feature(const_generics)]` to the crate attributes to enable
+   = note: see issue #74878 <https://github.com/rust-lang/rust/issues/74878> for more information
+   = help: add `#![feature(min_const_generics)]` to the crate attributes to enable
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/const-generics/defaults/needs-feature.rs b/src/test/ui/const-generics/defaults/needs-feature.rs
index ea38a4022ae..ec02dbf407d 100644
--- a/src/test/ui/const-generics/defaults/needs-feature.rs
+++ b/src/test/ui/const-generics/defaults/needs-feature.rs
@@ -1,8 +1,17 @@
+//[full] run-pass
 // Verifies that having generic parameters after constants is not permitted without the
 // `const_generics` feature.
+// revisions: none min full
+
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(min, feature(min_const_generics))]
 
 struct A<const N: usize, T=u32>(T);
-//~^ ERROR type parameters must be declared prior
-//~| ERROR const generics are unstable
+//[none]~^ ERROR type parameters must be declared prior
+//[none]~| ERROR const generics are unstable
+//[min]~^^^ ERROR type parameters must be declared prior
 
-fn main() {}
+fn main() {
+  let _: A<3> = A(0);
+}
diff --git a/src/test/ui/const-generics/defaults/right-order.rs b/src/test/ui/const-generics/defaults/right-order.rs
deleted file mode 100644
index fce3ab2e6a3..00000000000
--- a/src/test/ui/const-generics/defaults/right-order.rs
+++ /dev/null
@@ -1,11 +0,0 @@
-// run-pass
-// Verifies that having generic parameters after constants is permitted.
-
-#![feature(const_generics)]
-#![allow(incomplete_features)]
-
-struct A<const N: usize, T=u32>(T);
-
-fn main() {
-  let _: A<3> = A(0);
-}
diff --git a/src/test/ui/const-generics/defaults/simple-defaults.rs b/src/test/ui/const-generics/defaults/simple-defaults.rs
new file mode 100644
index 00000000000..b282dfd37cc
--- /dev/null
+++ b/src/test/ui/const-generics/defaults/simple-defaults.rs
@@ -0,0 +1,15 @@
+// run-pass
+// Checks some basic test cases for defaults.
+#![feature(const_generics)]
+#![allow(incomplete_features)]
+#![allow(dead_code)]
+
+struct FixedOutput<'a, const N: usize, T=u32> {
+  out: &'a [T; N],
+}
+
+trait FixedOutputter {
+  fn out(&self) -> FixedOutput<'_, 10>;
+}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/defaults/type-after-const-requires-default.rs b/src/test/ui/const-generics/type-after-const-ok.rs
index fc977d6617c..fc977d6617c 100644
--- a/src/test/ui/const-generics/defaults/type-after-const-requires-default.rs
+++ b/src/test/ui/const-generics/type-after-const-ok.rs