Gate fallback via #![feature(never_type_fallback)].

This commit is contained in:
Mazdak Farrokhzad 2019-10-31 04:33:31 +01:00
parent 8f6197f39f
commit 6eb0627b49
18 changed files with 64 additions and 19 deletions

View file

@ -2440,7 +2440,11 @@ impl<'tcx> TyCtxt<'tcx> {
#[inline]
pub fn mk_diverging_default(self) -> Ty<'tcx> {
if self.features().never_type_fallback {
self.types.never
} else {
self.types.unit
}
}
#[inline]

View file

@ -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.

View file

@ -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),

View file

@ -444,6 +444,7 @@ symbols! {
negate_unsigned,
never,
never_type,
never_type_fallback,
new,
next,
__next,

View file

@ -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
}

View file

@ -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

View file

@ -1,4 +1,5 @@
// run-pass
#![feature(never_type_fallback)]
#![feature(exhaustive_patterns)]
#![feature(slice_patterns)]
#![allow(unreachable_patterns)]

View file

@ -1,5 +1,5 @@
// check-pass
#![feature(never_type_fallback)]
#![allow(unreachable_code)]
use std::error::Error;

View file

@ -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 {

View file

@ -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`

View file

@ -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;
}

View 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!()
}

View file

@ -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`.

View file

@ -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

View file

@ -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

View file

@ -1,3 +1,4 @@
#![feature(never_type_fallback)]
#![feature(exhaustive_patterns)]
#![allow(unreachable_code)]

View file

@ -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 {}
| ^^^^^^^^^^^^^^^^^^^^^^^^

View file

@ -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