Skip to content

Commit 6eb0627

Browse files
committed
Gate fallback via #![feature(never_type_fallback)].
1 parent 8f6197f commit 6eb0627

18 files changed

+64
-19
lines changed

src/librustc/ty/context.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -2440,7 +2440,11 @@ impl<'tcx> TyCtxt<'tcx> {
24402440

24412441
#[inline]
24422442
pub fn mk_diverging_default(self) -> Ty<'tcx> {
2443-
self.types.never
2443+
if self.features().never_type_fallback {
2444+
self.types.never
2445+
} else {
2446+
self.types.unit
2447+
}
24442448
}
24452449

24462450
#[inline]

src/librustc_typeck/check/mod.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -3129,8 +3129,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
31293129
}
31303130

31313131
// Tries to apply a fallback to `ty` if it is an unsolved variable.
3132-
// Non-numerics get replaced with `!`, unconstrained ints with `i32`,
3133-
// unconstrained floats with `f64`.
3132+
//
3133+
// - Unconstrained ints are replaced with `i32`.
3134+
//
3135+
// - Unconstrained floats are replaced with with `f64`.
3136+
//
3137+
// - Non-numerics get replaced with `!` when `#![feature(never_type_fallback)]`
3138+
// is enabled. Otherwise, they are replaced with `()`.
3139+
//
31343140
// Fallback becomes very dubious if we have encountered type-checking errors.
31353141
// In that case, fallback to Error.
31363142
// The return value indicates whether fallback has occurred.

src/libsyntax/feature_gate/active.rs

+3
Original file line numberDiff line numberDiff line change
@@ -520,6 +520,9 @@ declare_features! (
520520
/// Allows using the `efiapi` ABI.
521521
(active, abi_efiapi, "1.40.0", Some(65815), None),
522522

523+
/// Allows diverging expressions to fall back to `!` rather than `()`.
524+
(active, never_type_fallback, "1.41.0", Some(65992), None),
525+
523526
/// Allows using the `#[register_attr]` attribute.
524527
(active, register_attr, "1.41.0", Some(66080), None),
525528

src/libsyntax_pos/symbol.rs

+1
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,7 @@ symbols! {
444444
negate_unsigned,
445445
never,
446446
never_type,
447+
never_type_fallback,
447448
new,
448449
next,
449450
__next,

src/test/ui/associated-types/associated-types-ICE-when-projecting-out-of-err.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,5 +21,5 @@ trait Add<RHS=Self> {
2121
fn ice<A>(a: A) {
2222
let r = loop {};
2323
r = r + a;
24-
//~^ ERROR the trait bound `!: Add<A>` is not satisfied
24+
//~^ ERROR the trait bound `(): Add<A>` is not satisfied
2525
}

src/test/ui/associated-types/associated-types-ICE-when-projecting-out-of-err.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
error[E0277]: the trait bound `!: Add<A>` is not satisfied
1+
error[E0277]: the trait bound `(): Add<A>` is not satisfied
22
--> $DIR/associated-types-ICE-when-projecting-out-of-err.rs:23:11
33
|
44
LL | r = r + a;
5-
| ^ the trait `Add<A>` is not implemented for `!`
5+
| ^ the trait `Add<A>` is not implemented for `()`
66

77
error: aborting due to previous error
88

src/test/ui/binding/empty-types-in-patterns.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
// run-pass
2+
#![feature(never_type_fallback)]
23
#![feature(exhaustive_patterns)]
34
#![feature(slice_patterns)]
45
#![allow(unreachable_patterns)]

src/test/ui/coercion/coerce-issue-49593-box-never.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// check-pass
2-
2+
#![feature(never_type_fallback)]
33
#![allow(unreachable_code)]
44

55
use std::error::Error;

src/test/ui/never_type/defaulted-never-note.rs

+4
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
// We need to opt into the `never_type_fallback` feature
2+
// to trigger the requirement that this is testing.
3+
#![feature(never_type_fallback)]
4+
15
#![allow(unused)]
26

37
trait Deserialize: Sized {

src/test/ui/never_type/defaulted-never-note.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error[E0277]: the trait bound `!: ImplementedForUnitButNotNever` is not satisfied
2-
--> $DIR/defaulted-never-note.rs:23:5
2+
--> $DIR/defaulted-never-note.rs:27:5
33
|
44
LL | fn foo<T: ImplementedForUnitButNotNever>(_t: T) {}
55
| --- ----------------------------- required by this bound in `foo`

src/test/ui/never_type/diverging-fallback-control-flow.rs

+2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
// These represent current behavior, but are pretty dubious. I would
1212
// like to revisit these and potentially change them. --nmatsakis
1313

14+
#![feature(never_type_fallback)]
15+
1416
trait BadDefault {
1517
fn default() -> Self;
1618
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// This is a feature gate test for `never_type_fallback`.
2+
// It works by using a scenario where the type fall backs to `()` rather than ´!`
3+
// in the case where `#![feature(never_type_fallback)]` would change it to `!`.
4+
5+
fn main() {}
6+
7+
trait T {}
8+
9+
fn should_ret_unit() -> impl T {
10+
//~^ ERROR the trait bound `(): T` is not satisfied
11+
panic!()
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
error[E0277]: the trait bound `(): T` is not satisfied
2+
--> $DIR/feature-gate-never_type_fallback.rs:9:25
3+
|
4+
LL | fn should_ret_unit() -> impl T {
5+
| ^^^^^^ the trait `T` is not implemented for `()`
6+
|
7+
= note: the return type of a function must have a statically known size
8+
9+
error: aborting due to previous error
10+
11+
For more information about this error, try `rustc --explain E0277`.

src/test/ui/never_type/issue-13352.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
error[E0277]: cannot add `!` to `usize`
1+
error[E0277]: cannot add `()` to `usize`
22
--> $DIR/issue-13352.rs:9:13
33
|
44
LL | 2_usize + (loop {});
5-
| ^ no implementation for `usize + !`
5+
| ^ no implementation for `usize + ()`
66
|
7-
= help: the trait `std::ops::Add<!>` is not implemented for `usize`
7+
= help: the trait `std::ops::Add<()>` is not implemented for `usize`
88

99
error: aborting due to previous error
1010

src/test/ui/never_type/issue-2149.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
error[E0277]: cannot add `std::vec::Vec<B>` to `!`
1+
error[E0277]: cannot add `std::vec::Vec<B>` to `()`
22
--> $DIR/issue-2149.rs:8:33
33
|
44
LL | for elt in self { r = r + f(*elt); }
5-
| ^ no implementation for `! + std::vec::Vec<B>`
5+
| ^ no implementation for `() + std::vec::Vec<B>`
66
|
7-
= help: the trait `std::ops::Add<std::vec::Vec<B>>` is not implemented for `!`
7+
= help: the trait `std::ops::Add<std::vec::Vec<B>>` is not implemented for `()`
88

99
error[E0599]: no method named `bind` found for type `[&str; 1]` in the current scope
1010
--> $DIR/issue-2149.rs:13:12

src/test/ui/reachable/unreachable-loop-patterns.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#![feature(never_type_fallback)]
12
#![feature(exhaustive_patterns)]
23

34
#![allow(unreachable_code)]

src/test/ui/reachable/unreachable-loop-patterns.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
error: unreachable pattern
2-
--> $DIR/unreachable-loop-patterns.rs:17:9
2+
--> $DIR/unreachable-loop-patterns.rs:18:9
33
|
44
LL | for _ in unimplemented!() as Void {}
55
| ^
66
|
77
note: lint level defined here
8-
--> $DIR/unreachable-loop-patterns.rs:4:9
8+
--> $DIR/unreachable-loop-patterns.rs:5:9
99
|
1010
LL | #![deny(unreachable_patterns)]
1111
| ^^^^^^^^^^^^^^^^^^^^
1212

1313
error: unreachable pattern
14-
--> $DIR/unreachable-loop-patterns.rs:17:14
14+
--> $DIR/unreachable-loop-patterns.rs:18:14
1515
|
1616
LL | for _ in unimplemented!() as Void {}
1717
| ^^^^^^^^^^^^^^^^^^^^^^^^

src/test/ui/type-alias-impl-trait/different_defining_uses_never_type.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ error: concrete type differs from previous defining opaque type use
44
LL | / fn bar() -> Foo {
55
LL | | panic!()
66
LL | | }
7-
| |_^ expected `&'static str`, got `!`
7+
| |_^ expected `&'static str`, got `()`
88
|
99
note: previous use here
1010
--> $DIR/different_defining_uses_never_type.rs:8:1
@@ -20,7 +20,7 @@ error: concrete type differs from previous defining opaque type use
2020
LL | / fn boo() -> Foo {
2121
LL | | loop {}
2222
LL | | }
23-
| |_^ expected `&'static str`, got `!`
23+
| |_^ expected `&'static str`, got `()`
2424
|
2525
note: previous use here
2626
--> $DIR/different_defining_uses_never_type.rs:8:1

0 commit comments

Comments
 (0)