Skip to content

Commit be0d6f1

Browse files
committed
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
1 parent 4f461f5 commit be0d6f1

15 files changed

+82
-55
lines changed

src/librustc_ast/ast.rs

+26-1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ use rustc_span::source_map::{respan, Spanned};
3535
use rustc_span::symbol::{kw, sym, Ident, Symbol};
3636
use rustc_span::{Span, DUMMY_SP};
3737

38+
use std::cmp::Ordering;
3839
use std::convert::TryFrom;
3940
use std::fmt;
4041
use std::iter;
@@ -309,13 +310,37 @@ pub type GenericBounds = Vec<GenericBound>;
309310
/// Specifies the enforced ordering for generic parameters. In the future,
310311
/// if we wanted to relax this order, we could override `PartialEq` and
311312
/// `PartialOrd`, to allow the kinds to be unordered.
312-
#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)]
313+
#[derive(PartialEq, Eq, Hash, Clone, Copy)]
313314
pub enum ParamKindOrd {
314315
Lifetime,
315316
Type,
317+
// `unordered` is only `true` if `sess.has_features().const_generics`
318+
// is active. Specifically, if it's only `min_const_generics`, it will still require
319+
// ordering consts after types.
316320
Const { unordered: bool },
317321
}
318322

323+
impl Ord for ParamKindOrd {
324+
fn cmp(&self, other: &Self) -> Ordering {
325+
use ParamKindOrd::*;
326+
let to_int = |v| match v {
327+
Lifetime => 0,
328+
Type | Const { unordered: true } => 1,
329+
// technically both consts should be ordered equally,
330+
// but only one is ever encountered at a time, so this is
331+
// fine.
332+
Const { unordered: false } => 2,
333+
};
334+
335+
to_int(*self).cmp(&to_int(*other))
336+
}
337+
}
338+
impl PartialOrd for ParamKindOrd {
339+
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
340+
Some(self.cmp(other))
341+
}
342+
}
343+
319344
impl fmt::Display for ParamKindOrd {
320345
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
321346
match self {

src/librustc_ast_passes/ast_validation.rs

-1
Original file line numberDiff line numberDiff line change
@@ -735,7 +735,6 @@ fn validate_generic_param_order<'a>(
735735
}
736736
let max_param = &mut max_param;
737737
match max_param {
738-
Some(ParamKindOrd::Const { unordered: true }) if kind != ParamKindOrd::Lifetime => (),
739738
Some(max_param) if *max_param > kind => {
740739
let entry = out_of_order.entry(kind).or_insert((*max_param, vec![]));
741740
entry.1.push(span);

src/librustc_typeck/astconv.rs

+9-7
Original file line numberDiff line numberDiff line change
@@ -504,14 +504,16 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
504504
GenericArg::Const(_) => ParamKindOrd::Const { unordered },
505505
};
506506

507-
// This note will be true as long as generic parameters are strictly ordered by their kind.
508-
let (first, last) =
509-
if kind_ord < arg_ord { (kind, arg.descr()) } else { (arg.descr(), kind) };
510-
err.note(&format!("{} arguments must be provided before {} arguments", first, last));
511-
512-
if let Some(help) = help {
513-
err.help(help);
507+
// This note is only true when generic parameters are strictly ordered by their kind.
508+
if kind_ord.cmp(&arg_ord) != core::cmp::Ordering::Equal {
509+
let (first, last) =
510+
if kind_ord < arg_ord { (kind, arg.descr()) } else { (arg.descr(), kind) };
511+
err.note(&format!("{} arguments must be provided before {} arguments", first, last));
512+
if let Some(help) = help {
513+
err.help(help);
514+
}
514515
}
516+
515517
err.emit();
516518
}
517519

src/test/ui/const-generics/argument_order.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error: lifetime parameters must be declared prior to const parameters
22
--> $DIR/argument_order.rs:9:32
33
|
44
LL | struct AlsoBad<const N: usize, 'a, T, 'b, const M: usize, U> {
5-
| -----------------^^-----^^-------------------- help: reorder the parameters: lifetimes, then consts and types: `<'a, 'b, T, U, const N: usize, const M: usize>`
5+
| -----------------^^-----^^-------------------- help: reorder the parameters: lifetimes, then consts and types: `<'a, 'b, const N: usize, T, const M: usize, U>`
66

77
error[E0747]: lifetime provided when a type was expected
88
--> $DIR/argument_order.rs:16:23
@@ -11,7 +11,7 @@ LL | let _: AlsoBad<7, 'static, u32, 'static, 17, u16>;
1111
| ^^^^^^^
1212
|
1313
= note: lifetime arguments must be provided before type arguments
14-
= help: reorder the arguments: lifetimes, then types, then consts: `<'a, 'b, T, U, N, M>`
14+
= help: reorder the arguments: lifetimes, then consts, then types, then consts, then types: `<'a, 'b, N, T, M, U>`
1515

1616
error: aborting due to 2 previous errors
1717

src/test/ui/const-generics/const-arg-type-arg-misordered.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#![feature(const_generics)]
2-
//~^ WARN the feature `const_generics` is incomplete
2+
#![allow(incomplete_features)]
33

44
type Array<T, const N: usize> = [T; N];
55

Original file line numberDiff line numberDiff line change
@@ -1,21 +1,9 @@
1-
warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes
2-
--> $DIR/const-arg-type-arg-misordered.rs:1:12
3-
|
4-
LL | #![feature(const_generics)]
5-
| ^^^^^^^^^^^^^^
6-
|
7-
= note: `#[warn(incomplete_features)]` on by default
8-
= note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
9-
101
error[E0747]: constant provided when a type was expected
112
--> $DIR/const-arg-type-arg-misordered.rs:6:35
123
|
134
LL | fn foo<const N: usize>() -> Array<N, ()> {
145
| ^
15-
|
16-
= note: type arguments must be provided before constant arguments
17-
= help: reorder the arguments: types, then consts: `<T, N>`
186

19-
error: aborting due to previous error; 1 warning emitted
7+
error: aborting due to previous error
208

219
For more information about this error, try `rustc --explain E0747`.

src/test/ui/const-generics/defaults/complex-unord-param.rs

-8
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,6 @@
55
#![allow(incomplete_features)]
66
#![allow(dead_code)]
77

8-
struct FixedOutput<'a, const N: usize, T=u32> {
9-
out: &'a [T; N],
10-
}
11-
12-
trait FixedOutputter {
13-
fn out(&self) -> FixedOutput<'_, 10>;
14-
}
15-
168
struct NestedArrays<'a, const N: usize, A: 'a, const M: usize, T:'a =u32> {
179
args: &'a [&'a [T; M]; N],
1810
specifier: A,

src/test/ui/const-generics/defaults/intermixed-lifetime.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,6 @@ struct Foo<const N: usize, 'a, T = u32>(&'a (), T);
77
//~^ Error lifetime parameters must be declared prior to const parameters
88

99
struct Bar<const N: usize, T = u32, 'a>(&'a (), T);
10-
//~^ Error lifetime parameters must be declared prior to const parameters
10+
//~^ Error lifetime parameters must be declared prior to type parameters
1111

1212
fn main() {}

src/test/ui/const-generics/defaults/intermixed-lifetime.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@ error: lifetime parameters must be declared prior to const parameters
22
--> $DIR/intermixed-lifetime.rs:6:28
33
|
44
LL | struct Foo<const N: usize, 'a, T = u32>(&'a (), T);
5-
| -----------------^^---------- help: reorder the parameters: lifetimes, then consts and types: `<'a, T, const N: usize>`
5+
| -----------------^^---------- help: reorder the parameters: lifetimes, then consts and types: `<'a, const N: usize, T>`
66

7-
error: lifetime parameters must be declared prior to const parameters
7+
error: lifetime parameters must be declared prior to type parameters
88
--> $DIR/intermixed-lifetime.rs:9:37
99
|
1010
LL | struct Bar<const N: usize, T = u32, 'a>(&'a (), T);
11-
| --------------------------^^- help: reorder the parameters: lifetimes, then consts and types: `<'a, T, const N: usize>`
11+
| --------------------------^^- help: reorder the parameters: lifetimes, then consts and types: `<'a, const N: usize, T>`
1212

1313
error: aborting due to 2 previous errors
1414

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
error: type parameters must be declared prior to const parameters
2+
--> $DIR/needs-feature.rs:10:26
3+
|
4+
LL | struct A<const N: usize, T=u32>(T);
5+
| -----------------^----- help: reorder the parameters: lifetimes, then consts, then types: `<T, const N: usize>`
6+
7+
error: aborting due to previous error
8+

src/test/ui/const-generics/defaults/needs-feature.stderr renamed to src/test/ui/const-generics/defaults/needs-feature.none.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
error: type parameters must be declared prior to const parameters
2-
--> $DIR/needs-feature.rs:4:26
2+
--> $DIR/needs-feature.rs:10:26
33
|
44
LL | struct A<const N: usize, T=u32>(T);
55
| -----------------^----- help: reorder the parameters: lifetimes, then types: `<T, const N: usize>`
66

77
error[E0658]: const generics are unstable
8-
--> $DIR/needs-feature.rs:4:16
8+
--> $DIR/needs-feature.rs:10:16
99
|
1010
LL | struct A<const N: usize, T=u32>(T);
1111
| ^
1212
|
13-
= note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
14-
= help: add `#![feature(const_generics)]` to the crate attributes to enable
13+
= note: see issue #74878 <https://github.com/rust-lang/rust/issues/74878> for more information
14+
= help: add `#![feature(min_const_generics)]` to the crate attributes to enable
1515

1616
error: aborting due to 2 previous errors
1717

Original file line numberDiff line numberDiff line change
@@ -1,8 +1,17 @@
1+
//[full] run-pass
12
// Verifies that having generic parameters after constants is not permitted without the
23
// `const_generics` feature.
4+
// revisions: none min full
5+
6+
#![cfg_attr(full, feature(const_generics))]
7+
#![cfg_attr(full, allow(incomplete_features))]
8+
#![cfg_attr(min, feature(min_const_generics))]
39

410
struct A<const N: usize, T=u32>(T);
5-
//~^ ERROR type parameters must be declared prior
6-
//~| ERROR const generics are unstable
11+
//[none]~^ ERROR type parameters must be declared prior
12+
//[none]~| ERROR const generics are unstable
13+
//[min]~^^^ ERROR type parameters must be declared prior
714

8-
fn main() {}
15+
fn main() {
16+
let _: A<3> = A(0);
17+
}

src/test/ui/const-generics/defaults/right-order.rs

-11
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// run-pass
2+
// Checks some basic test cases for defaults.
3+
#![feature(const_generics)]
4+
#![allow(incomplete_features)]
5+
#![allow(dead_code)]
6+
7+
struct FixedOutput<'a, const N: usize, T=u32> {
8+
out: &'a [T; N],
9+
}
10+
11+
trait FixedOutputter {
12+
fn out(&self) -> FixedOutput<'_, 10>;
13+
}
14+
15+
fn main() {}

0 commit comments

Comments
 (0)