diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index f39431f2494b..23805cdfd7a7 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -1275,6 +1275,13 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } } + /// Returns `false` if all non-auxiliary type variables unified with + /// `vid` is diverging. Returns `true` otherwise. + pub fn probe_ty_diverging(&self, vid: TyVid) -> bool { + let mut inner = self.inner.borrow_mut(); + inner.type_variables().var_diverges_with_unification(vid) + } + /// Resolve any type variables found in `value` -- but only one /// level. So, if the variable `?X` is bound to some type /// `Foo`, then this would return `Foo` (but `?Y` may diff --git a/compiler/rustc_infer/src/infer/type_variable.rs b/compiler/rustc_infer/src/infer/type_variable.rs index 683c1df783e6..b95548a8b35a 100644 --- a/compiler/rustc_infer/src/infer/type_variable.rs +++ b/compiler/rustc_infer/src/infer/type_variable.rs @@ -16,7 +16,7 @@ use rustc_data_structures::undo_log::{Rollback, UndoLogs}; /// Represents a single undo-able action that affects a type inference variable. pub(crate) enum UndoLog<'tcx> { EqRelation(sv::UndoLog>>), - SubRelation(sv::UndoLog>), + SubRelation(sv::UndoLog>), Values(sv::UndoLog), } @@ -28,8 +28,8 @@ impl<'tcx> From>>> for UndoLog<'tcx> { } /// Convert from a specific kind of undo to the more general UndoLog -impl<'tcx> From>> for UndoLog<'tcx> { - fn from(l: sv::UndoLog>) -> Self { +impl<'tcx> From>> for UndoLog<'tcx> { + fn from(l: sv::UndoLog>) -> Self { UndoLog::SubRelation(l) } } @@ -83,7 +83,7 @@ pub struct TypeVariableStorage<'tcx> { /// This is reasonable because, in Rust, subtypes have the same /// "skeleton" and hence there is no possible type such that /// (e.g.) `Box <: ?3` for any `?3`. - sub_relations: ut::UnificationTableStorage, + sub_relations: ut::UnificationTableStorage, } pub struct TypeVariableTable<'a, 'tcx> { @@ -169,6 +169,16 @@ impl<'tcx> TypeVariableStorage<'tcx> { } impl<'tcx> TypeVariableTable<'_, 'tcx> { + /// Returns `false` if all non-auxiliary type variables unified with + /// `vid` is diverging. Returns `true` otherwise. + /// + /// Precondition: `vid` should be unknown. + pub fn var_diverges_with_unification(&mut self, vid: ty::TyVid) -> bool { + debug_assert!(self.probe(vid).is_unknown()); + let kind = self.sub_relations().inlined_probe_value(vid); + matches!(kind, TyVarUnifiedDiverging::Yes) + } + /// Returns the diverges flag given when `vid` was created. /// /// Note that this function does not return care whether @@ -243,8 +253,9 @@ impl<'tcx> TypeVariableTable<'_, 'tcx> { ) -> ty::TyVid { let eq_key = self.eq_relations().new_key(TypeVariableValue::Unknown { universe }); - let sub_key = self.sub_relations().new_key(()); - assert_eq!(eq_key.vid, sub_key); + let diverging_kind = TyVarUnifiedDiverging::from(diverging, origin.kind); + let sub_key = self.sub_relations().new_key(diverging_kind); + assert_eq!(eq_key.vid, sub_key.vid); let index = self.values().push(TypeVariableData { origin, diverging }); assert_eq!(eq_key.vid.index, index as u32); @@ -279,7 +290,7 @@ impl<'tcx> TypeVariableTable<'_, 'tcx> { /// /// exists X. (a <: X || X <: a) && (b <: X || X <: b) pub fn sub_root_var(&mut self, vid: ty::TyVid) -> ty::TyVid { - self.sub_relations().find(vid) + self.sub_relations().find(vid).vid } /// Returns `true` if `a` and `b` have same "sub-root" (i.e., exists some @@ -326,7 +337,7 @@ impl<'tcx> TypeVariableTable<'_, 'tcx> { } #[inline] - fn sub_relations(&mut self) -> super::UnificationTable<'_, 'tcx, ty::TyVid> { + fn sub_relations(&mut self) -> super::UnificationTable<'_, 'tcx, TyVidSubKey> { self.storage.sub_relations.with_log(self.undo_log) } @@ -443,3 +454,84 @@ impl<'tcx> ut::UnifyValue for TypeVariableValue<'tcx> { } } } + +/////////////////////////////////////////////////////////////////////////// + +/// These structs (a newtyped TyVid) are used as the unification key +/// for the `sub_relations`; they carry a `TyVarUnifiedDiverging` +/// along with them. +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +pub(crate) struct TyVidSubKey { + vid: ty::TyVid, +} + +/// This enum denotes whether unified type variables are all diverging +/// variables. Note auxiliary type variables (guessed with the help of +/// `TypeVariableOriginKind`) should be ignored. +#[derive(Copy, Clone, Debug)] +pub enum TyVarUnifiedDiverging { + /// All unified type variables are diverging. + Yes, + /// Some unified type variable are not diverging. + No, + /// We don't know the final result at all because we haven't seen + /// any non-auxiliary type variables yet. + Maybe, +} + +impl From for TyVidSubKey { + fn from(vid: ty::TyVid) -> Self { + TyVidSubKey { vid } + } +} + +impl ut::UnifyKey for TyVidSubKey { + type Value = TyVarUnifiedDiverging; + fn index(&self) -> u32 { + self.vid.index + } + fn from_index(i: u32) -> Self { + TyVidSubKey::from(ty::TyVid { index: i }) + } + fn tag() -> &'static str { + "TyVidSubKey" + } +} + +impl ut::UnifyValue for TyVarUnifiedDiverging { + type Error = ut::NoError; + + fn unify_values(value1: &Self, value2: &Self) -> Result { + match (*value1, *value2) { + // Auxiliary type variables should be ignored. + (TyVarUnifiedDiverging::Maybe, other) => Ok(other), + (other, TyVarUnifiedDiverging::Maybe) => Ok(other), + + // We've found some non-diverging type variables. + (TyVarUnifiedDiverging::No, _) => Ok(TyVarUnifiedDiverging::No), + (_, TyVarUnifiedDiverging::No) => Ok(TyVarUnifiedDiverging::No), + + // All type variables are diverging yet. + (TyVarUnifiedDiverging::Yes, TyVarUnifiedDiverging::Yes) => { + Ok(TyVarUnifiedDiverging::Yes) + } + } + } +} + +impl TyVarUnifiedDiverging { + #[inline] + fn from(diverging: bool, origin: TypeVariableOriginKind) -> Self { + if diverging { + return TyVarUnifiedDiverging::Yes; + } + + // FIXME: Is it a complete list? Probably not. + match origin { + TypeVariableOriginKind::MiscVariable | TypeVariableOriginKind::LatticeVariable => { + TyVarUnifiedDiverging::Maybe + } + _ => TyVarUnifiedDiverging::No, + } + } +} diff --git a/compiler/rustc_infer/src/infer/undo_log.rs b/compiler/rustc_infer/src/infer/undo_log.rs index 5ad2519a93c5..a2132f81f138 100644 --- a/compiler/rustc_infer/src/infer/undo_log.rs +++ b/compiler/rustc_infer/src/infer/undo_log.rs @@ -46,7 +46,7 @@ impl_from! { TypeVariables(type_variable::UndoLog<'tcx>), TypeVariables(sv::UndoLog>>), - TypeVariables(sv::UndoLog>), + TypeVariables(sv::UndoLog>), TypeVariables(sv::UndoLog), TypeVariables(type_variable::Instantiate), diff --git a/compiler/rustc_typeck/src/check/_match.rs b/compiler/rustc_typeck/src/check/_match.rs index d056f2c90f98..6fb0529b6690 100644 --- a/compiler/rustc_typeck/src/check/_match.rs +++ b/compiler/rustc_typeck/src/check/_match.rs @@ -555,7 +555,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let Some(m) = contains_ref_bindings { self.check_expr_with_needs(scrut, Needs::maybe_mut_place(m)) } else if no_arms { - self.check_expr(scrut) + // The hint for never type is a little hacky, but it will make + // `match never {}` work even without `never_type_fallback`. + // We can remove it once the feature `never_type_fallback` gets + // stabilized. + self.check_expr_with_hint(scrut, self.tcx.types.never) } else { // ...but otherwise we want to use any supertype of the // scrutinee. This is sort of a workaround, see note (*) in diff --git a/compiler/rustc_typeck/src/check/coercion.rs b/compiler/rustc_typeck/src/check/coercion.rs index 236fec94bdba..3b305724f754 100644 --- a/compiler/rustc_typeck/src/check/coercion.rs +++ b/compiler/rustc_typeck/src/check/coercion.rs @@ -1022,8 +1022,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // First try to coerce the new expression to the type of the previous ones, // but only if the new expression has no coercion already applied to it. - let mut first_error = None; - if !self.typeck_results.borrow().adjustments().contains_key(new.hir_id) { + let first_try = match self.typeck_results.borrow().expr_adjustments(new) { + &[] | &[Adjustment { kind: Adjust::NeverToAny, .. }] => true, + _ => false, + }; + let first_error = if first_try { let result = self.commit_if_ok(|_| coerce.coerce(new_ty, prev_ty)); match result { Ok(ok) => { @@ -1035,9 +1038,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); return Ok(target); } - Err(e) => first_error = Some(e), + Err(e) => Some(e), } - } + } else { + None + }; // Then try to coerce the previous expressions to the type of the new one. // This requires ensuring there are no coercions applied to *any* of the diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs index d0cbb58fb10e..f0dc39ed8f43 100644 --- a/compiler/rustc_typeck/src/check/expr.rs +++ b/compiler/rustc_typeck/src/check/expr.rs @@ -68,25 +68,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { extend_err: impl Fn(&mut DiagnosticBuilder<'_>), ) -> Ty<'tcx> { let expected_ty = expected.to_option(&self).unwrap_or(self.tcx.types.bool); - let mut ty = self.check_expr_with_expectation(expr, expected); - - // While we don't allow *arbitrary* coercions here, we *do* allow - // coercions from ! to `expected`. - if ty.is_never() { - assert!( - !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 { - kind: TypeVariableOriginKind::AdjustmentType, - span: expr.span, - }); - self.apply_adjustments( - expr, - vec![Adjustment { kind: Adjust::NeverToAny, target: adj_ty }], - ); - ty = adj_ty; - } + let ty = self.check_expr_with_expectation(expr, expected); if let Some(mut err) = self.demand_suptype_diag(expr.span, expected_ty, ty) { let expr = expr.peel_drop_temps(); @@ -216,7 +198,43 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { debug!("type of {} is...", self.tcx.hir().node_to_string(expr.hir_id)); debug!("... {:?}, expected is {:?}", ty, expected); - ty + // Convert the never type to a diverging type variable. + // Overall it helps to improve the consistency. We expect that we can + // have the same behaviour for `return.foo()` and `{ return }.foo()`. + if ty.is_never() { + assert!( + !self.typeck_results.borrow().adjustments().contains_key(expr.hir_id), + "expression with never type wound up being adjusted" + ); + + let expected_ty = match expected { + ExpectHasType(target_ty) => Some(target_ty), + ExpectCastableToType(target_ty) => Some(target_ty), + _ => None, + }; + + // Mirco-optimization: No need to create a diverging type variable + // if the target type is known. + let target_ty = expected_ty + .map(|target_ty| self.infcx.shallow_resolve(target_ty)) + .filter(|target_ty| !target_ty.is_ty_var()) + .unwrap_or_else(|| { + self.next_diverging_ty_var(TypeVariableOrigin { + kind: TypeVariableOriginKind::AdjustmentType, + span: expr.span, + }) + }); + if !target_ty.is_never() { + self.apply_adjustments( + expr, + vec![Adjustment { kind: Adjust::NeverToAny, target: target_ty }], + ); + } + + target_ty + } else { + ty + } } fn check_expr_kind( diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs index 4de8216884a6..9be70094d532 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs @@ -1567,17 +1567,44 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// Numeric inference variables may be left unresolved. pub fn structurally_resolved_type(&self, sp: Span, ty: Ty<'tcx>) -> Ty<'tcx> { let ty = self.resolve_vars_with_obligations(ty); - if !ty.is_ty_var() { - ty + if let ty::Infer(ty::TyVar(vid)) = ty.kind() { + // If we get a type variable here, we may not want to issue "type + // annotations needed". For example, the code can be something like + // `panic!().foo()` or `{ return }.foo()`. + // + // However, we must issue the error message if we found the type + // variable is related to some non-auxiliary non-diverging ones. + // + // We'll issue the error message for this + // ``` + // let a = return; + // { if true { a } else { return } }.foo(); + // ``` + // but we won't for this + // ``` + // let a: ! = return; + // { if true { a } else { return } }.foo(); + // ``` + + let new_ty = if self.infcx.probe_ty_diverging(*vid) { + if self.tcx.features().never_type_fallback { + self.tcx.types.never + } else { + self.tcx.types.unit + } + } else { + if !self.is_tainted_by_errors() { + self.emit_inference_failure_err((**self).body_id, sp, ty.into(), vec![], E0282) + .note("type must be known at this point") + .emit(); + } + self.tcx.ty_error() + }; + + self.demand_suptype(sp, new_ty, ty); + new_ty } else { - if !self.is_tainted_by_errors() { - self.emit_inference_failure_err((**self).body_id, sp, ty.into(), vec![], E0282) - .note("type must be known at this point") - .emit(); - } - let err = self.tcx.ty_error(); - self.demand_suptype(sp, err, ty); - err + ty } } diff --git a/src/test/mir-opt/inline/inline_diverging.f.Inline.diff b/src/test/mir-opt/inline/inline_diverging.f.Inline.diff index 6e36dc06a201..6e5690823e9d 100644 --- a/src/test/mir-opt/inline/inline_diverging.f.Inline.diff +++ b/src/test/mir-opt/inline/inline_diverging.f.Inline.diff @@ -4,18 +4,20 @@ fn f() -> () { let mut _0: (); // return place in scope 0 at $DIR/inline-diverging.rs:7:12: 7:12 let mut _1: !; // in scope 0 at $DIR/inline-diverging.rs:7:12: 9:2 - let _2: !; // in scope 0 at $DIR/inline-diverging.rs:8:5: 8:12 -+ let mut _3: !; // in scope 0 at $DIR/inline-diverging.rs:8:5: 8:12 + let _2: (); // in scope 0 at $DIR/inline-diverging.rs:8:5: 8:12 + let mut _3: !; // in scope 0 at $DIR/inline-diverging.rs:8:5: 8:12 ++ let mut _4: !; // in scope 0 at $DIR/inline-diverging.rs:8:5: 8:12 + scope 1 (inlined sleep) { // at $DIR/inline-diverging.rs:8:5: 8:12 + } bb0: { StorageLive(_2); // scope 0 at $DIR/inline-diverging.rs:8:5: 8:12 + StorageLive(_3); // scope 0 at $DIR/inline-diverging.rs:8:5: 8:12 - sleep(); // scope 0 at $DIR/inline-diverging.rs:8:5: 8:12 - // mir::Constant - // + span: $DIR/inline-diverging.rs:8:5: 8:10 - // + literal: Const { ty: fn() -> ! {sleep}, val: Value(Scalar()) } -+ StorageLive(_3); // scope 0 at $DIR/inline-diverging.rs:8:5: 8:12 ++ StorageLive(_4); // scope 0 at $DIR/inline-diverging.rs:8:5: 8:12 + goto -> bb1; // scope 0 at $DIR/inline-diverging.rs:8:5: 8:12 + } + diff --git a/src/test/mir-opt/inline/inline_diverging.g.Inline.diff b/src/test/mir-opt/inline/inline_diverging.g.Inline.diff index 97ffd664463b..4c99529ab374 100644 --- a/src/test/mir-opt/inline/inline_diverging.g.Inline.diff +++ b/src/test/mir-opt/inline/inline_diverging.g.Inline.diff @@ -8,8 +8,9 @@ let mut _3: i32; // in scope 0 at $DIR/inline-diverging.rs:13:8: 13:9 let mut _4: i32; // in scope 0 at $DIR/inline-diverging.rs:14:9: 14:10 let mut _5: !; // in scope 0 at $DIR/inline-diverging.rs:15:12: 17:6 - let _6: !; // in scope 0 at $DIR/inline-diverging.rs:16:9: 16:16 -+ let mut _7: !; // in scope 0 at $DIR/inline-diverging.rs:16:9: 16:16 + let _6: (); // in scope 0 at $DIR/inline-diverging.rs:16:9: 16:16 + let mut _7: !; // in scope 0 at $DIR/inline-diverging.rs:16:9: 16:16 ++ let mut _8: !; // in scope 0 at $DIR/inline-diverging.rs:16:9: 16:16 + scope 1 (inlined panic) { // at $DIR/inline-diverging.rs:16:9: 16:16 + } @@ -33,8 +34,9 @@ bb2: { StorageLive(_6); // scope 0 at $DIR/inline-diverging.rs:16:9: 16:16 + StorageLive(_7); // scope 0 at $DIR/inline-diverging.rs:16:9: 16:16 - panic(); // scope 0 at $DIR/inline-diverging.rs:16:9: 16:16 -+ StorageLive(_7); // scope 0 at $DIR/inline-diverging.rs:16:9: 16:16 ++ StorageLive(_8); // scope 0 at $DIR/inline-diverging.rs:16:9: 16:16 + begin_panic::<&str>(const "explicit panic"); // scope 1 at $DIR/inline-diverging.rs:16:9: 16:16 // mir::Constant - // + span: $DIR/inline-diverging.rs:16:9: 16:14 diff --git a/src/test/mir-opt/issue_38669.main.SimplifyCfg-initial.after.mir b/src/test/mir-opt/issue_38669.main.SimplifyCfg-initial.after.mir index 8355b2d195e1..6a359cb6c26d 100644 --- a/src/test/mir-opt/issue_38669.main.SimplifyCfg-initial.after.mir +++ b/src/test/mir-opt/issue_38669.main.SimplifyCfg-initial.after.mir @@ -7,6 +7,8 @@ fn main() -> () { let _3: (); // in scope 0 at $DIR/issue-38669.rs:7:9: 9:10 let mut _4: bool; // in scope 0 at $DIR/issue-38669.rs:7:12: 7:24 let mut _5: !; // in scope 0 at $DIR/issue-38669.rs:7:25: 9:10 + let _6: (); // in scope 0 at $DIR/issue-38669.rs:8:13: 8:18 + let mut _7: !; // in scope 0 at $DIR/issue-38669.rs:8:13: 8:18 scope 1 { debug should_break => _1; // in scope 1 at $DIR/issue-38669.rs:5:9: 5:25 } @@ -30,7 +32,9 @@ fn main() -> () { } bb3: { + StorageLive(_6); // scope 1 at $DIR/issue-38669.rs:8:13: 8:18 _0 = const (); // scope 1 at $DIR/issue-38669.rs:8:13: 8:18 + StorageDead(_6); // scope 1 at $DIR/issue-38669.rs:8:18: 8:19 StorageDead(_4); // scope 1 at $DIR/issue-38669.rs:9:9: 9:10 StorageDead(_3); // scope 1 at $DIR/issue-38669.rs:9:9: 9:10 StorageDead(_1); // scope 0 at $DIR/issue-38669.rs:12:1: 12:2 diff --git a/src/test/mir-opt/issue_72181_1.main.mir_map.0.mir b/src/test/mir-opt/issue_72181_1.main.mir_map.0.mir index 3c26b20c35e2..74682b59d069 100644 --- a/src/test/mir-opt/issue_72181_1.main.mir_map.0.mir +++ b/src/test/mir-opt/issue_72181_1.main.mir_map.0.mir @@ -9,8 +9,9 @@ fn main() -> () { let mut _1: !; // in scope 0 at $DIR/issue-72181-1.rs:15:11: 21:2 let _2: Void as UserTypeProjection { base: UserType(0), projs: [] }; // in scope 0 at $DIR/issue-72181-1.rs:16:9: 16:10 let mut _3: (); // in scope 0 at $DIR/issue-72181-1.rs:17:41: 17:43 - let _4: !; // in scope 0 at $DIR/issue-72181-1.rs:20:5: 20:9 - let mut _5: Void; // in scope 0 at $DIR/issue-72181-1.rs:20:7: 20:8 + let _4: (); // in scope 0 at $DIR/issue-72181-1.rs:20:5: 20:9 + let mut _5: !; // in scope 0 at $DIR/issue-72181-1.rs:20:5: 20:9 + let mut _6: Void; // in scope 0 at $DIR/issue-72181-1.rs:20:7: 20:8 scope 1 { debug v => _2; // in scope 1 at $DIR/issue-72181-1.rs:16:9: 16:10 } @@ -32,15 +33,17 @@ fn main() -> () { FakeRead(ForLet(None), _2); // scope 0 at $DIR/issue-72181-1.rs:16:9: 16:10 AscribeUserType(_2, o, UserTypeProjection { base: UserType(1), projs: [] }); // scope 0 at $DIR/issue-72181-1.rs:16:12: 16:16 StorageLive(_4); // scope 1 at $DIR/issue-72181-1.rs:20:5: 20:9 - StorageLive(_5); // scope 1 at $DIR/issue-72181-1.rs:20:7: 20:8 - _5 = move _2; // scope 1 at $DIR/issue-72181-1.rs:20:7: 20:8 - f(move _5) -> bb4; // scope 1 at $DIR/issue-72181-1.rs:20:5: 20:9 + StorageLive(_5); // scope 1 at $DIR/issue-72181-1.rs:20:5: 20:9 + StorageLive(_6); // scope 1 at $DIR/issue-72181-1.rs:20:7: 20:8 + _6 = move _2; // scope 1 at $DIR/issue-72181-1.rs:20:7: 20:8 + f(move _6) -> bb4; // scope 1 at $DIR/issue-72181-1.rs:20:5: 20:9 // mir::Constant // + span: $DIR/issue-72181-1.rs:20:5: 20:6 // + literal: Const { ty: fn(Void) -> ! {f}, val: Value(Scalar()) } } bb2: { + StorageDead(_6); // scope 1 at $DIR/issue-72181-1.rs:20:8: 20:9 StorageDead(_5); // scope 1 at $DIR/issue-72181-1.rs:20:8: 20:9 StorageDead(_4); // scope 1 at $DIR/issue-72181-1.rs:20:9: 20:10 StorageDead(_2); // scope 0 at $DIR/issue-72181-1.rs:21:1: 21:2 diff --git a/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.32bit.diff b/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.32bit.diff index 261eb3b27eaf..f0e4d33cea91 100644 --- a/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.32bit.diff +++ b/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.32bit.diff @@ -19,13 +19,14 @@ let mut _17: i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL let mut _18: i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL let mut _19: !; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let _21: !; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let mut _22: core::panicking::AssertKind; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let mut _23: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let _24: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let mut _25: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let _26: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let mut _27: std::option::Option; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _21: (); // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _22: !; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _23: core::panicking::AssertKind; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _24: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _25: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _26: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _27: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _28: std::option::Option; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL scope 1 { debug split => _1; // in scope 1 at $DIR/issue-73223.rs:2:9: 2:14 let _6: std::option::Option; // in scope 1 at $DIR/issue-73223.rs:7:9: 7:14 @@ -33,7 +34,7 @@ debug _prev => _6; // in scope 3 at $DIR/issue-73223.rs:7:9: 7:14 let _13: &i32; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL let _14: &i32; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let mut _28: &i32; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _29: &i32; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL scope 4 { debug left_val => _13; // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL debug right_val => _14; // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL @@ -81,14 +82,14 @@ StorageLive(_10); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL _10 = &_1; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageLive(_11); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _28 = const main::promoted[0]; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _29 = const main::promoted[0]; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL // ty::Const // + ty: &i32 // + val: Unevaluated(main, [], Some(promoted[0])) // mir::Constant // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL // + literal: Const { ty: &i32, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ issue_73223[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) } - _11 = _28; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _11 = _29; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL (_9.0: &i32) = move _10; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL (_9.1: &i32) = move _11; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageDead(_11); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL @@ -116,24 +117,25 @@ discriminant(_20) = 0; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageLive(_21); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageLive(_22); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _22 = const core::panicking::AssertKind::Eq; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_23); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _23 = const core::panicking::AssertKind::Eq; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL // ty::Const // + ty: core::panicking::AssertKind // + val: Value(Scalar(0x00)) // mir::Constant // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL // + literal: Const { ty: core::panicking::AssertKind, val: Value(Scalar(0x00)) } - StorageLive(_23); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageLive(_24); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _24 = _13; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _23 = _24; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageLive(_25); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _25 = _13; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _24 = _25; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageLive(_26); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _26 = _14; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _25 = _26; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageLive(_27); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - discriminant(_27) = 0; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - core::panicking::assert_failed::(const core::panicking::AssertKind::Eq, move _23, move _25, move _27); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _27 = _14; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _26 = _27; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_28); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + discriminant(_28) = 0; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + core::panicking::assert_failed::(const core::panicking::AssertKind::Eq, move _24, move _26, move _28); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL // mir::Constant // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL // + literal: Const { ty: for<'r, 's, 't0> fn(core::panicking::AssertKind, &'r i32, &'s i32, std::option::Option>) -> ! {core::panicking::assert_failed::}, val: Value(Scalar()) } diff --git a/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.64bit.diff b/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.64bit.diff index 261eb3b27eaf..f0e4d33cea91 100644 --- a/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.64bit.diff +++ b/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.64bit.diff @@ -19,13 +19,14 @@ let mut _17: i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL let mut _18: i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL let mut _19: !; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let _21: !; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let mut _22: core::panicking::AssertKind; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let mut _23: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let _24: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let mut _25: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let _26: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let mut _27: std::option::Option; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _21: (); // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _22: !; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _23: core::panicking::AssertKind; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _24: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _25: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _26: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _27: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _28: std::option::Option; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL scope 1 { debug split => _1; // in scope 1 at $DIR/issue-73223.rs:2:9: 2:14 let _6: std::option::Option; // in scope 1 at $DIR/issue-73223.rs:7:9: 7:14 @@ -33,7 +34,7 @@ debug _prev => _6; // in scope 3 at $DIR/issue-73223.rs:7:9: 7:14 let _13: &i32; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL let _14: &i32; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let mut _28: &i32; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _29: &i32; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL scope 4 { debug left_val => _13; // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL debug right_val => _14; // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL @@ -81,14 +82,14 @@ StorageLive(_10); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL _10 = &_1; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageLive(_11); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _28 = const main::promoted[0]; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _29 = const main::promoted[0]; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL // ty::Const // + ty: &i32 // + val: Unevaluated(main, [], Some(promoted[0])) // mir::Constant // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL // + literal: Const { ty: &i32, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ issue_73223[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) } - _11 = _28; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _11 = _29; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL (_9.0: &i32) = move _10; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL (_9.1: &i32) = move _11; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageDead(_11); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL @@ -116,24 +117,25 @@ discriminant(_20) = 0; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageLive(_21); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageLive(_22); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _22 = const core::panicking::AssertKind::Eq; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_23); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _23 = const core::panicking::AssertKind::Eq; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL // ty::Const // + ty: core::panicking::AssertKind // + val: Value(Scalar(0x00)) // mir::Constant // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL // + literal: Const { ty: core::panicking::AssertKind, val: Value(Scalar(0x00)) } - StorageLive(_23); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageLive(_24); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _24 = _13; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _23 = _24; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageLive(_25); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _25 = _13; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _24 = _25; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageLive(_26); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _26 = _14; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _25 = _26; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageLive(_27); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - discriminant(_27) = 0; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - core::panicking::assert_failed::(const core::panicking::AssertKind::Eq, move _23, move _25, move _27); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _27 = _14; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _26 = _27; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_28); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + discriminant(_28) = 0; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + core::panicking::assert_failed::(const core::panicking::AssertKind::Eq, move _24, move _26, move _28); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL // mir::Constant // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL // + literal: Const { ty: for<'r, 's, 't0> fn(core::panicking::AssertKind, &'r i32, &'s i32, std::option::Option>) -> ! {core::panicking::assert_failed::}, val: Value(Scalar()) } diff --git a/src/test/mir-opt/loop_test.main.SimplifyCfg-promote-consts.after.mir b/src/test/mir-opt/loop_test.main.SimplifyCfg-promote-consts.after.mir index 99c7ac8d5b70..db85fe860931 100644 --- a/src/test/mir-opt/loop_test.main.SimplifyCfg-promote-consts.after.mir +++ b/src/test/mir-opt/loop_test.main.SimplifyCfg-promote-consts.after.mir @@ -5,11 +5,15 @@ fn main() -> () { let _1: (); // in scope 0 at $DIR/loop_test.rs:10:5: 12:6 let mut _2: bool; // in scope 0 at $DIR/loop_test.rs:10:8: 10:12 let mut _3: !; // in scope 0 at $DIR/loop_test.rs:10:13: 12:6 - let mut _4: !; // in scope 0 at $DIR/loop_test.rs:13:5: 16:6 - let mut _5: (); // in scope 0 at $DIR/loop_test.rs:6:1: 17:2 - let _6: i32; // in scope 0 at $DIR/loop_test.rs:14:13: 14:14 + let _4: (); // in scope 0 at $DIR/loop_test.rs:11:9: 11:15 + let mut _5: !; // in scope 0 at $DIR/loop_test.rs:11:9: 11:15 + let mut _6: !; // in scope 0 at $DIR/loop_test.rs:13:5: 16:6 + let mut _7: (); // in scope 0 at $DIR/loop_test.rs:6:1: 17:2 + let _8: i32; // in scope 0 at $DIR/loop_test.rs:14:13: 14:14 + let _9: (); // in scope 0 at $DIR/loop_test.rs:15:9: 15:17 + let mut _10: !; // in scope 0 at $DIR/loop_test.rs:15:9: 15:17 scope 1 { - debug x => _6; // in scope 1 at $DIR/loop_test.rs:14:13: 14:14 + debug x => _8; // in scope 1 at $DIR/loop_test.rs:14:13: 14:14 } bb0: { @@ -20,7 +24,9 @@ fn main() -> () { } bb1: { + StorageLive(_4); // scope 0 at $DIR/loop_test.rs:11:9: 11:15 _0 = const (); // scope 0 at $DIR/loop_test.rs:11:9: 11:15 + StorageDead(_4); // scope 0 at $DIR/loop_test.rs:11:15: 11:16 StorageDead(_2); // scope 0 at $DIR/loop_test.rs:12:5: 12:6 StorageDead(_1); // scope 0 at $DIR/loop_test.rs:12:5: 12:6 return; // scope 0 at $DIR/loop_test.rs:17:2: 17:2 @@ -30,7 +36,7 @@ fn main() -> () { _1 = const (); // scope 0 at $DIR/loop_test.rs:12:6: 12:6 StorageDead(_2); // scope 0 at $DIR/loop_test.rs:12:5: 12:6 StorageDead(_1); // scope 0 at $DIR/loop_test.rs:12:5: 12:6 - StorageLive(_4); // scope 0 at $DIR/loop_test.rs:13:5: 16:6 + StorageLive(_6); // scope 0 at $DIR/loop_test.rs:13:5: 16:6 goto -> bb3; // scope 0 at $DIR/loop_test.rs:13:5: 16:6 } @@ -39,10 +45,12 @@ fn main() -> () { } bb4: { - StorageLive(_6); // scope 0 at $DIR/loop_test.rs:14:13: 14:14 - _6 = const 1_i32; // scope 0 at $DIR/loop_test.rs:14:17: 14:18 - FakeRead(ForLet(None), _6); // scope 0 at $DIR/loop_test.rs:14:13: 14:14 - StorageDead(_6); // scope 0 at $DIR/loop_test.rs:16:5: 16:6 + StorageLive(_8); // scope 0 at $DIR/loop_test.rs:14:13: 14:14 + _8 = const 1_i32; // scope 0 at $DIR/loop_test.rs:14:17: 14:18 + FakeRead(ForLet(None), _8); // scope 0 at $DIR/loop_test.rs:14:13: 14:14 + StorageLive(_9); // scope 1 at $DIR/loop_test.rs:15:9: 15:17 + StorageDead(_9); // scope 1 at $DIR/loop_test.rs:15:17: 15:18 + StorageDead(_8); // scope 0 at $DIR/loop_test.rs:16:5: 16:6 goto -> bb3; // scope 0 at $DIR/loop_test.rs:1:1: 1:1 } diff --git a/src/test/mir-opt/retag.array_casts.SimplifyCfg-elaborate-drops.after.mir b/src/test/mir-opt/retag.array_casts.SimplifyCfg-elaborate-drops.after.mir index c6ef403c3c13..916b0aee12ef 100644 --- a/src/test/mir-opt/retag.array_casts.SimplifyCfg-elaborate-drops.after.mir +++ b/src/test/mir-opt/retag.array_casts.SimplifyCfg-elaborate-drops.after.mir @@ -23,13 +23,14 @@ fn array_casts() -> () { let mut _24: usize; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL let mut _25: usize; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL let mut _26: !; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let _28: !; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let mut _29: core::panicking::AssertKind; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let mut _30: &usize; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let _31: &usize; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let mut _32: &usize; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let _33: &usize; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let mut _34: std::option::Option; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _28: (); // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _29: !; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _30: core::panicking::AssertKind; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _31: &usize; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _32: &usize; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _33: &usize; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _34: &usize; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _35: std::option::Option; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL scope 1 { debug x => _1; // in scope 1 at $DIR/retag.rs:58:9: 58:14 let _2: *mut usize; // in scope 1 at $DIR/retag.rs:59:9: 59:10 @@ -45,7 +46,7 @@ fn array_casts() -> () { debug p => _9; // in scope 5 at $DIR/retag.rs:63:9: 63:10 let _20: &usize; // in scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL let _21: &usize; // in scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let mut _35: &usize; // in scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _36: &usize; // in scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL scope 6 { } scope 7 { @@ -121,15 +122,15 @@ fn array_casts() -> () { _14 = &_15; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL Retag(_14); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageLive(_18); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _35 = const array_casts::promoted[0]; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _36 = const array_casts::promoted[0]; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL // ty::Const // + ty: &usize // + val: Unevaluated(array_casts, [], Some(promoted[0])) // mir::Constant // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL // + literal: Const { ty: &usize, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:15 ~ retag[317d]::array_casts), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) } - Retag(_35); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _18 = &(*_35); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + Retag(_36); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _18 = &(*_36); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL Retag(_18); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL _13 = (move _14, move _18); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageDead(_18); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL @@ -159,22 +160,23 @@ fn array_casts() -> () { _27 = core::panicking::AssertKind::Eq; // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageLive(_28); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageLive(_29); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _29 = move _27; // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageLive(_30); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _30 = move _27; // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageLive(_31); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _31 = &(*_20); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - Retag(_31); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _30 = &(*_31); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - Retag(_30); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageLive(_32); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageLive(_33); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _33 = &(*_21); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - Retag(_33); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _32 = &(*_33); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _32 = &(*_20); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL Retag(_32); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _31 = &(*_32); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + Retag(_31); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_33); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageLive(_34); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _34 = Option::::None; // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - core::panicking::assert_failed::(move _29, move _30, move _32, move _34); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _34 = &(*_21); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + Retag(_34); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _33 = &(*_34); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + Retag(_33); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_35); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _35 = Option::::None; // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + core::panicking::assert_failed::(move _30, move _31, move _33, move _35); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL // mir::Constant // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL // + literal: Const { ty: for<'r, 's, 't0> fn(core::panicking::AssertKind, &'r usize, &'s usize, std::option::Option>) -> ! {core::panicking::assert_failed::}, val: Value(Scalar()) } diff --git a/src/test/mir-opt/simplify_cfg.main.SimplifyCfg-early-opt.diff b/src/test/mir-opt/simplify_cfg.main.SimplifyCfg-early-opt.diff index 52e705fdbeba..4f044a0d350f 100644 --- a/src/test/mir-opt/simplify_cfg.main.SimplifyCfg-early-opt.diff +++ b/src/test/mir-opt/simplify_cfg.main.SimplifyCfg-early-opt.diff @@ -6,6 +6,8 @@ let mut _1: (); // in scope 0 at $DIR/simplify_cfg.rs:5:1: 11:2 let mut _2: bool; // in scope 0 at $DIR/simplify_cfg.rs:7:12: 7:17 let mut _3: !; // in scope 0 at $DIR/simplify_cfg.rs:7:18: 9:10 + let _4: (); // in scope 0 at $DIR/simplify_cfg.rs:8:13: 8:18 + let mut _5: !; // in scope 0 at $DIR/simplify_cfg.rs:8:13: 8:18 bb0: { - goto -> bb1; // scope 0 at $DIR/simplify_cfg.rs:6:5: 10:6 @@ -28,7 +30,9 @@ - bb3: { + bb2: { + StorageLive(_4); // scope 0 at $DIR/simplify_cfg.rs:8:13: 8:18 _0 = const (); // scope 0 at $DIR/simplify_cfg.rs:8:13: 8:18 + StorageDead(_4); // scope 0 at $DIR/simplify_cfg.rs:8:18: 8:19 StorageDead(_2); // scope 0 at $DIR/simplify_cfg.rs:9:9: 9:10 return; // scope 0 at $DIR/simplify_cfg.rs:11:2: 11:2 } diff --git a/src/test/mir-opt/simplify_cfg.main.SimplifyCfg-initial.diff b/src/test/mir-opt/simplify_cfg.main.SimplifyCfg-initial.diff index fef3ae2e461d..35fca87efe78 100644 --- a/src/test/mir-opt/simplify_cfg.main.SimplifyCfg-initial.diff +++ b/src/test/mir-opt/simplify_cfg.main.SimplifyCfg-initial.diff @@ -6,6 +6,8 @@ let mut _1: (); // in scope 0 at $DIR/simplify_cfg.rs:5:1: 11:2 let mut _2: bool; // in scope 0 at $DIR/simplify_cfg.rs:7:12: 7:17 let mut _3: !; // in scope 0 at $DIR/simplify_cfg.rs:7:18: 9:10 + let _4: (); // in scope 0 at $DIR/simplify_cfg.rs:8:13: 8:18 + let mut _5: !; // in scope 0 at $DIR/simplify_cfg.rs:8:13: 8:18 bb0: { - goto -> bb1; // scope 0 at $DIR/simplify_cfg.rs:6:5: 10:6 @@ -13,12 +15,12 @@ } bb1: { -- falseUnwind -> [real: bb2, cleanup: bb10]; // scope 0 at $DIR/simplify_cfg.rs:6:5: 10:6 +- falseUnwind -> [real: bb2, cleanup: bb11]; // scope 0 at $DIR/simplify_cfg.rs:6:5: 10:6 - } - - bb2: { StorageLive(_2); // scope 0 at $DIR/simplify_cfg.rs:7:12: 7:17 -- _2 = bar() -> [return: bb3, unwind: bb10]; // scope 0 at $DIR/simplify_cfg.rs:7:12: 7:17 +- _2 = bar() -> [return: bb3, unwind: bb11]; // scope 0 at $DIR/simplify_cfg.rs:7:12: 7:17 + _2 = bar() -> [return: bb2, unwind: bb5]; // scope 0 at $DIR/simplify_cfg.rs:7:12: 7:17 // mir::Constant // + span: $DIR/simplify_cfg.rs:7:12: 7:15 @@ -33,38 +35,45 @@ - bb4: { + bb3: { + StorageLive(_4); // scope 0 at $DIR/simplify_cfg.rs:8:13: 8:18 _0 = const (); // scope 0 at $DIR/simplify_cfg.rs:8:13: 8:18 -- goto -> bb9; // scope 0 at $DIR/simplify_cfg.rs:8:13: 8:18 -+ StorageDead(_2); // scope 0 at $DIR/simplify_cfg.rs:9:9: 9:10 -+ return; // scope 0 at $DIR/simplify_cfg.rs:11:2: 11:2 - } - +- goto -> bb10; // scope 0 at $DIR/simplify_cfg.rs:8:13: 8:18 +- } +- - bb5: { -+ bb4: { - _1 = const (); // scope 0 at $DIR/simplify_cfg.rs:9:10: 9:10 -- goto -> bb8; // scope 0 at $DIR/simplify_cfg.rs:7:9: 9:10 +- _1 = const (); // scope 0 at $DIR/simplify_cfg.rs:9:10: 9:10 +- goto -> bb9; // scope 0 at $DIR/simplify_cfg.rs:7:9: 9:10 - } - - bb6: { -- unreachable; // scope 0 at $DIR/simplify_cfg.rs:7:18: 9:10 +- unreachable; // scope 0 at $DIR/simplify_cfg.rs:8:13: 8:18 - } - - bb7: { -- goto -> bb8; // scope 0 at $DIR/simplify_cfg.rs:7:9: 9:10 + StorageDead(_4); // scope 0 at $DIR/simplify_cfg.rs:8:18: 8:19 +- unreachable; // scope 0 at $DIR/simplify_cfg.rs:7:18: 9:10 - } - - bb8: { +- goto -> bb9; // scope 0 at $DIR/simplify_cfg.rs:7:9: 9:10 +- } +- +- bb9: { StorageDead(_2); // scope 0 at $DIR/simplify_cfg.rs:9:9: 9:10 - goto -> bb1; // scope 0 at $DIR/simplify_cfg.rs:6:5: 10:6 -+ goto -> bb0; // scope 0 at $DIR/simplify_cfg.rs:6:5: 10:6 ++ return; // scope 0 at $DIR/simplify_cfg.rs:11:2: 11:2 } -- bb9: { -- StorageDead(_2); // scope 0 at $DIR/simplify_cfg.rs:9:9: 9:10 +- bb10: { +- StorageDead(_4); // scope 0 at $DIR/simplify_cfg.rs:8:18: 8:19 ++ bb4: { ++ _1 = const (); // scope 0 at $DIR/simplify_cfg.rs:9:10: 9:10 + StorageDead(_2); // scope 0 at $DIR/simplify_cfg.rs:9:9: 9:10 - return; // scope 0 at $DIR/simplify_cfg.rs:11:2: 11:2 -- } -- -- bb10 (cleanup): { ++ goto -> bb0; // scope 0 at $DIR/simplify_cfg.rs:6:5: 10:6 + } + +- bb11 (cleanup): { + bb5 (cleanup): { resume; // scope 0 at $DIR/simplify_cfg.rs:5:1: 11:2 } 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 c17fe3bb7575..40b997edfa50 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 @@ -3,7 +3,7 @@ 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 + let _2: &(); // in scope 0 at $DIR/uninhabited-enum.rs:8:8: 8:14 scope 1 { debug _input => _2; // in scope 1 at $DIR/uninhabited-enum.rs:8:8: 8:14 } @@ -12,8 +12,6 @@ fn process_never(_1: *const !) -> () { 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 + unreachable; // scope 2 at $DIR/uninhabited-enum.rs:8:27: 8:33 } } diff --git a/src/test/mir-opt/while_let_loops.change_loop_body.ConstProp.32bit.diff b/src/test/mir-opt/while_let_loops.change_loop_body.ConstProp.32bit.diff index de8a29ea25fc..1c30d502e8a2 100644 --- a/src/test/mir-opt/while_let_loops.change_loop_body.ConstProp.32bit.diff +++ b/src/test/mir-opt/while_let_loops.change_loop_body.ConstProp.32bit.diff @@ -8,7 +8,9 @@ let mut _3: std::option::Option; // in scope 0 at $DIR/while_let_loops.rs:7:28: 7:32 let mut _4: isize; // in scope 0 at $DIR/while_let_loops.rs:7:15: 7:25 let mut _5: !; // in scope 0 at $DIR/while_let_loops.rs:7:33: 10:6 - let mut _6: !; // in scope 0 at $DIR/while_let_loops.rs:7:5: 10:6 + let _6: (); // in scope 0 at $DIR/while_let_loops.rs:9:9: 9:14 + let mut _7: !; // in scope 0 at $DIR/while_let_loops.rs:9:9: 9:14 + let mut _8: !; // in scope 0 at $DIR/while_let_loops.rs:7:5: 10:6 scope 1 { debug _x => _1; // in scope 1 at $DIR/while_let_loops.rs:6:9: 6:15 } @@ -35,8 +37,10 @@ bb3: { _1 = const 1_i32; // scope 1 at $DIR/while_let_loops.rs:8:9: 8:15 + StorageLive(_6); // scope 1 at $DIR/while_let_loops.rs:9:9: 9:14 nop; // scope 1 at $DIR/while_let_loops.rs:9:9: 9:14 - goto -> bb4; // scope 1 at $DIR/while_let_loops.rs:9:9: 9:14 + StorageDead(_6); // scope 1 at $DIR/while_let_loops.rs:9:14: 9:15 + goto -> bb4; // scope 1 at $DIR/while_let_loops.rs:1:1: 1:1 } bb4: { diff --git a/src/test/mir-opt/while_let_loops.change_loop_body.ConstProp.64bit.diff b/src/test/mir-opt/while_let_loops.change_loop_body.ConstProp.64bit.diff index de8a29ea25fc..1c30d502e8a2 100644 --- a/src/test/mir-opt/while_let_loops.change_loop_body.ConstProp.64bit.diff +++ b/src/test/mir-opt/while_let_loops.change_loop_body.ConstProp.64bit.diff @@ -8,7 +8,9 @@ let mut _3: std::option::Option; // in scope 0 at $DIR/while_let_loops.rs:7:28: 7:32 let mut _4: isize; // in scope 0 at $DIR/while_let_loops.rs:7:15: 7:25 let mut _5: !; // in scope 0 at $DIR/while_let_loops.rs:7:33: 10:6 - let mut _6: !; // in scope 0 at $DIR/while_let_loops.rs:7:5: 10:6 + let _6: (); // in scope 0 at $DIR/while_let_loops.rs:9:9: 9:14 + let mut _7: !; // in scope 0 at $DIR/while_let_loops.rs:9:9: 9:14 + let mut _8: !; // in scope 0 at $DIR/while_let_loops.rs:7:5: 10:6 scope 1 { debug _x => _1; // in scope 1 at $DIR/while_let_loops.rs:6:9: 6:15 } @@ -35,8 +37,10 @@ bb3: { _1 = const 1_i32; // scope 1 at $DIR/while_let_loops.rs:8:9: 8:15 + StorageLive(_6); // scope 1 at $DIR/while_let_loops.rs:9:9: 9:14 nop; // scope 1 at $DIR/while_let_loops.rs:9:9: 9:14 - goto -> bb4; // scope 1 at $DIR/while_let_loops.rs:9:9: 9:14 + StorageDead(_6); // scope 1 at $DIR/while_let_loops.rs:9:14: 9:15 + goto -> bb4; // scope 1 at $DIR/while_let_loops.rs:1:1: 1:1 } bb4: { diff --git a/src/test/ui/asm/type-check-2.rs b/src/test/ui/asm/type-check-2.rs index c70a8802814f..a56ccc707883 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 +// only-x86_6 -#![feature(asm, repr_simd, never_type)] +#![feature(asm, repr_simd, never_type, never_type_fallback)] #[repr(simd)] struct SimdNonCopy(f32, f32, f32, f32); diff --git a/src/test/ui/diverging-tuple-parts-39485.stderr b/src/test/ui/diverging-tuple-parts-39485.stderr index ad3e5ab3dc9d..90a6f2ede702 100644 --- a/src/test/ui/diverging-tuple-parts-39485.stderr +++ b/src/test/ui/diverging-tuple-parts-39485.stderr @@ -24,7 +24,7 @@ LL | (return 1, return 2) | ^^^^^^^^^^^^^^^^^^^^ expected `isize`, found tuple | = note: expected type `isize` - found tuple `(!, !)` + found tuple `(_, _)` error: aborting due to 2 previous errors diff --git a/src/test/ui/index-bot.rs b/src/test/ui/index-bot.rs index e69c4019f61e..a6930eaf08cc 100644 --- a/src/test/ui/index-bot.rs +++ b/src/test/ui/index-bot.rs @@ -1,3 +1,3 @@ fn main() { - (return)[0]; //~ ERROR cannot index into a value of type `!` + (return)[0]; //~ ERROR cannot index into a value of type `()` } diff --git a/src/test/ui/index-bot.stderr b/src/test/ui/index-bot.stderr index b5d78297505d..225bf7724af3 100644 --- a/src/test/ui/index-bot.stderr +++ b/src/test/ui/index-bot.stderr @@ -1,8 +1,8 @@ -error[E0608]: cannot index into a value of type `!` +error[E0608]: cannot index into a value of type `()` --> $DIR/index-bot.rs:2:5 | LL | (return)[0]; - | ^^^^^^^^^^^ + | ^^^^^^^^^^^ help: to access tuple elements, use: `(return).0` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-13847.rs b/src/test/ui/issues/issue-13847.rs index 06a0304ae497..c8e72d131525 100644 --- a/src/test/ui/issues/issue-13847.rs +++ b/src/test/ui/issues/issue-13847.rs @@ -1,3 +1,3 @@ fn main() { - return.is_failure //~ ERROR no field `is_failure` on type `!` + return.is_failure //~ ERROR no field `is_failure` on type `()` } diff --git a/src/test/ui/issues/issue-13847.stderr b/src/test/ui/issues/issue-13847.stderr index 52b8dc049702..c262802ca8a1 100644 --- a/src/test/ui/issues/issue-13847.stderr +++ b/src/test/ui/issues/issue-13847.stderr @@ -1,4 +1,4 @@ -error[E0609]: no field `is_failure` on type `!` +error[E0609]: no field `is_failure` on type `()` --> $DIR/issue-13847.rs:2:12 | LL | return.is_failure diff --git a/src/test/ui/issues/issue-15207.rs b/src/test/ui/issues/issue-15207.rs index 356e55ac912e..199cf71b7543 100644 --- a/src/test/ui/issues/issue-15207.rs +++ b/src/test/ui/issues/issue-15207.rs @@ -1,6 +1,6 @@ fn main() { loop { - break.push(1) //~ ERROR no method named `push` found for type `!` + break.push(1) //~ ERROR no method named `push` found for unit type `()` ; } } diff --git a/src/test/ui/issues/issue-15207.stderr b/src/test/ui/issues/issue-15207.stderr index 25ce7cb5cc06..f9624238b456 100644 --- a/src/test/ui/issues/issue-15207.stderr +++ b/src/test/ui/issues/issue-15207.stderr @@ -1,8 +1,8 @@ -error[E0599]: no method named `push` found for type `!` in the current scope +error[E0599]: no method named `push` found for unit type `()` in the current scope --> $DIR/issue-15207.rs:3:15 | LL | break.push(1) - | ^^^^ method not found in `!` + | ^^^^ method not found in `()` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-15965.rs b/src/test/ui/issues/issue-15965.rs index eef4900d432d..0bfe02c0689e 100644 --- a/src/test/ui/issues/issue-15965.rs +++ b/src/test/ui/issues/issue-15965.rs @@ -1,7 +1,7 @@ fn main() { return { return () } -//~^ ERROR type annotations needed [E0282] +//~^ ERROR expected function, found `_` () ; } diff --git a/src/test/ui/issues/issue-15965.stderr b/src/test/ui/issues/issue-15965.stderr index 90377c19dee0..517097b15994 100644 --- a/src/test/ui/issues/issue-15965.stderr +++ b/src/test/ui/issues/issue-15965.stderr @@ -1,13 +1,12 @@ -error[E0282]: type annotations needed +error[E0618]: expected function, found `_` --> $DIR/issue-15965.rs:3:9 | -LL | / { return () } +LL | { return () } + | _________-^^^^^^^^^^^^ LL | | LL | | () - | |______^ cannot infer type - | - = note: type must be known at this point + | |______- call expression requires function error: aborting due to previous error -For more information about this error, try `rustc --explain E0282`. +For more information about this error, try `rustc --explain E0618`. diff --git a/src/test/ui/issues/issue-17373.rs b/src/test/ui/issues/issue-17373.rs index dc3be48a7ead..149226e8ec2a 100644 --- a/src/test/ui/issues/issue-17373.rs +++ b/src/test/ui/issues/issue-17373.rs @@ -1,4 +1,4 @@ fn main() { - *return //~ ERROR type `!` cannot be dereferenced + *return //~ ERROR type `()` cannot be dereferenced ; } diff --git a/src/test/ui/issues/issue-17373.stderr b/src/test/ui/issues/issue-17373.stderr index 5c429d1113df..04d18911ce1b 100644 --- a/src/test/ui/issues/issue-17373.stderr +++ b/src/test/ui/issues/issue-17373.stderr @@ -1,4 +1,4 @@ -error[E0614]: type `!` cannot be dereferenced +error[E0614]: type `()` cannot be dereferenced --> $DIR/issue-17373.rs:2:5 | LL | *return diff --git a/src/test/ui/issues/issue-18532.rs b/src/test/ui/issues/issue-18532.rs index 31fd87961dc9..914a424f2c0d 100644 --- a/src/test/ui/issues/issue-18532.rs +++ b/src/test/ui/issues/issue-18532.rs @@ -3,5 +3,5 @@ // into it. fn main() { - (return)((),()); //~ ERROR expected function, found `!` + (return)((),()); //~ ERROR expected function, found `_` } diff --git a/src/test/ui/issues/issue-18532.stderr b/src/test/ui/issues/issue-18532.stderr index 4c224eb2d243..fd1782947996 100644 --- a/src/test/ui/issues/issue-18532.stderr +++ b/src/test/ui/issues/issue-18532.stderr @@ -1,4 +1,4 @@ -error[E0618]: expected function, found `!` +error[E0618]: expected function, found `_` --> $DIR/issue-18532.rs:6:5 | LL | (return)((),()); diff --git a/src/test/ui/loops/loop-break-value.stderr b/src/test/ui/loops/loop-break-value.stderr index adb099f9b176..3d244ccce85a 100644 --- a/src/test/ui/loops/loop-break-value.stderr +++ b/src/test/ui/loops/loop-break-value.stderr @@ -170,7 +170,7 @@ LL | break (break, break); | ^^^^^^^^^^^^^^ expected `()`, found tuple | = note: expected unit type `()` - found tuple `(!, !)` + found tuple `(_, _)` error[E0308]: mismatched types --> $DIR/loop-break-value.rs:85:15 diff --git a/src/test/ui/never_type/early-fallback.rs b/src/test/ui/never_type/early-fallback.rs new file mode 100644 index 000000000000..53df2321a841 --- /dev/null +++ b/src/test/ui/never_type/early-fallback.rs @@ -0,0 +1,27 @@ +#![feature(never_type)] +#![feature(never_type_fallback)] +#![allow(dead_code)] + +fn foo() { + { if true { return } else { return } }.test(); + //~^ ERROR no method named `test` found for type `!` +} + +fn bar() { + { if true { Default::default() } else { return } }.test(); + //~^ ERROR type annotations needed +} + +fn baz() { + let a = return; + { if true { return } else { a } }.test(); + //~^ ERROR type annotations needed +} + +fn qux() { + let a: ! = return; + { if true { return } else { a } }.test(); + //~^ ERROR no method named `test` found for type `!` +} + +fn main() {} diff --git a/src/test/ui/never_type/early-fallback.stderr b/src/test/ui/never_type/early-fallback.stderr new file mode 100644 index 000000000000..2c0286c011a5 --- /dev/null +++ b/src/test/ui/never_type/early-fallback.stderr @@ -0,0 +1,34 @@ +error[E0599]: no method named `test` found for type `!` in the current scope + --> $DIR/early-fallback.rs:6:44 + | +LL | { if true { return } else { return } }.test(); + | ^^^^ method not found in `!` + +error[E0282]: type annotations needed + --> $DIR/early-fallback.rs:11:5 + | +LL | { if true { Default::default() } else { return } }.test(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type + | + = note: type must be known at this point + +error[E0282]: type annotations needed + --> $DIR/early-fallback.rs:17:5 + | +LL | let a = return; + | - consider giving `a` a type +LL | { if true { return } else { a } }.test(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type + | + = note: type must be known at this point + +error[E0599]: no method named `test` found for type `!` in the current scope + --> $DIR/early-fallback.rs:23:39 + | +LL | { if true { return } else { a } }.test(); + | ^^^^ method not found in `!` + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0282, E0599. +For more information about an error, try `rustc --explain E0282`. diff --git a/src/test/ui/never_type/issue-10176.rs b/src/test/ui/never_type/issue-10176.rs index 6277aa05eb36..b9d34e005f88 100644 --- a/src/test/ui/never_type/issue-10176.rs +++ b/src/test/ui/never_type/issue-10176.rs @@ -2,7 +2,7 @@ fn f() -> isize { (return 1, return 2) //~^ ERROR mismatched types //~| expected type `isize` -//~| found tuple `(!, !)` +//~| found tuple `(_, _)` //~| expected `isize`, found tuple } diff --git a/src/test/ui/never_type/issue-10176.stderr b/src/test/ui/never_type/issue-10176.stderr index cd5361ffad39..6aab366ab5a0 100644 --- a/src/test/ui/never_type/issue-10176.stderr +++ b/src/test/ui/never_type/issue-10176.stderr @@ -7,7 +7,7 @@ LL | (return 1, return 2) | ^^^^^^^^^^^^^^^^^^^^ expected `isize`, found tuple | = note: expected type `isize` - found tuple `(!, !)` + found tuple `(_, _)` error: aborting due to previous error diff --git a/src/test/ui/never_type/tuple.rs b/src/test/ui/never_type/tuple.rs new file mode 100644 index 000000000000..c4f349277389 --- /dev/null +++ b/src/test/ui/never_type/tuple.rs @@ -0,0 +1,19 @@ +#[allow(dead_code)] + +fn foo() { + let mut a = (return, ); + a.0 = 1; + a.0 = 1.1; //~ ERROR mismatched types +} + +fn bar() { + let mut a = (return, ); + a.0.test(); //~ ERROR type annotations needed for `(_,)` +} + +fn baz() { + let mut a = (return, ); + a + 1; //~ ERROR cannot add `{integer}` to `(_,)` +} + +fn main() {} diff --git a/src/test/ui/never_type/tuple.stderr b/src/test/ui/never_type/tuple.stderr new file mode 100644 index 000000000000..ea18b7c70150 --- /dev/null +++ b/src/test/ui/never_type/tuple.stderr @@ -0,0 +1,28 @@ +error[E0308]: mismatched types + --> $DIR/tuple.rs:6:11 + | +LL | a.0 = 1.1; + | ^^^ expected integer, found floating-point number + +error[E0282]: type annotations needed for `(_,)` + --> $DIR/tuple.rs:11:5 + | +LL | let mut a = (return, ); + | ----- consider giving `a` the explicit type `(_,)`, with the type parameters specified +LL | a.0.test(); + | ^^^ cannot infer type + | + = note: type must be known at this point + +error[E0369]: cannot add `{integer}` to `(_,)` + --> $DIR/tuple.rs:16:7 + | +LL | a + 1; + | - ^ - {integer} + | | + | (_,) + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0282, E0308, E0369. +For more information about an error, try `rustc --explain E0282`.