From 15c30ddd69d6cc3fffe6d304c6dc968a5ed046f1 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sun, 13 Oct 2019 01:50:03 +0200 Subject: Stabilize the `never_type`, written `!`. --- src/libsyntax/feature_gate/accepted.rs | 2 ++ src/libsyntax/feature_gate/active.rs | 3 --- src/libsyntax/feature_gate/check.rs | 18 ------------------ 3 files changed, 2 insertions(+), 21 deletions(-) (limited to 'src/libsyntax/feature_gate') diff --git a/src/libsyntax/feature_gate/accepted.rs b/src/libsyntax/feature_gate/accepted.rs index 0107611460b..dab83f48a03 100644 --- a/src/libsyntax/feature_gate/accepted.rs +++ b/src/libsyntax/feature_gate/accepted.rs @@ -253,6 +253,8 @@ declare_features! ( (accepted, const_constructor, "1.40.0", Some(61456), None), /// Allows the use of `#[cfg(doctest)]`, set when rustdoc is collecting doctests. (accepted, cfg_doctest, "1.40.0", Some(62210), None), + /// Allows the `!` type. Does not imply 'exhaustive_patterns' any more. + (accepted, never_type, "1.41.0", Some(35121), None), /// Allows relaxing the coherence rules such that /// `impl ForeignTrait for ForeignType` is permitted. (accepted, re_rebalance_coherence, "1.41.0", Some(55437), None), diff --git a/src/libsyntax/feature_gate/active.rs b/src/libsyntax/feature_gate/active.rs index 2819ee273d9..23718f56246 100644 --- a/src/libsyntax/feature_gate/active.rs +++ b/src/libsyntax/feature_gate/active.rs @@ -318,9 +318,6 @@ declare_features! ( /// Allows `X..Y` patterns. (active, exclusive_range_pattern, "1.11.0", Some(37854), None), - /// Allows the `!` type. Does not imply 'exhaustive_patterns' (below) any more. - (active, never_type, "1.13.0", Some(35121), None), - /// Allows exhaustive pattern matching on types that contain uninhabited types. (active, exhaustive_patterns, "1.13.0", Some(51085), None), diff --git a/src/libsyntax/feature_gate/check.rs b/src/libsyntax/feature_gate/check.rs index abf9adefd3c..f966850254f 100644 --- a/src/libsyntax/feature_gate/check.rs +++ b/src/libsyntax/feature_gate/check.rs @@ -521,25 +521,11 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { ast::TyKind::BareFn(ref bare_fn_ty) => { self.check_extern(bare_fn_ty.ext); } - ast::TyKind::Never => { - gate_feature_post!(&self, never_type, ty.span, - "The `!` type is experimental"); - } _ => {} } visit::walk_ty(self, ty) } - fn visit_fn_ret_ty(&mut self, ret_ty: &'a ast::FunctionRetTy) { - if let ast::FunctionRetTy::Ty(ref output_ty) = *ret_ty { - if let ast::TyKind::Never = output_ty.kind { - // Do nothing. - } else { - self.visit_ty(output_ty) - } - } - } - fn visit_expr(&mut self, e: &'a ast::Expr) { match e.kind { ast::ExprKind::Box(_) => { @@ -567,10 +553,6 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { visit::walk_expr(self, e) } - fn visit_arm(&mut self, arm: &'a ast::Arm) { - visit::walk_arm(self, arm) - } - fn visit_pat(&mut self, pattern: &'a ast::Pat) { match &pattern.kind { PatKind::Slice(pats) => { -- cgit 1.4.1-3-g733a5 From 6eb0627b49edb03d27722cab4d13f92a9a65a1c8 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Thu, 31 Oct 2019 04:33:31 +0100 Subject: Gate fallback via `#![feature(never_type_fallback)]`. --- src/librustc/ty/context.rs | 6 +++++- src/librustc_typeck/check/mod.rs | 10 ++++++++-- src/libsyntax/feature_gate/active.rs | 3 +++ src/libsyntax_pos/symbol.rs | 1 + .../associated-types-ICE-when-projecting-out-of-err.rs | 2 +- .../associated-types-ICE-when-projecting-out-of-err.stderr | 4 ++-- src/test/ui/binding/empty-types-in-patterns.rs | 1 + src/test/ui/coercion/coerce-issue-49593-box-never.rs | 2 +- src/test/ui/never_type/defaulted-never-note.rs | 4 ++++ src/test/ui/never_type/defaulted-never-note.stderr | 2 +- src/test/ui/never_type/diverging-fallback-control-flow.rs | 2 ++ src/test/ui/never_type/feature-gate-never_type_fallback.rs | 12 ++++++++++++ .../ui/never_type/feature-gate-never_type_fallback.stderr | 11 +++++++++++ src/test/ui/never_type/issue-13352.stderr | 6 +++--- src/test/ui/never_type/issue-2149.stderr | 6 +++--- src/test/ui/reachable/unreachable-loop-patterns.rs | 1 + src/test/ui/reachable/unreachable-loop-patterns.stderr | 6 +++--- .../different_defining_uses_never_type.stderr | 4 ++-- 18 files changed, 64 insertions(+), 19 deletions(-) create mode 100644 src/test/ui/never_type/feature-gate-never_type_fallback.rs create mode 100644 src/test/ui/never_type/feature-gate-never_type_fallback.stderr (limited to 'src/libsyntax/feature_gate') diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 2dea2216f38..d0767a1fc4c 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -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] diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 8f3e274b79f..512a49d13e7 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -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. diff --git a/src/libsyntax/feature_gate/active.rs b/src/libsyntax/feature_gate/active.rs index 23718f56246..bd029514a95 100644 --- a/src/libsyntax/feature_gate/active.rs +++ b/src/libsyntax/feature_gate/active.rs @@ -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), diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs index 1139bf67a36..979074f17c7 100644 --- a/src/libsyntax_pos/symbol.rs +++ b/src/libsyntax_pos/symbol.rs @@ -444,6 +444,7 @@ symbols! { negate_unsigned, never, never_type, + never_type_fallback, new, next, __next, diff --git a/src/test/ui/associated-types/associated-types-ICE-when-projecting-out-of-err.rs b/src/test/ui/associated-types/associated-types-ICE-when-projecting-out-of-err.rs index 408e55f8903..707bcac78bf 100644 --- a/src/test/ui/associated-types/associated-types-ICE-when-projecting-out-of-err.rs +++ b/src/test/ui/associated-types/associated-types-ICE-when-projecting-out-of-err.rs @@ -21,5 +21,5 @@ trait Add { fn ice(a: A) { let r = loop {}; r = r + a; - //~^ ERROR the trait bound `!: Add` is not satisfied + //~^ ERROR the trait bound `(): Add` is not satisfied } diff --git a/src/test/ui/associated-types/associated-types-ICE-when-projecting-out-of-err.stderr b/src/test/ui/associated-types/associated-types-ICE-when-projecting-out-of-err.stderr index f85c8a1a515..8c3463a2832 100644 --- a/src/test/ui/associated-types/associated-types-ICE-when-projecting-out-of-err.stderr +++ b/src/test/ui/associated-types/associated-types-ICE-when-projecting-out-of-err.stderr @@ -1,8 +1,8 @@ -error[E0277]: the trait bound `!: Add` is not satisfied +error[E0277]: the trait bound `(): Add` is not satisfied --> $DIR/associated-types-ICE-when-projecting-out-of-err.rs:23:11 | LL | r = r + a; - | ^ the trait `Add` is not implemented for `!` + | ^ the trait `Add` is not implemented for `()` error: aborting due to previous error diff --git a/src/test/ui/binding/empty-types-in-patterns.rs b/src/test/ui/binding/empty-types-in-patterns.rs index facb70d1253..1864d4bb820 100644 --- a/src/test/ui/binding/empty-types-in-patterns.rs +++ b/src/test/ui/binding/empty-types-in-patterns.rs @@ -1,4 +1,5 @@ // run-pass +#![feature(never_type_fallback)] #![feature(exhaustive_patterns)] #![feature(slice_patterns)] #![allow(unreachable_patterns)] diff --git a/src/test/ui/coercion/coerce-issue-49593-box-never.rs b/src/test/ui/coercion/coerce-issue-49593-box-never.rs index b71c3663a4f..55beb7c2528 100644 --- a/src/test/ui/coercion/coerce-issue-49593-box-never.rs +++ b/src/test/ui/coercion/coerce-issue-49593-box-never.rs @@ -1,5 +1,5 @@ // check-pass - +#![feature(never_type_fallback)] #![allow(unreachable_code)] use std::error::Error; diff --git a/src/test/ui/never_type/defaulted-never-note.rs b/src/test/ui/never_type/defaulted-never-note.rs index 714ef6adaf5..c58b6117484 100644 --- a/src/test/ui/never_type/defaulted-never-note.rs +++ b/src/test/ui/never_type/defaulted-never-note.rs @@ -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 { diff --git a/src/test/ui/never_type/defaulted-never-note.stderr b/src/test/ui/never_type/defaulted-never-note.stderr index eb780b6328c..28c9da059ed 100644 --- a/src/test/ui/never_type/defaulted-never-note.stderr +++ b/src/test/ui/never_type/defaulted-never-note.stderr @@ -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: T) {} | --- ----------------------------- required by this bound in `foo` diff --git a/src/test/ui/never_type/diverging-fallback-control-flow.rs b/src/test/ui/never_type/diverging-fallback-control-flow.rs index 2ea9c18ee90..df04437b1ae 100644 --- a/src/test/ui/never_type/diverging-fallback-control-flow.rs +++ b/src/test/ui/never_type/diverging-fallback-control-flow.rs @@ -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; } diff --git a/src/test/ui/never_type/feature-gate-never_type_fallback.rs b/src/test/ui/never_type/feature-gate-never_type_fallback.rs new file mode 100644 index 00000000000..3b896ec9d70 --- /dev/null +++ b/src/test/ui/never_type/feature-gate-never_type_fallback.rs @@ -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!() +} diff --git a/src/test/ui/never_type/feature-gate-never_type_fallback.stderr b/src/test/ui/never_type/feature-gate-never_type_fallback.stderr new file mode 100644 index 00000000000..837e90d6ceb --- /dev/null +++ b/src/test/ui/never_type/feature-gate-never_type_fallback.stderr @@ -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`. diff --git a/src/test/ui/never_type/issue-13352.stderr b/src/test/ui/never_type/issue-13352.stderr index da914a2b49c..58ac74be3e3 100644 --- a/src/test/ui/never_type/issue-13352.stderr +++ b/src/test/ui/never_type/issue-13352.stderr @@ -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 diff --git a/src/test/ui/never_type/issue-2149.stderr b/src/test/ui/never_type/issue-2149.stderr index 67fe3966d62..8ce2ba03332 100644 --- a/src/test/ui/never_type/issue-2149.stderr +++ b/src/test/ui/never_type/issue-2149.stderr @@ -1,10 +1,10 @@ -error[E0277]: cannot add `std::vec::Vec` to `!` +error[E0277]: cannot add `std::vec::Vec` to `()` --> $DIR/issue-2149.rs:8:33 | LL | for elt in self { r = r + f(*elt); } - | ^ no implementation for `! + std::vec::Vec` + | ^ no implementation for `() + std::vec::Vec` | - = help: the trait `std::ops::Add>` is not implemented for `!` + = help: the trait `std::ops::Add>` 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 diff --git a/src/test/ui/reachable/unreachable-loop-patterns.rs b/src/test/ui/reachable/unreachable-loop-patterns.rs index 6d882737003..c8ff5653911 100644 --- a/src/test/ui/reachable/unreachable-loop-patterns.rs +++ b/src/test/ui/reachable/unreachable-loop-patterns.rs @@ -1,3 +1,4 @@ +#![feature(never_type_fallback)] #![feature(exhaustive_patterns)] #![allow(unreachable_code)] diff --git a/src/test/ui/reachable/unreachable-loop-patterns.stderr b/src/test/ui/reachable/unreachable-loop-patterns.stderr index 6ade480125b..bb5103320d2 100644 --- a/src/test/ui/reachable/unreachable-loop-patterns.stderr +++ b/src/test/ui/reachable/unreachable-loop-patterns.stderr @@ -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 {} | ^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/type-alias-impl-trait/different_defining_uses_never_type.stderr b/src/test/ui/type-alias-impl-trait/different_defining_uses_never_type.stderr index e6c7b566b44..5be656e8f44 100644 --- a/src/test/ui/type-alias-impl-trait/different_defining_uses_never_type.stderr +++ b/src/test/ui/type-alias-impl-trait/different_defining_uses_never_type.stderr @@ -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 -- cgit 1.4.1-3-g733a5