Gate fallback via #![feature(never_type_fallback)]
.
This commit is contained in:
parent
8f6197f39f
commit
6eb0627b49
18 changed files with 64 additions and 19 deletions
|
@ -2440,7 +2440,11 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
|
||||
#[inline]
|
||||
pub fn mk_diverging_default(self) -> Ty<'tcx> {
|
||||
self.types.never
|
||||
if self.features().never_type_fallback {
|
||||
self.types.never
|
||||
} else {
|
||||
self.types.unit
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
|
@ -3129,8 +3129,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
}
|
||||
|
||||
// Tries to apply a fallback to `ty` if it is an unsolved variable.
|
||||
// Non-numerics get replaced with `!`, unconstrained ints with `i32`,
|
||||
// unconstrained floats with `f64`.
|
||||
//
|
||||
// - Unconstrained ints are replaced with `i32`.
|
||||
//
|
||||
// - Unconstrained floats are replaced with with `f64`.
|
||||
//
|
||||
// - Non-numerics get replaced with `!` when `#![feature(never_type_fallback)]`
|
||||
// is enabled. Otherwise, they are replaced with `()`.
|
||||
//
|
||||
// Fallback becomes very dubious if we have encountered type-checking errors.
|
||||
// In that case, fallback to Error.
|
||||
// The return value indicates whether fallback has occurred.
|
||||
|
|
|
@ -520,6 +520,9 @@ declare_features! (
|
|||
/// Allows using the `efiapi` ABI.
|
||||
(active, abi_efiapi, "1.40.0", Some(65815), None),
|
||||
|
||||
/// Allows diverging expressions to fall back to `!` rather than `()`.
|
||||
(active, never_type_fallback, "1.41.0", Some(65992), None),
|
||||
|
||||
/// Allows using the `#[register_attr]` attribute.
|
||||
(active, register_attr, "1.41.0", Some(66080), None),
|
||||
|
||||
|
|
|
@ -444,6 +444,7 @@ symbols! {
|
|||
negate_unsigned,
|
||||
never,
|
||||
never_type,
|
||||
never_type_fallback,
|
||||
new,
|
||||
next,
|
||||
__next,
|
||||
|
|
|
@ -21,5 +21,5 @@ trait Add<RHS=Self> {
|
|||
fn ice<A>(a: A) {
|
||||
let r = loop {};
|
||||
r = r + a;
|
||||
//~^ ERROR the trait bound `!: Add<A>` is not satisfied
|
||||
//~^ ERROR the trait bound `(): Add<A>` is not satisfied
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
error[E0277]: the trait bound `!: Add<A>` is not satisfied
|
||||
error[E0277]: the trait bound `(): Add<A>` is not satisfied
|
||||
--> $DIR/associated-types-ICE-when-projecting-out-of-err.rs:23:11
|
||||
|
|
||||
LL | r = r + a;
|
||||
| ^ the trait `Add<A>` is not implemented for `!`
|
||||
| ^ the trait `Add<A>` is not implemented for `()`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
// run-pass
|
||||
#![feature(never_type_fallback)]
|
||||
#![feature(exhaustive_patterns)]
|
||||
#![feature(slice_patterns)]
|
||||
#![allow(unreachable_patterns)]
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// check-pass
|
||||
|
||||
#![feature(never_type_fallback)]
|
||||
#![allow(unreachable_code)]
|
||||
|
||||
use std::error::Error;
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
// We need to opt into the `never_type_fallback` feature
|
||||
// to trigger the requirement that this is testing.
|
||||
#![feature(never_type_fallback)]
|
||||
|
||||
#![allow(unused)]
|
||||
|
||||
trait Deserialize: Sized {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
error[E0277]: the trait bound `!: ImplementedForUnitButNotNever` is not satisfied
|
||||
--> $DIR/defaulted-never-note.rs:23:5
|
||||
--> $DIR/defaulted-never-note.rs:27:5
|
||||
|
|
||||
LL | fn foo<T: ImplementedForUnitButNotNever>(_t: T) {}
|
||||
| --- ----------------------------- required by this bound in `foo`
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
// These represent current behavior, but are pretty dubious. I would
|
||||
// like to revisit these and potentially change them. --nmatsakis
|
||||
|
||||
#![feature(never_type_fallback)]
|
||||
|
||||
trait BadDefault {
|
||||
fn default() -> Self;
|
||||
}
|
||||
|
|
12
src/test/ui/never_type/feature-gate-never_type_fallback.rs
Normal file
12
src/test/ui/never_type/feature-gate-never_type_fallback.rs
Normal file
|
@ -0,0 +1,12 @@
|
|||
// This is a feature gate test for `never_type_fallback`.
|
||||
// It works by using a scenario where the type fall backs to `()` rather than ´!`
|
||||
// in the case where `#![feature(never_type_fallback)]` would change it to `!`.
|
||||
|
||||
fn main() {}
|
||||
|
||||
trait T {}
|
||||
|
||||
fn should_ret_unit() -> impl T {
|
||||
//~^ ERROR the trait bound `(): T` is not satisfied
|
||||
panic!()
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
error[E0277]: the trait bound `(): T` is not satisfied
|
||||
--> $DIR/feature-gate-never_type_fallback.rs:9:25
|
||||
|
|
||||
LL | fn should_ret_unit() -> impl T {
|
||||
| ^^^^^^ the trait `T` is not implemented for `()`
|
||||
|
|
||||
= note: the return type of a function must have a statically known size
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
|
@ -1,10 +1,10 @@
|
|||
error[E0277]: cannot add `!` to `usize`
|
||||
error[E0277]: cannot add `()` to `usize`
|
||||
--> $DIR/issue-13352.rs:9:13
|
||||
|
|
||||
LL | 2_usize + (loop {});
|
||||
| ^ no implementation for `usize + !`
|
||||
| ^ no implementation for `usize + ()`
|
||||
|
|
||||
= help: the trait `std::ops::Add<!>` is not implemented for `usize`
|
||||
= help: the trait `std::ops::Add<()>` is not implemented for `usize`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
error[E0277]: cannot add `std::vec::Vec<B>` to `!`
|
||||
error[E0277]: cannot add `std::vec::Vec<B>` to `()`
|
||||
--> $DIR/issue-2149.rs:8:33
|
||||
|
|
||||
LL | for elt in self { r = r + f(*elt); }
|
||||
| ^ no implementation for `! + std::vec::Vec<B>`
|
||||
| ^ no implementation for `() + std::vec::Vec<B>`
|
||||
|
|
||||
= help: the trait `std::ops::Add<std::vec::Vec<B>>` is not implemented for `!`
|
||||
= help: the trait `std::ops::Add<std::vec::Vec<B>>` is not implemented for `()`
|
||||
|
||||
error[E0599]: no method named `bind` found for type `[&str; 1]` in the current scope
|
||||
--> $DIR/issue-2149.rs:13:12
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#![feature(never_type_fallback)]
|
||||
#![feature(exhaustive_patterns)]
|
||||
|
||||
#![allow(unreachable_code)]
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
error: unreachable pattern
|
||||
--> $DIR/unreachable-loop-patterns.rs:17:9
|
||||
--> $DIR/unreachable-loop-patterns.rs:18:9
|
||||
|
|
||||
LL | for _ in unimplemented!() as Void {}
|
||||
| ^
|
||||
|
|
||||
note: lint level defined here
|
||||
--> $DIR/unreachable-loop-patterns.rs:4:9
|
||||
--> $DIR/unreachable-loop-patterns.rs:5:9
|
||||
|
|
||||
LL | #![deny(unreachable_patterns)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/unreachable-loop-patterns.rs:17:14
|
||||
--> $DIR/unreachable-loop-patterns.rs:18:14
|
||||
|
|
||||
LL | for _ in unimplemented!() as Void {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
|
@ -4,7 +4,7 @@ error: concrete type differs from previous defining opaque type use
|
|||
LL | / fn bar() -> Foo {
|
||||
LL | | panic!()
|
||||
LL | | }
|
||||
| |_^ expected `&'static str`, got `!`
|
||||
| |_^ expected `&'static str`, got `()`
|
||||
|
|
||||
note: previous use here
|
||||
--> $DIR/different_defining_uses_never_type.rs:8:1
|
||||
|
@ -20,7 +20,7 @@ error: concrete type differs from previous defining opaque type use
|
|||
LL | / fn boo() -> Foo {
|
||||
LL | | loop {}
|
||||
LL | | }
|
||||
| |_^ expected `&'static str`, got `!`
|
||||
| |_^ expected `&'static str`, got `()`
|
||||
|
|
||||
note: previous use here
|
||||
--> $DIR/different_defining_uses_never_type.rs:8:1
|
||||
|
|
Loading…
Add table
Reference in a new issue