diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index 557271e32adb4..f7d3d588b8730 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -437,9 +437,6 @@ 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) diff --git a/compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs b/compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs index 6e13e4dcbfbff..89d7d9adea878 100644 --- a/compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs +++ b/compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs @@ -1,11 +1,11 @@ -#![feature(no_core, lang_items, never_type, linkage, extern_types, thread_local)] +#![feature(no_core, lang_items, linkage, extern_types, thread_local)] #![no_core] #![allow(dead_code, non_camel_case_types)] extern crate mini_core; -use mini_core::*; use mini_core::libc::*; +use mini_core::*; unsafe extern "C" fn my_puts(s: *const i8) { puts(s); @@ -14,7 +14,7 @@ unsafe extern "C" fn my_puts(s: *const i8) { macro_rules! assert { ($e:expr) => { if !$e { - panic(stringify!(! $e)); + panic(stringify!(!$e)); } }; } @@ -24,7 +24,7 @@ macro_rules! assert_eq { if $l != $r { panic(stringify!($l != $r)); } - } + }; } #[lang = "termination"] @@ -88,15 +88,17 @@ enum Ordering { } #[lang = "start"] -fn start( - main: fn() -> T, - argc: isize, - argv: *const *const u8, -) -> isize { +fn start(main: fn() -> T, argc: isize, argv: *const *const u8) -> isize { if argc == 3 { - unsafe { puts(*argv as *const i8); } - unsafe { puts(*((argv as usize + intrinsics::size_of::<*const u8>()) as *const *const i8)); } - unsafe { puts(*((argv as usize + 2 * intrinsics::size_of::<*const u8>()) as *const *const i8)); } + unsafe { + puts(*argv as *const i8); + } + unsafe { + puts(*((argv as usize + intrinsics::size_of::<*const u8>()) as *const *const i8)); + } + unsafe { + puts(*((argv as usize + 2 * intrinsics::size_of::<*const u8>()) as *const *const i8)); + } } main().report() as isize @@ -130,10 +132,7 @@ fn call_return_u128_pair() { } fn main() { - take_unique(Unique { - pointer: 0 as *const (), - _marker: PhantomData, - }); + take_unique(Unique { pointer: 0 as *const (), _marker: PhantomData }); take_f32(0.1); call_return_u128_pair(); @@ -176,15 +175,15 @@ fn main() { assert_eq!(intrinsics::size_of_val(&0u32) as u8, 4); assert_eq!(intrinsics::min_align_of::() as u8, 2); - assert_eq!(intrinsics::min_align_of_val(&a) as u8, intrinsics::min_align_of::<&str>() as u8); + assert_eq!( + intrinsics::min_align_of_val(&a) as u8, + intrinsics::min_align_of::<&str>() as u8 + ); assert!(!intrinsics::needs_drop::()); assert!(intrinsics::needs_drop::()); - Unique { - pointer: 0 as *const &str, - _marker: PhantomData, - } as Unique; + Unique { pointer: 0 as *const &str, _marker: PhantomData } as Unique; struct MyDst(T); @@ -210,19 +209,17 @@ fn main() { } } - let _ = box NoisyDrop { - text: "Boxed outer got dropped!\0", - inner: NoisyDropInner, - } as Box; + let _ = box NoisyDrop { text: "Boxed outer got dropped!\0", inner: NoisyDropInner } + as Box; const FUNC_REF: Option = Some(main); match FUNC_REF { - Some(_) => {}, + Some(_) => {} None => assert!(false), } match Ordering::Less { - Ordering::Less => {}, + Ordering::Less => {} _ => assert!(false), } @@ -238,19 +235,21 @@ fn main() { #[cfg(not(any(jit, windows)))] { - extern { + extern "C" { #[linkage = "extern_weak"] static ABC: *const u8; } { - extern { + extern "C" { #[linkage = "extern_weak"] static ABC: *const u8; } } - unsafe { assert_eq!(ABC as usize, 0); } + unsafe { + assert_eq!(ABC as usize, 0); + } } &mut (|| Some(0 as *const ())) as &mut dyn FnMut() -> Option<*const ()>; @@ -342,13 +341,10 @@ extern "C" { native: *mut pthread_t, attr: *const pthread_attr_t, f: extern "C" fn(_: *mut c_void) -> *mut c_void, - value: *mut c_void + value: *mut c_void, ) -> c_int; - fn pthread_join( - native: pthread_t, - value: *mut *mut c_void - ) -> c_int; + fn pthread_join(native: pthread_t, value: *mut *mut c_void) -> c_int; } #[thread_local] @@ -357,7 +353,9 @@ static mut TLS: u8 = 42; #[cfg(not(jit))] extern "C" fn mutate_tls(_: *mut c_void) -> *mut c_void { - unsafe { TLS = 0; } + unsafe { + TLS = 0; + } 0 as *mut c_void } @@ -407,44 +405,267 @@ pub enum E1 { pub enum E2 { V1 { f: bool }, - /*_00*/ _01(X), _02(X), _03(X), _04(X), _05(X), _06(X), _07(X), - _08(X), _09(X), _0A(X), _0B(X), _0C(X), _0D(X), _0E(X), _0F(X), - _10(X), _11(X), _12(X), _13(X), _14(X), _15(X), _16(X), _17(X), - _18(X), _19(X), _1A(X), _1B(X), _1C(X), _1D(X), _1E(X), _1F(X), - _20(X), _21(X), _22(X), _23(X), _24(X), _25(X), _26(X), _27(X), - _28(X), _29(X), _2A(X), _2B(X), _2C(X), _2D(X), _2E(X), _2F(X), - _30(X), _31(X), _32(X), _33(X), _34(X), _35(X), _36(X), _37(X), - _38(X), _39(X), _3A(X), _3B(X), _3C(X), _3D(X), _3E(X), _3F(X), - _40(X), _41(X), _42(X), _43(X), _44(X), _45(X), _46(X), _47(X), - _48(X), _49(X), _4A(X), _4B(X), _4C(X), _4D(X), _4E(X), _4F(X), - _50(X), _51(X), _52(X), _53(X), _54(X), _55(X), _56(X), _57(X), - _58(X), _59(X), _5A(X), _5B(X), _5C(X), _5D(X), _5E(X), _5F(X), - _60(X), _61(X), _62(X), _63(X), _64(X), _65(X), _66(X), _67(X), - _68(X), _69(X), _6A(X), _6B(X), _6C(X), _6D(X), _6E(X), _6F(X), - _70(X), _71(X), _72(X), _73(X), _74(X), _75(X), _76(X), _77(X), - _78(X), _79(X), _7A(X), _7B(X), _7C(X), _7D(X), _7E(X), _7F(X), - _80(X), _81(X), _82(X), _83(X), _84(X), _85(X), _86(X), _87(X), - _88(X), _89(X), _8A(X), _8B(X), _8C(X), _8D(X), _8E(X), _8F(X), - _90(X), _91(X), _92(X), _93(X), _94(X), _95(X), _96(X), _97(X), - _98(X), _99(X), _9A(X), _9B(X), _9C(X), _9D(X), _9E(X), _9F(X), - _A0(X), _A1(X), _A2(X), _A3(X), _A4(X), _A5(X), _A6(X), _A7(X), - _A8(X), _A9(X), _AA(X), _AB(X), _AC(X), _AD(X), _AE(X), _AF(X), - _B0(X), _B1(X), _B2(X), _B3(X), _B4(X), _B5(X), _B6(X), _B7(X), - _B8(X), _B9(X), _BA(X), _BB(X), _BC(X), _BD(X), _BE(X), _BF(X), - _C0(X), _C1(X), _C2(X), _C3(X), _C4(X), _C5(X), _C6(X), _C7(X), - _C8(X), _C9(X), _CA(X), _CB(X), _CC(X), _CD(X), _CE(X), _CF(X), - _D0(X), _D1(X), _D2(X), _D3(X), _D4(X), _D5(X), _D6(X), _D7(X), - _D8(X), _D9(X), _DA(X), _DB(X), _DC(X), _DD(X), _DE(X), _DF(X), - _E0(X), _E1(X), _E2(X), _E3(X), _E4(X), _E5(X), _E6(X), _E7(X), - _E8(X), _E9(X), _EA(X), _EB(X), _EC(X), _ED(X), _EE(X), _EF(X), - _F0(X), _F1(X), _F2(X), _F3(X), _F4(X), _F5(X), _F6(X), _F7(X), - _F8(X), _F9(X), _FA(X), _FB(X), _FC(X), _FD(X), _FE(X), _FF(X), + /*_00*/ _01(X), + _02(X), + _03(X), + _04(X), + _05(X), + _06(X), + _07(X), + _08(X), + _09(X), + _0A(X), + _0B(X), + _0C(X), + _0D(X), + _0E(X), + _0F(X), + _10(X), + _11(X), + _12(X), + _13(X), + _14(X), + _15(X), + _16(X), + _17(X), + _18(X), + _19(X), + _1A(X), + _1B(X), + _1C(X), + _1D(X), + _1E(X), + _1F(X), + _20(X), + _21(X), + _22(X), + _23(X), + _24(X), + _25(X), + _26(X), + _27(X), + _28(X), + _29(X), + _2A(X), + _2B(X), + _2C(X), + _2D(X), + _2E(X), + _2F(X), + _30(X), + _31(X), + _32(X), + _33(X), + _34(X), + _35(X), + _36(X), + _37(X), + _38(X), + _39(X), + _3A(X), + _3B(X), + _3C(X), + _3D(X), + _3E(X), + _3F(X), + _40(X), + _41(X), + _42(X), + _43(X), + _44(X), + _45(X), + _46(X), + _47(X), + _48(X), + _49(X), + _4A(X), + _4B(X), + _4C(X), + _4D(X), + _4E(X), + _4F(X), + _50(X), + _51(X), + _52(X), + _53(X), + _54(X), + _55(X), + _56(X), + _57(X), + _58(X), + _59(X), + _5A(X), + _5B(X), + _5C(X), + _5D(X), + _5E(X), + _5F(X), + _60(X), + _61(X), + _62(X), + _63(X), + _64(X), + _65(X), + _66(X), + _67(X), + _68(X), + _69(X), + _6A(X), + _6B(X), + _6C(X), + _6D(X), + _6E(X), + _6F(X), + _70(X), + _71(X), + _72(X), + _73(X), + _74(X), + _75(X), + _76(X), + _77(X), + _78(X), + _79(X), + _7A(X), + _7B(X), + _7C(X), + _7D(X), + _7E(X), + _7F(X), + _80(X), + _81(X), + _82(X), + _83(X), + _84(X), + _85(X), + _86(X), + _87(X), + _88(X), + _89(X), + _8A(X), + _8B(X), + _8C(X), + _8D(X), + _8E(X), + _8F(X), + _90(X), + _91(X), + _92(X), + _93(X), + _94(X), + _95(X), + _96(X), + _97(X), + _98(X), + _99(X), + _9A(X), + _9B(X), + _9C(X), + _9D(X), + _9E(X), + _9F(X), + _A0(X), + _A1(X), + _A2(X), + _A3(X), + _A4(X), + _A5(X), + _A6(X), + _A7(X), + _A8(X), + _A9(X), + _AA(X), + _AB(X), + _AC(X), + _AD(X), + _AE(X), + _AF(X), + _B0(X), + _B1(X), + _B2(X), + _B3(X), + _B4(X), + _B5(X), + _B6(X), + _B7(X), + _B8(X), + _B9(X), + _BA(X), + _BB(X), + _BC(X), + _BD(X), + _BE(X), + _BF(X), + _C0(X), + _C1(X), + _C2(X), + _C3(X), + _C4(X), + _C5(X), + _C6(X), + _C7(X), + _C8(X), + _C9(X), + _CA(X), + _CB(X), + _CC(X), + _CD(X), + _CE(X), + _CF(X), + _D0(X), + _D1(X), + _D2(X), + _D3(X), + _D4(X), + _D5(X), + _D6(X), + _D7(X), + _D8(X), + _D9(X), + _DA(X), + _DB(X), + _DC(X), + _DD(X), + _DE(X), + _DF(X), + _E0(X), + _E1(X), + _E2(X), + _E3(X), + _E4(X), + _E5(X), + _E6(X), + _E7(X), + _E8(X), + _E9(X), + _EA(X), + _EB(X), + _EC(X), + _ED(X), + _EE(X), + _EF(X), + _F0(X), + _F1(X), + _F2(X), + _F3(X), + _F4(X), + _F5(X), + _F6(X), + _F7(X), + _F8(X), + _F9(X), + _FA(X), + _FB(X), + _FC(X), + _FD(X), + _FE(X), + _FF(X), V3, V4, } -fn check_niche_behavior () { +fn check_niche_behavior() { if let E1::V2 { .. } = (E1::V1 { f: true }) { intrinsics::abort(); } diff --git a/compiler/rustc_data_structures/src/graph/iterate/mod.rs b/compiler/rustc_data_structures/src/graph/iterate/mod.rs index 09b91083a6347..a9db3497b2390 100644 --- a/compiler/rustc_data_structures/src/graph/iterate/mod.rs +++ b/compiler/rustc_data_structures/src/graph/iterate/mod.rs @@ -83,8 +83,58 @@ impl DepthFirstSearch<'graph, G> where G: ?Sized + DirectedGraph + WithNumNodes + WithSuccessors, { - pub fn new(graph: &'graph G, start_node: G::Node) -> Self { - Self { graph, stack: vec![start_node], visited: BitSet::new_empty(graph.num_nodes()) } + pub fn new(graph: &'graph G) -> Self { + Self { graph, stack: vec![], visited: BitSet::new_empty(graph.num_nodes()) } + } + + /// Version of `push_start_node` that is convenient for chained + /// use. + pub fn with_start_node(mut self, start_node: G::Node) -> Self { + self.push_start_node(start_node); + self + } + + /// Pushes another start node onto the stack. If the node + /// has not already been visited, then you will be able to + /// walk its successors (and so forth) after the current + /// contents of the stack are drained. If multiple start nodes + /// are added into the walk, then their mutual successors + /// will all be walked. You can use this method once the + /// iterator has been completely drained to add additional + /// start nodes. + pub fn push_start_node(&mut self, start_node: G::Node) { + if self.visited.insert(start_node) { + self.stack.push(start_node); + } + } + + /// Searches all nodes reachable from the current start nodes. + /// This is equivalent to just invoke `next` repeatedly until + /// you get a `None` result. + pub fn complete_search(&mut self) { + while let Some(_) = self.next() {} + } + + /// Returns true if node has been visited thus far. + /// A node is considered "visited" once it is pushed + /// onto the internal stack; it may not yet have been yielded + /// from the iterator. This method is best used after + /// the iterator is completely drained. + pub fn visited(&self, node: G::Node) -> bool { + self.visited.contains(node) + } +} + +impl std::fmt::Debug for DepthFirstSearch<'_, G> +where + G: ?Sized + DirectedGraph + WithNumNodes + WithSuccessors, +{ + fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let mut f = fmt.debug_set(); + for n in self.visited.iter() { + f.entry(&n); + } + f.finish() } } diff --git a/compiler/rustc_data_structures/src/graph/iterate/tests.rs b/compiler/rustc_data_structures/src/graph/iterate/tests.rs index 0e038e88b221d..fbdcb01b5f453 100644 --- a/compiler/rustc_data_structures/src/graph/iterate/tests.rs +++ b/compiler/rustc_data_structures/src/graph/iterate/tests.rs @@ -20,3 +20,19 @@ fn is_cyclic() { assert!(!is_cyclic(&diamond_acyclic)); assert!(is_cyclic(&diamond_cyclic)); } + +#[test] +fn dfs() { + let graph = TestGraph::new(0, &[(0, 1), (0, 2), (1, 3), (2, 3), (3, 0)]); + + let result: Vec = DepthFirstSearch::new(&graph).with_start_node(0).collect(); + assert_eq!(result, vec![0, 2, 3, 1]); +} + +#[test] +fn dfs_debug() { + let graph = TestGraph::new(0, &[(0, 1), (0, 2), (1, 3), (2, 3), (3, 0)]); + let mut dfs = DepthFirstSearch::new(&graph).with_start_node(0); + while let Some(_) = dfs.next() {} + assert_eq!(format!("{{0, 1, 2, 3}}"), format!("{:?}", dfs)); +} diff --git a/compiler/rustc_data_structures/src/graph/mod.rs b/compiler/rustc_data_structures/src/graph/mod.rs index dff22855629a8..3560df6e5e204 100644 --- a/compiler/rustc_data_structures/src/graph/mod.rs +++ b/compiler/rustc_data_structures/src/graph/mod.rs @@ -32,7 +32,7 @@ where where Self: WithNumNodes, { - iterate::DepthFirstSearch::new(self, from) + iterate::DepthFirstSearch::new(self).with_start_node(from) } } diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs index 18294dfad240d..10e6df687a1e3 100644 --- a/compiler/rustc_feature/src/accepted.rs +++ b/compiler/rustc_feature/src/accepted.rs @@ -296,6 +296,10 @@ declare_features! ( (accepted, const_fn_union, "1.56.0", Some(51909), None), /// Allows explicit discriminants on non-unit enum variants. (accepted, arbitrary_enum_discriminant, "1.56.0", Some(60553), None), + /// Allows the `!` type. Does not imply 'exhaustive_patterns' (below) any more. + (accepted, never_type, "1.60.0", Some(35121), None), + /// Allows diverging expressions to fall back to `!` rather than `()`. + (accepted, never_type_fallback, "1.60.0", Some(65992), None), // ------------------------------------------------------------------------- // feature-group-end: accepted features diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs index 5ae106353da61..bb5a323664fb0 100644 --- a/compiler/rustc_feature/src/active.rs +++ b/compiler/rustc_feature/src/active.rs @@ -334,9 +334,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), @@ -494,9 +491,6 @@ declare_features! ( /// Allows `&raw const $place_expr` and `&raw mut $place_expr` expressions. (active, raw_ref_op, "1.41.0", Some(64490), 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/compiler/rustc_infer/src/infer/combine.rs b/compiler/rustc_infer/src/infer/combine.rs index 32308910aa7d9..310d641e92f19 100644 --- a/compiler/rustc_infer/src/infer/combine.rs +++ b/compiler/rustc_infer/src/infer/combine.rs @@ -22,6 +22,7 @@ // is also useful to track which value is the "expected" value in // terms of error reporting. +use super::equate::Equate; use super::glb::Glb; use super::lub::Lub; use super::sub::Sub; @@ -29,7 +30,6 @@ use super::type_variable::TypeVariableValue; use super::unify_key::replace_if_possible; use super::unify_key::{ConstVarValue, ConstVariableValue}; use super::unify_key::{ConstVariableOrigin, ConstVariableOriginKind}; -use super::{equate::Equate, type_variable::Diverging}; use super::{InferCtxt, MiscVariable, TypeTrace}; use crate::traits::{Obligation, PredicateObligations}; @@ -645,7 +645,7 @@ impl TypeRelation<'tcx> for Generalizer<'_, 'tcx> { .inner .borrow_mut() .type_variables() - .new_var(self.for_universe, Diverging::NotDiverging, origin); + .new_var(self.for_universe, origin); let u = self.tcx().mk_ty_var(new_var_id); // Record that we replaced `vid` with `new_var_id` as part of a generalization @@ -885,11 +885,12 @@ impl TypeRelation<'tcx> for ConstInferUnifier<'_, 'tcx> { let origin = *self.infcx.inner.borrow_mut().type_variables().var_origin(vid); - let new_var_id = self.infcx.inner.borrow_mut().type_variables().new_var( - self.for_universe, - Diverging::NotDiverging, - origin, - ); + let new_var_id = self + .infcx + .inner + .borrow_mut() + .type_variables() + .new_var(self.for_universe, origin); let u = self.tcx().mk_ty_var(new_var_id); debug!( "ConstInferUnifier: replacing original vid={:?} with new={:?}", diff --git a/compiler/rustc_infer/src/infer/fudge.rs b/compiler/rustc_infer/src/infer/fudge.rs index c292b2bdb3040..35ebe92c59246 100644 --- a/compiler/rustc_infer/src/infer/fudge.rs +++ b/compiler/rustc_infer/src/infer/fudge.rs @@ -187,7 +187,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for InferenceFudger<'a, 'tcx> { if self.type_vars.0.contains(&vid) { // This variable was created during the fudging. // Recreate it with a fresh variable here. - let idx = (vid.index - self.type_vars.0.start.index) as usize; + let idx = (vid.as_usize() - self.type_vars.0.start.as_usize()) as usize; let origin = self.type_vars.1[idx]; self.infcx.next_ty_var(origin) } else { diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index bc98a3aa3f95e..1c7a5d9257fc7 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -46,7 +46,7 @@ use self::region_constraints::{GenericKind, RegionConstraintData, VarInfos, Veri use self::region_constraints::{ RegionConstraintCollector, RegionConstraintStorage, RegionSnapshot, }; -use self::type_variable::{Diverging, TypeVariableOrigin, TypeVariableOriginKind}; +use self::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; pub mod at; pub mod canonical; @@ -692,17 +692,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { t.fold_with(&mut self.freshener()) } - /// Returns whether `ty` is a diverging type variable or not. - /// (If `ty` is not a type variable at all, returns not diverging.) - /// - /// No attempt is made to resolve `ty`. - pub fn type_var_diverges(&'a self, ty: Ty<'_>) -> Diverging { - match *ty.kind() { - ty::Infer(ty::TyVar(vid)) => self.inner.borrow_mut().type_variables().var_diverges(vid), - _ => Diverging::NotDiverging, - } - } - /// Returns the origin of the type variable identified by `vid`, or `None` /// if this is not a type variable. /// @@ -1061,12 +1050,17 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { }) } - pub fn next_ty_var_id(&self, diverging: Diverging, origin: TypeVariableOrigin) -> TyVid { - self.inner.borrow_mut().type_variables().new_var(self.universe(), diverging, origin) + /// Number of type variables created so far. + pub fn num_ty_vars(&self) -> usize { + self.inner.borrow_mut().type_variables().num_vars() + } + + pub fn next_ty_var_id(&self, origin: TypeVariableOrigin) -> TyVid { + self.inner.borrow_mut().type_variables().new_var(self.universe(), origin) } pub fn next_ty_var(&self, origin: TypeVariableOrigin) -> Ty<'tcx> { - self.tcx.mk_ty_var(self.next_ty_var_id(Diverging::NotDiverging, origin)) + self.tcx.mk_ty_var(self.next_ty_var_id(origin)) } pub fn next_ty_var_in_universe( @@ -1074,18 +1068,10 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { origin: TypeVariableOrigin, universe: ty::UniverseIndex, ) -> Ty<'tcx> { - let vid = self.inner.borrow_mut().type_variables().new_var( - universe, - Diverging::NotDiverging, - origin, - ); + let vid = self.inner.borrow_mut().type_variables().new_var(universe, origin); self.tcx.mk_ty_var(vid) } - pub fn next_diverging_ty_var(&self, origin: TypeVariableOrigin) -> Ty<'tcx> { - self.tcx.mk_ty_var(self.next_ty_var_id(Diverging::Diverges, origin)) - } - pub fn next_const_var( &self, ty: Ty<'tcx>, @@ -1197,7 +1183,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { // as the substitutions for the default, `(T, U)`. let ty_var_id = self.inner.borrow_mut().type_variables().new_var( self.universe(), - Diverging::NotDiverging, TypeVariableOrigin { kind: TypeVariableOriginKind::TypeParameterDefinition( param.name, diff --git a/compiler/rustc_infer/src/infer/nll_relate/mod.rs b/compiler/rustc_infer/src/infer/nll_relate/mod.rs index c211d8e94a68b..637266c1ce3d7 100644 --- a/compiler/rustc_infer/src/infer/nll_relate/mod.rs +++ b/compiler/rustc_infer/src/infer/nll_relate/mod.rs @@ -22,7 +22,6 @@ //! constituents) use crate::infer::combine::ConstEquateRelation; -use crate::infer::type_variable::Diverging; use crate::infer::InferCtxt; use crate::infer::{ConstVarValue, ConstVariableValue}; use rustc_data_structures::fx::FxHashMap; @@ -927,8 +926,7 @@ where // Replacing with a new variable in the universe `self.universe`, // it will be unified later with the original type variable in // the universe `_universe`. - let new_var_id = - variables.new_var(self.universe, Diverging::NotDiverging, origin); + let new_var_id = variables.new_var(self.universe, origin); let u = self.tcx().mk_ty_var(new_var_id); debug!("generalize: replacing original vid={:?} with new={:?}", vid, u); diff --git a/compiler/rustc_infer/src/infer/type_variable.rs b/compiler/rustc_infer/src/infer/type_variable.rs index d2b0bdaf97802..602987e15b68f 100644 --- a/compiler/rustc_infer/src/infer/type_variable.rs +++ b/compiler/rustc_infer/src/infer/type_variable.rs @@ -129,19 +129,16 @@ pub enum TypeVariableOriginKind { SubstitutionPlaceholder, AutoDeref, AdjustmentType, - DivergingFn, + + /// In type check, when we are type checking a function that + /// returns `-> dyn Foo`, we substitute a type variable for the + /// return type for diagnostic purposes. + DynReturnFn, LatticeVariable, } pub(crate) struct TypeVariableData { origin: TypeVariableOrigin, - diverging: Diverging, -} - -#[derive(Copy, Clone, Debug)] -pub enum Diverging { - NotDiverging, - Diverges, } #[derive(Copy, Clone, Debug)] @@ -191,20 +188,12 @@ impl<'tcx> TypeVariableStorage<'tcx> { } impl<'tcx> TypeVariableTable<'_, 'tcx> { - /// Returns the diverges flag given when `vid` was created. - /// - /// Note that this function does not return care whether - /// `vid` has been unified with something else or not. - pub fn var_diverges(&self, vid: ty::TyVid) -> Diverging { - self.storage.values.get(vid.index as usize).diverging - } - /// Returns the origin that was given when `vid` was created. /// /// Note that this function does not return care whether /// `vid` has been unified with something else or not. pub fn var_origin(&self, vid: ty::TyVid) -> &TypeVariableOrigin { - &self.storage.values.get(vid.index as usize).origin + &self.storage.values.get(vid.as_usize()).origin } /// Records that `a == b`, depending on `dir`. @@ -260,7 +249,6 @@ impl<'tcx> TypeVariableTable<'_, 'tcx> { pub fn new_var( &mut self, universe: ty::UniverseIndex, - diverging: Diverging, origin: TypeVariableOrigin, ) -> ty::TyVid { let eq_key = self.eq_relations().new_key(TypeVariableValue::Unknown { universe }); @@ -268,13 +256,10 @@ impl<'tcx> TypeVariableTable<'_, 'tcx> { let sub_key = self.sub_relations().new_key(()); assert_eq!(eq_key.vid, sub_key); - let index = self.values().push(TypeVariableData { origin, diverging }); - assert_eq!(eq_key.vid.index, index as u32); + let index = self.values().push(TypeVariableData { origin }); + assert_eq!(eq_key.vid.as_u32(), index as u32); - debug!( - "new_var(index={:?}, universe={:?}, diverging={:?}, origin={:?}", - eq_key.vid, universe, diverging, origin, - ); + debug!("new_var(index={:?}, universe={:?}, origin={:?}", eq_key.vid, universe, origin,); eq_key.vid } @@ -357,11 +342,11 @@ impl<'tcx> TypeVariableTable<'_, 'tcx> { &mut self, value_count: usize, ) -> (Range, Vec) { - let range = TyVid { index: value_count as u32 }..TyVid { index: self.num_vars() as u32 }; + let range = TyVid::from_u32(value_count as u32)..TyVid::from_usize(self.num_vars()); ( range.start..range.end, - (range.start.index..range.end.index) - .map(|index| self.storage.values.get(index as usize).origin) + (range.start.as_usize()..range.end.as_usize()) + .map(|index| self.storage.values.get(index).origin) .collect(), ) } @@ -371,7 +356,7 @@ impl<'tcx> TypeVariableTable<'_, 'tcx> { pub fn unsolved_variables(&mut self) -> Vec { (0..self.storage.values.len()) .filter_map(|i| { - let vid = ty::TyVid { index: i as u32 }; + let vid = ty::TyVid::from_usize(i); match self.probe(vid) { TypeVariableValue::Unknown { .. } => Some(vid), TypeVariableValue::Known { .. } => None, @@ -424,10 +409,10 @@ impl<'tcx> ut::UnifyKey for TyVidEqKey<'tcx> { type Value = TypeVariableValue<'tcx>; #[inline(always)] fn index(&self) -> u32 { - self.vid.index + self.vid.as_u32() } fn from_index(i: u32) -> Self { - TyVidEqKey::from(ty::TyVid { index: i }) + TyVidEqKey::from(ty::TyVid::from_u32(i)) } fn tag() -> &'static str { "TyVidEqKey" diff --git a/compiler/rustc_infer/src/lib.rs b/compiler/rustc_infer/src/lib.rs index a4cfaddeeb96f..1fb58587fa04e 100644 --- a/compiler/rustc_infer/src/lib.rs +++ b/compiler/rustc_infer/src/lib.rs @@ -17,7 +17,7 @@ #![feature(box_patterns)] #![feature(extend_one)] #![feature(iter_zip)] -#![feature(never_type)] +#![cfg_attr(bootstrap, feature(never_type))] #![feature(in_band_lifetimes)] #![feature(control_flow_enum)] #![feature(min_specialization)] diff --git a/compiler/rustc_infer/src/traits/engine.rs b/compiler/rustc_infer/src/traits/engine.rs index 42333dc29bc7c..a12f7dc759c09 100644 --- a/compiler/rustc_infer/src/traits/engine.rs +++ b/compiler/rustc_infer/src/traits/engine.rs @@ -1,5 +1,6 @@ use crate::infer::InferCtxt; use crate::traits::Obligation; +use rustc_data_structures::fx::FxHashMap; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_middle::ty::{self, ToPredicate, Ty, WithConstness}; @@ -73,6 +74,8 @@ pub trait TraitEngine<'tcx>: 'tcx { } fn pending_obligations(&self) -> Vec>; + + fn relationships(&mut self) -> &mut FxHashMap; } pub trait TraitEngineExt<'tcx> { diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index 24ac723f2c913..e992f4a83587b 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -34,7 +34,7 @@ #![feature(format_args_capture)] #![feature(iter_order_by)] #![feature(iter_zip)] -#![feature(never_type)] +#![cfg_attr(bootstrap, feature(never_type))] #![feature(nll)] #![feature(control_flow_enum)] #![recursion_limit = "256"] diff --git a/compiler/rustc_metadata/src/lib.rs b/compiler/rustc_metadata/src/lib.rs index 2c9bad7e5cedb..1a7d9cf147ea1 100644 --- a/compiler/rustc_metadata/src/lib.rs +++ b/compiler/rustc_metadata/src/lib.rs @@ -7,7 +7,7 @@ #![feature(proc_macro_internals)] #![feature(min_specialization)] #![feature(try_blocks)] -#![feature(never_type)] +#![cfg_attr(bootstrap, feature(never_type))] #![recursion_limit = "256"] extern crate proc_macro; diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs index 573fa913d680a..09a90c46c6611 100644 --- a/compiler/rustc_middle/src/lib.rs +++ b/compiler/rustc_middle/src/lib.rs @@ -32,7 +32,7 @@ #![feature(core_intrinsics)] #![feature(discriminant_kind)] #![feature(if_let_guard)] -#![feature(never_type)] +#![cfg_attr(bootstrap, feature(never_type))] #![feature(extern_types)] #![feature(new_uninit)] #![feature(nll)] diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 89542a1ebabe2..f99f8d70f023b 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -2375,7 +2375,7 @@ 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 } + self.types.never } #[inline] diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 8aa27d4ca53e3..88fdcbc49fa87 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -2084,3 +2084,16 @@ impl<'tcx> fmt::Debug for SymbolName<'tcx> { fmt::Display::fmt(&self.name, fmt) } } + +#[derive(Debug, Default, Copy, Clone)] +pub struct FoundRelationships { + /// This is true if we identified that this Ty (`?T`) is found in a `?T: Foo` + /// obligation, where: + /// + /// * `Foo` is not `Sized` + /// * `(): Foo` may be satisfied + pub self_in_trait: bool, + /// This is true if we identified that this Ty (`?T`) is found in a `<_ as + /// _>::AssocType = ?T` + pub output: bool, +} diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 65dd61b63295c..c48b768b2513e 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -1672,6 +1672,14 @@ impl<'tcx> TyS<'tcx> { matches!(self.kind(), Infer(TyVar(_))) } + #[inline] + pub fn ty_vid(&self) -> Option { + match self.kind() { + &Infer(TyVar(vid)) => Some(vid), + _ => None, + } + } + #[inline] pub fn is_ty_infer(&self) -> bool { matches!(self.kind(), Infer(_)) diff --git a/compiler/rustc_mir/src/lib.rs b/compiler/rustc_mir/src/lib.rs index e439a247c7f6c..2741543d8234b 100644 --- a/compiler/rustc_mir/src/lib.rs +++ b/compiler/rustc_mir/src/lib.rs @@ -16,7 +16,7 @@ Rust MIR: a lowered representation of Rust. #![feature(exact_size_is_empty)] #![feature(format_args_capture)] #![feature(iter_zip)] -#![feature(never_type)] +#![cfg_attr(bootstrap, feature(never_type))] #![feature(map_try_insert)] #![feature(min_specialization)] #![feature(slice_ptr_get)] diff --git a/compiler/rustc_serialize/src/lib.rs b/compiler/rustc_serialize/src/lib.rs index b31fbab20ac92..4d46994a4e794 100644 --- a/compiler/rustc_serialize/src/lib.rs +++ b/compiler/rustc_serialize/src/lib.rs @@ -9,7 +9,7 @@ Core encoding and decoding interfaces. html_playground_url = "https://play.rust-lang.org/", test(attr(allow(unused_variables), deny(warnings))) )] -#![feature(never_type)] +#![cfg_attr(bootstrap, feature(never_type))] #![feature(nll)] #![feature(associated_type_bounds)] #![feature(min_specialization)] diff --git a/compiler/rustc_symbol_mangling/src/lib.rs b/compiler/rustc_symbol_mangling/src/lib.rs index 220c9f7e2ec2b..e42d0afa03693 100644 --- a/compiler/rustc_symbol_mangling/src/lib.rs +++ b/compiler/rustc_symbol_mangling/src/lib.rs @@ -88,7 +88,7 @@ //! DefPaths which are much more robust in the face of changes to the code base. #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] -#![feature(never_type)] +#![cfg_attr(bootstrap, feature(never_type))] #![feature(nll)] #![feature(in_band_lifetimes)] #![feature(iter_zip)] diff --git a/compiler/rustc_target/src/lib.rs b/compiler/rustc_target/src/lib.rs index e75c52555b903..5465416ce2a3e 100644 --- a/compiler/rustc_target/src/lib.rs +++ b/compiler/rustc_target/src/lib.rs @@ -10,7 +10,7 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![feature(bool_to_option)] #![feature(nll)] -#![feature(never_type)] +#![cfg_attr(bootstrap, feature(never_type))] #![feature(associated_type_bounds)] #![feature(exhaustive_patterns)] #![feature(min_specialization)] diff --git a/compiler/rustc_trait_selection/src/lib.rs b/compiler/rustc_trait_selection/src/lib.rs index 017a7c45bbf9d..bd0e44bd7714b 100644 --- a/compiler/rustc_trait_selection/src/lib.rs +++ b/compiler/rustc_trait_selection/src/lib.rs @@ -17,7 +17,7 @@ #![feature(hash_drain_filter)] #![feature(in_band_lifetimes)] #![feature(iter_zip)] -#![feature(never_type)] +#![cfg_attr(bootstrap, feature(never_type))] #![feature(crate_visibility_modifier)] #![feature(control_flow_enum)] #![recursion_limit = "512"] // For rustdoc diff --git a/compiler/rustc_trait_selection/src/traits/chalk_fulfill.rs b/compiler/rustc_trait_selection/src/traits/chalk_fulfill.rs index 7a690af0cc6e5..2071d034c5adf 100644 --- a/compiler/rustc_trait_selection/src/traits/chalk_fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/chalk_fulfill.rs @@ -7,16 +7,21 @@ use crate::traits::{ ChalkEnvironmentAndGoal, FulfillmentError, FulfillmentErrorCode, ObligationCause, PredicateObligation, SelectionError, TraitEngine, }; -use rustc_data_structures::fx::FxIndexSet; +use rustc_data_structures::fx::{FxHashMap, FxIndexSet}; use rustc_middle::ty::{self, Ty}; pub struct FulfillmentContext<'tcx> { obligations: FxIndexSet>, + + relationships: FxHashMap, } impl FulfillmentContext<'tcx> { crate fn new() -> Self { - FulfillmentContext { obligations: FxIndexSet::default() } + FulfillmentContext { + obligations: FxIndexSet::default(), + relationships: FxHashMap::default(), + } } } @@ -39,6 +44,8 @@ impl TraitEngine<'tcx> for FulfillmentContext<'tcx> { assert!(!infcx.is_in_snapshot()); let obligation = infcx.resolve_vars_if_possible(obligation); + super::relationships::update(self, infcx, &obligation); + self.obligations.insert(obligation); } @@ -149,4 +156,8 @@ impl TraitEngine<'tcx> for FulfillmentContext<'tcx> { fn pending_obligations(&self) -> Vec> { self.obligations.iter().cloned().collect() } + + fn relationships(&mut self) -> &mut FxHashMap { + &mut self.relationships + } } diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 40841a6e32d00..865de7c162320 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -1244,7 +1244,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { let sig = if let ty::Tuple(inputs) = inputs.kind() { tcx.mk_fn_sig( inputs.iter().map(|k| k.expect_ty()), - tcx.mk_ty_infer(ty::TyVar(ty::TyVid { index: 0 })), + tcx.mk_ty_infer(ty::TyVar(ty::TyVid::from_u32(0))), false, hir::Unsafety::Normal, abi::Abi::Rust, @@ -1252,7 +1252,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { } else { tcx.mk_fn_sig( std::iter::once(inputs), - tcx.mk_ty_infer(ty::TyVar(ty::TyVid { index: 0 })), + tcx.mk_ty_infer(ty::TyVar(ty::TyVid::from_u32(0))), false, hir::Unsafety::Normal, abi::Abi::Rust, diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index f214930c57fe4..59da87bf49515 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -1,4 +1,5 @@ use crate::infer::{InferCtxt, TyOrConstInferVar}; +use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::obligation_forest::ProcessResult; use rustc_data_structures::obligation_forest::{Error, ForestObligation, Outcome}; use rustc_data_structures::obligation_forest::{ObligationForest, ObligationProcessor}; @@ -53,6 +54,9 @@ pub struct FulfillmentContext<'tcx> { // A list of all obligations that have been registered with this // fulfillment context. predicates: ObligationForest>, + + relationships: FxHashMap, + // Should this fulfillment context register type-lives-for-region // obligations on its parent infcx? In some cases, region // obligations are either already known to hold (normalization) or @@ -97,6 +101,7 @@ impl<'a, 'tcx> FulfillmentContext<'tcx> { pub fn new() -> FulfillmentContext<'tcx> { FulfillmentContext { predicates: ObligationForest::new(), + relationships: FxHashMap::default(), register_region_obligations: true, usable_in_snapshot: false, } @@ -105,6 +110,7 @@ impl<'a, 'tcx> FulfillmentContext<'tcx> { pub fn new_in_snapshot() -> FulfillmentContext<'tcx> { FulfillmentContext { predicates: ObligationForest::new(), + relationships: FxHashMap::default(), register_region_obligations: true, usable_in_snapshot: true, } @@ -113,6 +119,7 @@ impl<'a, 'tcx> FulfillmentContext<'tcx> { pub fn new_ignoring_regions() -> FulfillmentContext<'tcx> { FulfillmentContext { predicates: ObligationForest::new(), + relationships: FxHashMap::default(), register_region_obligations: false, usable_in_snapshot: false, } @@ -210,6 +217,8 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentContext<'tcx> { assert!(!infcx.is_in_snapshot() || self.usable_in_snapshot); + super::relationships::update(self, infcx, &obligation); + self.predicates .register_obligation(PendingPredicateObligation { obligation, stalled_on: vec![] }); } @@ -265,6 +274,10 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentContext<'tcx> { fn pending_obligations(&self) -> Vec> { self.predicates.map_pending_obligations(|o| o.obligation.clone()) } + + fn relationships(&mut self) -> &mut FxHashMap { + &mut self.relationships + } } struct FulfillProcessor<'a, 'b, 'tcx> { diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 17a4184c3c9ef..e715ad5dd0c62 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -15,6 +15,7 @@ mod object_safety; mod on_unimplemented; mod project; pub mod query; +pub(crate) mod relationships; mod select; mod specialize; mod structural_match; diff --git a/compiler/rustc_trait_selection/src/traits/relationships.rs b/compiler/rustc_trait_selection/src/traits/relationships.rs new file mode 100644 index 0000000000000..0f10ae11eb4ac --- /dev/null +++ b/compiler/rustc_trait_selection/src/traits/relationships.rs @@ -0,0 +1,89 @@ +use crate::infer::InferCtxt; +use crate::traits::query::evaluate_obligation::InferCtxtExt; +use crate::traits::{ObligationCause, PredicateObligation}; +use rustc_infer::traits::TraitEngine; +use rustc_middle::ty::{self, ToPredicate, TypeFoldable}; + +pub(crate) fn update<'tcx, T>( + engine: &mut T, + infcx: &InferCtxt<'_, 'tcx>, + obligation: &PredicateObligation<'tcx>, +) where + T: TraitEngine<'tcx>, +{ + if let ty::PredicateKind::Trait(predicate) = obligation.predicate.kind().skip_binder() { + if predicate.trait_ref.def_id + != infcx.tcx.require_lang_item(rustc_hir::LangItem::Sized, None) + { + // fixme: copy of mk_trait_obligation_with_new_self_ty + let new_self_ty = infcx.tcx.types.unit; + + let trait_ref = ty::TraitRef { + substs: infcx.tcx.mk_substs_trait(new_self_ty, &predicate.trait_ref.substs[1..]), + ..predicate.trait_ref + }; + + // Then contstruct a new obligation with Self = () added + // to the ParamEnv, and see if it holds. + let o = rustc_infer::traits::Obligation::new( + ObligationCause::dummy(), + obligation.param_env, + obligation + .predicate + .kind() + .map_bound(|_| { + ty::PredicateKind::Trait(ty::TraitPredicate { + trait_ref, + constness: predicate.constness, + }) + }) + .to_predicate(infcx.tcx), + ); + // Don't report overflow errors. Otherwise equivalent to may_hold. + if let Ok(result) = infcx.probe(|_| infcx.evaluate_obligation(&o)) { + if result.may_apply() { + if let Some(ty) = infcx + .shallow_resolve(predicate.self_ty()) + .ty_vid() + .map(|t| infcx.root_var(t)) + { + debug!("relationship: {:?}.self_in_trait = true", ty); + engine.relationships().entry(ty).or_default().self_in_trait = true; + } else { + debug!("relationship: did not find TyVid for self ty..."); + } + } + } + } + } + + if let ty::PredicateKind::Projection(predicate) = obligation.predicate.kind().skip_binder() { + // If the projection predicate (Foo::Bar == X) has X as a non-TyVid, + // we need to make it into one. + if let Some(vid) = predicate.ty.ty_vid() { + debug!("relationship: {:?}.output = true", vid); + engine.relationships().entry(vid).or_default().output = true; + } else { + // This will have registered a projection obligation that will hit + // the Some(vid) branch above. So we don't need to do anything + // further here. + debug!( + "skipping relationship for obligation {:?} -- would need to normalize", + obligation + ); + if !predicate.projection_ty.has_escaping_bound_vars() { + // FIXME: We really *should* do this even with escaping bound + // vars, but there's not much we can do here. In the worst case + // (if this ends up being important) we just don't register a relationship and then end up falling back to !, + // which is not terrible. + + //engine.normalize_projection_type( + // infcx, + // obligation.param_env, + // predicate.projection_ty, + // obligation.cause.clone(), + //); + } + } + } +} diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index c405bbe2d1f53..d9ce169efc15c 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -363,10 +363,11 @@ pub enum IntVarValue { #[derive(Clone, Copy, PartialEq, Eq)] pub struct FloatVarValue(pub FloatTy); -/// A **ty**pe **v**ariable **ID**. -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Encodable, Decodable)] -pub struct TyVid { - pub index: u32, +rustc_index::newtype_index! { + /// A **ty**pe **v**ariable **ID**. + pub struct TyVid { + DEBUG_FORMAT = "_#{}t" + } } /// An **int**egral (`u32`, `i32`, `usize`, etc.) type **v**ariable **ID**. @@ -422,10 +423,10 @@ pub enum InferTy { impl UnifyKey for TyVid { type Value = (); fn index(&self) -> u32 { - self.index + self.as_u32() } fn from_index(i: u32) -> TyVid { - TyVid { index: i } + TyVid::from_u32(i) } fn tag() -> &'static str { "TyVid" @@ -558,7 +559,7 @@ impl HashStable for InferTy { fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { use InferTy::*; match self { - TyVar(v) => v.index.hash_stable(ctx, hasher), + TyVar(v) => v.as_u32().hash_stable(ctx, hasher), IntVar(v) => v.index.hash_stable(ctx, hasher), FloatVar(v) => v.index.hash_stable(ctx, hasher), FreshTy(v) | FreshIntTy(v) | FreshFloatTy(v) => v.hash_stable(ctx, hasher), @@ -587,12 +588,6 @@ impl fmt::Debug for FloatVarValue { } } -impl fmt::Debug for TyVid { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "_#{}t", self.index) - } -} - impl fmt::Debug for IntVid { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "_#{}i", self.index) diff --git a/compiler/rustc_typeck/src/check/cast.rs b/compiler/rustc_typeck/src/check/cast.rs index 14550690e63e0..400bc52e1f29f 100644 --- a/compiler/rustc_typeck/src/check/cast.rs +++ b/compiler/rustc_typeck/src/check/cast.rs @@ -54,8 +54,8 @@ use rustc_trait_selection::traits::error_reporting::report_object_safety_error; #[derive(Debug)] pub struct CastCheck<'tcx> { expr: &'tcx hir::Expr<'tcx>, - expr_ty: Ty<'tcx>, - cast_ty: Ty<'tcx>, + pub(crate) expr_ty: Ty<'tcx>, + pub(crate) cast_ty: Ty<'tcx>, cast_span: Span, span: Span, } diff --git a/compiler/rustc_typeck/src/check/check.rs b/compiler/rustc_typeck/src/check/check.rs index 3c9d5b4def4e7..c01cf4f2a5a75 100644 --- a/compiler/rustc_typeck/src/check/check.rs +++ b/compiler/rustc_typeck/src/check/check.rs @@ -241,32 +241,16 @@ pub(super) fn check_fn<'a, 'tcx>( // we saw and assigning it to the expected return type. This isn't // really expected to fail, since the coercions would have failed // earlier when trying to find a LUB. - // - // However, the behavior around `!` is sort of complex. In the - // event that the `actual_return_ty` comes back as `!`, that - // indicates that the fn either does not return or "returns" only - // values of type `!`. In this case, if there is an expected - // return type that is *not* `!`, that should be ok. But if the - // return type is being inferred, we want to "fallback" to `!`: - // - // let x = move || panic!(); - // - // To allow for that, I am creating a type variable with diverging - // fallback. This was deemed ever so slightly better than unifying - // the return value with `!` because it allows for the caller to - // make more assumptions about the return type (e.g., they could do - // - // let y: Option = Some(x()); - // - // which would then cause this return type to become `u32`, not - // `!`). let coercion = fcx.ret_coercion.take().unwrap().into_inner(); let mut actual_return_ty = coercion.complete(&fcx); - if actual_return_ty.is_never() { - actual_return_ty = fcx.next_diverging_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::DivergingFn, - span, - }); + debug!("actual_return_ty = {:?}", actual_return_ty); + if let ty::Dynamic(..) = declared_ret_ty.kind() { + // We have special-cased the case where the function is declared + // `-> dyn Foo` and we don't actually relate it to the + // `fcx.ret_coercion`, so just substitute a type variable. + actual_return_ty = + fcx.next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::DynReturnFn, span }); + debug!("actual_return_ty replaced with {:?}", actual_return_ty); } fcx.demand_suptype(span, revealed_ret_ty, actual_return_ty); diff --git a/compiler/rustc_typeck/src/check/coercion.rs b/compiler/rustc_typeck/src/check/coercion.rs index 3bfab9d513f37..7c9e1233a4a10 100644 --- a/compiler/rustc_typeck/src/check/coercion.rs +++ b/compiler/rustc_typeck/src/check/coercion.rs @@ -62,7 +62,7 @@ use rustc_trait_selection::traits::{self, ObligationCause, ObligationCauseCode}; use smallvec::{smallvec, SmallVec}; use std::ops::Deref; -struct Coerce<'a, 'tcx> { +pub(crate) struct Coerce<'a, 'tcx> { fcx: &'a FnCtxt<'a, 'tcx>, cause: ObligationCause<'tcx>, use_lub: bool, @@ -116,7 +116,7 @@ fn success<'tcx>( } impl<'f, 'tcx> Coerce<'f, 'tcx> { - fn new( + pub(crate) fn new( fcx: &'f FnCtxt<'f, 'tcx>, cause: ObligationCause<'tcx>, allow_two_phase: AllowTwoPhase, @@ -146,7 +146,15 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { .and_then(|InferOk { value: ty, obligations }| success(f(ty), ty, obligations)) } + pub(crate) fn coerce_silent(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> CoerceResult<'tcx> { + self.coerce_(false, a, b) + } + fn coerce(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> CoerceResult<'tcx> { + self.coerce_(true, a, b) + } + + fn coerce_(&self, report_error: bool, a: Ty<'tcx>, b: Ty<'tcx>) -> CoerceResult<'tcx> { // First, remove any resolved type variables (at the top level, at least): let a = self.shallow_resolve(a); let b = self.shallow_resolve(b); @@ -159,24 +167,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { // Coercing from `!` to any type is allowed: if a.is_never() { - // Subtle: If we are coercing from `!` to `?T`, where `?T` is an unbound - // type variable, we want `?T` to fallback to `!` if not - // otherwise constrained. An example where this arises: - // - // let _: Option = Some({ return; }); - // - // here, we would coerce from `!` to `?T`. - return if b.is_ty_var() { - // Micro-optimization: no need for this if `b` is - // already resolved in some way. - let diverging_ty = self.next_diverging_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::AdjustmentType, - span: self.cause.span, - }); - self.coerce_from_inference_variable(diverging_ty, b, simple(Adjust::NeverToAny)) - } else { - success(simple(Adjust::NeverToAny)(b), b, vec![]) - }; + return success(simple(Adjust::NeverToAny)(b), b, vec![]); } // Coercing *from* an unresolved inference variable means that @@ -191,7 +182,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { // NOTE: this is wrapped in a `commit_if_ok` because it creates // a "spurious" type variable, and we don't want to have that // type variable in memory if the coercion fails. - let unsize = self.commit_if_ok(|_| self.coerce_unsized(a, b)); + let unsize = self.commit_if_ok(|_| self.coerce_unsized(report_error, a, b)); match unsize { Ok(_) => { debug!("coerce: unsize successful"); @@ -499,7 +490,12 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { // &[T; n] or &mut [T; n] -> &[T] // or &mut [T; n] -> &mut [T] // or &Concrete -> &Trait, etc. - fn coerce_unsized(&self, mut source: Ty<'tcx>, mut target: Ty<'tcx>) -> CoerceResult<'tcx> { + fn coerce_unsized( + &self, + report_error: bool, + mut source: Ty<'tcx>, + mut target: Ty<'tcx>, + ) -> CoerceResult<'tcx> { debug!("coerce_unsized(source={:?}, target={:?})", source, target); source = self.shallow_resolve(source); @@ -707,13 +703,15 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { // Object safety violations or miscellaneous. Err(err) => { - self.report_selection_error( - obligation.clone(), - &obligation, - &err, - false, - false, - ); + if report_error { + self.report_selection_error( + obligation.clone(), + &obligation, + &err, + false, + false, + ); + } // Treat this like an obligation and follow through // with the unsizing - the lack of a coercion should // be silent, as it causes a type mismatch later. @@ -724,13 +722,15 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { } if has_unsized_tuple_coercion && !self.tcx.features().unsized_tuple_coercion { - feature_err( - &self.tcx.sess.parse_sess, - sym::unsized_tuple_coercion, - self.cause.span, - "unsized tuple coercion is not stable enough for use and is subject to change", - ) - .emit(); + if report_error { + feature_err( + &self.tcx.sess.parse_sess, + sym::unsized_tuple_coercion, + self.cause.span, + "unsized tuple coercion is not stable enough for use and is subject to change", + ) + .emit(); + } } if has_trait_upcasting_coercion && !self.tcx().features().trait_upcasting { diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs index 51c646e500ca3..ca3a38457d3e3 100644 --- a/compiler/rustc_typeck/src/check/expr.rs +++ b/compiler/rustc_typeck/src/check/expr.rs @@ -77,7 +77,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { !self.typeck_results.borrow().adjustments().contains_key(expr.hir_id), "expression with never type wound up being adjusted" ); - let adj_ty = self.next_diverging_ty_var(TypeVariableOrigin { + let adj_ty = self.next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::AdjustmentType, span: expr.span, }); diff --git a/compiler/rustc_typeck/src/check/fallback.rs b/compiler/rustc_typeck/src/check/fallback.rs index 8f6cdc7bb12a7..c7ffb21ba20b8 100644 --- a/compiler/rustc_typeck/src/check/fallback.rs +++ b/compiler/rustc_typeck/src/check/fallback.rs @@ -1,29 +1,100 @@ use crate::check::FnCtxt; -use rustc_infer::infer::type_variable::Diverging; -use rustc_middle::ty::{self, Ty}; +use rustc_data_structures::{ + fx::FxHashMap, + graph::WithSuccessors, + graph::{iterate::DepthFirstSearch, vec_graph::VecGraph}, + stable_set::FxHashSet, +}; +use rustc_infer::traits::ObligationCauseCode; +use rustc_middle::ty::{self, adjustment::AllowTwoPhase, Ty, TypeFoldable}; impl<'tcx> FnCtxt<'_, 'tcx> { /// Performs type inference fallback, returning true if any fallback /// occurs. pub(super) fn type_inference_fallback(&self) -> bool { + debug!( + "type-inference-fallback start obligations: {:#?}", + self.fulfillment_cx.borrow_mut().pending_obligations() + ); + + let mut cast_vars = Vec::new(); + + // FIXME: This seems to cause extra object safety errors. Not clear why; one would expect the probe and such to eat them. + for cast in self.deferred_cast_checks.borrow().iter() { + let source = cast.expr_ty; + let target = cast.cast_ty; + debug!("attempting coerce {:?} -> {:?}", source, target,); + let source = self.resolve_vars_with_obligations(source); + + let cause = self.cause(rustc_span::DUMMY_SP, ObligationCauseCode::ExprAssignable); + // We don't ever need two-phase here since we throw out the result of the coercion + let coerce = crate::check::coercion::Coerce::new(self, cause, AllowTwoPhase::No); + if let Ok(infok) = self.probe(|_| coerce.coerce_silent(source, target)) { + for obligation in infok.obligations { + if let ty::PredicateKind::Projection(predicate) = + obligation.predicate.kind().skip_binder() + { + if !predicate.projection_ty.has_escaping_bound_vars() { + // FIXME: We really *should* do this even with escaping bound + // vars, but there's not much we can do here. In the worst case + // (if this ends up being important) we just don't register a relationship and then end up falling back to !, + // which is not terrible. + + if let Some(vid) = self + .fulfillment_cx + .borrow_mut() + .normalize_projection_type( + &self.infcx, + obligation.param_env, + predicate.projection_ty, + obligation.cause.clone(), + ) + .ty_vid() + { + cast_vars.push(vid); + } + } + } + } + } + } + // All type checking constraints were added, try to fallback unsolved variables. self.select_obligations_where_possible(false, |_| {}); + + let relationships = self.fulfillment_cx.borrow_mut().relationships().clone(); + + debug!("relationships: {:#?}", relationships); + debug!( + "type-inference-fallback post selection obligations: {:#?}", + self.fulfillment_cx.borrow_mut().pending_obligations() + ); + let mut fallback_has_occurred = false; + // Check if we have any unsolved varibales. If not, no need for fallback. + let unsolved_variables = self.unsolved_variables(); + if unsolved_variables.is_empty() { + return false; + } + + let diverging_fallback = + self.calculate_diverging_fallback(&unsolved_variables, &relationships, &cast_vars); + // We do fallback in two passes, to try to generate // better error messages. // The first time, we do *not* replace opaque types. - for ty in &self.unsolved_variables() { + for ty in unsolved_variables { debug!("unsolved_variable = {:?}", ty); - fallback_has_occurred |= self.fallback_if_possible(ty); + fallback_has_occurred |= self.fallback_if_possible(ty, &diverging_fallback); } - // We now see if we can make progress. This might - // cause us to unify inference variables for opaque types, - // since we may have unified some other type variables - // during the first phase of fallback. - // This means that we only replace inference variables with their underlying - // opaque types as a last resort. + // We now see if we can make progress. This might cause us to + // unify inference variables for opaque types, since we may + // have unified some other type variables during the first + // phase of fallback. This means that we only replace + // inference variables with their underlying opaque types as a + // last resort. // // In code like this: // @@ -62,36 +133,43 @@ impl<'tcx> FnCtxt<'_, 'tcx> { // // - Unconstrained floats are replaced with with `f64`. // - // - Non-numerics get replaced with `!` when `#![feature(never_type_fallback)]` - // is enabled. Otherwise, they are replaced with `()`. + // - Non-numerics may get replaced with `()` or `!`, depending on + // how they were categorized by `calculate_diverging_fallback`. + // + // Fallback becomes very dubious if we have encountered + // type-checking errors. In that case, fallback to Error. // - // 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. - fn fallback_if_possible(&self, ty: Ty<'tcx>) -> bool { + fn fallback_if_possible( + &self, + ty: Ty<'tcx>, + diverging_fallback: &FxHashMap, Ty<'tcx>>, + ) -> bool { // Careful: we do NOT shallow-resolve `ty`. We know that `ty` - // is an unsolved variable, and we determine its fallback based - // solely on how it was created, not what other type variables - // it may have been unified with since then. + // is an unsolved variable, and we determine its fallback + // based solely on how it was created, not what other type + // variables it may have been unified with since then. // - // The reason this matters is that other attempts at fallback may - // (in principle) conflict with this fallback, and we wish to generate - // a type error in that case. (However, this actually isn't true right now, - // because we're only using the builtin fallback rules. This would be - // true if we were using user-supplied fallbacks. But it's still useful - // to write the code to detect bugs.) + // The reason this matters is that other attempts at fallback + // may (in principle) conflict with this fallback, and we wish + // to generate a type error in that case. (However, this + // actually isn't true right now, because we're only using the + // builtin fallback rules. This would be true if we were using + // user-supplied fallbacks. But it's still useful to write the + // code to detect bugs.) // - // (Note though that if we have a general type variable `?T` that is then unified - // with an integer type variable `?I` that ultimately never gets - // resolved to a special integral type, `?T` is not considered unsolved, - // but `?I` is. The same is true for float variables.) + // (Note though that if we have a general type variable `?T` + // that is then unified with an integer type variable `?I` + // that ultimately never gets resolved to a special integral + // type, `?T` is not considered unsolved, but `?I` is. The + // same is true for float variables.) let fallback = match ty.kind() { _ if self.is_tainted_by_errors() => self.tcx.ty_error(), ty::Infer(ty::IntVar(_)) => self.tcx.types.i32, ty::Infer(ty::FloatVar(_)) => self.tcx.types.f64, - _ => match self.type_var_diverges(ty) { - Diverging::Diverges => self.tcx.mk_diverging_default(), - Diverging::NotDiverging => return false, + _ => match diverging_fallback.get(&ty) { + Some(&fallback_ty) => fallback_ty, + None => return false, }, }; debug!("fallback_if_possible(ty={:?}): defaulting to `{:?}`", ty, fallback); @@ -105,11 +183,10 @@ impl<'tcx> FnCtxt<'_, 'tcx> { true } - /// Second round of fallback: Unconstrained type variables - /// created from the instantiation of an opaque - /// type fall back to the opaque type itself. This is a - /// somewhat incomplete attempt to manage "identity passthrough" - /// for `impl Trait` types. + /// Second round of fallback: Unconstrained type variables created + /// from the instantiation of an opaque type fall back to the + /// opaque type itself. This is a somewhat incomplete attempt to + /// manage "identity passthrough" for `impl Trait` types. /// /// For example, in this code: /// @@ -158,4 +235,253 @@ impl<'tcx> FnCtxt<'_, 'tcx> { return false; } } + + /// The "diverging fallback" system is rather complicated. This is + /// a result of our need to balance 'do the right thing' with + /// backwards compatibility. + /// + /// "Diverging" type variables are variables created when we + /// coerce a `!` type into an unbound type variable `?X`. If they + /// never wind up being constrained, the "right and natural" thing + /// is that `?X` should "fallback" to `!`. This means that e.g. an + /// expression like `Some(return)` will ultimately wind up with a + /// type like `Option` (presuming it is not assigned or + /// constrained to have some other type). + /// + /// However, the fallback used to be `()` (before the `!` type was + /// added). Moreover, there are cases where the `!` type 'leaks + /// out' from dead code into type variables that affect live + /// code. The most common case is something like this: + /// + /// ```rust + /// match foo() { + /// 22 => Default::default(), // call this type `?D` + /// _ => return, // return has type `!` + /// } // call the type of this match `?M` + /// ``` + /// + /// Here, coercing the type `!` into `?M` will create a diverging + /// type variable `?X` where `?X <: ?M`. We also have that `?D <: + /// ?M`. If `?M` winds up unconstrained, then `?X` will + /// fallback. If it falls back to `!`, then all the type variables + /// will wind up equal to `!` -- this includes the type `?D` + /// (since `!` doesn't implement `Default`, we wind up a "trait + /// not implemented" error in code like this). But since the + /// original fallback was `()`, this code used to compile with `?D + /// = ()`. This is somewhat surprising, since `Default::default()` + /// on its own would give an error because the types are + /// insufficiently constrained. + /// + /// Our solution to this dilemma is to modify diverging variables + /// so that they can *either* fallback to `!` (the default) or to + /// `()` (the backwards compatibility case). We decide which + /// fallback to use based on whether there is a coercion pattern + /// like this: + /// + /// ``` + /// ?Diverging -> ?V + /// ?NonDiverging -> ?V + /// ?V != ?NonDiverging + /// ``` + /// + /// Here `?Diverging` represents some diverging type variable and + /// `?NonDiverging` represents some non-diverging type + /// variable. `?V` can be any type variable (diverging or not), so + /// long as it is not equal to `?NonDiverging`. + /// + /// Intuitively, what we are looking for is a case where a + /// "non-diverging" type variable (like `?M` in our example above) + /// is coerced *into* some variable `?V` that would otherwise + /// fallback to `!`. In that case, we make `?V` fallback to `!`, + /// along with anything that would flow into `?V`. + /// + /// The algorithm we use: + /// * Identify all variables that are coerced *into* by a + /// diverging variable. Do this by iterating over each + /// diverging, unsolved variable and finding all variables + /// reachable from there. Call that set `D`. + /// * Walk over all unsolved, non-diverging variables, and find + /// any variable that has an edge into `D`. + fn calculate_diverging_fallback( + &self, + unsolved_variables: &[Ty<'tcx>], + relationships: &FxHashMap, + cast_vars: &[ty::TyVid], + ) -> FxHashMap, Ty<'tcx>> { + debug!("calculate_diverging_fallback({:?})", unsolved_variables); + + // Construct a coercion graph where an edge `A -> B` indicates + // a type variable is that is coerced + let coercion_graph = self.create_coercion_graph(); + + // Extract the unsolved type inference variable vids; note that some + // unsolved variables are integer/float variables and are excluded. + let unsolved_vids = unsolved_variables.iter().filter_map(|ty| ty.ty_vid()); + + // Compute the diverging root vids D -- that is, the root vid of + // those type variables that (a) are the target of a coercion from + // a `!` type and (b) have not yet been solved. + // + // These variables are the ones that are targets for fallback to + // either `!` or `()`. + let diverging_roots: FxHashSet = self + .diverging_type_vars + .borrow() + .iter() + .map(|&ty| self.infcx.shallow_resolve(ty)) + .filter_map(|ty| ty.ty_vid()) + .map(|vid| self.infcx.root_var(vid)) + .collect(); + debug!( + "calculate_diverging_fallback: diverging_type_vars={:?}", + self.diverging_type_vars.borrow() + ); + debug!("calculate_diverging_fallback: diverging_roots={:?}", diverging_roots); + + // Find all type variables that are reachable from a diverging + // type variable. These will typically default to `!`, unless + // we find later that they are *also* reachable from some + // other type variable outside this set. + let mut roots_reachable_from_diverging = DepthFirstSearch::new(&coercion_graph); + let mut diverging_vids = vec![]; + let mut non_diverging_vids = vec![]; + for unsolved_vid in unsolved_vids { + let root_vid = self.infcx.root_var(unsolved_vid); + debug!( + "calculate_diverging_fallback: unsolved_vid={:?} root_vid={:?} diverges={:?}", + unsolved_vid, + root_vid, + diverging_roots.contains(&root_vid), + ); + if diverging_roots.contains(&root_vid) { + diverging_vids.push(unsolved_vid); + roots_reachable_from_diverging.push_start_node(root_vid); + + debug!( + "calculate_diverging_fallback: root_vid={:?} reaches {:?}", + root_vid, + coercion_graph.depth_first_search(root_vid).collect::>() + ); + + // drain the iterator to visit all nodes reachable from this node + roots_reachable_from_diverging.complete_search(); + } else { + non_diverging_vids.push(unsolved_vid); + } + } + + debug!( + "calculate_diverging_fallback: roots_reachable_from_diverging={:?}", + roots_reachable_from_diverging, + ); + + // Find all type variables N0 that are not reachable from a + // diverging variable, and then compute the set reachable from + // N0, which we call N. These are the *non-diverging* type + // variables. (Note that this set consists of "root variables".) + let mut roots_reachable_from_non_diverging = DepthFirstSearch::new(&coercion_graph); + for &non_diverging_vid in &non_diverging_vids { + let root_vid = self.infcx.root_var(non_diverging_vid); + if roots_reachable_from_diverging.visited(root_vid) { + continue; + } + roots_reachable_from_non_diverging.push_start_node(root_vid); + roots_reachable_from_non_diverging.complete_search(); + } + debug!( + "calculate_diverging_fallback: roots_reachable_from_non_diverging={:?}", + roots_reachable_from_non_diverging, + ); + + debug!("inherited: {:#?}", self.inh.fulfillment_cx.borrow_mut().pending_obligations()); + debug!("obligations: {:#?}", self.fulfillment_cx.borrow_mut().pending_obligations()); + debug!("relationships: {:#?}", relationships); + + // For each diverging variable, figure out whether it can + // reach a member of N. If so, it falls back to `()`. Else + // `!`. + let mut diverging_fallback = FxHashMap::default(); + diverging_fallback.reserve(diverging_vids.len()); + for &diverging_vid in &diverging_vids { + let diverging_ty = self.tcx.mk_ty_var(diverging_vid); + let root_vid = self.infcx.root_var(diverging_vid); + let can_reach_non_diverging = coercion_graph + .depth_first_search(root_vid) + .any(|n| roots_reachable_from_non_diverging.visited(n)); + + let mut relationship = ty::FoundRelationships { self_in_trait: false, output: false }; + + for (vid, rel) in relationships.iter() { + if self.infcx.root_var(*vid) == root_vid { + relationship.self_in_trait |= rel.self_in_trait; + relationship.output |= rel.output; + } + } + + let mut is_cast = false; + for vid in cast_vars.iter() { + if self.infcx.root_var(*vid) == root_vid { + is_cast = true; + break; + } + } + + if relationship.self_in_trait && relationship.output { + debug!("fallback to () - found trait and projection: {:?}", diverging_vid); + diverging_fallback.insert(diverging_ty, self.tcx.types.unit); + } else if is_cast { + debug!("fallback to () - interacted with cast: {:?}", diverging_vid); + diverging_fallback.insert(diverging_ty, self.tcx.types.unit); + } else if can_reach_non_diverging { + debug!("fallback to () - reached non-diverging: {:?}", diverging_vid); + diverging_fallback.insert(diverging_ty, self.tcx.types.unit); + } else { + debug!("fallback to ! - all diverging: {:?}", diverging_vid); + diverging_fallback.insert(diverging_ty, self.tcx.mk_diverging_default()); + } + } + + diverging_fallback + } + + /// Returns a graph whose nodes are (unresolved) inference variables and where + /// an edge `?A -> ?B` indicates that the variable `?A` is coerced to `?B`. + fn create_coercion_graph(&self) -> VecGraph { + let pending_obligations = self.fulfillment_cx.borrow_mut().pending_obligations(); + debug!("create_coercion_graph: pending_obligations={:?}", pending_obligations); + let coercion_edges: Vec<(ty::TyVid, ty::TyVid)> = pending_obligations + .into_iter() + .filter_map(|obligation| { + // The predicates we are looking for look like `Coerce(?A -> ?B)`. + // They will have no bound variables. + obligation.predicate.kind().no_bound_vars() + }) + .filter_map(|atom| { + if let ty::PredicateKind::Coerce(ty::CoercePredicate { a, b }) = atom { + let a_vid = self.root_vid(a)?; + let b_vid = self.root_vid(b)?; + Some((a_vid, b_vid)) + } else if let ty::PredicateKind::Subtype(ty::SubtypePredicate { + a_is_expected: _, + a, + b, + }) = atom + { + let a_vid = self.root_vid(a)?; + let b_vid = self.root_vid(b)?; + Some((a_vid, b_vid)) + } else { + None + } + }) + .collect(); + debug!("create_coercion_graph: coercion_edges={:?}", coercion_edges); + let num_ty_vars = self.infcx.num_ty_vars(); + VecGraph::new(num_ty_vars, coercion_edges) + } + + /// If `ty` is an unresolved type variable, returns its root vid. + pub fn root_vid(&self, ty: Ty<'tcx>) -> Option { + Some(self.infcx.root_var(self.infcx.shallow_resolve(ty).ty_vid()?)) + } } diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs index 25d1c8706e874..2bca8c063a56f 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs @@ -278,6 +278,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return; } + for a in &adj { + if let Adjust::NeverToAny = a.kind { + if a.target.is_ty_var() { + self.diverging_type_vars.borrow_mut().insert(a.target); + debug!("apply_adjustments: adding `{:?}` as diverging type var", a.target); + } + } + } + let autoborrow_mut = adj.iter().any(|adj| { matches!( adj, diff --git a/compiler/rustc_typeck/src/check/inherited.rs b/compiler/rustc_typeck/src/check/inherited.rs index 6006c8f7513d7..f7552c1f4eb0c 100644 --- a/compiler/rustc_typeck/src/check/inherited.rs +++ b/compiler/rustc_typeck/src/check/inherited.rs @@ -1,6 +1,7 @@ use super::callee::DeferredCallResolution; use super::MaybeInProgressTables; +use rustc_data_structures::fx::FxHashSet; use rustc_hir as hir; use rustc_hir::def_id::{DefIdMap, LocalDefId}; use rustc_hir::HirIdMap; @@ -56,6 +57,11 @@ pub struct Inherited<'a, 'tcx> { pub(super) constness: hir::Constness, pub(super) body_id: Option, + + /// Whenever we introduce an adjustment from `!` into a type variable, + /// we record that type variable here. This is later used to inform + /// fallback. See the `fallback` module for details. + pub(super) diverging_type_vars: RefCell>>, } impl<'a, 'tcx> Deref for Inherited<'a, 'tcx> { @@ -121,6 +127,7 @@ impl Inherited<'a, 'tcx> { deferred_call_resolutions: RefCell::new(Default::default()), deferred_cast_checks: RefCell::new(Vec::new()), deferred_generator_interiors: RefCell::new(Vec::new()), + diverging_type_vars: RefCell::new(Default::default()), constness, body_id, } diff --git a/compiler/rustc_typeck/src/check/method/suggest.rs b/compiler/rustc_typeck/src/check/method/suggest.rs index afe274a2a796e..43444492cc748 100644 --- a/compiler/rustc_typeck/src/check/method/suggest.rs +++ b/compiler/rustc_typeck/src/check/method/suggest.rs @@ -743,7 +743,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let projection_ty = pred.skip_binder().projection_ty; let substs_with_infer_self = tcx.mk_substs( - iter::once(tcx.mk_ty_var(ty::TyVid { index: 0 }).into()) + iter::once(tcx.mk_ty_var(ty::TyVid::from_u32(0)).into()) .chain(projection_ty.substs.iter().skip(1)), ); diff --git a/compiler/rustc_typeck/src/lib.rs b/compiler/rustc_typeck/src/lib.rs index 749f681e92ed1..0e2e491a017b5 100644 --- a/compiler/rustc_typeck/src/lib.rs +++ b/compiler/rustc_typeck/src/lib.rs @@ -66,7 +66,7 @@ This API is completely unstable and subject to change. #![feature(iter_zip)] #![feature(nll)] #![feature(try_blocks)] -#![feature(never_type)] +#![cfg_attr(bootstrap, feature(never_type))] #![feature(slice_partition_dedup)] #![feature(control_flow_enum)] #![cfg_attr(bootstrap, allow(incomplete_features))] // if_let_guard diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index 1a387f291ccf4..b010b4eef50f9 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -116,7 +116,7 @@ #![feature(lang_items)] #![feature(layout_for_ptr)] #![feature(negative_impls)] -#![feature(never_type)] +#![cfg_attr(bootstrap, feature(never_type))] #![feature(nll)] #![feature(nonnull_slice_from_raw_parts)] #![feature(auto_traits)] diff --git a/library/core/src/clone.rs b/library/core/src/clone.rs index 19faf9cddac6f..a92fd93a2cf38 100644 --- a/library/core/src/clone.rs +++ b/library/core/src/clone.rs @@ -195,7 +195,7 @@ mod impls { bool char } - #[unstable(feature = "never_type", issue = "35121")] + #[stable(feature = "never_type", since = "1.53.0")] impl Clone for ! { #[inline] fn clone(&self) -> Self { diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs index 79610bb409d37..256cf3fd7601d 100644 --- a/library/core/src/cmp.rs +++ b/library/core/src/cmp.rs @@ -1357,24 +1357,24 @@ mod impls { ord_impl! { char usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 } - #[unstable(feature = "never_type", issue = "35121")] + #[stable(feature = "never_type", since = "1.53.0")] impl PartialEq for ! { fn eq(&self, _: &!) -> bool { *self } } - #[unstable(feature = "never_type", issue = "35121")] + #[stable(feature = "never_type", since = "1.53.0")] impl Eq for ! {} - #[unstable(feature = "never_type", issue = "35121")] + #[stable(feature = "never_type", since = "1.53.0")] impl PartialOrd for ! { fn partial_cmp(&self, _: &!) -> Option { *self } } - #[unstable(feature = "never_type", issue = "35121")] + #[stable(feature = "never_type", since = "1.53.0")] impl Ord for ! { fn cmp(&self, _: &!) -> Ordering { *self diff --git a/library/core/src/convert/mod.rs b/library/core/src/convert/mod.rs index 1e512af48051e..f8d84f5c77f2c 100644 --- a/library/core/src/convert/mod.rs +++ b/library/core/src/convert/mod.rs @@ -34,9 +34,6 @@ #![stable(feature = "rust1", since = "1.0.0")] -use crate::fmt; -use crate::hash::{Hash, Hasher}; - mod num; #[unstable(feature = "convert_float_to_int", issue = "67057")] @@ -648,91 +645,7 @@ impl AsMut for str { /// } /// ``` /// -/// # Future compatibility -/// -/// This enum has the same role as [the `!` “never” type][never], -/// which is unstable in this version of Rust. -/// When `!` is stabilized, we plan to make `Infallible` a type alias to it: -/// -/// ```ignore (illustrates future std change) -/// pub type Infallible = !; -/// ``` -/// -/// … and eventually deprecate `Infallible`. -/// -/// However there is one case where `!` syntax can be used -/// before `!` is stabilized as a full-fledged type: in the position of a function’s return type. -/// Specifically, it is possible implementations for two different function pointer types: -/// -/// ``` -/// trait MyTrait {} -/// impl MyTrait for fn() -> ! {} -/// impl MyTrait for fn() -> std::convert::Infallible {} -/// ``` -/// -/// With `Infallible` being an enum, this code is valid. -/// However when `Infallible` becomes an alias for the never type, -/// the two `impl`s will start to overlap -/// and therefore will be disallowed by the language’s trait coherence rules. -#[stable(feature = "convert_infallible", since = "1.34.0")] -#[derive(Copy)] -pub enum Infallible {} - -#[stable(feature = "convert_infallible", since = "1.34.0")] -impl Clone for Infallible { - fn clone(&self) -> Infallible { - match *self {} - } -} - +/// This has the same role as [the `!` “never” type][never], and is in fact an +/// alias to it. Generally speaking, you should prefer the never type. #[stable(feature = "convert_infallible", since = "1.34.0")] -impl fmt::Debug for Infallible { - fn fmt(&self, _: &mut fmt::Formatter<'_>) -> fmt::Result { - match *self {} - } -} - -#[stable(feature = "convert_infallible", since = "1.34.0")] -impl fmt::Display for Infallible { - fn fmt(&self, _: &mut fmt::Formatter<'_>) -> fmt::Result { - match *self {} - } -} - -#[stable(feature = "convert_infallible", since = "1.34.0")] -impl PartialEq for Infallible { - fn eq(&self, _: &Infallible) -> bool { - match *self {} - } -} - -#[stable(feature = "convert_infallible", since = "1.34.0")] -impl Eq for Infallible {} - -#[stable(feature = "convert_infallible", since = "1.34.0")] -impl PartialOrd for Infallible { - fn partial_cmp(&self, _other: &Self) -> Option { - match *self {} - } -} - -#[stable(feature = "convert_infallible", since = "1.34.0")] -impl Ord for Infallible { - fn cmp(&self, _other: &Self) -> crate::cmp::Ordering { - match *self {} - } -} - -#[stable(feature = "convert_infallible", since = "1.34.0")] -impl From for Infallible { - fn from(x: !) -> Self { - x - } -} - -#[stable(feature = "convert_infallible_hash", since = "1.44.0")] -impl Hash for Infallible { - fn hash(&self, _: &mut H) { - match *self {} - } -} +pub type Infallible = !; diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs index 1d75ac3d254bd..1b512579389a9 100644 --- a/library/core/src/fmt/mod.rs +++ b/library/core/src/fmt/mod.rs @@ -2083,14 +2083,14 @@ macro_rules! fmt_refs { fmt_refs! { Debug, Display, Octal, Binary, LowerHex, UpperHex, LowerExp, UpperExp } -#[unstable(feature = "never_type", issue = "35121")] +#[stable(feature = "never_type", since = "1.53.0")] impl Debug for ! { fn fmt(&self, _: &mut Formatter<'_>) -> Result { *self } } -#[unstable(feature = "never_type", issue = "35121")] +#[stable(feature = "never_type", since = "1.53.0")] impl Display for ! { fn fmt(&self, _: &mut Formatter<'_>) -> Result { *self diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 1a6d1aed2fd1e..ae9480830acca 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -143,7 +143,6 @@ #![feature(llvm_asm)] #![feature(min_specialization)] #![feature(negative_impls)] -#![feature(never_type)] #![feature(no_core)] #![feature(no_coverage)] // rust-lang/rust#84605 #![feature(no_niche)] // rust-lang/rust#68303 @@ -160,6 +159,7 @@ #![feature(try_blocks)] #![feature(unboxed_closures)] #![feature(unsized_fn_params)] +#![cfg_attr(bootstrap, feature(never_type))] // // Target features: #![feature(aarch64_target_feature)] diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index 333f81ce4cfc4..d9371ebc75d55 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -819,7 +819,7 @@ mod copy_impls { bool char } - #[unstable(feature = "never_type", issue = "35121")] + #[stable(feature = "never_type", since = "1.53.0")] impl Copy for ! {} #[stable(feature = "rust1", since = "1.0.0")] diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs index 84fd1a532c1aa..652c4b96efd30 100644 --- a/library/core/src/mem/mod.rs +++ b/library/core/src/mem/mod.rs @@ -1036,7 +1036,7 @@ pub const fn discriminant(v: &T) -> Discriminant { /// # Examples /// /// ``` -/// # #![feature(never_type)] +/// # #![cfg_attr(bootstrap, feature(never_type))] /// # #![feature(variant_count)] /// /// use std::mem; diff --git a/library/core/src/num/error.rs b/library/core/src/num/error.rs index cdeba9c079273..d3ac3859b8cd2 100644 --- a/library/core/src/num/error.rs +++ b/library/core/src/num/error.rs @@ -1,6 +1,5 @@ //! Error types for conversion to integral types. -use crate::convert::Infallible; use crate::fmt; /// The error type returned when a checked integral type conversion fails. @@ -28,14 +27,7 @@ impl fmt::Display for TryFromIntError { } } -#[stable(feature = "try_from", since = "1.34.0")] -impl From for TryFromIntError { - fn from(x: Infallible) -> TryFromIntError { - match x {} - } -} - -#[unstable(feature = "never_type", issue = "35121")] +#[stable(feature = "never_type", since = "1.53.0")] impl From for TryFromIntError { fn from(never: !) -> TryFromIntError { // Match rather than coerce to make sure that code like diff --git a/library/core/src/result.rs b/library/core/src/result.rs index 092e6544342b7..1c513968de981 100644 --- a/library/core/src/result.rs +++ b/library/core/src/result.rs @@ -1410,7 +1410,7 @@ impl> Result { /// Basic usage: /// /// ``` - /// # #![feature(never_type)] + /// # #![cfg_attr(bootstrap, feature(never_type))] /// # #![feature(unwrap_infallible)] /// /// fn only_good_news() -> Result { @@ -1446,7 +1446,7 @@ impl, E> Result { /// Basic usage: /// /// ``` - /// # #![feature(never_type)] + /// # #![cfg_attr(bootstrap, feature(never_type))] /// # #![feature(unwrap_infallible)] /// /// fn only_bad_news() -> Result { diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs index 13f483f19b770..def97957265aa 100644 --- a/library/core/tests/lib.rs +++ b/library/core/tests/lib.rs @@ -56,7 +56,7 @@ #![feature(const_pin)] #![feature(const_slice_from_raw_parts)] #![feature(const_raw_ptr_deref)] -#![feature(never_type)] +#![cfg_attr(bootstrap, feature(never_type))] #![feature(unwrap_infallible)] #![feature(option_result_unwrap_unchecked)] #![feature(result_into_ok_or_err)] diff --git a/library/std/src/error.rs b/library/std/src/error.rs index ec9f012295000..cb04c704b394a 100644 --- a/library/std/src/error.rs +++ b/library/std/src/error.rs @@ -17,7 +17,6 @@ mod tests; use core::array; -use core::convert::Infallible; use crate::alloc::{AllocError, LayoutError}; use crate::any::TypeId; @@ -385,7 +384,7 @@ impl<'a> From> for Box { } } -#[unstable(feature = "never_type", issue = "35121")] +#[stable(feature = "never_type", since = "1.53.0")] impl Error for ! {} #[unstable( @@ -462,13 +461,6 @@ impl Error for string::FromUtf16Error { } } -#[stable(feature = "str_parse_error2", since = "1.8.0")] -impl Error for Infallible { - fn description(&self) -> &str { - match *self {} - } -} - #[stable(feature = "decode_utf16", since = "1.9.0")] impl Error for char::DecodeUtf16Error { #[allow(deprecated)] diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 028a066b5a130..766daaceb1164 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -297,7 +297,7 @@ #![feature(min_specialization)] #![feature(needs_panic_runtime)] #![feature(negative_impls)] -#![feature(never_type)] +#![cfg_attr(bootstrap, feature(never_type))] #![feature(new_uninit)] #![feature(nll)] #![feature(nonnull_slice_from_raw_parts)] diff --git a/library/std/src/primitive_docs.rs b/library/std/src/primitive_docs.rs index dc4572cd9363b..bed810e101c37 100644 --- a/library/std/src/primitive_docs.rs +++ b/library/std/src/primitive_docs.rs @@ -70,7 +70,7 @@ mod prim_bool {} /// write: /// /// ``` -/// #![feature(never_type)] +/// #![cfg_attr(bootstrap, feature(never_type))] /// # fn foo() -> u32 { /// let x: ! = { /// return 123 @@ -229,7 +229,7 @@ mod prim_bool {} /// for example: /// /// ``` -/// #![feature(never_type)] +/// #![cfg_attr(bootstrap, feature(never_type))] /// # use std::fmt; /// # trait Debug { /// # fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result; @@ -265,7 +265,7 @@ mod prim_bool {} /// [`Debug`]: fmt::Debug /// [`default()`]: Default::default /// -#[unstable(feature = "never_type", issue = "35121")] +#[stable(feature = "never_type", since = "1.53.0")] mod prim_never {} #[doc(primitive = "char")] diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index de32e31ca872f..db0cc688e6bb0 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -10,7 +10,7 @@ #![feature(nll)] #![feature(test)] #![feature(crate_visibility_modifier)] -#![feature(never_type)] +#![cfg_attr(bootstrap, feature(never_type))] #![feature(once_cell)] #![feature(type_ascription)] #![feature(iter_intersperse)] diff --git a/src/test/codegen/enum-debug-niche-2.rs b/src/test/codegen/enum-debug-niche-2.rs index 9c72ad9d248a0..6207078f91ede 100644 --- a/src/test/codegen/enum-debug-niche-2.rs +++ b/src/test/codegen/enum-debug-niche-2.rs @@ -10,8 +10,6 @@ // CHECK: {{.*}}DIDerivedType{{.*}}tag: DW_TAG_member,{{.*}}name: "Placeholder",{{.*}}extraData: i64 4294967295{{[,)].*}} // CHECK: {{.*}}DIDerivedType{{.*}}tag: DW_TAG_member,{{.*}}name: "Error",{{.*}}extraData: i64 0{{[,)].*}} -#![feature(never_type)] - #[derive(Copy, Clone)] pub struct Entity { private: std::num::NonZeroU32, diff --git a/src/test/mir-opt/generator_tiny.main-{closure#0}.generator_resume.0.mir b/src/test/mir-opt/generator_tiny.main-{closure#0}.generator_resume.0.mir index 539988cad245e..a2935265295a4 100644 --- a/src/test/mir-opt/generator_tiny.main-{closure#0}.generator_resume.0.mir +++ b/src/test/mir-opt/generator_tiny.main-{closure#0}.generator_resume.0.mir @@ -10,16 +10,16 @@ storage_conflicts: BitMatrix(0x0) {}, } */ -fn main::{closure#0}(_1: Pin<&mut [generator@$DIR/generator-tiny.rs:19:16: 25:6]>, _2: u8) -> GeneratorState<(), ()> { +fn main::{closure#0}(_1: Pin<&mut [generator@$DIR/generator-tiny.rs:19:16: 25:6]>, _2: u8) -> GeneratorState<(), !> { debug _x => _10; // in scope 0 at $DIR/generator-tiny.rs:19:17: 19:19 - let mut _0: std::ops::GeneratorState<(), ()>; // return place in scope 0 at $DIR/generator-tiny.rs:19:16: 25:6 + let mut _0: std::ops::GeneratorState<(), !>; // return place in scope 0 at $DIR/generator-tiny.rs:19:16: 25:6 let _3: HasDrop; // in scope 0 at $DIR/generator-tiny.rs:20:13: 20:15 let mut _4: !; // in scope 0 at $DIR/generator-tiny.rs:21:9: 24:10 let mut _5: (); // in scope 0 at $DIR/generator-tiny.rs:19:16: 25:6 let _6: u8; // in scope 0 at $DIR/generator-tiny.rs:22:13: 22:18 let mut _7: (); // in scope 0 at $DIR/generator-tiny.rs:22:13: 22:18 let _8: (); // in scope 0 at $DIR/generator-tiny.rs:23:13: 23:21 - let mut _9: (); // in scope 0 at $DIR/generator-tiny.rs:19:25: 19:25 + let mut _9: !; // in scope 0 at $DIR/generator-tiny.rs:19:25: 19:25 let _10: u8; // in scope 0 at $DIR/generator-tiny.rs:19:17: 19:19 let mut _11: u32; // in scope 0 at $DIR/generator-tiny.rs:19:16: 25:6 scope 1 { diff --git a/src/test/mir-opt/issue-72181-1.rs b/src/test/mir-opt/issue-72181-1.rs index 91e98adbe8049..a410fe3d1c519 100644 --- a/src/test/mir-opt/issue-72181-1.rs +++ b/src/test/mir-opt/issue-72181-1.rs @@ -1,7 +1,7 @@ // compile-flags: -Z mir-opt-level=1 // Regression test for #72181, this ICE requires `-Z mir-opt-level=1` flags. -#![feature(never_type)] + #![allow(unused, invalid_value)] enum Void {} diff --git a/src/test/mir-opt/issue_62289.test.ElaborateDrops.before.mir b/src/test/mir-opt/issue_62289.test.ElaborateDrops.before.mir index 95efa74289d85..39471ea68de9c 100644 --- a/src/test/mir-opt/issue_62289.test.ElaborateDrops.before.mir +++ b/src/test/mir-opt/issue_62289.test.ElaborateDrops.before.mir @@ -4,12 +4,12 @@ fn test() -> Option> { let mut _0: std::option::Option>; // return place in scope 0 at $DIR/issue-62289.rs:8:14: 8:30 let mut _1: std::boxed::Box; // in scope 0 at $DIR/issue-62289.rs:9:10: 9:21 let mut _2: std::boxed::Box; // in scope 0 at $DIR/issue-62289.rs:9:10: 9:21 - let mut _3: std::ops::ControlFlow, u32>; // in scope 0 at $DIR/issue-62289.rs:9:15: 9:20 + let mut _3: std::ops::ControlFlow, u32>; // in scope 0 at $DIR/issue-62289.rs:9:15: 9:20 let mut _4: std::option::Option; // in scope 0 at $DIR/issue-62289.rs:9:15: 9:19 let mut _5: isize; // in scope 0 at $DIR/issue-62289.rs:9:19: 9:20 - let _6: std::option::Option; // in scope 0 at $DIR/issue-62289.rs:9:19: 9:20 + let _6: std::option::Option; // in scope 0 at $DIR/issue-62289.rs:9:19: 9:20 let mut _7: !; // in scope 0 at $DIR/issue-62289.rs:9:19: 9:20 - let mut _8: std::option::Option; // in scope 0 at $DIR/issue-62289.rs:9:19: 9:20 + let mut _8: std::option::Option; // in scope 0 at $DIR/issue-62289.rs:9:19: 9:20 let _9: u32; // in scope 0 at $DIR/issue-62289.rs:9:15: 9:20 scope 1 { debug residual => _6; // in scope 1 at $DIR/issue-62289.rs:9:19: 9:20 @@ -56,13 +56,13 @@ fn test() -> Option> { bb4: { StorageLive(_6); // scope 0 at $DIR/issue-62289.rs:9:19: 9:20 - _6 = ((_3 as Break).0: std::option::Option); // scope 0 at $DIR/issue-62289.rs:9:19: 9:20 + _6 = ((_3 as Break).0: std::option::Option); // scope 0 at $DIR/issue-62289.rs:9:19: 9:20 StorageLive(_8); // scope 2 at $DIR/issue-62289.rs:9:19: 9:20 _8 = _6; // scope 2 at $DIR/issue-62289.rs:9:19: 9:20 - _0 = > as FromResidual>>::from_residual(move _8) -> [return: bb5, unwind: bb11]; // scope 2 at $DIR/issue-62289.rs:9:15: 9:20 + _0 = > as FromResidual>>::from_residual(move _8) -> [return: bb5, unwind: bb11]; // scope 2 at $DIR/issue-62289.rs:9:15: 9:20 // mir::Constant // + span: $DIR/issue-62289.rs:9:19: 9:20 - // + literal: Const { ty: fn(std::option::Option) -> std::option::Option> {> as std::ops::FromResidual>>::from_residual}, val: Value(Scalar()) } + // + literal: Const { ty: fn(std::option::Option) -> std::option::Option> {> as std::ops::FromResidual>>::from_residual}, val: Value(Scalar()) } } bb5: { diff --git a/src/test/mir-opt/lower_intrinsics.unreachable.LowerIntrinsics.diff b/src/test/mir-opt/lower_intrinsics.unreachable.LowerIntrinsics.diff index a04b79d47d4ce..774cdf296d4d7 100644 --- a/src/test/mir-opt/lower_intrinsics.unreachable.LowerIntrinsics.diff +++ b/src/test/mir-opt/lower_intrinsics.unreachable.LowerIntrinsics.diff @@ -4,7 +4,7 @@ fn unreachable() -> ! { let mut _0: !; // return place in scope 0 at $DIR/lower_intrinsics.rs:23:25: 23:26 let mut _1: !; // in scope 0 at $DIR/lower_intrinsics.rs:23:27: 25:2 - let _2: (); // in scope 0 at $DIR/lower_intrinsics.rs:24:14: 24:45 + let _2: !; // in scope 0 at $DIR/lower_intrinsics.rs:24:14: 24:45 let mut _3: !; // in scope 0 at $DIR/lower_intrinsics.rs:24:14: 24:45 scope 1 { } diff --git a/src/test/mir-opt/remove-never-const.rs b/src/test/mir-opt/remove-never-const.rs index 1673f14b45ce4..7d2fd5e18c9fd 100644 --- a/src/test/mir-opt/remove-never-const.rs +++ b/src/test/mir-opt/remove-never-const.rs @@ -6,7 +6,7 @@ // compile-flags: --emit mir,link #![feature(const_panic)] -#![feature(never_type)] + #![warn(const_err)] struct PrintName(T); diff --git a/src/test/mir-opt/separate_const_switch.identity.SeparateConstSwitch.diff b/src/test/mir-opt/separate_const_switch.identity.SeparateConstSwitch.diff index 69f3bec6fea25..4a06fb27a3588 100644 --- a/src/test/mir-opt/separate_const_switch.identity.SeparateConstSwitch.diff +++ b/src/test/mir-opt/separate_const_switch.identity.SeparateConstSwitch.diff @@ -1,16 +1,16 @@ - // MIR for `identity` before SeparateConstSwitch + // MIR for `identity` after SeparateConstSwitch - + fn identity(_1: Result) -> Result { debug x => _1; // in scope 0 at $DIR/separate_const_switch.rs:28:13: 28:14 let mut _0: std::result::Result; // return place in scope 0 at $DIR/separate_const_switch.rs:28:37: 28:53 let mut _2: i32; // in scope 0 at $DIR/separate_const_switch.rs:29:8: 29:10 - let mut _3: std::ops::ControlFlow, i32>; // in scope 0 at $DIR/separate_const_switch.rs:29:8: 29:10 + let mut _3: std::ops::ControlFlow, i32>; // in scope 0 at $DIR/separate_const_switch.rs:29:8: 29:10 let mut _4: std::result::Result; // in scope 0 at $DIR/separate_const_switch.rs:29:8: 29:9 let mut _5: isize; // in scope 0 at $DIR/separate_const_switch.rs:29:9: 29:10 - let _6: std::result::Result; // in scope 0 at $DIR/separate_const_switch.rs:29:9: 29:10 + let _6: std::result::Result; // in scope 0 at $DIR/separate_const_switch.rs:29:9: 29:10 let mut _7: !; // in scope 0 at $DIR/separate_const_switch.rs:29:9: 29:10 - let mut _8: std::result::Result; // in scope 0 at $DIR/separate_const_switch.rs:29:9: 29:10 + let mut _8: std::result::Result; // in scope 0 at $DIR/separate_const_switch.rs:29:9: 29:10 let _9: i32; // in scope 0 at $DIR/separate_const_switch.rs:29:8: 29:10 scope 1 { debug residual => _6; // in scope 1 at $DIR/separate_const_switch.rs:29:9: 29:10 @@ -40,7 +40,7 @@ let _11: i32; // in scope 5 at $DIR/separate_const_switch.rs:29:8: 29:10 let mut _12: i32; // in scope 5 at $DIR/separate_const_switch.rs:29:8: 29:10 let _13: i32; // in scope 5 at $DIR/separate_const_switch.rs:29:8: 29:10 - let mut _14: std::result::Result; // in scope 5 at $DIR/separate_const_switch.rs:29:8: 29:10 + let mut _14: std::result::Result; // in scope 5 at $DIR/separate_const_switch.rs:29:8: 29:10 let mut _15: i32; // in scope 5 at $DIR/separate_const_switch.rs:29:8: 29:10 scope 6 { debug v => _11; // in scope 6 at $DIR/separate_const_switch.rs:29:8: 29:10 @@ -49,7 +49,7 @@ debug e => _13; // in scope 7 at $DIR/separate_const_switch.rs:29:8: 29:10 } } - + bb0: { StorageLive(_2); // scope 0 at $DIR/separate_const_switch.rs:29:8: 29:10 StorageLive(_3); // scope 0 at $DIR/separate_const_switch.rs:29:8: 29:10 @@ -60,14 +60,14 @@ - switchInt(move _10) -> [0_isize: bb6, 1_isize: bb4, otherwise: bb5]; // scope 5 at $DIR/separate_const_switch.rs:29:8: 29:10 + switchInt(move _10) -> [0_isize: bb5, 1_isize: bb3, otherwise: bb4]; // scope 5 at $DIR/separate_const_switch.rs:29:8: 29:10 } - + bb1: { - StorageDead(_10); // scope 0 at $DIR/separate_const_switch.rs:29:8: 29:10 - StorageDead(_4); // scope 0 at $DIR/separate_const_switch.rs:29:9: 29:10 - _5 = discriminant(_3); // scope 0 at $DIR/separate_const_switch.rs:29:8: 29:10 - switchInt(move _5) -> [0_isize: bb2, otherwise: bb3]; // scope 0 at $DIR/separate_const_switch.rs:29:8: 29:10 - } -- +- - bb2: { StorageLive(_9); // scope 0 at $DIR/separate_const_switch.rs:29:8: 29:10 _9 = ((_3 as Continue).0: i32); // scope 0 at $DIR/separate_const_switch.rs:29:8: 29:10 @@ -79,11 +79,11 @@ StorageDead(_3); // scope 0 at $DIR/separate_const_switch.rs:30:1: 30:2 return; // scope 0 at $DIR/separate_const_switch.rs:30:2: 30:2 } - + - bb3: { + bb2: { StorageLive(_6); // scope 0 at $DIR/separate_const_switch.rs:29:9: 29:10 - _6 = ((_3 as Break).0: std::result::Result); // scope 0 at $DIR/separate_const_switch.rs:29:9: 29:10 + _6 = ((_3 as Break).0: std::result::Result); // scope 0 at $DIR/separate_const_switch.rs:29:9: 29:10 StorageLive(_8); // scope 2 at $DIR/separate_const_switch.rs:29:9: 29:10 _8 = _6; // scope 2 at $DIR/separate_const_switch.rs:29:9: 29:10 StorageLive(_16); // scope 8 at $DIR/separate_const_switch.rs:29:8: 29:10 @@ -103,7 +103,7 @@ StorageDead(_3); // scope 0 at $DIR/separate_const_switch.rs:30:1: 30:2 return; // scope 0 at $DIR/separate_const_switch.rs:30:2: 30:2 } - + - bb4: { + bb3: { StorageLive(_13); // scope 5 at $DIR/separate_const_switch.rs:29:8: 29:10 @@ -114,7 +114,7 @@ ((_14 as Err).0: i32) = move _15; // scope 7 at $DIR/separate_const_switch.rs:29:8: 29:10 discriminant(_14) = 1; // scope 7 at $DIR/separate_const_switch.rs:29:8: 29:10 StorageDead(_15); // scope 7 at $DIR/separate_const_switch.rs:29:8: 29:10 - ((_3 as Break).0: std::result::Result) = move _14; // scope 7 at $DIR/separate_const_switch.rs:29:8: 29:10 + ((_3 as Break).0: std::result::Result) = move _14; // scope 7 at $DIR/separate_const_switch.rs:29:8: 29:10 discriminant(_3) = 1; // scope 7 at $DIR/separate_const_switch.rs:29:8: 29:10 StorageDead(_14); // scope 7 at $DIR/separate_const_switch.rs:29:8: 29:10 StorageDead(_13); // scope 5 at $DIR/separate_const_switch.rs:29:8: 29:10 @@ -124,12 +124,12 @@ + _5 = discriminant(_3); // scope 0 at $DIR/separate_const_switch.rs:29:8: 29:10 + switchInt(move _5) -> [0_isize: bb1, otherwise: bb2]; // scope 0 at $DIR/separate_const_switch.rs:29:8: 29:10 } - + - bb5: { + bb4: { unreachable; // scope 5 at $DIR/separate_const_switch.rs:29:8: 29:10 } - + - bb6: { + bb5: { StorageLive(_11); // scope 5 at $DIR/separate_const_switch.rs:29:8: 29:10 @@ -147,4 +147,4 @@ + switchInt(move _5) -> [0_isize: bb1, otherwise: bb2]; // scope 0 at $DIR/separate_const_switch.rs:29:8: 29:10 } } - + diff --git a/src/test/mir-opt/uninhabited-enum.rs b/src/test/mir-opt/uninhabited-enum.rs index 97c6e8cd53111..ff35948829b5c 100644 --- a/src/test/mir-opt/uninhabited-enum.rs +++ b/src/test/mir-opt/uninhabited-enum.rs @@ -1,5 +1,3 @@ -#![feature(never_type)] - pub enum Void {} // EMIT_MIR uninhabited_enum.process_never.SimplifyLocals.after.mir diff --git a/src/test/mir-opt/uninhabited_enum.process_never.SimplifyLocals.after.mir b/src/test/mir-opt/uninhabited_enum.process_never.SimplifyLocals.after.mir index c17fe3bb75757..2e95c0403ed18 100644 --- a/src/test/mir-opt/uninhabited_enum.process_never.SimplifyLocals.after.mir +++ b/src/test/mir-opt/uninhabited_enum.process_never.SimplifyLocals.after.mir @@ -1,19 +1,19 @@ // MIR for `process_never` after SimplifyLocals fn process_never(_1: *const !) -> () { - debug input => _1; // in scope 0 at $DIR/uninhabited-enum.rs:7:22: 7:27 - let mut _0: (); // return place in scope 0 at $DIR/uninhabited-enum.rs:7:39: 7:39 - let _2: &!; // in scope 0 at $DIR/uninhabited-enum.rs:8:8: 8:14 + debug input => _1; // in scope 0 at $DIR/uninhabited-enum.rs:5:22: 5:27 + let mut _0: (); // return place in scope 0 at $DIR/uninhabited-enum.rs:5:39: 5:39 + let _2: &!; // in scope 0 at $DIR/uninhabited-enum.rs:6:8: 6:14 scope 1 { - debug _input => _2; // in scope 1 at $DIR/uninhabited-enum.rs:8:8: 8:14 + debug _input => _2; // in scope 1 at $DIR/uninhabited-enum.rs:6:8: 6:14 } scope 2 { } bb0: { - StorageLive(_2); // scope 0 at $DIR/uninhabited-enum.rs:8:8: 8:14 - _2 = &(*_1); // scope 2 at $DIR/uninhabited-enum.rs:8:26: 8:33 - StorageDead(_2); // scope 0 at $DIR/uninhabited-enum.rs:9:1: 9:2 - unreachable; // scope 0 at $DIR/uninhabited-enum.rs:7:39: 9:2 + StorageLive(_2); // scope 0 at $DIR/uninhabited-enum.rs:6:8: 6:14 + _2 = &(*_1); // scope 2 at $DIR/uninhabited-enum.rs:6:26: 6:33 + StorageDead(_2); // scope 0 at $DIR/uninhabited-enum.rs:7:1: 7:2 + unreachable; // scope 0 at $DIR/uninhabited-enum.rs:5:39: 7:2 } } diff --git a/src/test/mir-opt/uninhabited_enum.process_void.SimplifyLocals.after.mir b/src/test/mir-opt/uninhabited_enum.process_void.SimplifyLocals.after.mir index eeaabb7b9884e..efdb9e304db1f 100644 --- a/src/test/mir-opt/uninhabited_enum.process_void.SimplifyLocals.after.mir +++ b/src/test/mir-opt/uninhabited_enum.process_void.SimplifyLocals.after.mir @@ -1,19 +1,19 @@ // MIR for `process_void` after SimplifyLocals fn process_void(_1: *const Void) -> () { - debug input => _1; // in scope 0 at $DIR/uninhabited-enum.rs:13:21: 13:26 - let mut _0: (); // return place in scope 0 at $DIR/uninhabited-enum.rs:13:41: 13:41 - let _2: &Void; // in scope 0 at $DIR/uninhabited-enum.rs:14:8: 14:14 + debug input => _1; // in scope 0 at $DIR/uninhabited-enum.rs:11:21: 11:26 + let mut _0: (); // return place in scope 0 at $DIR/uninhabited-enum.rs:11:41: 11:41 + let _2: &Void; // in scope 0 at $DIR/uninhabited-enum.rs:12:8: 12:14 scope 1 { - debug _input => _2; // in scope 1 at $DIR/uninhabited-enum.rs:14:8: 14:14 + debug _input => _2; // in scope 1 at $DIR/uninhabited-enum.rs:12:8: 12:14 } scope 2 { } bb0: { - StorageLive(_2); // scope 0 at $DIR/uninhabited-enum.rs:14:8: 14:14 - _2 = &(*_1); // scope 2 at $DIR/uninhabited-enum.rs:14:26: 14:33 - StorageDead(_2); // scope 0 at $DIR/uninhabited-enum.rs:17:1: 17:2 - return; // scope 0 at $DIR/uninhabited-enum.rs:17:2: 17:2 + StorageLive(_2); // scope 0 at $DIR/uninhabited-enum.rs:12:8: 12:14 + _2 = &(*_1); // scope 2 at $DIR/uninhabited-enum.rs:12:26: 12:33 + StorageDead(_2); // scope 0 at $DIR/uninhabited-enum.rs:15:1: 15:2 + return; // scope 0 at $DIR/uninhabited-enum.rs:15:2: 15:2 } } diff --git a/src/test/ui/asm/noreturn.rs b/src/test/ui/asm/noreturn.rs index 5e1ee93bfb073..8768cad0c6bce 100644 --- a/src/test/ui/asm/noreturn.rs +++ b/src/test/ui/asm/noreturn.rs @@ -1,7 +1,7 @@ // only-x86_64 // check-pass -#![feature(asm, never_type)] +#![feature(asm)] #![crate_type = "rlib"] pub unsafe fn asm1() { diff --git a/src/test/ui/asm/type-check-2.rs b/src/test/ui/asm/type-check-2.rs index c70a8802814f7..6907e9b6943f7 100644 --- a/src/test/ui/asm/type-check-2.rs +++ b/src/test/ui/asm/type-check-2.rs @@ -1,6 +1,6 @@ // only-x86_64 -#![feature(asm, repr_simd, never_type)] +#![feature(asm, repr_simd)] #[repr(simd)] struct SimdNonCopy(f32, f32, f32, f32); diff --git a/src/test/ui/async-await/async-error-span.rs b/src/test/ui/async-await/async-error-span.rs index 86d459bf084b1..37caa07f5a00b 100644 --- a/src/test/ui/async-await/async-error-span.rs +++ b/src/test/ui/async-await/async-error-span.rs @@ -5,7 +5,7 @@ use std::future::Future; fn get_future() -> impl Future { -//~^ ERROR `()` is not a future +//~^ ERROR `!` is not a future panic!() } diff --git a/src/test/ui/async-await/async-error-span.stderr b/src/test/ui/async-await/async-error-span.stderr index 994bfd33ba42e..a25c91f8b598f 100644 --- a/src/test/ui/async-await/async-error-span.stderr +++ b/src/test/ui/async-await/async-error-span.stderr @@ -1,10 +1,10 @@ -error[E0277]: `()` is not a future +error[E0277]: `!` is not a future --> $DIR/async-error-span.rs:7:20 | LL | fn get_future() -> impl Future { - | ^^^^^^^^^^^^^^^^^^^^^^^^ `()` is not a future + | ^^^^^^^^^^^^^^^^^^^^^^^^ `!` is not a future | - = help: the trait `Future` is not implemented for `()` + = help: the trait `Future` is not implemented for `!` error[E0698]: type inside `async fn` body must be known in this context --> $DIR/async-error-span.rs:13:9 diff --git a/src/test/ui/async-await/try-on-option-in-async.stderr b/src/test/ui/async-await/try-on-option-in-async.stderr index e8bb4aca9a9c9..8796be6b072e4 100644 --- a/src/test/ui/async-await/try-on-option-in-async.stderr +++ b/src/test/ui/async-await/try-on-option-in-async.stderr @@ -10,7 +10,7 @@ LL | | 22 LL | | } | |_____- this function should return `Result` or `Option` to accept `?` | - = help: the trait `FromResidual>` is not implemented for `{integer}` + = help: the trait `FromResidual>` is not implemented for `{integer}` note: required by `from_residual` --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL | @@ -29,7 +29,7 @@ LL | | 22_u32 LL | | }; | |_____- this function should return `Result` or `Option` to accept `?` | - = help: the trait `FromResidual>` is not implemented for `u32` + = help: the trait `FromResidual>` is not implemented for `u32` note: required by `from_residual` --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL | @@ -48,7 +48,7 @@ LL | | 22 LL | | } | |_- this function should return `Result` or `Option` to accept `?` | - = help: the trait `FromResidual>` is not implemented for `u32` + = help: the trait `FromResidual>` is not implemented for `u32` note: required by `from_residual` --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL | diff --git a/src/test/ui/binding/empty-types-in-patterns.rs b/src/test/ui/binding/empty-types-in-patterns.rs index 0d0dbcaf40f43..5b9b721e99f97 100644 --- a/src/test/ui/binding/empty-types-in-patterns.rs +++ b/src/test/ui/binding/empty-types-in-patterns.rs @@ -1,6 +1,6 @@ // run-pass -#![feature(never_type, never_type_fallback)] + #![feature(exhaustive_patterns)] #![allow(unreachable_patterns)] diff --git a/src/test/ui/borrowck/assign-never-type.rs b/src/test/ui/borrowck/assign-never-type.rs index 4f30ea1467023..c71aac0156ff6 100644 --- a/src/test/ui/borrowck/assign-never-type.rs +++ b/src/test/ui/borrowck/assign-never-type.rs @@ -2,7 +2,7 @@ // check-pass -#![feature(never_type)] + pub fn main() { loop { diff --git a/src/test/ui/break-diverging-value.rs b/src/test/ui/break-diverging-value.rs index d070fddaffc19..1f8995736ec3c 100644 --- a/src/test/ui/break-diverging-value.rs +++ b/src/test/ui/break-diverging-value.rs @@ -1,5 +1,3 @@ -#![feature(never_type)] - fn loop_break_return() -> i32 { let loop_value = loop { break return 0 }; // ok } diff --git a/src/test/ui/break-diverging-value.stderr b/src/test/ui/break-diverging-value.stderr index 69edcd2408002..e4f2f3dd7f692 100644 --- a/src/test/ui/break-diverging-value.stderr +++ b/src/test/ui/break-diverging-value.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/break-diverging-value.rs:11:26 + --> $DIR/break-diverging-value.rs:9:26 | LL | fn loop_break_break() -> i32 { | ---------------- ^^^ expected `i32`, found `()` @@ -7,7 +7,7 @@ LL | fn loop_break_break() -> i32 { | implicitly returns `()` as its body has no tail or `return` expression error[E0308]: mismatched types - --> $DIR/break-diverging-value.rs:25:25 + --> $DIR/break-diverging-value.rs:23:25 | LL | fn loop_break_void() -> i32 { | --------------- ^^^ expected `i32`, found `()` diff --git a/src/test/ui/break-while-condition.rs b/src/test/ui/break-while-condition.rs index 6064e6ab00235..7aa5682b923a6 100644 --- a/src/test/ui/break-while-condition.rs +++ b/src/test/ui/break-while-condition.rs @@ -1,5 +1,3 @@ -#![feature(never_type)] - fn main() { // The `if false` expressions are simply to // make sure we don't avoid checking everything diff --git a/src/test/ui/break-while-condition.stderr b/src/test/ui/break-while-condition.stderr index 6960c4fd86735..bbc9f21edb06e 100644 --- a/src/test/ui/break-while-condition.stderr +++ b/src/test/ui/break-while-condition.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/break-while-condition.rs:9:20 + --> $DIR/break-while-condition.rs:7:20 | LL | let _: ! = { | ____________________^ @@ -11,7 +11,7 @@ LL | | }; found unit type `()` error[E0308]: mismatched types - --> $DIR/break-while-condition.rs:16:13 + --> $DIR/break-while-condition.rs:14:13 | LL | / while false { LL | | break @@ -22,7 +22,7 @@ LL | | } found unit type `()` error[E0308]: mismatched types - --> $DIR/break-while-condition.rs:24:13 + --> $DIR/break-while-condition.rs:22:13 | LL | / while false { LL | | return diff --git a/src/test/ui/closures/2229_closure_analysis/match/pattern-matching-should-fail.rs b/src/test/ui/closures/2229_closure_analysis/match/pattern-matching-should-fail.rs index 0f288ffa95a87..27b257d0124bf 100644 --- a/src/test/ui/closures/2229_closure_analysis/match/pattern-matching-should-fail.rs +++ b/src/test/ui/closures/2229_closure_analysis/match/pattern-matching-should-fail.rs @@ -1,7 +1,5 @@ // edition:2021 -#![feature(never_type)] - // Should fake read the discriminant and throw an error fn test1() { let x: !; diff --git a/src/test/ui/closures/2229_closure_analysis/match/pattern-matching-should-fail.stderr b/src/test/ui/closures/2229_closure_analysis/match/pattern-matching-should-fail.stderr index 45641ea3de3e0..6fe3122139e2e 100644 --- a/src/test/ui/closures/2229_closure_analysis/match/pattern-matching-should-fail.stderr +++ b/src/test/ui/closures/2229_closure_analysis/match/pattern-matching-should-fail.stderr @@ -1,5 +1,5 @@ error[E0004]: non-exhaustive patterns: type `u8` is non-empty - --> $DIR/pattern-matching-should-fail.rs:70:23 + --> $DIR/pattern-matching-should-fail.rs:68:23 | LL | let c1 = || match x { }; | ^ @@ -8,13 +8,13 @@ LL | let c1 = || match x { }; = note: the matched value is of type `u8` error[E0381]: use of possibly-uninitialized variable: `x` - --> $DIR/pattern-matching-should-fail.rs:8:23 + --> $DIR/pattern-matching-should-fail.rs:6:23 | LL | let c1 = || match x { }; | ^ use of possibly-uninitialized `x` error[E0381]: borrow of possibly-uninitialized variable: `x` - --> $DIR/pattern-matching-should-fail.rs:15:14 + --> $DIR/pattern-matching-should-fail.rs:13:14 | LL | let c2 = || match x { _ => () }; | ^^ - borrow occurs due to use in closure @@ -22,7 +22,7 @@ LL | let c2 = || match x { _ => () }; | use of possibly-uninitialized `x` error[E0381]: borrow of possibly-uninitialized variable: `variant` - --> $DIR/pattern-matching-should-fail.rs:27:13 + --> $DIR/pattern-matching-should-fail.rs:25:13 | LL | let c = || { | ^^ use of possibly-uninitialized `variant` @@ -31,7 +31,7 @@ LL | match variant { | ------- borrow occurs due to use in closure error[E0381]: borrow of possibly-uninitialized variable: `variant` - --> $DIR/pattern-matching-should-fail.rs:39:13 + --> $DIR/pattern-matching-should-fail.rs:37:13 | LL | let c = || { | ^^ use of possibly-uninitialized `variant` @@ -40,19 +40,19 @@ LL | match variant { | ------- borrow occurs due to use in closure error[E0381]: use of possibly-uninitialized variable: `g` - --> $DIR/pattern-matching-should-fail.rs:55:15 + --> $DIR/pattern-matching-should-fail.rs:53:15 | LL | match g { }; | ^ use of possibly-uninitialized `g` error[E0381]: use of possibly-uninitialized variable: `t` - --> $DIR/pattern-matching-should-fail.rs:58:19 + --> $DIR/pattern-matching-should-fail.rs:56:19 | LL | match t { }; | ^ use of possibly-uninitialized `t` error[E0381]: use of possibly-uninitialized variable: `x` - --> $DIR/pattern-matching-should-fail.rs:70:23 + --> $DIR/pattern-matching-should-fail.rs:68:23 | LL | let c1 = || match x { }; | ^ use of possibly-uninitialized `x` diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.fixed b/src/test/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.fixed index a5652154682c5..745c107eeab02 100644 --- a/src/test/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.fixed +++ b/src/test/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.fixed @@ -4,7 +4,6 @@ //~^ NOTE: the lint level is defined here // ignore-wasm32-bare compiled with panic=abort by default #![feature(fn_traits)] -#![feature(never_type)] use std::panic; diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.rs b/src/test/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.rs index d9acde073fc3d..41aaf90857eff 100644 --- a/src/test/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.rs +++ b/src/test/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.rs @@ -4,7 +4,6 @@ //~^ NOTE: the lint level is defined here // ignore-wasm32-bare compiled with panic=abort by default #![feature(fn_traits)] -#![feature(never_type)] use std::panic; diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.stderr b/src/test/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.stderr index 10816b7bc3adf..278d590119155 100644 --- a/src/test/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.stderr +++ b/src/test/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.stderr @@ -1,5 +1,5 @@ error: changes to closure capture in Rust 2021 will affect `UnwindSafe`, `RefUnwindSafe` trait implementation for closure - --> $DIR/mir_calls_to_shims.rs:20:38 + --> $DIR/mir_calls_to_shims.rs:19:38 | LL | let result = panic::catch_unwind(move || { | ^^^^^^^ in Rust 2018, this closure implements `UnwindSafe`, `RefUnwindSafe` as `f` implements `UnwindSafe`, `RefUnwindSafe`, but in Rust 2021, this closure will no longer implement `UnwindSafe`, `RefUnwindSafe` as `f.0` does not implement `UnwindSafe`, `RefUnwindSafe` 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 0824ce8cd585b..b71c3663a4f63 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, never_type_fallback)] + #![allow(unreachable_code)] use std::error::Error; diff --git a/src/test/ui/coercion/coerce-to-bang-cast.rs b/src/test/ui/coercion/coerce-to-bang-cast.rs index 85598a42eccd9..7fb9235ea3669 100644 --- a/src/test/ui/coercion/coerce-to-bang-cast.rs +++ b/src/test/ui/coercion/coerce-to-bang-cast.rs @@ -1,5 +1,3 @@ -#![feature(never_type)] - fn cast_a() { let y = {return; 22} as !; //~^ ERROR non-primitive cast diff --git a/src/test/ui/coercion/coerce-to-bang-cast.stderr b/src/test/ui/coercion/coerce-to-bang-cast.stderr index 50e009aa25bb1..92d798ac12c15 100644 --- a/src/test/ui/coercion/coerce-to-bang-cast.stderr +++ b/src/test/ui/coercion/coerce-to-bang-cast.stderr @@ -1,11 +1,11 @@ error[E0605]: non-primitive cast: `i32` as `!` - --> $DIR/coerce-to-bang-cast.rs:4:13 + --> $DIR/coerce-to-bang-cast.rs:2:13 | LL | let y = {return; 22} as !; | ^^^^^^^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object error[E0605]: non-primitive cast: `i32` as `!` - --> $DIR/coerce-to-bang-cast.rs:9:13 + --> $DIR/coerce-to-bang-cast.rs:7:13 | LL | let y = 22 as !; | ^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object diff --git a/src/test/ui/coercion/coerce-to-bang.rs b/src/test/ui/coercion/coerce-to-bang.rs index 1e06934d09f9e..d52f79fbb7a98 100644 --- a/src/test/ui/coercion/coerce-to-bang.rs +++ b/src/test/ui/coercion/coerce-to-bang.rs @@ -1,5 +1,3 @@ -#![feature(never_type)] - fn foo(x: usize, y: !, z: usize) { } fn call_foo_a() { diff --git a/src/test/ui/coercion/coerce-to-bang.stderr b/src/test/ui/coercion/coerce-to-bang.stderr index 390aa7c692d18..ca42705973750 100644 --- a/src/test/ui/coercion/coerce-to-bang.stderr +++ b/src/test/ui/coercion/coerce-to-bang.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/coerce-to-bang.rs:6:17 + --> $DIR/coerce-to-bang.rs:4:17 | LL | foo(return, 22, 44); | ^^ expected `!`, found integer @@ -8,7 +8,7 @@ LL | foo(return, 22, 44); found type `{integer}` error[E0308]: mismatched types - --> $DIR/coerce-to-bang.rs:18:13 + --> $DIR/coerce-to-bang.rs:16:13 | LL | foo(22, 44, return); | ^^ expected `!`, found integer @@ -17,7 +17,7 @@ LL | foo(22, 44, return); found type `{integer}` error[E0308]: mismatched types - --> $DIR/coerce-to-bang.rs:26:12 + --> $DIR/coerce-to-bang.rs:24:12 | LL | foo(a, b, c); // ... and hence a reference to `a` is expected to diverge. | ^ expected `!`, found integer @@ -26,7 +26,7 @@ LL | foo(a, b, c); // ... and hence a reference to `a` is expected to diverg found type `{integer}` error[E0308]: mismatched types - --> $DIR/coerce-to-bang.rs:36:12 + --> $DIR/coerce-to-bang.rs:34:12 | LL | foo(a, b, c); | ^ expected `!`, found integer @@ -35,7 +35,7 @@ LL | foo(a, b, c); found type `{integer}` error[E0308]: mismatched types - --> $DIR/coerce-to-bang.rs:45:12 + --> $DIR/coerce-to-bang.rs:43:12 | LL | foo(a, b, c); | ^ expected `!`, found integer @@ -44,7 +44,7 @@ LL | foo(a, b, c); found type `{integer}` error[E0308]: mismatched types - --> $DIR/coerce-to-bang.rs:50:21 + --> $DIR/coerce-to-bang.rs:48:21 | LL | let x: [!; 2] = [return, 22]; | ------ ^^^^^^^^^^^^ expected `!`, found integer @@ -55,7 +55,7 @@ LL | let x: [!; 2] = [return, 22]; found array `[{integer}; 2]` error[E0308]: mismatched types - --> $DIR/coerce-to-bang.rs:55:22 + --> $DIR/coerce-to-bang.rs:53:22 | LL | let x: [!; 2] = [22, return]; | ^^ expected `!`, found integer @@ -64,7 +64,7 @@ LL | let x: [!; 2] = [22, return]; found type `{integer}` error[E0308]: mismatched types - --> $DIR/coerce-to-bang.rs:60:37 + --> $DIR/coerce-to-bang.rs:58:37 | LL | let x: (usize, !, usize) = (22, 44, 66); | ^^ expected `!`, found integer @@ -73,7 +73,7 @@ LL | let x: (usize, !, usize) = (22, 44, 66); found type `{integer}` error[E0308]: mismatched types - --> $DIR/coerce-to-bang.rs:65:41 + --> $DIR/coerce-to-bang.rs:63:41 | LL | let x: (usize, !, usize) = (return, 44, 66); | ^^ expected `!`, found integer @@ -82,7 +82,7 @@ LL | let x: (usize, !, usize) = (return, 44, 66); found type `{integer}` error[E0308]: mismatched types - --> $DIR/coerce-to-bang.rs:76:37 + --> $DIR/coerce-to-bang.rs:74:37 | LL | let x: (usize, !, usize) = (22, 44, return); | ^^ expected `!`, found integer diff --git a/src/test/ui/const-generics/min_const_generics/complex-types.rs b/src/test/ui/const-generics/min_const_generics/complex-types.rs index 057bd5af89ef7..f3d103d46ce65 100644 --- a/src/test/ui/const-generics/min_const_generics/complex-types.rs +++ b/src/test/ui/const-generics/min_const_generics/complex-types.rs @@ -1,5 +1,3 @@ -#![feature(never_type)] - struct Foo; //~^ ERROR `[u8; 0]` is forbidden diff --git a/src/test/ui/const-generics/min_const_generics/complex-types.stderr b/src/test/ui/const-generics/min_const_generics/complex-types.stderr index a658a7b395689..faa5e0f8a753a 100644 --- a/src/test/ui/const-generics/min_const_generics/complex-types.stderr +++ b/src/test/ui/const-generics/min_const_generics/complex-types.stderr @@ -1,5 +1,5 @@ error: `[u8; 0]` is forbidden as the type of a const generic parameter - --> $DIR/complex-types.rs:3:21 + --> $DIR/complex-types.rs:1:21 | LL | struct Foo; | ^^^^^^^ @@ -8,7 +8,7 @@ LL | struct Foo; = help: more complex types are supported with `#![feature(const_generics)]` error: `()` is forbidden as the type of a const generic parameter - --> $DIR/complex-types.rs:6:21 + --> $DIR/complex-types.rs:4:21 | LL | struct Bar; | ^^ @@ -17,7 +17,7 @@ LL | struct Bar; = help: more complex types are supported with `#![feature(const_generics)]` error: `No` is forbidden as the type of a const generic parameter - --> $DIR/complex-types.rs:11:21 + --> $DIR/complex-types.rs:9:21 | LL | struct Fez; | ^^ @@ -26,7 +26,7 @@ LL | struct Fez; = help: more complex types are supported with `#![feature(const_generics)]` error: `&'static u8` is forbidden as the type of a const generic parameter - --> $DIR/complex-types.rs:14:21 + --> $DIR/complex-types.rs:12:21 | LL | struct Faz; | ^^^^^^^^^^^ @@ -35,7 +35,7 @@ LL | struct Faz; = help: more complex types are supported with `#![feature(const_generics)]` error: `!` is forbidden as the type of a const generic parameter - --> $DIR/complex-types.rs:17:21 + --> $DIR/complex-types.rs:15:21 | LL | struct Fiz; | ^ @@ -44,7 +44,7 @@ LL | struct Fiz; = help: more complex types are supported with `#![feature(const_generics)]` error: `()` is forbidden as the type of a const generic parameter - --> $DIR/complex-types.rs:20:19 + --> $DIR/complex-types.rs:18:19 | LL | enum Goo { A, B } | ^^ @@ -53,7 +53,7 @@ LL | enum Goo { A, B } = help: more complex types are supported with `#![feature(const_generics)]` error: `()` is forbidden as the type of a const generic parameter - --> $DIR/complex-types.rs:23:20 + --> $DIR/complex-types.rs:21:20 | LL | union Boo { a: () } | ^^ diff --git a/src/test/ui/consts/assume-type-intrinsics.rs b/src/test/ui/consts/assume-type-intrinsics.rs index 77370e1ccc59e..5023606471539 100644 --- a/src/test/ui/consts/assume-type-intrinsics.rs +++ b/src/test/ui/consts/assume-type-intrinsics.rs @@ -1,6 +1,6 @@ // error-pattern: any use of this value will cause an error -#![feature(never_type)] + #![feature(const_maybe_uninit_assume_init)] #[allow(invalid_value)] diff --git a/src/test/ui/consts/const-eval/index-out-of-bounds-never-type.rs b/src/test/ui/consts/const-eval/index-out-of-bounds-never-type.rs index 8064cc49359ee..54c48b812a0f4 100644 --- a/src/test/ui/consts/const-eval/index-out-of-bounds-never-type.rs +++ b/src/test/ui/consts/const-eval/index-out-of-bounds-never-type.rs @@ -2,7 +2,7 @@ // Regression test for #66975 #![warn(const_err, unconditional_panic)] -#![feature(never_type)] + struct PrintName(T); diff --git a/src/test/ui/consts/const-eval/panic-assoc-never-type.rs b/src/test/ui/consts/const-eval/panic-assoc-never-type.rs index ab0256a986dbc..94ff55b198a7c 100644 --- a/src/test/ui/consts/const-eval/panic-assoc-never-type.rs +++ b/src/test/ui/consts/const-eval/panic-assoc-never-type.rs @@ -3,7 +3,7 @@ // Regression test for #66975 #![warn(const_err)] #![feature(const_panic)] -#![feature(never_type)] + struct PrintName; diff --git a/src/test/ui/consts/const-eval/panic-never-type.rs b/src/test/ui/consts/const-eval/panic-never-type.rs index dd875768b168f..58e6fc056fbe0 100644 --- a/src/test/ui/consts/const-eval/panic-never-type.rs +++ b/src/test/ui/consts/const-eval/panic-never-type.rs @@ -1,7 +1,7 @@ // Regression test for #66975 #![warn(const_err)] #![feature(const_panic)] -#![feature(never_type)] + const VOID: ! = panic!(); //~^ ERROR evaluation of constant value failed diff --git a/src/test/ui/consts/const-eval/ub-enum.rs b/src/test/ui/consts/const-eval/ub-enum.rs index e408d8ec072e3..790fecaf4cf0a 100644 --- a/src/test/ui/consts/const-eval/ub-enum.rs +++ b/src/test/ui/consts/const-eval/ub-enum.rs @@ -1,7 +1,7 @@ // stderr-per-bitwidth -#![feature(never_type)] #![allow(const_err)] // make sure we cannot allow away the errors tested here + use std::mem; #[repr(transparent)] diff --git a/src/test/ui/consts/const-variant-count.rs b/src/test/ui/consts/const-variant-count.rs index 455419d2c7f1d..35a2500b9fc09 100644 --- a/src/test/ui/consts/const-variant-count.rs +++ b/src/test/ui/consts/const-variant-count.rs @@ -1,7 +1,7 @@ // run-pass #![allow(dead_code)] #![feature(variant_count)] -#![feature(never_type)] + use std::mem::variant_count; diff --git a/src/test/ui/consts/validate_never_arrays.rs b/src/test/ui/consts/validate_never_arrays.rs index 1990fb073970e..0b13e054d5c88 100644 --- a/src/test/ui/consts/validate_never_arrays.rs +++ b/src/test/ui/consts/validate_never_arrays.rs @@ -1,5 +1,5 @@ // stderr-per-bitwidth -#![feature(const_raw_ptr_deref, never_type)] +#![feature(const_raw_ptr_deref)] const _: &[!; 1] = unsafe { &*(1_usize as *const [!; 1]) }; //~ ERROR undefined behavior const _: &[!; 0] = unsafe { &*(1_usize as *const [!; 0]) }; // ok diff --git a/src/test/ui/empty/empty-never-array.rs b/src/test/ui/empty/empty-never-array.rs index 01b99134a445f..a5024449d91d9 100644 --- a/src/test/ui/empty/empty-never-array.rs +++ b/src/test/ui/empty/empty-never-array.rs @@ -1,5 +1,3 @@ -#![feature(never_type)] - enum Helper { T(T, [!; 0]), #[allow(dead_code)] diff --git a/src/test/ui/empty/empty-never-array.stderr b/src/test/ui/empty/empty-never-array.stderr index 64d640c0e9dbc..e90523cb9223e 100644 --- a/src/test/ui/empty/empty-never-array.stderr +++ b/src/test/ui/empty/empty-never-array.stderr @@ -1,5 +1,5 @@ error[E0005]: refutable pattern in local binding: `T(_, _)` not covered - --> $DIR/empty-never-array.rs:10:9 + --> $DIR/empty-never-array.rs:8:9 | LL | / enum Helper { LL | | T(T, [!; 0]), diff --git a/src/test/ui/feature-gates/feature-gate-exhaustive-patterns.rs b/src/test/ui/feature-gates/feature-gate-exhaustive-patterns.rs index f0cc9ea70550e..c27089d2a0590 100644 --- a/src/test/ui/feature-gates/feature-gate-exhaustive-patterns.rs +++ b/src/test/ui/feature-gates/feature-gate-exhaustive-patterns.rs @@ -1,5 +1,3 @@ -#![feature(never_type)] - fn foo() -> Result { Ok(123) } diff --git a/src/test/ui/feature-gates/feature-gate-exhaustive-patterns.stderr b/src/test/ui/feature-gates/feature-gate-exhaustive-patterns.stderr index c5ffa55ebec6f..e33b66df0c3b8 100644 --- a/src/test/ui/feature-gates/feature-gate-exhaustive-patterns.stderr +++ b/src/test/ui/feature-gates/feature-gate-exhaustive-patterns.stderr @@ -1,5 +1,5 @@ error[E0005]: refutable pattern in local binding: `Err(_)` not covered - --> $DIR/feature-gate-exhaustive-patterns.rs:8:9 + --> $DIR/feature-gate-exhaustive-patterns.rs:6:9 | LL | let Ok(_x) = foo(); | ^^^^^^ pattern `Err(_)` not covered diff --git a/src/test/ui/feature-gates/feature-gate-never_type.rs b/src/test/ui/feature-gates/feature-gate-never_type.rs deleted file mode 100644 index be8c27dbb1b02..0000000000000 --- a/src/test/ui/feature-gates/feature-gate-never_type.rs +++ /dev/null @@ -1,17 +0,0 @@ -// Test that ! errors when used in illegal positions with feature(never_type) disabled - -trait Foo { - type Wub; -} - -type Ma = (u32, !, i32); //~ ERROR type is experimental -type Meeshka = Vec; //~ ERROR type is experimental -type Mow = &'static fn(!) -> !; //~ ERROR type is experimental -type Skwoz = &'static mut !; //~ ERROR type is experimental - -impl Foo for Meeshka { - type Wub = !; //~ ERROR type is experimental -} - -fn main() { -} diff --git a/src/test/ui/feature-gates/feature-gate-never_type.stderr b/src/test/ui/feature-gates/feature-gate-never_type.stderr deleted file mode 100644 index 0a59cae9c8c46..0000000000000 --- a/src/test/ui/feature-gates/feature-gate-never_type.stderr +++ /dev/null @@ -1,48 +0,0 @@ -error[E0658]: the `!` type is experimental - --> $DIR/feature-gate-never_type.rs:7:17 - | -LL | type Ma = (u32, !, i32); - | ^ - | - = note: see issue #35121 for more information - = help: add `#![feature(never_type)]` to the crate attributes to enable - -error[E0658]: the `!` type is experimental - --> $DIR/feature-gate-never_type.rs:8:20 - | -LL | type Meeshka = Vec; - | ^ - | - = note: see issue #35121 for more information - = help: add `#![feature(never_type)]` to the crate attributes to enable - -error[E0658]: the `!` type is experimental - --> $DIR/feature-gate-never_type.rs:9:24 - | -LL | type Mow = &'static fn(!) -> !; - | ^ - | - = note: see issue #35121 for more information - = help: add `#![feature(never_type)]` to the crate attributes to enable - -error[E0658]: the `!` type is experimental - --> $DIR/feature-gate-never_type.rs:10:27 - | -LL | type Skwoz = &'static mut !; - | ^ - | - = note: see issue #35121 for more information - = help: add `#![feature(never_type)]` to the crate attributes to enable - -error[E0658]: the `!` type is experimental - --> $DIR/feature-gate-never_type.rs:13:16 - | -LL | type Wub = !; - | ^ - | - = note: see issue #35121 for more information - = help: add `#![feature(never_type)]` to the crate attributes to enable - -error: aborting due to 5 previous errors - -For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/for-loop-while/loop-break-value.rs b/src/test/ui/for-loop-while/loop-break-value.rs index d7209fc4de867..e629ce48b994d 100644 --- a/src/test/ui/for-loop-while/loop-break-value.rs +++ b/src/test/ui/for-loop-while/loop-break-value.rs @@ -1,7 +1,7 @@ // run-pass #![allow(unreachable_code)] -#![feature(never_type)] + #[allow(unused)] fn never_returns() { diff --git a/src/test/ui/intrinsics/panic-uninitialized-zeroed.rs b/src/test/ui/intrinsics/panic-uninitialized-zeroed.rs index 88ef8182f0238..a87f2d957df56 100644 --- a/src/test/ui/intrinsics/panic-uninitialized-zeroed.rs +++ b/src/test/ui/intrinsics/panic-uninitialized-zeroed.rs @@ -3,11 +3,10 @@ // revisions: mir thir // [thir]compile-flags: -Zthir-unsafeck -// This test checks panic emitted from `mem::{uninitialized,zeroed}`. - -#![feature(never_type)] #![allow(deprecated, invalid_value)] +// This test checks panic emitted from `mem::{uninitialized,zeroed}`. + use std::{ mem::{self, MaybeUninit, ManuallyDrop}, panic, diff --git a/src/test/ui/issues/issue-22034.rs b/src/test/ui/issues/issue-22034.rs index 405ffd089c245..c6dedff1eea36 100644 --- a/src/test/ui/issues/issue-22034.rs +++ b/src/test/ui/issues/issue-22034.rs @@ -1,3 +1,4 @@ +//~ ERROR expected a `FnOnce<()>` closure, found `()` #![feature(rustc_private)] extern crate libc; diff --git a/src/test/ui/issues/issue-22034.stderr b/src/test/ui/issues/issue-22034.stderr index edcd21ebd6b9b..93d43d0453376 100644 --- a/src/test/ui/issues/issue-22034.stderr +++ b/src/test/ui/issues/issue-22034.stderr @@ -1,5 +1,11 @@ +error[E0277]: expected a `FnOnce<()>` closure, found `()` + | + = help: the trait `FnOnce<()>` is not implemented for `()` + = note: wrap the `()` in a closure with no arguments: `|| { /* code */ }` + = note: required for the cast to the object type `dyn Fn()` + error[E0277]: expected a `Fn<()>` closure, found `()` - --> $DIR/issue-22034.rs:8:16 + --> $DIR/issue-22034.rs:9:16 | LL | &mut *(ptr as *mut dyn Fn()) | ^^^ expected an `Fn<()>` closure, found `()` @@ -8,6 +14,6 @@ LL | &mut *(ptr as *mut dyn Fn()) = note: wrap the `()` in a closure with no arguments: `|| { /* code */ }` = note: required for the cast to the object type `dyn Fn()` -error: aborting due to previous error +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/issues/issue-32709.stderr b/src/test/ui/issues/issue-32709.stderr index bc7eb0688ee84..f9ff7a8618bd2 100644 --- a/src/test/ui/issues/issue-32709.stderr +++ b/src/test/ui/issues/issue-32709.stderr @@ -7,7 +7,7 @@ LL | Err(5)?; | ^ the trait `From<{integer}>` is not implemented for `()` | = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait - = note: required because of the requirements on the impl of `FromResidual>` for `Result` + = note: required because of the requirements on the impl of `FromResidual>` for `Result` note: required by `from_residual` --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL | diff --git a/src/test/ui/layout/debug.rs b/src/test/ui/layout/debug.rs index 299151df66493..7f39b2beef7d6 100644 --- a/src/test/ui/layout/debug.rs +++ b/src/test/ui/layout/debug.rs @@ -1,5 +1,5 @@ // normalize-stderr-test "pref: Align \{\n *pow2: [1-3],\n *\}" -> "pref: $$PREF_ALIGN" -#![feature(never_type, rustc_attrs, type_alias_impl_trait)] +#![feature(rustc_attrs, type_alias_impl_trait)] #![crate_type = "lib"] #[rustc_layout(debug)] diff --git a/src/test/ui/layout/hexagon-enum.rs b/src/test/ui/layout/hexagon-enum.rs index 4c58537e309ea..f3997177b374c 100644 --- a/src/test/ui/layout/hexagon-enum.rs +++ b/src/test/ui/layout/hexagon-enum.rs @@ -4,7 +4,7 @@ // Verify that the hexagon targets implement the repr(C) for enums correctly. // // See #82100 -#![feature(never_type, rustc_attrs, no_core, lang_items)] +#![feature(rustc_attrs, no_core, lang_items)] #![crate_type = "lib"] #![no_core] diff --git a/src/test/ui/lint/uninitialized-zeroed.rs b/src/test/ui/lint/uninitialized-zeroed.rs index 122933c3c4e46..3e9551fcc58e4 100644 --- a/src/test/ui/lint/uninitialized-zeroed.rs +++ b/src/test/ui/lint/uninitialized-zeroed.rs @@ -1,7 +1,7 @@ // This test checks that calling `mem::{uninitialized,zeroed}` with certain types results // in a lint. -#![feature(never_type, rustc_attrs)] +#![feature(rustc_attrs)] #![allow(deprecated)] #![deny(invalid_value)] diff --git a/src/test/ui/lint/unused/must_use-unit.rs b/src/test/ui/lint/unused/must_use-unit.rs index 4dd4798abb7ce..8f59bab26d3ef 100644 --- a/src/test/ui/lint/unused/must_use-unit.rs +++ b/src/test/ui/lint/unused/must_use-unit.rs @@ -1,4 +1,3 @@ -#![feature(never_type)] #![deny(unused_must_use)] #[must_use] diff --git a/src/test/ui/lint/unused/must_use-unit.stderr b/src/test/ui/lint/unused/must_use-unit.stderr index 7f25a19350862..50dbcb0a527fd 100644 --- a/src/test/ui/lint/unused/must_use-unit.stderr +++ b/src/test/ui/lint/unused/must_use-unit.stderr @@ -1,17 +1,17 @@ error: unused return value of `foo` that must be used - --> $DIR/must_use-unit.rs:13:5 + --> $DIR/must_use-unit.rs:12:5 | LL | foo(); | ^^^^^^ | note: the lint level is defined here - --> $DIR/must_use-unit.rs:2:9 + --> $DIR/must_use-unit.rs:1:9 | LL | #![deny(unused_must_use)] | ^^^^^^^^^^^^^^^ error: unused return value of `bar` that must be used - --> $DIR/must_use-unit.rs:15:5 + --> $DIR/must_use-unit.rs:14:5 | LL | bar(); | ^^^^^^ diff --git a/src/test/ui/loops/loop-break-value.rs b/src/test/ui/loops/loop-break-value.rs index 51c9a36a03956..4102280f33cfc 100644 --- a/src/test/ui/loops/loop-break-value.rs +++ b/src/test/ui/loops/loop-break-value.rs @@ -1,5 +1,3 @@ -#![feature(never_type)] - fn main() { let val: ! = loop { break break; }; //~^ ERROR mismatched types diff --git a/src/test/ui/loops/loop-break-value.stderr b/src/test/ui/loops/loop-break-value.stderr index ccb27c3507076..ff9a90964a6e6 100644 --- a/src/test/ui/loops/loop-break-value.stderr +++ b/src/test/ui/loops/loop-break-value.stderr @@ -1,5 +1,5 @@ error[E0425]: cannot find value `LOOP` in this scope - --> $DIR/loop-break-value.rs:95:15 + --> $DIR/loop-break-value.rs:93:15 | LL | 'LOOP: for _ in 0 .. 9 { | ----- a label with a similar name exists @@ -10,7 +10,7 @@ LL | break LOOP; | help: use the similarly named label: `'LOOP` warning: denote infinite loops with `loop { ... }` - --> $DIR/loop-break-value.rs:26:5 + --> $DIR/loop-break-value.rs:24:5 | LL | 'while_loop: while true { | ^^^^^^^^^^^^^^^^^^^^^^^ help: use `loop` @@ -18,7 +18,7 @@ LL | 'while_loop: while true { = note: `#[warn(while_true)]` on by default error[E0571]: `break` with value from a `while` loop - --> $DIR/loop-break-value.rs:28:9 + --> $DIR/loop-break-value.rs:26:9 | LL | 'while_loop: while true { | ----------------------- you can't `break` with a value in a `while` loop @@ -36,7 +36,7 @@ LL | break 'while_loop; | ~~~~~~~~~~~ error[E0571]: `break` with value from a `while` loop - --> $DIR/loop-break-value.rs:30:13 + --> $DIR/loop-break-value.rs:28:13 | LL | 'while_loop: while true { | ----------------------- you can't `break` with a value in a `while` loop @@ -50,7 +50,7 @@ LL | break 'while_loop; | ~~~~~~~~~~~~~~~~~ error[E0571]: `break` with value from a `while` loop - --> $DIR/loop-break-value.rs:38:12 + --> $DIR/loop-break-value.rs:36:12 | LL | while let Some(_) = Some(()) { | ---------------------------- you can't `break` with a value in a `while` loop @@ -63,7 +63,7 @@ LL | if break { | ~~~~~ error[E0571]: `break` with value from a `while` loop - --> $DIR/loop-break-value.rs:43:9 + --> $DIR/loop-break-value.rs:41:9 | LL | while let Some(_) = Some(()) { | ---------------------------- you can't `break` with a value in a `while` loop @@ -76,7 +76,7 @@ LL | break; | ~~~~~ error[E0571]: `break` with value from a `while` loop - --> $DIR/loop-break-value.rs:49:13 + --> $DIR/loop-break-value.rs:47:13 | LL | 'while_let_loop: while let Some(_) = Some(()) { | --------------------------------------------- you can't `break` with a value in a `while` loop @@ -90,7 +90,7 @@ LL | break 'while_let_loop; | ~~~~~~~~~~~~~~~~~~~~~ error[E0571]: `break` with value from a `for` loop - --> $DIR/loop-break-value.rs:56:9 + --> $DIR/loop-break-value.rs:54:9 | LL | for _ in &[1,2,3] { | ----------------- you can't `break` with a value in a `for` loop @@ -103,7 +103,7 @@ LL | break; | ~~~~~ error[E0571]: `break` with value from a `for` loop - --> $DIR/loop-break-value.rs:57:9 + --> $DIR/loop-break-value.rs:55:9 | LL | for _ in &[1,2,3] { | ----------------- you can't `break` with a value in a `for` loop @@ -117,7 +117,7 @@ LL | break; | ~~~~~ error[E0571]: `break` with value from a `for` loop - --> $DIR/loop-break-value.rs:64:13 + --> $DIR/loop-break-value.rs:62:13 | LL | 'for_loop: for _ in &[1,2,3] { | ---------------------------- you can't `break` with a value in a `for` loop @@ -131,7 +131,7 @@ LL | break 'for_loop; | ~~~~~~~~~~~~~~~ error[E0308]: mismatched types - --> $DIR/loop-break-value.rs:4:31 + --> $DIR/loop-break-value.rs:2:31 | LL | let val: ! = loop { break break; }; | ^^^^^ expected `!`, found `()` @@ -140,31 +140,31 @@ LL | let val: ! = loop { break break; }; found unit type `()` error[E0308]: mismatched types - --> $DIR/loop-break-value.rs:11:19 + --> $DIR/loop-break-value.rs:9:19 | LL | break 123; | ^^^ expected `&str`, found integer error[E0308]: mismatched types - --> $DIR/loop-break-value.rs:16:15 + --> $DIR/loop-break-value.rs:14:15 | LL | break "asdf"; | ^^^^^^ expected `i32`, found `&str` error[E0308]: mismatched types - --> $DIR/loop-break-value.rs:21:31 + --> $DIR/loop-break-value.rs:19:31 | LL | break 'outer_loop "nope"; | ^^^^^^ expected `i32`, found `&str` error[E0308]: mismatched types - --> $DIR/loop-break-value.rs:73:26 + --> $DIR/loop-break-value.rs:71:26 | LL | break 'c 123; | ^^^ expected `()`, found integer error[E0308]: mismatched types - --> $DIR/loop-break-value.rs:80:15 + --> $DIR/loop-break-value.rs:78:15 | LL | break (break, break); | ^^^^^^^^^^^^^^ expected `()`, found tuple @@ -173,13 +173,13 @@ LL | break (break, break); found tuple `(!, !)` error[E0308]: mismatched types - --> $DIR/loop-break-value.rs:85:15 + --> $DIR/loop-break-value.rs:83:15 | LL | break 2; | ^ expected `()`, found integer error[E0308]: mismatched types - --> $DIR/loop-break-value.rs:90:9 + --> $DIR/loop-break-value.rs:88:9 | LL | break; | ^^^^^ diff --git a/src/test/ui/mir/mir_calls_to_shims.rs b/src/test/ui/mir/mir_calls_to_shims.rs index 6f13d5612ce51..df7c45ad1d1c7 100644 --- a/src/test/ui/mir/mir_calls_to_shims.rs +++ b/src/test/ui/mir/mir_calls_to_shims.rs @@ -2,7 +2,6 @@ // ignore-wasm32-bare compiled with panic=abort by default #![feature(fn_traits)] -#![feature(never_type)] use std::panic; diff --git a/src/test/ui/never_type/adjust_never.rs b/src/test/ui/never_type/adjust_never.rs index 0d7d2c0ed3fa9..3833322d55a74 100644 --- a/src/test/ui/never_type/adjust_never.rs +++ b/src/test/ui/never_type/adjust_never.rs @@ -2,7 +2,7 @@ // check-pass -#![feature(never_type)] + fn main() { let x: ! = panic!(); diff --git a/src/test/ui/never_type/auto-traits.rs b/src/test/ui/never_type/auto-traits.rs index 42ede708e66df..d6c3a13d6ae40 100644 --- a/src/test/ui/never_type/auto-traits.rs +++ b/src/test/ui/never_type/auto-traits.rs @@ -2,7 +2,7 @@ #![feature(auto_traits)] #![feature(negative_impls)] -#![feature(never_type)] + fn main() { enum Void {} diff --git a/src/test/ui/never_type/call-fn-never-arg-wrong-type.rs b/src/test/ui/never_type/call-fn-never-arg-wrong-type.rs index d06637e74a2f2..cd3686c95be60 100644 --- a/src/test/ui/never_type/call-fn-never-arg-wrong-type.rs +++ b/src/test/ui/never_type/call-fn-never-arg-wrong-type.rs @@ -1,6 +1,6 @@ // Test that we can't pass other types for ! -#![feature(never_type)] + fn foo(x: !) -> ! { x diff --git a/src/test/ui/never_type/call-fn-never-arg.rs b/src/test/ui/never_type/call-fn-never-arg.rs index 9d355817ee80d..9ae9962378758 100644 --- a/src/test/ui/never_type/call-fn-never-arg.rs +++ b/src/test/ui/never_type/call-fn-never-arg.rs @@ -2,7 +2,7 @@ // check-pass -#![feature(never_type)] + #![allow(unreachable_code)] fn foo(x: !) -> ! { diff --git a/src/test/ui/never_type/cast-never.rs b/src/test/ui/never_type/cast-never.rs index 0139ebe4640be..db6971e8bec39 100644 --- a/src/test/ui/never_type/cast-never.rs +++ b/src/test/ui/never_type/cast-never.rs @@ -2,7 +2,7 @@ // check-pass -#![feature(never_type)] + fn main() { let x: ! = panic!(); diff --git a/src/test/ui/never_type/defaulted-never-note.rs b/src/test/ui/never_type/defaulted-never-note.rs index 70333c5f324f7..f66c5c1210576 100644 --- a/src/test/ui/never_type/defaulted-never-note.rs +++ b/src/test/ui/never_type/defaulted-never-note.rs @@ -1,6 +1,6 @@ // We need to opt into the `never_type_fallback` feature // to trigger the requirement that this is testing. -#![feature(never_type, never_type_fallback)] +#![feature(never_type_fallback)] #![allow(unused)] diff --git a/src/test/ui/never_type/dispatch_from_dyn_zst.rs b/src/test/ui/never_type/dispatch_from_dyn_zst.rs index 764f58ce9e805..342d5e4791515 100644 --- a/src/test/ui/never_type/dispatch_from_dyn_zst.rs +++ b/src/test/ui/never_type/dispatch_from_dyn_zst.rs @@ -1,6 +1,6 @@ // run-pass -#![feature(unsize, dispatch_from_dyn, never_type)] +#![feature(unsize, dispatch_from_dyn)] #![allow(dead_code)] 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 ea4881049d792..a0a90d6a53b8e 100644 --- a/src/test/ui/never_type/diverging-fallback-control-flow.rs +++ b/src/test/ui/never_type/diverging-fallback-control-flow.rs @@ -4,27 +4,24 @@ #![allow(unused_assignments)] #![allow(unused_variables)] #![allow(unreachable_code)] - // Test various cases where we permit an unconstrained variable -// to fallback based on control-flow. +// to fallback based on control-flow. In all of these cases, +// the type variable winds up being the target of both a `!` coercion +// and a coercion from a non-`!` variable, and hence falls back to `()`. // -// These represent current behavior, but are pretty dubious. I would -// like to revisit these and potentially change them. --nmatsakis - -#![feature(never_type, never_type_fallback)] -trait BadDefault { +trait UnitDefault { fn default() -> Self; } -impl BadDefault for u32 { +impl UnitDefault for u32 { fn default() -> Self { 0 } } -impl BadDefault for ! { - fn default() -> ! { +impl UnitDefault for () { + fn default() -> () { panic!() } } @@ -33,7 +30,7 @@ fn assignment() { let x; if true { - x = BadDefault::default(); + x = UnitDefault::default(); } else { x = return; } @@ -45,13 +42,13 @@ fn assignment_rev() { if true { x = return; } else { - x = BadDefault::default(); + x = UnitDefault::default(); } } fn if_then_else() { let _x = if true { - BadDefault::default() + UnitDefault::default() } else { return; }; @@ -61,19 +58,19 @@ fn if_then_else_rev() { let _x = if true { return; } else { - BadDefault::default() + UnitDefault::default() }; } fn match_arm() { - let _x = match Ok(BadDefault::default()) { + let _x = match Ok(UnitDefault::default()) { Ok(v) => v, Err(()) => return, }; } fn match_arm_rev() { - let _x = match Ok(BadDefault::default()) { + let _x = match Ok(UnitDefault::default()) { Err(()) => return, Ok(v) => v, }; @@ -84,7 +81,7 @@ fn loop_break() { if false { break return; } else { - break BadDefault::default(); + break UnitDefault::default(); } }; } @@ -94,9 +91,9 @@ fn loop_break_rev() { if false { break return; } else { - break BadDefault::default(); + break UnitDefault::default(); } }; } -fn main() { } +fn main() {} diff --git a/src/test/ui/never_type/diverging-fallback-no-leak.rs b/src/test/ui/never_type/diverging-fallback-no-leak.rs new file mode 100644 index 0000000000000..ffcc81e0ff90e --- /dev/null +++ b/src/test/ui/never_type/diverging-fallback-no-leak.rs @@ -0,0 +1,13 @@ +fn make_unit() {} + +trait Test {} +impl Test for i32 {} +impl Test for () {} + +fn unconstrained_arg(_: T) {} + +fn main() { + // Here the type variable falls back to `!`, + // and hence we get a type error: + unconstrained_arg(return); //~ ERROR trait bound `!: Test` is not satisfied +} diff --git a/src/test/ui/never_type/diverging-fallback-no-leak.stderr b/src/test/ui/never_type/diverging-fallback-no-leak.stderr new file mode 100644 index 0000000000000..e69ef492e8d4b --- /dev/null +++ b/src/test/ui/never_type/diverging-fallback-no-leak.stderr @@ -0,0 +1,18 @@ +error[E0277]: the trait bound `!: Test` is not satisfied + --> $DIR/diverging-fallback-no-leak.rs:12:5 + | +LL | unconstrained_arg(return); + | ^^^^^^^^^^^^^^^^^ the trait `Test` is not implemented for `!` + | + = note: this trait is implemented for `()`. + = note: this error might have been caused by changes to Rust's type-inference algorithm (see issue #48950 for more information). + = help: did you intend to use the type `()` here instead? +note: required by a bound in `unconstrained_arg` + --> $DIR/diverging-fallback-no-leak.rs:7:25 + | +LL | fn unconstrained_arg(_: T) {} + | ^^^^ required by this bound in `unconstrained_arg` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/never_type/diverging-fallback-unconstrained-return.rs b/src/test/ui/never_type/diverging-fallback-unconstrained-return.rs new file mode 100644 index 0000000000000..2a85062bacfde --- /dev/null +++ b/src/test/ui/never_type/diverging-fallback-unconstrained-return.rs @@ -0,0 +1,34 @@ +// Variant of diverging-falllback-control-flow that tests +// the specific case of a free function with an unconstrained +// return type. This captures the pattern we saw in the wild +// in the objc crate, where changing the fallback from `!` to `()` +// resulted in unsoundness. +// +// check-pass + + + +fn make_unit() {} + +trait UnitReturn {} +impl UnitReturn for i32 {} +impl UnitReturn for () {} + +fn unconstrained_return() -> T { + unsafe { + let make_unit_fn: fn() = make_unit; + let ffi: fn() -> T = std::mem::transmute(make_unit_fn); + ffi() + } +} + +fn main() { + // In Ye Olde Days, the `T` parameter of `unconstrained_return` + // winds up "entangled" with the `!` type that results from + // `panic!`, and hence falls back to `()`. This is kind of unfortunate + // and unexpected. When we introduced the `!` type, the original + // idea was to change that fallback to `!`, but that would have resulted + // in this code no longer compiling (or worse, in some cases it injected + // unsound results). + let _ = if true { unconstrained_return() } else { panic!() }; +} diff --git a/src/test/ui/never_type/fallback-closure-wrap.rs b/src/test/ui/never_type/fallback-closure-wrap.rs new file mode 100644 index 0000000000000..3c6dac83fb990 --- /dev/null +++ b/src/test/ui/never_type/fallback-closure-wrap.rs @@ -0,0 +1,17 @@ +// check-pass + +use std::marker::PhantomData; + +fn main() { + let error = Closure::wrap(Box::new(move || { + panic!("Can't connect to server."); + }) as Box); +} + +struct Closure(PhantomData); + +impl Closure { + fn wrap(data: Box) -> Closure { + todo!() + } +} diff --git a/src/test/ui/never_type/fallback-future.rs b/src/test/ui/never_type/fallback-future.rs new file mode 100644 index 0000000000000..86d0cb7985e5b --- /dev/null +++ b/src/test/ui/never_type/fallback-future.rs @@ -0,0 +1,22 @@ +// check-pass +// edition:2018 + +use std::future::Future; + +fn foo() { + let ticker = loopify(async move { loop {} }); + + match ticker { + Ok(v) => v, + Err(()) => return, + }; +} + +fn loopify(_: F) -> Result +where + F: Future, +{ + loop {} +} + +fn main() {} diff --git a/src/test/ui/never_type/fallback-trait-bound.rs b/src/test/ui/never_type/fallback-trait-bound.rs new file mode 100644 index 0000000000000..30abd12360010 --- /dev/null +++ b/src/test/ui/never_type/fallback-trait-bound.rs @@ -0,0 +1,20 @@ +// check-pass + +trait Bar {} + +impl Bar for () {} +impl Bar for u32 {} + +fn takes_closure_ret(f: F) +where + F: FnOnce() -> R, + R: Bar, +{ +} + +fn main() { + takes_closure_ret(|| ()); + // This would normally fallback to ! without v2 fallback algorithm, + // and then fail because !: Bar is not satisfied. + takes_closure_ret(|| panic!()); +} 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 deleted file mode 100644 index 3b896ec9d70c2..0000000000000 --- a/src/test/ui/never_type/feature-gate-never_type_fallback.rs +++ /dev/null @@ -1,12 +0,0 @@ -// 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 deleted file mode 100644 index 670f76867ce45..0000000000000 --- a/src/test/ui/never_type/feature-gate-never_type_fallback.stderr +++ /dev/null @@ -1,9 +0,0 @@ -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 `()` - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/never_type/impl-for-never.rs b/src/test/ui/never_type/impl-for-never.rs index 9423f08858b9b..fb6d03a6bca27 100644 --- a/src/test/ui/never_type/impl-for-never.rs +++ b/src/test/ui/never_type/impl-for-never.rs @@ -1,6 +1,6 @@ // run-pass -#![feature(never_type)] + // Test that we can call static methods on ! both directly and when it appears in a generic diff --git a/src/test/ui/never_type/issue-13352.stderr b/src/test/ui/never_type/issue-13352.stderr index b98f6c93923b9..7a05489efd97d 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:7:13 | LL | 2_usize + (loop {}); - | ^ no implementation for `usize + ()` + | ^ no implementation for `usize + !` | - = help: the trait `Add<()>` is not implemented for `usize` + = help: the trait `Add` is not implemented for `usize` error: aborting due to previous error diff --git a/src/test/ui/never_type/issue-44402.rs b/src/test/ui/never_type/issue-44402.rs index 699e480dfe7e5..ed21c1cde647a 100644 --- a/src/test/ui/never_type/issue-44402.rs +++ b/src/test/ui/never_type/issue-44402.rs @@ -1,7 +1,7 @@ // check-pass #![allow(dead_code)] -#![feature(never_type)] + #![feature(exhaustive_patterns)] // Regression test for inhabitedness check. The old diff --git a/src/test/ui/never_type/issue-51506.rs b/src/test/ui/never_type/issue-51506.rs index d0fe6a0f59a87..acb042fb92be4 100644 --- a/src/test/ui/never_type/issue-51506.rs +++ b/src/test/ui/never_type/issue-51506.rs @@ -1,4 +1,4 @@ -#![feature(never_type, specialization)] +#![feature(specialization)] #![allow(incomplete_features)] use std::iter::{self, Empty}; diff --git a/src/test/ui/never_type/never-assign-dead-code.rs b/src/test/ui/never_type/never-assign-dead-code.rs index 7bb7c87097c50..6082839363cf3 100644 --- a/src/test/ui/never_type/never-assign-dead-code.rs +++ b/src/test/ui/never_type/never-assign-dead-code.rs @@ -2,7 +2,7 @@ // check-pass -#![feature(never_type)] + #![warn(unused)] fn main() { diff --git a/src/test/ui/never_type/never-assign-wrong-type.rs b/src/test/ui/never_type/never-assign-wrong-type.rs index 67e26f5663f41..0856fc674db4e 100644 --- a/src/test/ui/never_type/never-assign-wrong-type.rs +++ b/src/test/ui/never_type/never-assign-wrong-type.rs @@ -1,6 +1,6 @@ // Test that we can't use another type in place of ! -#![feature(never_type)] + #![deny(warnings)] fn main() { diff --git a/src/test/ui/never_type/never-associated-type.rs b/src/test/ui/never_type/never-associated-type.rs index 3bb917c931635..e3a269fcee266 100644 --- a/src/test/ui/never_type/never-associated-type.rs +++ b/src/test/ui/never_type/never-associated-type.rs @@ -2,7 +2,7 @@ // check-pass -#![feature(never_type)] + trait Foo { type Wow; diff --git a/src/test/ui/never_type/never-from-impl-is-reserved.rs b/src/test/ui/never_type/never-from-impl-is-reserved.rs index 9d16015bdc129..11d307d17a002 100644 --- a/src/test/ui/never_type/never-from-impl-is-reserved.rs +++ b/src/test/ui/never_type/never-from-impl-is-reserved.rs @@ -1,6 +1,6 @@ // check that the `for T: From` impl is reserved -#![feature(never_type)] + pub struct MyFoo; pub trait MyTrait {} diff --git a/src/test/ui/never_type/never-result.rs b/src/test/ui/never_type/never-result.rs index 35af37910ef3e..0627453c618f8 100644 --- a/src/test/ui/never_type/never-result.rs +++ b/src/test/ui/never_type/never-result.rs @@ -5,7 +5,7 @@ // Test that we can extract a ! through pattern matching then use it as several different types. -#![feature(never_type)] + fn main() { let x: Result = Ok(123); diff --git a/src/test/ui/never_type/never-type-arg.rs b/src/test/ui/never_type/never-type-arg.rs index 13cd59e6aa9f1..7ab1eee1acaff 100644 --- a/src/test/ui/never_type/never-type-arg.rs +++ b/src/test/ui/never_type/never-type-arg.rs @@ -2,7 +2,7 @@ // check-pass -#![feature(never_type)] + struct Wub; diff --git a/src/test/ui/never_type/never-type-rvalues.rs b/src/test/ui/never_type/never-type-rvalues.rs index 9ccc73dbf92d4..78818c347c3aa 100644 --- a/src/test/ui/never_type/never-type-rvalues.rs +++ b/src/test/ui/never_type/never-type-rvalues.rs @@ -1,6 +1,6 @@ // run-pass -#![feature(never_type)] + #![allow(dead_code)] #![allow(path_statements)] #![allow(unreachable_patterns)] diff --git a/src/test/ui/never_type/never-value-fallback-issue-66757.rs b/src/test/ui/never_type/never-value-fallback-issue-66757.rs index f2e9e087307db..89444e63c815c 100644 --- a/src/test/ui/never_type/never-value-fallback-issue-66757.rs +++ b/src/test/ui/never_type/never-value-fallback-issue-66757.rs @@ -6,11 +6,6 @@ // // run-pass -#![feature(never_type)] - -// FIXME(#67225) -- this should be true even without the fallback gate. -#![feature(never_type_fallback)] - struct E; impl From for E { diff --git a/src/test/ui/never_type/never_transmute_never.rs b/src/test/ui/never_type/never_transmute_never.rs index fce3ced9aac7f..8e1324389d7ab 100644 --- a/src/test/ui/never_type/never_transmute_never.rs +++ b/src/test/ui/never_type/never_transmute_never.rs @@ -2,7 +2,7 @@ #![crate_type="lib"] -#![feature(never_type)] + #![allow(dead_code)] #![allow(unreachable_code)] #![allow(unused_variables)] diff --git a/src/test/ui/never_type/try_from.rs b/src/test/ui/never_type/try_from.rs index 50451576f9c97..2af567a3da947 100644 --- a/src/test/ui/never_type/try_from.rs +++ b/src/test/ui/never_type/try_from.rs @@ -5,7 +5,7 @@ // This test was added to show the motivation for doing this // over `TryFrom` being blanket impl for all `T: From` -#![feature(never_type)] + use std::convert::{TryInto, Infallible}; diff --git a/src/test/ui/pattern/usefulness/always-inhabited-union-ref.rs b/src/test/ui/pattern/usefulness/always-inhabited-union-ref.rs index 7d1cac8a442f5..56f4f7ea348e3 100644 --- a/src/test/ui/pattern/usefulness/always-inhabited-union-ref.rs +++ b/src/test/ui/pattern/usefulness/always-inhabited-union-ref.rs @@ -2,7 +2,7 @@ // undecided. This test file currently checks a conservative choice. #![feature(exhaustive_patterns)] -#![feature(never_type)] + #![allow(dead_code)] #![allow(unreachable_code)] diff --git a/src/test/ui/pattern/usefulness/empty-match.exhaustive_patterns.stderr b/src/test/ui/pattern/usefulness/empty-match.exhaustive_patterns.stderr index b99386e74020e..5b4836a4d74b7 100644 --- a/src/test/ui/pattern/usefulness/empty-match.exhaustive_patterns.stderr +++ b/src/test/ui/pattern/usefulness/empty-match.exhaustive_patterns.stderr @@ -1,47 +1,47 @@ error: unreachable pattern - --> $DIR/empty-match.rs:37:9 + --> $DIR/empty-match.rs:36:9 | LL | _ => {}, | ^ | note: the lint level is defined here - --> $DIR/empty-match.rs:8:9 + --> $DIR/empty-match.rs:7:9 | LL | #![deny(unreachable_patterns)] | ^^^^^^^^^^^^^^^^^^^^ error: unreachable pattern - --> $DIR/empty-match.rs:40:9 + --> $DIR/empty-match.rs:39:9 | LL | _ if false => {}, | ^ error: unreachable pattern - --> $DIR/empty-match.rs:47:9 + --> $DIR/empty-match.rs:46:9 | LL | _ => {}, | ^ error: unreachable pattern - --> $DIR/empty-match.rs:50:9 + --> $DIR/empty-match.rs:49:9 | LL | _ if false => {}, | ^ error: unreachable pattern - --> $DIR/empty-match.rs:57:9 + --> $DIR/empty-match.rs:56:9 | LL | _ => {}, | ^ error: unreachable pattern - --> $DIR/empty-match.rs:60:9 + --> $DIR/empty-match.rs:59:9 | LL | _ if false => {}, | ^ error[E0004]: non-exhaustive patterns: type `u8` is non-empty - --> $DIR/empty-match.rs:78:20 + --> $DIR/empty-match.rs:77:20 | LL | match_no_arms!(0u8); | ^^^ @@ -50,7 +50,7 @@ LL | match_no_arms!(0u8); = note: the matched value is of type `u8` error[E0004]: non-exhaustive patterns: type `NonEmptyStruct1` is non-empty - --> $DIR/empty-match.rs:79:20 + --> $DIR/empty-match.rs:78:20 | LL | struct NonEmptyStruct1; | ----------------------- `NonEmptyStruct1` defined here @@ -62,7 +62,7 @@ LL | match_no_arms!(NonEmptyStruct1); = note: the matched value is of type `NonEmptyStruct1` error[E0004]: non-exhaustive patterns: type `NonEmptyStruct2` is non-empty - --> $DIR/empty-match.rs:80:20 + --> $DIR/empty-match.rs:79:20 | LL | struct NonEmptyStruct2(bool); | ----------------------------- `NonEmptyStruct2` defined here @@ -74,7 +74,7 @@ LL | match_no_arms!(NonEmptyStruct2(true)); = note: the matched value is of type `NonEmptyStruct2` error[E0004]: non-exhaustive patterns: type `NonEmptyUnion1` is non-empty - --> $DIR/empty-match.rs:81:20 + --> $DIR/empty-match.rs:80:20 | LL | / union NonEmptyUnion1 { LL | | foo: (), @@ -88,7 +88,7 @@ LL | match_no_arms!((NonEmptyUnion1 { foo: () })); = note: the matched value is of type `NonEmptyUnion1` error[E0004]: non-exhaustive patterns: type `NonEmptyUnion2` is non-empty - --> $DIR/empty-match.rs:82:20 + --> $DIR/empty-match.rs:81:20 | LL | / union NonEmptyUnion2 { LL | | foo: (), @@ -103,7 +103,7 @@ LL | match_no_arms!((NonEmptyUnion2 { foo: () })); = note: the matched value is of type `NonEmptyUnion2` error[E0004]: non-exhaustive patterns: `Foo(_)` not covered - --> $DIR/empty-match.rs:83:20 + --> $DIR/empty-match.rs:82:20 | LL | / enum NonEmptyEnum1 { LL | | Foo(bool), @@ -118,7 +118,7 @@ LL | match_no_arms!(NonEmptyEnum1::Foo(true)); = note: the matched value is of type `NonEmptyEnum1` error[E0004]: non-exhaustive patterns: `Foo(_)` and `Bar` not covered - --> $DIR/empty-match.rs:84:20 + --> $DIR/empty-match.rs:83:20 | LL | / enum NonEmptyEnum2 { LL | | Foo(bool), @@ -135,7 +135,7 @@ LL | match_no_arms!(NonEmptyEnum2::Foo(true)); = note: the matched value is of type `NonEmptyEnum2` error[E0004]: non-exhaustive patterns: `V1`, `V2`, `V3` and 2 more not covered - --> $DIR/empty-match.rs:85:20 + --> $DIR/empty-match.rs:84:20 | LL | / enum NonEmptyEnum5 { LL | | V1, V2, V3, V4, V5, @@ -149,7 +149,7 @@ LL | match_no_arms!(NonEmptyEnum5::V1); = note: the matched value is of type `NonEmptyEnum5` error[E0004]: non-exhaustive patterns: `_` not covered - --> $DIR/empty-match.rs:87:24 + --> $DIR/empty-match.rs:86:24 | LL | match_guarded_arm!(0u8); | ^^^ pattern `_` not covered @@ -158,7 +158,7 @@ LL | match_guarded_arm!(0u8); = note: the matched value is of type `u8` error[E0004]: non-exhaustive patterns: `NonEmptyStruct1` not covered - --> $DIR/empty-match.rs:88:24 + --> $DIR/empty-match.rs:87:24 | LL | struct NonEmptyStruct1; | ----------------------- `NonEmptyStruct1` defined here @@ -170,7 +170,7 @@ LL | match_guarded_arm!(NonEmptyStruct1); = note: the matched value is of type `NonEmptyStruct1` error[E0004]: non-exhaustive patterns: `NonEmptyStruct2(_)` not covered - --> $DIR/empty-match.rs:89:24 + --> $DIR/empty-match.rs:88:24 | LL | struct NonEmptyStruct2(bool); | ----------------------------- `NonEmptyStruct2` defined here @@ -182,7 +182,7 @@ LL | match_guarded_arm!(NonEmptyStruct2(true)); = note: the matched value is of type `NonEmptyStruct2` error[E0004]: non-exhaustive patterns: `NonEmptyUnion1 { .. }` not covered - --> $DIR/empty-match.rs:90:24 + --> $DIR/empty-match.rs:89:24 | LL | / union NonEmptyUnion1 { LL | | foo: (), @@ -196,7 +196,7 @@ LL | match_guarded_arm!((NonEmptyUnion1 { foo: () })); = note: the matched value is of type `NonEmptyUnion1` error[E0004]: non-exhaustive patterns: `NonEmptyUnion2 { .. }` not covered - --> $DIR/empty-match.rs:91:24 + --> $DIR/empty-match.rs:90:24 | LL | / union NonEmptyUnion2 { LL | | foo: (), @@ -211,7 +211,7 @@ LL | match_guarded_arm!((NonEmptyUnion2 { foo: () })); = note: the matched value is of type `NonEmptyUnion2` error[E0004]: non-exhaustive patterns: `Foo(_)` not covered - --> $DIR/empty-match.rs:92:24 + --> $DIR/empty-match.rs:91:24 | LL | / enum NonEmptyEnum1 { LL | | Foo(bool), @@ -226,7 +226,7 @@ LL | match_guarded_arm!(NonEmptyEnum1::Foo(true)); = note: the matched value is of type `NonEmptyEnum1` error[E0004]: non-exhaustive patterns: `Foo(_)` and `Bar` not covered - --> $DIR/empty-match.rs:93:24 + --> $DIR/empty-match.rs:92:24 | LL | / enum NonEmptyEnum2 { LL | | Foo(bool), @@ -243,7 +243,7 @@ LL | match_guarded_arm!(NonEmptyEnum2::Foo(true)); = note: the matched value is of type `NonEmptyEnum2` error[E0004]: non-exhaustive patterns: `V1`, `V2`, `V3` and 2 more not covered - --> $DIR/empty-match.rs:94:24 + --> $DIR/empty-match.rs:93:24 | LL | / enum NonEmptyEnum5 { LL | | V1, V2, V3, V4, V5, diff --git a/src/test/ui/pattern/usefulness/empty-match.normal.stderr b/src/test/ui/pattern/usefulness/empty-match.normal.stderr index b99386e74020e..5b4836a4d74b7 100644 --- a/src/test/ui/pattern/usefulness/empty-match.normal.stderr +++ b/src/test/ui/pattern/usefulness/empty-match.normal.stderr @@ -1,47 +1,47 @@ error: unreachable pattern - --> $DIR/empty-match.rs:37:9 + --> $DIR/empty-match.rs:36:9 | LL | _ => {}, | ^ | note: the lint level is defined here - --> $DIR/empty-match.rs:8:9 + --> $DIR/empty-match.rs:7:9 | LL | #![deny(unreachable_patterns)] | ^^^^^^^^^^^^^^^^^^^^ error: unreachable pattern - --> $DIR/empty-match.rs:40:9 + --> $DIR/empty-match.rs:39:9 | LL | _ if false => {}, | ^ error: unreachable pattern - --> $DIR/empty-match.rs:47:9 + --> $DIR/empty-match.rs:46:9 | LL | _ => {}, | ^ error: unreachable pattern - --> $DIR/empty-match.rs:50:9 + --> $DIR/empty-match.rs:49:9 | LL | _ if false => {}, | ^ error: unreachable pattern - --> $DIR/empty-match.rs:57:9 + --> $DIR/empty-match.rs:56:9 | LL | _ => {}, | ^ error: unreachable pattern - --> $DIR/empty-match.rs:60:9 + --> $DIR/empty-match.rs:59:9 | LL | _ if false => {}, | ^ error[E0004]: non-exhaustive patterns: type `u8` is non-empty - --> $DIR/empty-match.rs:78:20 + --> $DIR/empty-match.rs:77:20 | LL | match_no_arms!(0u8); | ^^^ @@ -50,7 +50,7 @@ LL | match_no_arms!(0u8); = note: the matched value is of type `u8` error[E0004]: non-exhaustive patterns: type `NonEmptyStruct1` is non-empty - --> $DIR/empty-match.rs:79:20 + --> $DIR/empty-match.rs:78:20 | LL | struct NonEmptyStruct1; | ----------------------- `NonEmptyStruct1` defined here @@ -62,7 +62,7 @@ LL | match_no_arms!(NonEmptyStruct1); = note: the matched value is of type `NonEmptyStruct1` error[E0004]: non-exhaustive patterns: type `NonEmptyStruct2` is non-empty - --> $DIR/empty-match.rs:80:20 + --> $DIR/empty-match.rs:79:20 | LL | struct NonEmptyStruct2(bool); | ----------------------------- `NonEmptyStruct2` defined here @@ -74,7 +74,7 @@ LL | match_no_arms!(NonEmptyStruct2(true)); = note: the matched value is of type `NonEmptyStruct2` error[E0004]: non-exhaustive patterns: type `NonEmptyUnion1` is non-empty - --> $DIR/empty-match.rs:81:20 + --> $DIR/empty-match.rs:80:20 | LL | / union NonEmptyUnion1 { LL | | foo: (), @@ -88,7 +88,7 @@ LL | match_no_arms!((NonEmptyUnion1 { foo: () })); = note: the matched value is of type `NonEmptyUnion1` error[E0004]: non-exhaustive patterns: type `NonEmptyUnion2` is non-empty - --> $DIR/empty-match.rs:82:20 + --> $DIR/empty-match.rs:81:20 | LL | / union NonEmptyUnion2 { LL | | foo: (), @@ -103,7 +103,7 @@ LL | match_no_arms!((NonEmptyUnion2 { foo: () })); = note: the matched value is of type `NonEmptyUnion2` error[E0004]: non-exhaustive patterns: `Foo(_)` not covered - --> $DIR/empty-match.rs:83:20 + --> $DIR/empty-match.rs:82:20 | LL | / enum NonEmptyEnum1 { LL | | Foo(bool), @@ -118,7 +118,7 @@ LL | match_no_arms!(NonEmptyEnum1::Foo(true)); = note: the matched value is of type `NonEmptyEnum1` error[E0004]: non-exhaustive patterns: `Foo(_)` and `Bar` not covered - --> $DIR/empty-match.rs:84:20 + --> $DIR/empty-match.rs:83:20 | LL | / enum NonEmptyEnum2 { LL | | Foo(bool), @@ -135,7 +135,7 @@ LL | match_no_arms!(NonEmptyEnum2::Foo(true)); = note: the matched value is of type `NonEmptyEnum2` error[E0004]: non-exhaustive patterns: `V1`, `V2`, `V3` and 2 more not covered - --> $DIR/empty-match.rs:85:20 + --> $DIR/empty-match.rs:84:20 | LL | / enum NonEmptyEnum5 { LL | | V1, V2, V3, V4, V5, @@ -149,7 +149,7 @@ LL | match_no_arms!(NonEmptyEnum5::V1); = note: the matched value is of type `NonEmptyEnum5` error[E0004]: non-exhaustive patterns: `_` not covered - --> $DIR/empty-match.rs:87:24 + --> $DIR/empty-match.rs:86:24 | LL | match_guarded_arm!(0u8); | ^^^ pattern `_` not covered @@ -158,7 +158,7 @@ LL | match_guarded_arm!(0u8); = note: the matched value is of type `u8` error[E0004]: non-exhaustive patterns: `NonEmptyStruct1` not covered - --> $DIR/empty-match.rs:88:24 + --> $DIR/empty-match.rs:87:24 | LL | struct NonEmptyStruct1; | ----------------------- `NonEmptyStruct1` defined here @@ -170,7 +170,7 @@ LL | match_guarded_arm!(NonEmptyStruct1); = note: the matched value is of type `NonEmptyStruct1` error[E0004]: non-exhaustive patterns: `NonEmptyStruct2(_)` not covered - --> $DIR/empty-match.rs:89:24 + --> $DIR/empty-match.rs:88:24 | LL | struct NonEmptyStruct2(bool); | ----------------------------- `NonEmptyStruct2` defined here @@ -182,7 +182,7 @@ LL | match_guarded_arm!(NonEmptyStruct2(true)); = note: the matched value is of type `NonEmptyStruct2` error[E0004]: non-exhaustive patterns: `NonEmptyUnion1 { .. }` not covered - --> $DIR/empty-match.rs:90:24 + --> $DIR/empty-match.rs:89:24 | LL | / union NonEmptyUnion1 { LL | | foo: (), @@ -196,7 +196,7 @@ LL | match_guarded_arm!((NonEmptyUnion1 { foo: () })); = note: the matched value is of type `NonEmptyUnion1` error[E0004]: non-exhaustive patterns: `NonEmptyUnion2 { .. }` not covered - --> $DIR/empty-match.rs:91:24 + --> $DIR/empty-match.rs:90:24 | LL | / union NonEmptyUnion2 { LL | | foo: (), @@ -211,7 +211,7 @@ LL | match_guarded_arm!((NonEmptyUnion2 { foo: () })); = note: the matched value is of type `NonEmptyUnion2` error[E0004]: non-exhaustive patterns: `Foo(_)` not covered - --> $DIR/empty-match.rs:92:24 + --> $DIR/empty-match.rs:91:24 | LL | / enum NonEmptyEnum1 { LL | | Foo(bool), @@ -226,7 +226,7 @@ LL | match_guarded_arm!(NonEmptyEnum1::Foo(true)); = note: the matched value is of type `NonEmptyEnum1` error[E0004]: non-exhaustive patterns: `Foo(_)` and `Bar` not covered - --> $DIR/empty-match.rs:93:24 + --> $DIR/empty-match.rs:92:24 | LL | / enum NonEmptyEnum2 { LL | | Foo(bool), @@ -243,7 +243,7 @@ LL | match_guarded_arm!(NonEmptyEnum2::Foo(true)); = note: the matched value is of type `NonEmptyEnum2` error[E0004]: non-exhaustive patterns: `V1`, `V2`, `V3` and 2 more not covered - --> $DIR/empty-match.rs:94:24 + --> $DIR/empty-match.rs:93:24 | LL | / enum NonEmptyEnum5 { LL | | V1, V2, V3, V4, V5, diff --git a/src/test/ui/pattern/usefulness/empty-match.rs b/src/test/ui/pattern/usefulness/empty-match.rs index 8110ec013d7c1..b92d1e8692f63 100644 --- a/src/test/ui/pattern/usefulness/empty-match.rs +++ b/src/test/ui/pattern/usefulness/empty-match.rs @@ -2,7 +2,6 @@ // revisions: normal exhaustive_patterns // // This tests a match with no arms on various types. -#![feature(never_type)] #![feature(never_type_fallback)] #![cfg_attr(exhaustive_patterns, feature(exhaustive_patterns))] #![deny(unreachable_patterns)] diff --git a/src/test/ui/pattern/usefulness/match-privately-empty.rs b/src/test/ui/pattern/usefulness/match-privately-empty.rs index 315eb03d16564..520df830f0291 100644 --- a/src/test/ui/pattern/usefulness/match-privately-empty.rs +++ b/src/test/ui/pattern/usefulness/match-privately-empty.rs @@ -1,4 +1,3 @@ -#![feature(never_type)] #![feature(exhaustive_patterns)] mod private { @@ -11,11 +10,8 @@ mod private { fn main() { match private::DATA { - //~^ ERROR non-exhaustive patterns: `Some(Private { misc: true, .. })` not covered + //~^ ERROR non-exhaustive patterns: `Some(Private { misc: true, .. })` not covered None => {} - Some(private::Private { - misc: false, - .. - }) => {} + Some(private::Private { misc: false, .. }) => {} } } diff --git a/src/test/ui/pattern/usefulness/match-privately-empty.stderr b/src/test/ui/pattern/usefulness/match-privately-empty.stderr index 4efb41978a241..e9e233808650e 100644 --- a/src/test/ui/pattern/usefulness/match-privately-empty.stderr +++ b/src/test/ui/pattern/usefulness/match-privately-empty.stderr @@ -1,5 +1,5 @@ error[E0004]: non-exhaustive patterns: `Some(Private { misc: true, .. })` not covered - --> $DIR/match-privately-empty.rs:13:11 + --> $DIR/match-privately-empty.rs:12:11 | LL | match private::DATA { | ^^^^^^^^^^^^^ pattern `Some(Private { misc: true, .. })` not covered diff --git a/src/test/ui/pattern/usefulness/uninhabited.rs b/src/test/ui/pattern/usefulness/uninhabited.rs index 77cd0f4005e95..dae2f5dcdf220 100644 --- a/src/test/ui/pattern/usefulness/uninhabited.rs +++ b/src/test/ui/pattern/usefulness/uninhabited.rs @@ -3,8 +3,7 @@ // // This tests plays with matching and uninhabited types. This also serves as a test for the // `tcx.is_ty_uninhabited_from()` function. -#![feature(never_type)] -#![feature(never_type_fallback)] +// #![feature(exhaustive_patterns)] #![deny(unreachable_patterns)] diff --git a/src/test/ui/print_type_sizes/uninhabited.rs b/src/test/ui/print_type_sizes/uninhabited.rs index c234547bd14b1..5031e1decab0f 100644 --- a/src/test/ui/print_type_sizes/uninhabited.rs +++ b/src/test/ui/print_type_sizes/uninhabited.rs @@ -4,7 +4,7 @@ // ^-- needed because `--pass check` does not emit the output needed. // FIXME: consider using an attribute instead of side-effects. -#![feature(never_type)] + #![feature(start)] #[start] diff --git a/src/test/ui/process/process-panic-after-fork.rs b/src/test/ui/process/process-panic-after-fork.rs index ad749371beac0..985459189d66a 100644 --- a/src/test/ui/process/process-panic-after-fork.rs +++ b/src/test/ui/process/process-panic-after-fork.rs @@ -9,7 +9,6 @@ #![feature(bench_black_box)] #![feature(rustc_private)] -#![feature(never_type)] #![feature(panic_always_abort)] extern crate libc; diff --git a/src/test/ui/reachable/expr_add.rs b/src/test/ui/reachable/expr_add.rs index b45e5daf42c8d..640c2a2cf8fcc 100644 --- a/src/test/ui/reachable/expr_add.rs +++ b/src/test/ui/reachable/expr_add.rs @@ -1,4 +1,3 @@ -#![feature(never_type)] #![allow(unused_variables)] #![deny(unreachable_code)] diff --git a/src/test/ui/reachable/expr_add.stderr b/src/test/ui/reachable/expr_add.stderr index 692bd20f50940..90b5488c81a0e 100644 --- a/src/test/ui/reachable/expr_add.stderr +++ b/src/test/ui/reachable/expr_add.stderr @@ -1,5 +1,5 @@ error: unreachable expression - --> $DIR/expr_add.rs:17:13 + --> $DIR/expr_add.rs:16:13 | LL | let x = Foo + return; | ^^^^^^------ @@ -8,7 +8,7 @@ LL | let x = Foo + return; | unreachable expression | note: the lint level is defined here - --> $DIR/expr_add.rs:3:9 + --> $DIR/expr_add.rs:2:9 | LL | #![deny(unreachable_code)] | ^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/reachable/expr_assign.rs b/src/test/ui/reachable/expr_assign.rs index e547f75e2697b..3914fb32432ef 100644 --- a/src/test/ui/reachable/expr_assign.rs +++ b/src/test/ui/reachable/expr_assign.rs @@ -1,4 +1,3 @@ -#![feature(never_type)] #![allow(unused_variables)] #![allow(unused_assignments)] #![allow(dead_code)] diff --git a/src/test/ui/reachable/expr_assign.stderr b/src/test/ui/reachable/expr_assign.stderr index c51156b3f40cf..2b05cb2a2966c 100644 --- a/src/test/ui/reachable/expr_assign.stderr +++ b/src/test/ui/reachable/expr_assign.stderr @@ -1,5 +1,5 @@ error: unreachable expression - --> $DIR/expr_assign.rs:10:5 + --> $DIR/expr_assign.rs:9:5 | LL | x = return; | ^^^^------ @@ -8,13 +8,13 @@ LL | x = return; | unreachable expression | note: the lint level is defined here - --> $DIR/expr_assign.rs:5:9 + --> $DIR/expr_assign.rs:4:9 | LL | #![deny(unreachable_code)] | ^^^^^^^^^^^^^^^^ error: unreachable expression - --> $DIR/expr_assign.rs:20:14 + --> $DIR/expr_assign.rs:19:14 | LL | *p = return; | -- ^^^^^^ unreachable expression @@ -22,7 +22,7 @@ LL | *p = return; | any code following this expression is unreachable error: unreachable expression - --> $DIR/expr_assign.rs:26:15 + --> $DIR/expr_assign.rs:25:15 | LL | *{return; &mut i} = 22; | ------ ^^^^^^ unreachable expression diff --git a/src/test/ui/reachable/expr_call.rs b/src/test/ui/reachable/expr_call.rs index 1eaa96c3ce773..ce1a94e3c4a25 100644 --- a/src/test/ui/reachable/expr_call.rs +++ b/src/test/ui/reachable/expr_call.rs @@ -1,4 +1,3 @@ -#![feature(never_type)] #![allow(unused_variables)] #![allow(unused_assignments)] #![allow(dead_code)] diff --git a/src/test/ui/reachable/expr_call.stderr b/src/test/ui/reachable/expr_call.stderr index a5ad9a329f06e..2d7675bbadc40 100644 --- a/src/test/ui/reachable/expr_call.stderr +++ b/src/test/ui/reachable/expr_call.stderr @@ -1,5 +1,5 @@ error: unreachable expression - --> $DIR/expr_call.rs:13:17 + --> $DIR/expr_call.rs:12:17 | LL | foo(return, 22); | ------ ^^ unreachable expression @@ -7,13 +7,13 @@ LL | foo(return, 22); | any code following this expression is unreachable | note: the lint level is defined here - --> $DIR/expr_call.rs:5:9 + --> $DIR/expr_call.rs:4:9 | LL | #![deny(unreachable_code)] | ^^^^^^^^^^^^^^^^ error: unreachable call - --> $DIR/expr_call.rs:18:5 + --> $DIR/expr_call.rs:17:5 | LL | bar(return); | ^^^ ------ any code following this expression is unreachable diff --git a/src/test/ui/reachable/expr_cast.rs b/src/test/ui/reachable/expr_cast.rs index f53bcb97e6972..76a7306b9d9e0 100644 --- a/src/test/ui/reachable/expr_cast.rs +++ b/src/test/ui/reachable/expr_cast.rs @@ -2,7 +2,7 @@ #![allow(unused_assignments)] #![allow(dead_code)] #![deny(unreachable_code)] -#![feature(never_type, type_ascription)] +#![feature(type_ascription)] fn a() { // the cast is unreachable: diff --git a/src/test/ui/reachable/expr_method.rs b/src/test/ui/reachable/expr_method.rs index d917df05b3c3d..e74a7daec8828 100644 --- a/src/test/ui/reachable/expr_method.rs +++ b/src/test/ui/reachable/expr_method.rs @@ -1,4 +1,3 @@ -#![feature(never_type)] #![allow(unused_variables)] #![allow(unused_assignments)] #![allow(dead_code)] diff --git a/src/test/ui/reachable/expr_method.stderr b/src/test/ui/reachable/expr_method.stderr index 41c3b8a39060f..1bf797ec06307 100644 --- a/src/test/ui/reachable/expr_method.stderr +++ b/src/test/ui/reachable/expr_method.stderr @@ -1,5 +1,5 @@ error: unreachable expression - --> $DIR/expr_method.rs:16:21 + --> $DIR/expr_method.rs:15:21 | LL | Foo.foo(return, 22); | ------ ^^ unreachable expression @@ -7,13 +7,13 @@ LL | Foo.foo(return, 22); | any code following this expression is unreachable | note: the lint level is defined here - --> $DIR/expr_method.rs:5:9 + --> $DIR/expr_method.rs:4:9 | LL | #![deny(unreachable_code)] | ^^^^^^^^^^^^^^^^ error: unreachable call - --> $DIR/expr_method.rs:21:9 + --> $DIR/expr_method.rs:20:9 | LL | Foo.bar(return); | ^^^ ------ any code following this expression is unreachable diff --git a/src/test/ui/reachable/expr_type.rs b/src/test/ui/reachable/expr_type.rs index 8d32397b54248..ff647bda0e87e 100644 --- a/src/test/ui/reachable/expr_type.rs +++ b/src/test/ui/reachable/expr_type.rs @@ -2,7 +2,7 @@ #![allow(unused_assignments)] #![allow(dead_code)] #![deny(unreachable_code)] -#![feature(never_type, type_ascription)] +#![feature(type_ascription)] fn a() { // the cast is unreachable: diff --git a/src/test/ui/reachable/expr_unary.rs b/src/test/ui/reachable/expr_unary.rs index e229d22ebc798..6f221c360cb17 100644 --- a/src/test/ui/reachable/expr_unary.rs +++ b/src/test/ui/reachable/expr_unary.rs @@ -1,4 +1,3 @@ -#![feature(never_type)] #![allow(unused_variables)] #![allow(unused_assignments)] #![allow(dead_code)] diff --git a/src/test/ui/reachable/expr_unary.stderr b/src/test/ui/reachable/expr_unary.stderr index 063d841c25e39..5186252f945e6 100644 --- a/src/test/ui/reachable/expr_unary.stderr +++ b/src/test/ui/reachable/expr_unary.stderr @@ -1,11 +1,11 @@ error[E0600]: cannot apply unary operator `!` to type `!` - --> $DIR/expr_unary.rs:8:16 + --> $DIR/expr_unary.rs:7:16 | LL | let x: ! = ! { return; }; | ^^^^^^^^^^^^^ cannot apply unary operator `!` error: unreachable expression - --> $DIR/expr_unary.rs:8:16 + --> $DIR/expr_unary.rs:7:16 | LL | let x: ! = ! { return; }; | ^^^^------^^^ @@ -14,7 +14,7 @@ LL | let x: ! = ! { return; }; | unreachable expression | note: the lint level is defined here - --> $DIR/expr_unary.rs:5:9 + --> $DIR/expr_unary.rs:4:9 | LL | #![deny(unreachable_code)] | ^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/reachable/unreachable-loop-patterns.rs b/src/test/ui/reachable/unreachable-loop-patterns.rs index 4de29c3c3d761..c8ff56539116f 100644 --- a/src/test/ui/reachable/unreachable-loop-patterns.rs +++ b/src/test/ui/reachable/unreachable-loop-patterns.rs @@ -1,4 +1,4 @@ -#![feature(never_type, never_type_fallback)] +#![feature(never_type_fallback)] #![feature(exhaustive_patterns)] #![allow(unreachable_code)] diff --git a/src/test/ui/reachable/unreachable-try-pattern.rs b/src/test/ui/reachable/unreachable-try-pattern.rs index 23360e73f4a3a..e2d89e93a2aa0 100644 --- a/src/test/ui/reachable/unreachable-try-pattern.rs +++ b/src/test/ui/reachable/unreachable-try-pattern.rs @@ -1,5 +1,5 @@ // check-pass -#![feature(never_type, exhaustive_patterns)] +#![feature(exhaustive_patterns)] #![warn(unreachable_code)] #![warn(unreachable_patterns)] diff --git a/src/test/ui/reachable/unwarned-match-on-never.rs b/src/test/ui/reachable/unwarned-match-on-never.rs index 71f8fe3a783e2..639d60ae0ebf8 100644 --- a/src/test/ui/reachable/unwarned-match-on-never.rs +++ b/src/test/ui/reachable/unwarned-match-on-never.rs @@ -1,7 +1,7 @@ #![deny(unreachable_code)] #![allow(dead_code)] -#![feature(never_type)] + fn foo(x: !) -> bool { // Explicit matches on the never type are unwarned. diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/auxiliary/uninhabited.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/auxiliary/uninhabited.rs index a2735d4cbfb29..30918aa6bba3c 100644 --- a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/auxiliary/uninhabited.rs +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/auxiliary/uninhabited.rs @@ -1,5 +1,5 @@ #![crate_type = "rlib"] -#![feature(never_type)] + #[non_exhaustive] pub enum UninhabitedEnum { diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/coercions.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/coercions.rs index 80b9dc4c1c338..586d26ac9a23f 100644 --- a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/coercions.rs +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/coercions.rs @@ -1,5 +1,5 @@ // aux-build:uninhabited.rs -#![feature(never_type)] + extern crate uninhabited; diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/coercions_same_crate.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/coercions_same_crate.rs index 6b911dd989cc5..c3c0ce650d73e 100644 --- a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/coercions_same_crate.rs +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/coercions_same_crate.rs @@ -1,5 +1,3 @@ -#![feature(never_type)] - #[non_exhaustive] pub enum UninhabitedEnum { } diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/coercions_same_crate.stderr b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/coercions_same_crate.stderr index fd2c56974bd4a..16a62a992497d 100644 --- a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/coercions_same_crate.stderr +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/coercions_same_crate.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/coercions_same_crate.rs:30:5 + --> $DIR/coercions_same_crate.rs:28:5 | LL | fn cannot_coerce_empty_enum_to_anything(x: UninhabitedEnum) -> A { | - expected `A` because of return type @@ -7,7 +7,7 @@ LL | x | ^ expected struct `A`, found enum `UninhabitedEnum` error[E0308]: mismatched types - --> $DIR/coercions_same_crate.rs:34:5 + --> $DIR/coercions_same_crate.rs:32:5 | LL | fn cannot_coerce_empty_tuple_struct_to_anything(x: UninhabitedTupleStruct) -> A { | - expected `A` because of return type @@ -15,7 +15,7 @@ LL | x | ^ expected struct `A`, found struct `UninhabitedTupleStruct` error[E0308]: mismatched types - --> $DIR/coercions_same_crate.rs:38:5 + --> $DIR/coercions_same_crate.rs:36:5 | LL | fn cannot_coerce_empty_struct_to_anything(x: UninhabitedStruct) -> A { | - expected `A` because of return type @@ -23,7 +23,7 @@ LL | x | ^ expected struct `A`, found struct `UninhabitedStruct` error[E0308]: mismatched types - --> $DIR/coercions_same_crate.rs:42:5 + --> $DIR/coercions_same_crate.rs:40:5 | LL | fn cannot_coerce_enum_with_empty_variants_to_anything(x: UninhabitedVariants) -> A { | - expected `A` because of return type diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match.rs index 98a7fdbc5049a..3a2c3ca93fa0c 100644 --- a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match.rs +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match.rs @@ -1,5 +1,5 @@ // aux-build:uninhabited.rs -#![feature(never_type)] + extern crate uninhabited; diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_same_crate.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_same_crate.rs index 8f090fe886a00..9c3ec4240a5fd 100644 --- a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_same_crate.rs +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_same_crate.rs @@ -1,5 +1,3 @@ -#![feature(never_type)] - #[non_exhaustive] pub enum UninhabitedEnum { } diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_same_crate.stderr b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_same_crate.stderr index 42bf67c0a45df..b076dcb54d8f2 100644 --- a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_same_crate.stderr +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_same_crate.stderr @@ -1,5 +1,5 @@ error[E0004]: non-exhaustive patterns: type `IndirectUninhabitedEnum` is non-empty - --> $DIR/indirect_match_same_crate.rs:34:11 + --> $DIR/indirect_match_same_crate.rs:32:11 | LL | pub struct IndirectUninhabitedEnum(UninhabitedEnum); | ---------------------------------------------------- `IndirectUninhabitedEnum` defined here @@ -11,7 +11,7 @@ LL | match x {} = note: the matched value is of type `IndirectUninhabitedEnum` error[E0004]: non-exhaustive patterns: type `IndirectUninhabitedStruct` is non-empty - --> $DIR/indirect_match_same_crate.rs:38:11 + --> $DIR/indirect_match_same_crate.rs:36:11 | LL | pub struct IndirectUninhabitedStruct(UninhabitedStruct); | -------------------------------------------------------- `IndirectUninhabitedStruct` defined here @@ -23,7 +23,7 @@ LL | match x {} = note: the matched value is of type `IndirectUninhabitedStruct` error[E0004]: non-exhaustive patterns: type `IndirectUninhabitedTupleStruct` is non-empty - --> $DIR/indirect_match_same_crate.rs:42:11 + --> $DIR/indirect_match_same_crate.rs:40:11 | LL | pub struct IndirectUninhabitedTupleStruct(UninhabitedTupleStruct); | ------------------------------------------------------------------ `IndirectUninhabitedTupleStruct` defined here @@ -35,7 +35,7 @@ LL | match x {} = note: the matched value is of type `IndirectUninhabitedTupleStruct` error[E0004]: non-exhaustive patterns: type `IndirectUninhabitedVariants` is non-empty - --> $DIR/indirect_match_same_crate.rs:48:11 + --> $DIR/indirect_match_same_crate.rs:46:11 | LL | pub struct IndirectUninhabitedVariants(UninhabitedVariants); | ------------------------------------------------------------ `IndirectUninhabitedVariants` defined here diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_with_exhaustive_patterns.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_with_exhaustive_patterns.rs index be86519ecb159..ceee3033aa5f8 100644 --- a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_with_exhaustive_patterns.rs +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_with_exhaustive_patterns.rs @@ -1,7 +1,7 @@ // aux-build:uninhabited.rs #![deny(unreachable_patterns)] #![feature(exhaustive_patterns)] -#![feature(never_type)] + extern crate uninhabited; diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_with_exhaustive_patterns_same_crate.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_with_exhaustive_patterns_same_crate.rs index 60289aa780378..bc2c471c2d2cf 100644 --- a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_with_exhaustive_patterns_same_crate.rs +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_with_exhaustive_patterns_same_crate.rs @@ -2,7 +2,7 @@ #![deny(unreachable_patterns)] #![feature(exhaustive_patterns)] -#![feature(never_type)] + #[non_exhaustive] pub enum UninhabitedEnum { diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/issue-65157-repeated-match-arm.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/issue-65157-repeated-match-arm.rs index 230ac75298e72..5840012fe2eaf 100644 --- a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/issue-65157-repeated-match-arm.rs +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/issue-65157-repeated-match-arm.rs @@ -1,6 +1,6 @@ // aux-build:uninhabited.rs #![deny(unreachable_patterns)] -#![feature(never_type)] + extern crate uninhabited; diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match.rs index e54098d4d48b9..c401af7cbdb07 100644 --- a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match.rs +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match.rs @@ -1,5 +1,5 @@ // aux-build:uninhabited.rs -#![feature(never_type)] + extern crate uninhabited; diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_same_crate.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_same_crate.rs index ebbdfba15f3a3..c31688add91b2 100644 --- a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_same_crate.rs +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_same_crate.rs @@ -1,5 +1,3 @@ -#![feature(never_type)] - #[non_exhaustive] pub enum UninhabitedEnum { } diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_same_crate.stderr b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_same_crate.stderr index e4d0c7022f3b4..7c7fad21ba429 100644 --- a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_same_crate.stderr +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_same_crate.stderr @@ -1,5 +1,5 @@ error[E0004]: non-exhaustive patterns: type `UninhabitedStruct` is non-empty - --> $DIR/match_same_crate.rs:30:11 + --> $DIR/match_same_crate.rs:28:11 | LL | / pub struct UninhabitedStruct { LL | | _priv: !, @@ -13,7 +13,7 @@ LL | match x {} = note: the matched value is of type `UninhabitedStruct` error[E0004]: non-exhaustive patterns: type `UninhabitedTupleStruct` is non-empty - --> $DIR/match_same_crate.rs:34:11 + --> $DIR/match_same_crate.rs:32:11 | LL | pub struct UninhabitedTupleStruct(!); | ------------------------------------- `UninhabitedTupleStruct` defined here @@ -25,7 +25,7 @@ LL | match x {} = note: the matched value is of type `UninhabitedTupleStruct` error[E0004]: non-exhaustive patterns: `Tuple(_)` and `Struct { .. }` not covered - --> $DIR/match_same_crate.rs:38:11 + --> $DIR/match_same_crate.rs:36:11 | LL | / pub enum UninhabitedVariants { LL | | #[non_exhaustive] Tuple(!), diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.rs index 900dfff652ea6..212244db9a442 100644 --- a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.rs +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.rs @@ -1,7 +1,7 @@ // aux-build:uninhabited.rs #![deny(unreachable_patterns)] #![feature(exhaustive_patterns)] -#![feature(never_type)] + extern crate uninhabited; diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns_same_crate.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns_same_crate.rs index de5530485f3e6..67296b2759b08 100644 --- a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns_same_crate.rs +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns_same_crate.rs @@ -2,7 +2,7 @@ #![deny(unreachable_patterns)] #![feature(exhaustive_patterns)] -#![feature(never_type)] + #[non_exhaustive] pub enum UninhabitedEnum { diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/patterns_same_crate.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/patterns_same_crate.rs index ffc496a975ecf..b0294af0766fe 100644 --- a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/patterns_same_crate.rs +++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/patterns_same_crate.rs @@ -1,6 +1,6 @@ #![deny(unreachable_patterns)] #![feature(exhaustive_patterns)] -#![feature(never_type)] + #[non_exhaustive] pub enum UninhabitedEnum { diff --git a/src/test/ui/rfc-2497-if-let-chains/protect-precedences.rs b/src/test/ui/rfc-2497-if-let-chains/protect-precedences.rs index fcc09b159ec23..822237dbb1a93 100644 --- a/src/test/ui/rfc-2497-if-let-chains/protect-precedences.rs +++ b/src/test/ui/rfc-2497-if-let-chains/protect-precedences.rs @@ -1,6 +1,6 @@ // run-pass -#![allow(irrefutable_let_patterns)] +#![allow(irrefutable_let_patterns, unreachable_patterns)] fn main() { let x: bool; diff --git a/src/test/ui/self/arbitrary-self-types-not-object-safe.stderr b/src/test/ui/self/arbitrary-self-types-not-object-safe.stderr deleted file mode 100644 index 353da8fd20b22..0000000000000 --- a/src/test/ui/self/arbitrary-self-types-not-object-safe.stderr +++ /dev/null @@ -1,23 +0,0 @@ -error[E0038]: the trait `Foo` cannot be made into an object - --> $DIR/arbitrary-self-types-not-object-safe.rs:29:32 - | -LL | fn foo(self: &Rc) -> usize; - | --- method `foo`'s `self` parameter cannot be dispatched on -... -LL | let x = Rc::new(5usize) as Rc; - | ^^^^^^^^^^^ the trait `Foo` cannot be made into an object - -error[E0038]: the trait `Foo` cannot be made into an object - --> $DIR/arbitrary-self-types-not-object-safe.rs:29:13 - | -LL | fn foo(self: &Rc) -> usize; - | --- method `foo`'s `self` parameter cannot be dispatched on -... -LL | let x = Rc::new(5usize) as Rc; - | ^^^^^^^^^^^^^^^ the trait `Foo` cannot be made into an object - | - = note: required because of the requirements on the impl of `std::ops::CoerceUnsized>` for `std::rc::Rc` - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0038`. diff --git a/src/test/ui/statics/uninhabited-static.rs b/src/test/ui/statics/uninhabited-static.rs index cc78f6cfa53f7..8b459f26139db 100644 --- a/src/test/ui/statics/uninhabited-static.rs +++ b/src/test/ui/statics/uninhabited-static.rs @@ -1,4 +1,3 @@ -#![feature(never_type)] #![deny(uninhabited_static)] enum Void {} diff --git a/src/test/ui/statics/uninhabited-static.stderr b/src/test/ui/statics/uninhabited-static.stderr index 5d95b29993827..fe4f86c865bf5 100644 --- a/src/test/ui/statics/uninhabited-static.stderr +++ b/src/test/ui/statics/uninhabited-static.stderr @@ -1,11 +1,11 @@ error: static of uninhabited type - --> $DIR/uninhabited-static.rs:6:5 + --> $DIR/uninhabited-static.rs:5:5 | LL | static VOID: Void; | ^^^^^^^^^^^^^^^^^^ | note: the lint level is defined here - --> $DIR/uninhabited-static.rs:2:9 + --> $DIR/uninhabited-static.rs:1:9 | LL | #![deny(uninhabited_static)] | ^^^^^^^^^^^^^^^^^^ @@ -14,7 +14,7 @@ LL | #![deny(uninhabited_static)] = note: uninhabited statics cannot be initialized, and any access would be an immediate error error: static of uninhabited type - --> $DIR/uninhabited-static.rs:8:5 + --> $DIR/uninhabited-static.rs:7:5 | LL | static NEVER: !; | ^^^^^^^^^^^^^^^^ @@ -24,7 +24,7 @@ LL | static NEVER: !; = note: uninhabited statics cannot be initialized, and any access would be an immediate error error: static of uninhabited type - --> $DIR/uninhabited-static.rs:12:1 + --> $DIR/uninhabited-static.rs:11:1 | LL | static VOID2: Void = unsafe { std::mem::transmute(()) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -34,7 +34,7 @@ LL | static VOID2: Void = unsafe { std::mem::transmute(()) }; = note: uninhabited statics cannot be initialized, and any access would be an immediate error error: static of uninhabited type - --> $DIR/uninhabited-static.rs:14:1 + --> $DIR/uninhabited-static.rs:13:1 | LL | static NEVER2: Void = unsafe { std::mem::transmute(()) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/structs-enums/type-sizes.rs b/src/test/ui/structs-enums/type-sizes.rs index 73a11a5e743f6..a25e407a54474 100644 --- a/src/test/ui/structs-enums/type-sizes.rs +++ b/src/test/ui/structs-enums/type-sizes.rs @@ -2,7 +2,7 @@ #![allow(non_camel_case_types)] #![allow(dead_code)] -#![feature(never_type)] + use std::mem::size_of; use std::num::NonZeroU8; diff --git a/src/test/ui/traits/reservation-impl/non-lattice-ok.rs b/src/test/ui/traits/reservation-impl/non-lattice-ok.rs index a71051243c893..e562b41fd9926 100644 --- a/src/test/ui/traits/reservation-impl/non-lattice-ok.rs +++ b/src/test/ui/traits/reservation-impl/non-lattice-ok.rs @@ -30,7 +30,7 @@ // // [ii]: https://smallcultfollowing.com/babysteps/blog/2016/09/24/intersection-impls/ -#![feature(rustc_attrs, never_type)] +#![feature(rustc_attrs)] trait MyTrait {} diff --git a/src/test/ui/try-block/try-block-bad-type.stderr b/src/test/ui/try-block/try-block-bad-type.stderr index fce8dbab4856c..25b9990b78bc9 100644 --- a/src/test/ui/try-block/try-block-bad-type.stderr +++ b/src/test/ui/try-block/try-block-bad-type.stderr @@ -6,8 +6,8 @@ LL | Err("")?; | = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait = help: the following implementations were found: - > - = note: required because of the requirements on the impl of `FromResidual>` for `Result` + > + = note: required because of the requirements on the impl of `FromResidual>` for `Result` note: required by `from_residual` --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL | diff --git a/src/test/ui/try-trait/bad-interconversion.rs b/src/test/ui/try-trait/bad-interconversion.rs index 385f5510fb414..3f2aca2977502 100644 --- a/src/test/ui/try-trait/bad-interconversion.rs +++ b/src/test/ui/try-trait/bad-interconversion.rs @@ -9,7 +9,7 @@ fn result_to_result() -> Result { fn option_to_result() -> Result { Some(3)?; - //~^ ERROR the `?` operator can only be used on `Result`s, not `Option`s, in a function that returns `Result` + //~^ ERROR the `?` operator can only be used on `Result`s in a function that returns `Result` Ok(10) } diff --git a/src/test/ui/try-trait/bad-interconversion.stderr b/src/test/ui/try-trait/bad-interconversion.stderr index 5cecf9128bb2c..18b9a888d7653 100644 --- a/src/test/ui/try-trait/bad-interconversion.stderr +++ b/src/test/ui/try-trait/bad-interconversion.stderr @@ -10,25 +10,25 @@ LL | Ok(Err(123_i32)?) = help: the following implementations were found: > > - = note: required because of the requirements on the impl of `FromResidual>` for `Result` + = note: required because of the requirements on the impl of `FromResidual>` for `Result` note: required by `from_residual` --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL | LL | fn from_residual(residual: R) -> Self; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0277]: the `?` operator can only be used on `Result`s, not `Option`s, in a function that returns `Result` +error[E0277]: the `?` operator can only be used on `Result`s in a function that returns `Result` --> $DIR/bad-interconversion.rs:11:12 | LL | / fn option_to_result() -> Result { LL | | Some(3)?; - | | ^ use `.ok_or(...)?` to provide an error compatible with `Result` + | | ^ this `?` produces `Option`, which is incompatible with `Result` LL | | LL | | Ok(10) LL | | } | |_- this function returns a `Result` | - = help: the trait `FromResidual>` is not implemented for `Result` + = help: the trait `FromResidual>` is not implemented for `Result` note: required by `from_residual` --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL | @@ -40,12 +40,12 @@ error[E0277]: the `?` operator can only be used on `Result`s in a function that | LL | / fn control_flow_to_result() -> Result { LL | | Ok(ControlFlow::Break(123)?) - | | ^ this `?` produces `ControlFlow<{integer}, Infallible>`, which is incompatible with `Result` + | | ^ this `?` produces `ControlFlow<{integer}, !>`, which is incompatible with `Result` LL | | LL | | } | |_- this function returns a `Result` | - = help: the trait `FromResidual>` is not implemented for `Result` + = help: the trait `FromResidual>` is not implemented for `Result` note: required by `from_residual` --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL | @@ -57,12 +57,12 @@ error[E0277]: the `?` operator can only be used on `Option`s, not `Result`s, in | LL | / fn result_to_option() -> Option { LL | | Some(Err("hello")?) - | | ^ use `.ok()?` if you want to discard the `Result` error information + | | ^ use `.ok()?` if you want to discard the `Result` error information LL | | LL | | } | |_- this function returns an `Option` | - = help: the trait `FromResidual>` is not implemented for `Option` + = help: the trait `FromResidual>` is not implemented for `Option` note: required by `from_residual` --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL | @@ -74,12 +74,12 @@ error[E0277]: the `?` operator can only be used on `Option`s in a function that | LL | / fn control_flow_to_option() -> Option { LL | | Some(ControlFlow::Break(123)?) - | | ^ this `?` produces `ControlFlow<{integer}, Infallible>`, which is incompatible with `Option` + | | ^ this `?` produces `ControlFlow<{integer}, !>`, which is incompatible with `Option` LL | | LL | | } | |_- this function returns an `Option` | - = help: the trait `FromResidual>` is not implemented for `Option` + = help: the trait `FromResidual>` is not implemented for `Option` note: required by `from_residual` --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL | @@ -91,12 +91,12 @@ error[E0277]: the `?` operator can only be used on `ControlFlow`s in a function | LL | / fn result_to_control_flow() -> ControlFlow { LL | | ControlFlow::Continue(Err("hello")?) - | | ^ this `?` produces `Result`, which is incompatible with `ControlFlow` + | | ^ this `?` produces `Result`, which is incompatible with `ControlFlow` LL | | LL | | } | |_- this function returns a `ControlFlow` | - = help: the trait `FromResidual>` is not implemented for `ControlFlow` + = help: the trait `FromResidual>` is not implemented for `ControlFlow` note: required by `from_residual` --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL | @@ -108,13 +108,13 @@ error[E0277]: the `?` operator can only be used on `ControlFlow`s in a function | LL | / fn option_to_control_flow() -> ControlFlow { LL | | Some(3)?; - | | ^ this `?` produces `Option`, which is incompatible with `ControlFlow` + | | ^ this `?` produces `Option`, which is incompatible with `ControlFlow` LL | | LL | | ControlFlow::Break(10) LL | | } | |_- this function returns a `ControlFlow` | - = help: the trait `FromResidual>` is not implemented for `ControlFlow` + = help: the trait `FromResidual>` is not implemented for `ControlFlow` note: required by `from_residual` --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL | @@ -126,13 +126,13 @@ error[E0277]: the `?` operator in a function that returns `ControlFlow` ca | LL | / fn control_flow_to_control_flow() -> ControlFlow { LL | | ControlFlow::Break(4_u8)?; - | | ^ this `?` produces `ControlFlow`, which is incompatible with `ControlFlow` + | | ^ this `?` produces `ControlFlow`, which is incompatible with `ControlFlow` LL | | LL | | ControlFlow::Continue(()) LL | | } | |_- this function returns a `ControlFlow` | - = help: the trait `FromResidual>` is not implemented for `ControlFlow` + = help: the trait `FromResidual>` is not implemented for `ControlFlow` = note: unlike `Result`, there's no `From`-conversion performed for `ControlFlow` note: required by `from_residual` --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL diff --git a/src/test/ui/try-trait/option-to-result.stderr b/src/test/ui/try-trait/option-to-result.stderr index f89813e729fad..edfbae79bad36 100644 --- a/src/test/ui/try-trait/option-to-result.stderr +++ b/src/test/ui/try-trait/option-to-result.stderr @@ -1,15 +1,15 @@ -error[E0277]: the `?` operator can only be used on `Result`s, not `Option`s, in a function that returns `Result` +error[E0277]: the `?` operator can only be used on `Result`s in a function that returns `Result` --> $DIR/option-to-result.rs:5:6 | LL | / fn test_result() -> Result<(),()> { LL | | let a:Option<()> = Some(()); LL | | a?; - | | ^ use `.ok_or(...)?` to provide an error compatible with `Result<(), ()>` + | | ^ this `?` produces `Option`, which is incompatible with `Result<(), ()>` LL | | Ok(()) LL | | } | |_- this function returns a `Result` | - = help: the trait `FromResidual>` is not implemented for `Result<(), ()>` + = help: the trait `FromResidual>` is not implemented for `Result<(), ()>` note: required by `from_residual` --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL | @@ -22,12 +22,12 @@ error[E0277]: the `?` operator can only be used on `Option`s, not `Result`s, in LL | / fn test_option() -> Option{ LL | | let a:Result = Ok(5); LL | | a?; - | | ^ use `.ok()?` if you want to discard the `Result` error information + | | ^ use `.ok()?` if you want to discard the `Result` error information LL | | Some(5) LL | | } | |_- this function returns an `Option` | - = help: the trait `FromResidual>` is not implemented for `Option` + = help: the trait `FromResidual>` is not implemented for `Option` note: required by `from_residual` --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL | diff --git a/src/test/ui/try-trait/try-on-option-diagnostics.stderr b/src/test/ui/try-trait/try-on-option-diagnostics.stderr index bb65aae561f97..358fc02f668a6 100644 --- a/src/test/ui/try-trait/try-on-option-diagnostics.stderr +++ b/src/test/ui/try-trait/try-on-option-diagnostics.stderr @@ -9,7 +9,7 @@ LL | | 22 LL | | } | |_- this function should return `Result` or `Option` to accept `?` | - = help: the trait `FromResidual>` is not implemented for `u32` + = help: the trait `FromResidual>` is not implemented for `u32` note: required by `from_residual` --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL | @@ -28,7 +28,7 @@ LL | | 22 LL | | }; | |_____- this function should return `Result` or `Option` to accept `?` | - = help: the trait `FromResidual>` is not implemented for `{integer}` + = help: the trait `FromResidual>` is not implemented for `{integer}` note: required by `from_residual` --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL | @@ -45,7 +45,7 @@ LL | | x?; LL | | } | |_________- this function should return `Result` or `Option` to accept `?` | - = help: the trait `FromResidual>` is not implemented for `()` + = help: the trait `FromResidual>` is not implemented for `()` note: required by `from_residual` --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL | @@ -62,7 +62,7 @@ LL | | x?; LL | | } | |_________- this function should return `Result` or `Option` to accept `?` | - = help: the trait `FromResidual>` is not implemented for `()` + = help: the trait `FromResidual>` is not implemented for `()` note: required by `from_residual` --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL | diff --git a/src/test/ui/try-trait/try-on-option.stderr b/src/test/ui/try-trait/try-on-option.stderr index b522dd5709b29..20f11ae0aa5c4 100644 --- a/src/test/ui/try-trait/try-on-option.stderr +++ b/src/test/ui/try-trait/try-on-option.stderr @@ -1,15 +1,15 @@ -error[E0277]: the `?` operator can only be used on `Result`s, not `Option`s, in a function that returns `Result` +error[E0277]: the `?` operator can only be used on `Result`s in a function that returns `Result` --> $DIR/try-on-option.rs:7:6 | LL | / fn foo() -> Result { LL | | let x: Option = None; LL | | x?; - | | ^ use `.ok_or(...)?` to provide an error compatible with `Result` + | | ^ this `?` produces `Option`, which is incompatible with `Result` LL | | Ok(22) LL | | } | |_- this function returns a `Result` | - = help: the trait `FromResidual>` is not implemented for `Result` + = help: the trait `FromResidual>` is not implemented for `Result` note: required by `from_residual` --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL | @@ -27,7 +27,7 @@ LL | | 22 LL | | } | |_- this function should return `Result` or `Option` to accept `?` | - = help: the trait `FromResidual>` is not implemented for `u32` + = help: the trait `FromResidual>` is not implemented for `u32` note: required by `from_residual` --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL | diff --git a/src/test/ui/try-trait/try-operator-on-main.stderr b/src/test/ui/try-trait/try-operator-on-main.stderr index d669124e9f112..048f13c33709a 100644 --- a/src/test/ui/try-trait/try-operator-on-main.stderr +++ b/src/test/ui/try-trait/try-operator-on-main.stderr @@ -11,7 +11,7 @@ LL | | try_trait_generic::<()>(); LL | | } | |_- this function should return `Result` or `Option` to accept `?` | - = help: the trait `FromResidual>` is not implemented for `()` + = help: the trait `FromResidual>` is not implemented for `()` note: required by `from_residual` --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL | diff --git a/src/test/ui/type-alias-impl-trait/different_defining_uses_never_type.full_tait.stderr b/src/test/ui/type-alias-impl-trait/different_defining_uses_never_type.full_tait.stderr new file mode 100644 index 0000000000000..8b137891791fe --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/different_defining_uses_never_type.full_tait.stderr @@ -0,0 +1 @@ + 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 6274029e4f524..003d3cd862ab6 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 @@ -2,7 +2,7 @@ error: concrete type differs from previous defining opaque type use --> $DIR/different_defining_uses_never_type.rs:12:1 | LL | fn bar() -> Foo { - | ^^^^^^^^^^^^^^^ expected `&'static str`, got `()` + | ^^^^^^^^^^^^^^^ expected `&'static str`, got `!` | note: previous use here --> $DIR/different_defining_uses_never_type.rs:8:1 @@ -14,7 +14,7 @@ error: concrete type differs from previous defining opaque type use --> $DIR/different_defining_uses_never_type.rs:17:1 | LL | fn boo() -> Foo { - | ^^^^^^^^^^^^^^^ expected `&'static str`, got `()` + | ^^^^^^^^^^^^^^^ expected `&'static str`, got `!` | note: previous use here --> $DIR/different_defining_uses_never_type.rs:8:1 diff --git a/src/test/ui/uninhabited/uninhabited-irrefutable.rs b/src/test/ui/uninhabited/uninhabited-irrefutable.rs index 48cd92719b49a..84daa35484f81 100644 --- a/src/test/ui/uninhabited/uninhabited-irrefutable.rs +++ b/src/test/ui/uninhabited/uninhabited-irrefutable.rs @@ -1,4 +1,3 @@ -#![feature(never_type)] #![feature(exhaustive_patterns)] mod foo { diff --git a/src/test/ui/uninhabited/uninhabited-irrefutable.stderr b/src/test/ui/uninhabited/uninhabited-irrefutable.stderr index 3cb9955674800..dd952a1b61412 100644 --- a/src/test/ui/uninhabited/uninhabited-irrefutable.stderr +++ b/src/test/ui/uninhabited/uninhabited-irrefutable.stderr @@ -1,5 +1,5 @@ error[E0005]: refutable pattern in local binding: `A(_)` not covered - --> $DIR/uninhabited-irrefutable.rs:27:9 + --> $DIR/uninhabited-irrefutable.rs:26:9 | LL | / enum Foo { LL | | A(foo::SecretlyEmpty), diff --git a/src/test/ui/uninhabited/uninhabited-patterns.rs b/src/test/ui/uninhabited/uninhabited-patterns.rs index 58c726d2185c4..1422bcf4f6098 100644 --- a/src/test/ui/uninhabited/uninhabited-patterns.rs +++ b/src/test/ui/uninhabited/uninhabited-patterns.rs @@ -1,8 +1,8 @@ #![feature(box_patterns)] #![feature(box_syntax)] -#![feature(never_type)] #![feature(exhaustive_patterns)] + #![deny(unreachable_patterns)] mod foo { diff --git a/src/tools/clippy/clippy_lints/src/empty_enum.rs b/src/tools/clippy/clippy_lints/src/empty_enum.rs index 3453c2da2784f..b2d1bc79f3510 100644 --- a/src/tools/clippy/clippy_lints/src/empty_enum.rs +++ b/src/tools/clippy/clippy_lints/src/empty_enum.rs @@ -30,8 +30,6 @@ declare_clippy_lint! { /// /// Good: /// ```rust - /// #![feature(never_type)] - /// /// struct Test(!); /// ``` pub EMPTY_ENUM, @@ -43,11 +41,6 @@ declare_lint_pass!(EmptyEnum => [EMPTY_ENUM]); impl<'tcx> LateLintPass<'tcx> for EmptyEnum { fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) { - // Only suggest the `never_type` if the feature is enabled - if !cx.tcx.features().never_type { - return; - } - if let ItemKind::Enum(..) = item.kind { let ty = cx.tcx.type_of(item.def_id); let adt = ty.ty_adt_def().expect("already checked whether this is an enum"); diff --git a/src/tools/clippy/tests/ui/empty_enum.rs b/src/tools/clippy/tests/ui/empty_enum.rs index a2e5c13c45282..4ffaca317f470 100644 --- a/src/tools/clippy/tests/ui/empty_enum.rs +++ b/src/tools/clippy/tests/ui/empty_enum.rs @@ -1,7 +1,6 @@ #![allow(dead_code)] #![warn(clippy::empty_enum)] // Enable never type to test empty enum lint -#![feature(never_type)] enum Empty {} fn main() {} diff --git a/src/tools/clippy/tests/ui/empty_enum.stderr b/src/tools/clippy/tests/ui/empty_enum.stderr index 7125e5f602b75..466dfbe7cee7a 100644 --- a/src/tools/clippy/tests/ui/empty_enum.stderr +++ b/src/tools/clippy/tests/ui/empty_enum.stderr @@ -1,5 +1,5 @@ error: enum with no variants - --> $DIR/empty_enum.rs:5:1 + --> $DIR/empty_enum.rs:4:1 | LL | enum Empty {} | ^^^^^^^^^^^^^ diff --git a/src/tools/clippy/tests/ui/empty_enum_without_never_type.stderr b/src/tools/clippy/tests/ui/empty_enum_without_never_type.stderr new file mode 100644 index 0000000000000..7517ed69d9e1b --- /dev/null +++ b/src/tools/clippy/tests/ui/empty_enum_without_never_type.stderr @@ -0,0 +1,11 @@ +error: enum with no variants + --> $DIR/empty_enum_without_never_type.rs:5:1 + | +LL | enum Empty {} + | ^^^^^^^^^^^^^ + | + = note: `-D clippy::empty-enum` implied by `-D warnings` + = help: consider using the uninhabited type `!` (never type) or a wrapper around it to introduce a type which can't be instantiated + +error: aborting due to previous error + diff --git a/src/tools/clippy/tests/ui/infallible_destructuring_match.fixed b/src/tools/clippy/tests/ui/infallible_destructuring_match.fixed index b8e40d995531a..04133d1c1d2db 100644 --- a/src/tools/clippy/tests/ui/infallible_destructuring_match.fixed +++ b/src/tools/clippy/tests/ui/infallible_destructuring_match.fixed @@ -1,5 +1,5 @@ // run-rustfix -#![feature(exhaustive_patterns, never_type)] +#![feature(exhaustive_patterns)] #![allow(dead_code, unreachable_code, unused_variables)] #![allow(clippy::let_and_return)] diff --git a/src/tools/clippy/tests/ui/infallible_destructuring_match.rs b/src/tools/clippy/tests/ui/infallible_destructuring_match.rs index 106cd438b90e7..d32404dff3385 100644 --- a/src/tools/clippy/tests/ui/infallible_destructuring_match.rs +++ b/src/tools/clippy/tests/ui/infallible_destructuring_match.rs @@ -1,5 +1,5 @@ // run-rustfix -#![feature(exhaustive_patterns, never_type)] +#![feature(exhaustive_patterns)] #![allow(dead_code, unreachable_code, unused_variables)] #![allow(clippy::let_and_return)] diff --git a/src/tools/clippy/tests/ui/must_use_candidates.fixed b/src/tools/clippy/tests/ui/must_use_candidates.fixed index 9556f6f82cc63..db4142f19262c 100644 --- a/src/tools/clippy/tests/ui/must_use_candidates.fixed +++ b/src/tools/clippy/tests/ui/must_use_candidates.fixed @@ -1,5 +1,4 @@ // run-rustfix -#![feature(never_type)] #![allow(unused_mut, clippy::redundant_allocation)] #![warn(clippy::must_use_candidate)] use std::rc::Rc; diff --git a/src/tools/clippy/tests/ui/must_use_candidates.rs b/src/tools/clippy/tests/ui/must_use_candidates.rs index 3732422017104..99426384fabee 100644 --- a/src/tools/clippy/tests/ui/must_use_candidates.rs +++ b/src/tools/clippy/tests/ui/must_use_candidates.rs @@ -1,5 +1,4 @@ // run-rustfix -#![feature(never_type)] #![allow(unused_mut, clippy::redundant_allocation)] #![warn(clippy::must_use_candidate)] use std::rc::Rc; diff --git a/src/tools/clippy/tests/ui/must_use_candidates.stderr b/src/tools/clippy/tests/ui/must_use_candidates.stderr index 0fa3849d03bff..2f33f5df5f407 100644 --- a/src/tools/clippy/tests/ui/must_use_candidates.stderr +++ b/src/tools/clippy/tests/ui/must_use_candidates.stderr @@ -1,5 +1,5 @@ error: this function could have a `#[must_use]` attribute - --> $DIR/must_use_candidates.rs:12:1 + --> $DIR/must_use_candidates.rs:11:1 | LL | pub fn pure(i: u8) -> u8 { | ^^^^^^^^^^^^^^^^^^^^^^^^ help: add the attribute: `#[must_use] pub fn pure(i: u8) -> u8` @@ -7,25 +7,25 @@ LL | pub fn pure(i: u8) -> u8 { = note: `-D clippy::must-use-candidate` implied by `-D warnings` error: this method could have a `#[must_use]` attribute - --> $DIR/must_use_candidates.rs:17:5 + --> $DIR/must_use_candidates.rs:16:5 | LL | pub fn inherent_pure(&self) -> u8 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: add the attribute: `#[must_use] pub fn inherent_pure(&self) -> u8` error: this function could have a `#[must_use]` attribute - --> $DIR/must_use_candidates.rs:48:1 + --> $DIR/must_use_candidates.rs:47:1 | LL | pub fn with_marker(_d: std::marker::PhantomData<&mut u32>) -> bool { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: add the attribute: `#[must_use] pub fn with_marker(_d: std::marker::PhantomData<&mut u32>) -> bool` error: this function could have a `#[must_use]` attribute - --> $DIR/must_use_candidates.rs:60:1 + --> $DIR/must_use_candidates.rs:59:1 | LL | pub fn rcd(_x: Rc) -> bool { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: add the attribute: `#[must_use] pub fn rcd(_x: Rc) -> bool` error: this function could have a `#[must_use]` attribute - --> $DIR/must_use_candidates.rs:68:1 + --> $DIR/must_use_candidates.rs:67:1 | LL | pub fn arcd(_x: Arc) -> bool { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: add the attribute: `#[must_use] pub fn arcd(_x: Arc) -> bool` diff --git a/src/tools/clippy/tests/ui/result_map_unit_fn_unfixable.rs b/src/tools/clippy/tests/ui/result_map_unit_fn_unfixable.rs index b197c609d7bfc..c00bd437588c4 100644 --- a/src/tools/clippy/tests/ui/result_map_unit_fn_unfixable.rs +++ b/src/tools/clippy/tests/ui/result_map_unit_fn_unfixable.rs @@ -1,5 +1,4 @@ #![warn(clippy::result_map_unit_fn)] -#![feature(never_type)] #![allow(unused)] struct HasResult { diff --git a/src/tools/clippy/tests/ui/result_map_unit_fn_unfixable.stderr b/src/tools/clippy/tests/ui/result_map_unit_fn_unfixable.stderr index 88e4efdb0f054..125276d10804f 100644 --- a/src/tools/clippy/tests/ui/result_map_unit_fn_unfixable.stderr +++ b/src/tools/clippy/tests/ui/result_map_unit_fn_unfixable.stderr @@ -1,5 +1,5 @@ error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type `()` - --> $DIR/result_map_unit_fn_unfixable.rs:23:5 + --> $DIR/result_map_unit_fn_unfixable.rs:22:5 | LL | x.field.map(|value| { do_nothing(value); do_nothing(value) }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- @@ -9,7 +9,7 @@ LL | x.field.map(|value| { do_nothing(value); do_nothing(value) }); = note: `-D clippy::result-map-unit-fn` implied by `-D warnings` error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type `()` - --> $DIR/result_map_unit_fn_unfixable.rs:25:5 + --> $DIR/result_map_unit_fn_unfixable.rs:24:5 | LL | x.field.map(|value| if value > 0 { do_nothing(value); do_nothing(value) }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- @@ -17,7 +17,7 @@ LL | x.field.map(|value| if value > 0 { do_nothing(value); do_nothing(value) | help: try this: `if let Ok(value) = x.field { ... }` error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type `()` - --> $DIR/result_map_unit_fn_unfixable.rs:29:5 + --> $DIR/result_map_unit_fn_unfixable.rs:28:5 | LL | x.field.map(|value| { | _____^ @@ -31,7 +31,7 @@ LL | || }); | error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type `()` - --> $DIR/result_map_unit_fn_unfixable.rs:33:5 + --> $DIR/result_map_unit_fn_unfixable.rs:32:5 | LL | x.field.map(|value| { do_nothing(value); do_nothing(value); }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- @@ -39,7 +39,7 @@ LL | x.field.map(|value| { do_nothing(value); do_nothing(value); }); | help: try this: `if let Ok(value) = x.field { ... }` error: called `map(f)` on an `Result` value where `f` is a function that returns the unit type `()` - --> $DIR/result_map_unit_fn_unfixable.rs:37:5 + --> $DIR/result_map_unit_fn_unfixable.rs:36:5 | LL | "12".parse::().map(diverge); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- @@ -47,7 +47,7 @@ LL | "12".parse::().map(diverge); | help: try this: `if let Ok(a) = "12".parse::() { diverge(a) }` error: called `map(f)` on an `Result` value where `f` is a function that returns the unit type `()` - --> $DIR/result_map_unit_fn_unfixable.rs:43:5 + --> $DIR/result_map_unit_fn_unfixable.rs:42:5 | LL | y.map(do_nothing); | ^^^^^^^^^^^^^^^^^-