From ba51fc65bd7ff507e6f4a7da94e0a1db7dcf3859 Mon Sep 17 00:00:00 2001 From: jackh726 Date: Mon, 15 Dec 2025 17:03:52 +0000 Subject: [PATCH 1/3] Change branch to assert --- compiler/rustc_hir_typeck/src/coercion.rs | 36 +++++++++++------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index 127965cb4b301..93f500dc5dd82 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -1290,29 +1290,29 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let mut coerce = Coerce::new(self, cause.clone(), AllowTwoPhase::No, true); coerce.use_lub = true; - // 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 result = self.commit_if_ok(|_| coerce.coerce(new_ty, prev_ty)); - match result { - Ok(ok) => { - let (adjustments, target) = self.register_infer_ok_obligations(ok); - self.apply_adjustments(new, adjustments); - debug!( - "coercion::try_find_coercion_lub: was able to coerce from new type {:?} to previous type {:?} ({:?})", - new_ty, prev_ty, target - ); - return Ok(target); - } - Err(e) => first_error = Some(e), + // This might be okay, but we previously branched on this without any + // test, so I'm just keeping the assert to avoid surprising behavior. + assert!(!self.typeck_results.borrow().adjustments().contains_key(new.hir_id)); + + // First try to coerce the new expression to the type of the previous ones. + let result = self.commit_if_ok(|_| coerce.coerce(new_ty, prev_ty)); + let first_error = match result { + Ok(ok) => { + let (adjustments, target) = self.register_infer_ok_obligations(ok); + self.apply_adjustments(new, adjustments); + debug!( + "coercion::try_find_coercion_lub: was able to coerce from new type {:?} to previous type {:?} ({:?})", + new_ty, prev_ty, target + ); + return Ok(target); } - } + Err(e) => e, + }; let ok = self .commit_if_ok(|_| coerce.coerce(prev_ty, new_ty)) // Avoid giving strange errors on failed attempts. - .map_err(|e| first_error.unwrap_or(e))?; + .map_err(|_| first_error)?; let (adjustments, target) = self.register_infer_ok_obligations(ok); for expr in exprs { From a19c16d7d1ff72d171a6f73bda4a432373c6d3b5 Mon Sep 17 00:00:00 2001 From: jackh726 Date: Tue, 16 Dec 2025 22:37:45 +0000 Subject: [PATCH 2/3] Add some tests for multistep coercion ICEs --- tests/ui/coercion/multistep-fail.rs | 111 ++++++++++++ tests/ui/coercion/multistep-fail.stderr | 22 +++ tests/ui/coercion/multistep.rs | 202 +++++++++++++++++++++ tests/ui/coercion/multistep.stderr | 230 ++++++++++++++++++++++++ 4 files changed, 565 insertions(+) create mode 100644 tests/ui/coercion/multistep-fail.rs create mode 100644 tests/ui/coercion/multistep-fail.stderr create mode 100644 tests/ui/coercion/multistep.rs create mode 100644 tests/ui/coercion/multistep.stderr diff --git a/tests/ui/coercion/multistep-fail.rs b/tests/ui/coercion/multistep-fail.rs new file mode 100644 index 0000000000000..f29388269247f --- /dev/null +++ b/tests/ui/coercion/multistep-fail.rs @@ -0,0 +1,111 @@ +//@ check-fail +//@ known-bug: #148283 + +#![allow(static_mut_refs)] +#![allow(dead_code)] +use std::ops::Deref; + +pub static mut ACTIONS: Vec<&'static str> = Vec::new(); + +pub struct Wrap(T); + +// Deref Chain: FinalType <- UnsizedArray <- IntWrapper <- ArrayWrapper <- TopType +pub struct TopType; +pub type ArrayWrapper = Wrap<[i32; 0]>; +pub struct IntWrapper; +pub type UnsizedArray = Wrap<[i32]>; +pub struct FinalType; +pub struct TopTypeNoTrait; + +impl Deref for TopType { + type Target = ArrayWrapper; + fn deref(&self) -> &Self::Target { + unsafe { ACTIONS.push("deref TopType->ArrayWrapper"); } + &Wrap([]) + } +} + +impl Deref for ArrayWrapper { + type Target = IntWrapper; + fn deref(&self) -> &Self::Target { + unsafe { ACTIONS.push("deref ArrayWrapper->IntWrapper"); } + &IntWrapper + } +} + +impl Deref for IntWrapper { + type Target = UnsizedArray; + fn deref(&self) -> &Self::Target { + unsafe { ACTIONS.push("deref IntWrapper->UnsizedArray"); } + &Wrap([]) + } +} + +impl Deref for UnsizedArray { + type Target = FinalType; + fn deref(&self) -> &Self::Target { + unsafe { ACTIONS.push("deref UnsizedArray->FinalType"); } + &FinalType + } +} + +impl Deref for TopTypeNoTrait { + type Target = ArrayWrapper; + fn deref(&self) -> &Self::Target { + unsafe { ACTIONS.push("deref TopTypeNoTrait->ArrayWrapper"); } + &Wrap([]) + } +} + +trait Trait { + fn self_ty(&self); + + fn complete(&self) -> Vec<&'static str> { + self.self_ty(); + let actions = unsafe { ACTIONS.clone() }; + unsafe { ACTIONS.clear() }; + actions + } +} + +impl Trait for TopType { + fn self_ty(&self) { + unsafe { ACTIONS.push("self_ty TopType"); } + } +} + +impl Trait for ArrayWrapper { + fn self_ty(&self) { + unsafe { ACTIONS.push("self_ty ArrayWrapper"); } + } +} + +impl Trait for IntWrapper { + fn self_ty(&self) { + unsafe { ACTIONS.push("self_ty IntWrapper"); } + } +} + +impl Trait for UnsizedArray { + fn self_ty(&self) { + unsafe { ACTIONS.push("self_ty UnsizedArray"); } + } +} + +impl Trait for FinalType { + fn self_ty(&self) { + unsafe { ACTIONS.push("self_ty FinalType"); } + } +} + +fn deref_to_dyn_direct() { + let x = match 0 { + 0 => &TopTypeNoTrait as &TopTypeNoTrait, + 1 => &TopTypeNoTrait as &FinalType as &dyn Trait, + _ => loop {}, + }; +} + +fn main() { + deref_to_dyn_direct(); +} diff --git a/tests/ui/coercion/multistep-fail.stderr b/tests/ui/coercion/multistep-fail.stderr new file mode 100644 index 0000000000000..b95bcc84656cd --- /dev/null +++ b/tests/ui/coercion/multistep-fail.stderr @@ -0,0 +1,22 @@ +error[E0277]: the trait bound `TopTypeNoTrait: Trait` is not satisfied + --> $DIR/multistep-fail.rs:104:14 + | +LL | 1 => &TopTypeNoTrait as &FinalType as &dyn Trait, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unsatisfied trait bound + | +help: the trait `Trait` is not implemented for `TopTypeNoTrait` + --> $DIR/multistep-fail.rs:18:1 + | +LL | pub struct TopTypeNoTrait; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + = help: the following other types implement trait `Trait`: + FinalType + IntWrapper + TopType + Wrap<[i32; 0]> + Wrap<[i32]> + = note: required for the cast from `&TopTypeNoTrait` to `&dyn Trait` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/coercion/multistep.rs b/tests/ui/coercion/multistep.rs new file mode 100644 index 0000000000000..d255767d830dd --- /dev/null +++ b/tests/ui/coercion/multistep.rs @@ -0,0 +1,202 @@ +//@ check-fail +//@ known-bug: #148283 +//@ failure-status: 101 +//@ rustc-env:RUST_BACKTRACE=0 + +#![allow(static_mut_refs)] +#![allow(dead_code)] +use std::ops::Deref; + +pub static mut ACTIONS: Vec<&'static str> = Vec::new(); + +pub struct Wrap(T); + +// Deref Chain: FinalType <- UnsizedArray <- IntWrapper <- ArrayWrapper <- TopType +pub struct TopType; +pub type ArrayWrapper = Wrap<[i32; 0]>; +pub struct IntWrapper; +pub type UnsizedArray = Wrap<[i32]>; +pub struct FinalType; +pub struct TopTypeNoTrait; + +impl Deref for TopType { + type Target = ArrayWrapper; + fn deref(&self) -> &Self::Target { + unsafe { ACTIONS.push("deref TopType->ArrayWrapper"); } + &Wrap([]) + } +} + +impl Deref for ArrayWrapper { + type Target = IntWrapper; + fn deref(&self) -> &Self::Target { + unsafe { ACTIONS.push("deref ArrayWrapper->IntWrapper"); } + &IntWrapper + } +} + +impl Deref for IntWrapper { + type Target = UnsizedArray; + fn deref(&self) -> &Self::Target { + unsafe { ACTIONS.push("deref IntWrapper->UnsizedArray"); } + &Wrap([]) + } +} + +impl Deref for UnsizedArray { + type Target = FinalType; + fn deref(&self) -> &Self::Target { + unsafe { ACTIONS.push("deref UnsizedArray->FinalType"); } + &FinalType + } +} + +impl Deref for TopTypeNoTrait { + type Target = ArrayWrapper; + fn deref(&self) -> &Self::Target { + unsafe { ACTIONS.push("deref TopTypeNoTrait->ArrayWrapper"); } + &Wrap([]) + } +} + +trait Trait { + fn self_ty(&self); + + fn complete(&self) -> Vec<&'static str> { + self.self_ty(); + let actions = unsafe { ACTIONS.clone() }; + unsafe { ACTIONS.clear() }; + actions + } +} + +impl Trait for TopType { + fn self_ty(&self) { + unsafe { ACTIONS.push("self_ty TopType"); } + } +} + +impl Trait for ArrayWrapper { + fn self_ty(&self) { + unsafe { ACTIONS.push("self_ty ArrayWrapper"); } + } +} + +impl Trait for IntWrapper { + fn self_ty(&self) { + unsafe { ACTIONS.push("self_ty IntWrapper"); } + } +} + +impl Trait for UnsizedArray { + fn self_ty(&self) { + unsafe { ACTIONS.push("self_ty UnsizedArray"); } + } +} + +impl Trait for FinalType { + fn self_ty(&self) { + unsafe { ACTIONS.push("self_ty FinalType"); } + } +} + +fn simple() { + let x = match 0 { + 0 => &Wrap([]) as &ArrayWrapper, + _ => &Wrap([]) as &UnsizedArray, + }; + assert_eq!(x.complete(), vec!["self_ty UnsizedArray"]); +} + +fn long_chain() { + let x = match 0 { + 0 => &TopType as &TopType, + 1 => &Wrap([]) as &ArrayWrapper, + 2 => &IntWrapper as &IntWrapper, + 3 => &Wrap([]) as &UnsizedArray, + 4 => &FinalType as &FinalType, + _ => loop {}, + }; + assert_eq!( + x.complete(), + vec![ + "deref TopType->ArrayWrapper", + "deref ArrayWrapper->IntWrapper", + "deref IntWrapper->UnsizedArray", + "deref UnsizedArray->FinalType", + "self_ty FinalType", + ], + ); +} + +fn mixed_coercion() { + let x = match 0 { + 0 => &TopType as &TopType, + 1 => &Wrap([]) as &ArrayWrapper, + // IntWrapper arm removed + 2 => &Wrap([]) as &UnsizedArray, + 3 => &FinalType as &FinalType, + _ => loop {}, + }; + assert_eq!( + x.complete(), + vec![ + "deref TopType->ArrayWrapper", + "deref UnsizedArray->FinalType", + "self_ty FinalType", + ] + ); +} + +fn order_dependence() { + let a = match 0 { + 0 => &Wrap([]) as &ArrayWrapper, + 1 => &IntWrapper as &IntWrapper, + 2 => &Wrap([]) as &UnsizedArray, + _ => loop {}, + }; + assert_eq!( + a.complete(), + vec![ + "deref ArrayWrapper->IntWrapper", + "deref IntWrapper->UnsizedArray", + "self_ty UnsizedArray", + ], + ); + + unsafe { ACTIONS.clear() } + let b = match 0 { + 0 => &Wrap([]) as &ArrayWrapper, + 1 => &Wrap([]) as &UnsizedArray, + 2 => &IntWrapper as &IntWrapper, + _ => loop {}, + }; + assert_eq!(b.complete(), vec!["self_ty UnsizedArray"]); +} + +fn deref_to_dyn() { + let x = match 0 { + 0 => &TopTypeNoTrait as &TopTypeNoTrait, + 1 => &TopTypeNoTrait as &FinalType, + 2 => &TopTypeNoTrait as &FinalType as &dyn Trait, + _ => loop {}, + }; + assert_eq!( + x.complete(), + vec![ + "deref TopTypeNoTrait->ArrayWrapper", + "deref ArrayWrapper->IntWrapper", + "deref IntWrapper->UnsizedArray", + "deref UnsizedArray->FinalType", + "self_ty FinalType", + ], + ); +} + +fn main() { + simple(); + long_chain(); + mixed_coercion(); + order_dependence(); + deref_to_dyn(); +} diff --git a/tests/ui/coercion/multistep.stderr b/tests/ui/coercion/multistep.stderr new file mode 100644 index 0000000000000..ab307487b0114 --- /dev/null +++ b/tests/ui/coercion/multistep.stderr @@ -0,0 +1,230 @@ +note: no errors encountered even though delayed bugs were created + +note: those delayed bugs will now be shown as internal compiler errors + +error: internal compiler error: while adjusting Expr { hir_id: HirId(DefId(0:49 ~ multistep[afa8]::long_chain).8), kind: Cast(Expr { hir_id: HirId(DefId(0:49 ~ multistep[afa8]::long_chain).9), kind: AddrOf(Ref, Not, Expr { hir_id: HirId(DefId(0:49 ~ multistep[afa8]::long_chain).10), kind: Path(Resolved(None, Path { span: $DIR/multistep.rs:113:15: 113:22 (#0), res: Def(Ctor(Struct, Const), DefId(0:10 ~ multistep[afa8]::TopType::{constructor#0})), segments: [PathSegment { ident: TopType#0, hir_id: HirId(DefId(0:49 ~ multistep[afa8]::long_chain).11), res: Def(Ctor(Struct, Const), DefId(0:10 ~ multistep[afa8]::TopType::{constructor#0})), args: None, infer_args: true }] })), span: $DIR/multistep.rs:113:15: 113:22 (#0) }), span: $DIR/multistep.rs:113:14: 113:22 (#0) }, Ty { hir_id: HirId(DefId(0:49 ~ multistep[afa8]::long_chain).15), span: $DIR/multistep.rs:113:31: 113:39 (#0), kind: Ref(Lifetime { hir_id: HirId(DefId(0:49 ~ multistep[afa8]::long_chain).12), ident: '_#0, kind: Infer, source: Reference, syntax: Implicit }, MutTy { ty: Ty { hir_id: HirId(DefId(0:49 ~ multistep[afa8]::long_chain).13), span: $DIR/multistep.rs:113:32: 113:39 (#0), kind: Path(Resolved(None, Path { span: $DIR/multistep.rs:113:32: 113:39 (#0), res: Def(Struct, DefId(0:9 ~ multistep[afa8]::TopType)), segments: [PathSegment { ident: TopType#0, hir_id: HirId(DefId(0:49 ~ multistep[afa8]::long_chain).14), res: Def(Struct, DefId(0:9 ~ multistep[afa8]::TopType)), args: None, infer_args: false }] })) }, mutbl: Not }) }), span: $DIR/multistep.rs:113:14: 113:39 (#0) }, can't compose [Deref(None) -> TopType, Deref(Some(OverloadedDeref { mutbl: Not, span: $DIR/multistep.rs:114:14: 114:44 (#0) })) -> Wrap<[i32; 0]>, Borrow(Ref(Not)) -> &Wrap<[i32; 0]>] and [Deref(None) -> Wrap<[i32; 0]>, Deref(Some(OverloadedDeref { mutbl: Not, span: $DIR/multistep.rs:115:14: 115:42 (#0) })) -> IntWrapper, Borrow(Ref(Not)) -> &IntWrapper] + --> $DIR/multistep.rs:113:14 + | +LL | 0 => &TopType as &TopType, + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: delayed at compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs:343:36 - disabled backtrace + --> $DIR/multistep.rs:113:14 + | +LL | 0 => &TopType as &TopType, + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: internal compiler error: while adjusting Expr { hir_id: HirId(DefId(0:49 ~ multistep[afa8]::long_chain).8), kind: Cast(Expr { hir_id: HirId(DefId(0:49 ~ multistep[afa8]::long_chain).9), kind: AddrOf(Ref, Not, Expr { hir_id: HirId(DefId(0:49 ~ multistep[afa8]::long_chain).10), kind: Path(Resolved(None, Path { span: $DIR/multistep.rs:113:15: 113:22 (#0), res: Def(Ctor(Struct, Const), DefId(0:10 ~ multistep[afa8]::TopType::{constructor#0})), segments: [PathSegment { ident: TopType#0, hir_id: HirId(DefId(0:49 ~ multistep[afa8]::long_chain).11), res: Def(Ctor(Struct, Const), DefId(0:10 ~ multistep[afa8]::TopType::{constructor#0})), args: None, infer_args: true }] })), span: $DIR/multistep.rs:113:15: 113:22 (#0) }), span: $DIR/multistep.rs:113:14: 113:22 (#0) }, Ty { hir_id: HirId(DefId(0:49 ~ multistep[afa8]::long_chain).15), span: $DIR/multistep.rs:113:31: 113:39 (#0), kind: Ref(Lifetime { hir_id: HirId(DefId(0:49 ~ multistep[afa8]::long_chain).12), ident: '_#0, kind: Infer, source: Reference, syntax: Implicit }, MutTy { ty: Ty { hir_id: HirId(DefId(0:49 ~ multistep[afa8]::long_chain).13), span: $DIR/multistep.rs:113:32: 113:39 (#0), kind: Path(Resolved(None, Path { span: $DIR/multistep.rs:113:32: 113:39 (#0), res: Def(Struct, DefId(0:9 ~ multistep[afa8]::TopType)), segments: [PathSegment { ident: TopType#0, hir_id: HirId(DefId(0:49 ~ multistep[afa8]::long_chain).14), res: Def(Struct, DefId(0:9 ~ multistep[afa8]::TopType)), args: None, infer_args: false }] })) }, mutbl: Not }) }), span: $DIR/multistep.rs:113:14: 113:39 (#0) }, can't compose [Deref(None) -> Wrap<[i32; 0]>, Deref(Some(OverloadedDeref { mutbl: Not, span: $DIR/multistep.rs:115:14: 115:42 (#0) })) -> IntWrapper, Borrow(Ref(Not)) -> &IntWrapper] and [Deref(None) -> IntWrapper, Deref(Some(OverloadedDeref { mutbl: Not, span: $DIR/multistep.rs:116:14: 116:44 (#0) })) -> Wrap<[i32]>, Borrow(Ref(Not)) -> &Wrap<[i32]>] + --> $DIR/multistep.rs:113:14 + | +LL | 0 => &TopType as &TopType, + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: delayed at compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs:343:36 - disabled backtrace + --> $DIR/multistep.rs:113:14 + | +LL | 0 => &TopType as &TopType, + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: internal compiler error: while adjusting Expr { hir_id: HirId(DefId(0:49 ~ multistep[afa8]::long_chain).19), kind: Cast(Expr { hir_id: HirId(DefId(0:49 ~ multistep[afa8]::long_chain).20), kind: AddrOf(Ref, Not, Expr { hir_id: HirId(DefId(0:49 ~ multistep[afa8]::long_chain).21), kind: Call(Expr { hir_id: HirId(DefId(0:49 ~ multistep[afa8]::long_chain).22), kind: Path(Resolved(None, Path { span: $DIR/multistep.rs:114:15: 114:19 (#0), res: Def(Ctor(Struct, Fn), DefId(0:6 ~ multistep[afa8]::Wrap::{constructor#0})), segments: [PathSegment { ident: Wrap#0, hir_id: HirId(DefId(0:49 ~ multistep[afa8]::long_chain).23), res: Def(Ctor(Struct, Fn), DefId(0:6 ~ multistep[afa8]::Wrap::{constructor#0})), args: None, infer_args: true }] })), span: $DIR/multistep.rs:114:15: 114:19 (#0) }, [Expr { hir_id: HirId(DefId(0:49 ~ multistep[afa8]::long_chain).24), kind: Array([]), span: $DIR/multistep.rs:114:20: 114:22 (#0) }]), span: $DIR/multistep.rs:114:15: 114:23 (#0) }), span: $DIR/multistep.rs:114:14: 114:23 (#0) }, Ty { hir_id: HirId(DefId(0:49 ~ multistep[afa8]::long_chain).28), span: $DIR/multistep.rs:114:31: 114:44 (#0), kind: Ref(Lifetime { hir_id: HirId(DefId(0:49 ~ multistep[afa8]::long_chain).25), ident: '_#0, kind: Infer, source: Reference, syntax: Implicit }, MutTy { ty: Ty { hir_id: HirId(DefId(0:49 ~ multistep[afa8]::long_chain).26), span: $DIR/multistep.rs:114:32: 114:44 (#0), kind: Path(Resolved(None, Path { span: $DIR/multistep.rs:114:32: 114:44 (#0), res: Def(TyAlias, DefId(0:11 ~ multistep[afa8]::ArrayWrapper)), segments: [PathSegment { ident: ArrayWrapper#0, hir_id: HirId(DefId(0:49 ~ multistep[afa8]::long_chain).27), res: Def(TyAlias, DefId(0:11 ~ multistep[afa8]::ArrayWrapper)), args: None, infer_args: false }] })) }, mutbl: Not }) }), span: $DIR/multistep.rs:114:14: 114:44 (#0) }, can't compose [Deref(None) -> Wrap<[i32; 0]>, Deref(Some(OverloadedDeref { mutbl: Not, span: $DIR/multistep.rs:115:14: 115:42 (#0) })) -> IntWrapper, Borrow(Ref(Not)) -> &IntWrapper] and [Deref(None) -> IntWrapper, Deref(Some(OverloadedDeref { mutbl: Not, span: $DIR/multistep.rs:116:14: 116:44 (#0) })) -> Wrap<[i32]>, Borrow(Ref(Not)) -> &Wrap<[i32]>] + --> $DIR/multistep.rs:114:14 + | +LL | 1 => &Wrap([]) as &ArrayWrapper, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: delayed at compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs:343:36 - disabled backtrace + --> $DIR/multistep.rs:114:14 + | +LL | 1 => &Wrap([]) as &ArrayWrapper, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: internal compiler error: while adjusting Expr { hir_id: HirId(DefId(0:49 ~ multistep[afa8]::long_chain).8), kind: Cast(Expr { hir_id: HirId(DefId(0:49 ~ multistep[afa8]::long_chain).9), kind: AddrOf(Ref, Not, Expr { hir_id: HirId(DefId(0:49 ~ multistep[afa8]::long_chain).10), kind: Path(Resolved(None, Path { span: $DIR/multistep.rs:113:15: 113:22 (#0), res: Def(Ctor(Struct, Const), DefId(0:10 ~ multistep[afa8]::TopType::{constructor#0})), segments: [PathSegment { ident: TopType#0, hir_id: HirId(DefId(0:49 ~ multistep[afa8]::long_chain).11), res: Def(Ctor(Struct, Const), DefId(0:10 ~ multistep[afa8]::TopType::{constructor#0})), args: None, infer_args: true }] })), span: $DIR/multistep.rs:113:15: 113:22 (#0) }), span: $DIR/multistep.rs:113:14: 113:22 (#0) }, Ty { hir_id: HirId(DefId(0:49 ~ multistep[afa8]::long_chain).15), span: $DIR/multistep.rs:113:31: 113:39 (#0), kind: Ref(Lifetime { hir_id: HirId(DefId(0:49 ~ multistep[afa8]::long_chain).12), ident: '_#0, kind: Infer, source: Reference, syntax: Implicit }, MutTy { ty: Ty { hir_id: HirId(DefId(0:49 ~ multistep[afa8]::long_chain).13), span: $DIR/multistep.rs:113:32: 113:39 (#0), kind: Path(Resolved(None, Path { span: $DIR/multistep.rs:113:32: 113:39 (#0), res: Def(Struct, DefId(0:9 ~ multistep[afa8]::TopType)), segments: [PathSegment { ident: TopType#0, hir_id: HirId(DefId(0:49 ~ multistep[afa8]::long_chain).14), res: Def(Struct, DefId(0:9 ~ multistep[afa8]::TopType)), args: None, infer_args: false }] })) }, mutbl: Not }) }), span: $DIR/multistep.rs:113:14: 113:39 (#0) }, can't compose [Deref(None) -> IntWrapper, Deref(Some(OverloadedDeref { mutbl: Not, span: $DIR/multistep.rs:116:14: 116:44 (#0) })) -> Wrap<[i32]>, Borrow(Ref(Not)) -> &Wrap<[i32]>] and [Deref(None) -> Wrap<[i32]>, Deref(Some(OverloadedDeref { mutbl: Not, span: $DIR/multistep.rs:117:14: 117:41 (#0) })) -> FinalType, Borrow(Ref(Not)) -> &FinalType] + --> $DIR/multistep.rs:113:14 + | +LL | 0 => &TopType as &TopType, + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: delayed at compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs:343:36 - disabled backtrace + --> $DIR/multistep.rs:113:14 + | +LL | 0 => &TopType as &TopType, + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: internal compiler error: while adjusting Expr { hir_id: HirId(DefId(0:49 ~ multistep[afa8]::long_chain).19), kind: Cast(Expr { hir_id: HirId(DefId(0:49 ~ multistep[afa8]::long_chain).20), kind: AddrOf(Ref, Not, Expr { hir_id: HirId(DefId(0:49 ~ multistep[afa8]::long_chain).21), kind: Call(Expr { hir_id: HirId(DefId(0:49 ~ multistep[afa8]::long_chain).22), kind: Path(Resolved(None, Path { span: $DIR/multistep.rs:114:15: 114:19 (#0), res: Def(Ctor(Struct, Fn), DefId(0:6 ~ multistep[afa8]::Wrap::{constructor#0})), segments: [PathSegment { ident: Wrap#0, hir_id: HirId(DefId(0:49 ~ multistep[afa8]::long_chain).23), res: Def(Ctor(Struct, Fn), DefId(0:6 ~ multistep[afa8]::Wrap::{constructor#0})), args: None, infer_args: true }] })), span: $DIR/multistep.rs:114:15: 114:19 (#0) }, [Expr { hir_id: HirId(DefId(0:49 ~ multistep[afa8]::long_chain).24), kind: Array([]), span: $DIR/multistep.rs:114:20: 114:22 (#0) }]), span: $DIR/multistep.rs:114:15: 114:23 (#0) }), span: $DIR/multistep.rs:114:14: 114:23 (#0) }, Ty { hir_id: HirId(DefId(0:49 ~ multistep[afa8]::long_chain).28), span: $DIR/multistep.rs:114:31: 114:44 (#0), kind: Ref(Lifetime { hir_id: HirId(DefId(0:49 ~ multistep[afa8]::long_chain).25), ident: '_#0, kind: Infer, source: Reference, syntax: Implicit }, MutTy { ty: Ty { hir_id: HirId(DefId(0:49 ~ multistep[afa8]::long_chain).26), span: $DIR/multistep.rs:114:32: 114:44 (#0), kind: Path(Resolved(None, Path { span: $DIR/multistep.rs:114:32: 114:44 (#0), res: Def(TyAlias, DefId(0:11 ~ multistep[afa8]::ArrayWrapper)), segments: [PathSegment { ident: ArrayWrapper#0, hir_id: HirId(DefId(0:49 ~ multistep[afa8]::long_chain).27), res: Def(TyAlias, DefId(0:11 ~ multistep[afa8]::ArrayWrapper)), args: None, infer_args: false }] })) }, mutbl: Not }) }), span: $DIR/multistep.rs:114:14: 114:44 (#0) }, can't compose [Deref(None) -> IntWrapper, Deref(Some(OverloadedDeref { mutbl: Not, span: $DIR/multistep.rs:116:14: 116:44 (#0) })) -> Wrap<[i32]>, Borrow(Ref(Not)) -> &Wrap<[i32]>] and [Deref(None) -> Wrap<[i32]>, Deref(Some(OverloadedDeref { mutbl: Not, span: $DIR/multistep.rs:117:14: 117:41 (#0) })) -> FinalType, Borrow(Ref(Not)) -> &FinalType] + --> $DIR/multistep.rs:114:14 + | +LL | 1 => &Wrap([]) as &ArrayWrapper, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: delayed at compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs:343:36 - disabled backtrace + --> $DIR/multistep.rs:114:14 + | +LL | 1 => &Wrap([]) as &ArrayWrapper, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: internal compiler error: while adjusting Expr { hir_id: HirId(DefId(0:49 ~ multistep[afa8]::long_chain).32), kind: Cast(Expr { hir_id: HirId(DefId(0:49 ~ multistep[afa8]::long_chain).33), kind: AddrOf(Ref, Not, Expr { hir_id: HirId(DefId(0:49 ~ multistep[afa8]::long_chain).34), kind: Path(Resolved(None, Path { span: $DIR/multistep.rs:115:15: 115:25 (#0), res: Def(Ctor(Struct, Const), DefId(0:14 ~ multistep[afa8]::IntWrapper::{constructor#0})), segments: [PathSegment { ident: IntWrapper#0, hir_id: HirId(DefId(0:49 ~ multistep[afa8]::long_chain).35), res: Def(Ctor(Struct, Const), DefId(0:14 ~ multistep[afa8]::IntWrapper::{constructor#0})), args: None, infer_args: true }] })), span: $DIR/multistep.rs:115:15: 115:25 (#0) }), span: $DIR/multistep.rs:115:14: 115:25 (#0) }, Ty { hir_id: HirId(DefId(0:49 ~ multistep[afa8]::long_chain).39), span: $DIR/multistep.rs:115:31: 115:42 (#0), kind: Ref(Lifetime { hir_id: HirId(DefId(0:49 ~ multistep[afa8]::long_chain).36), ident: '_#0, kind: Infer, source: Reference, syntax: Implicit }, MutTy { ty: Ty { hir_id: HirId(DefId(0:49 ~ multistep[afa8]::long_chain).37), span: $DIR/multistep.rs:115:32: 115:42 (#0), kind: Path(Resolved(None, Path { span: $DIR/multistep.rs:115:32: 115:42 (#0), res: Def(Struct, DefId(0:13 ~ multistep[afa8]::IntWrapper)), segments: [PathSegment { ident: IntWrapper#0, hir_id: HirId(DefId(0:49 ~ multistep[afa8]::long_chain).38), res: Def(Struct, DefId(0:13 ~ multistep[afa8]::IntWrapper)), args: None, infer_args: false }] })) }, mutbl: Not }) }), span: $DIR/multistep.rs:115:14: 115:42 (#0) }, can't compose [Deref(None) -> IntWrapper, Deref(Some(OverloadedDeref { mutbl: Not, span: $DIR/multistep.rs:116:14: 116:44 (#0) })) -> Wrap<[i32]>, Borrow(Ref(Not)) -> &Wrap<[i32]>] and [Deref(None) -> Wrap<[i32]>, Deref(Some(OverloadedDeref { mutbl: Not, span: $DIR/multistep.rs:117:14: 117:41 (#0) })) -> FinalType, Borrow(Ref(Not)) -> &FinalType] + --> $DIR/multistep.rs:115:14 + | +LL | 2 => &IntWrapper as &IntWrapper, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: delayed at compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs:343:36 - disabled backtrace + --> $DIR/multistep.rs:115:14 + | +LL | 2 => &IntWrapper as &IntWrapper, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: internal compiler error: while adjusting Expr { hir_id: HirId(DefId(0:50 ~ multistep[afa8]::mixed_coercion).8), kind: Cast(Expr { hir_id: HirId(DefId(0:50 ~ multistep[afa8]::mixed_coercion).9), kind: AddrOf(Ref, Not, Expr { hir_id: HirId(DefId(0:50 ~ multistep[afa8]::mixed_coercion).10), kind: Path(Resolved(None, Path { span: $DIR/multistep.rs:134:15: 134:22 (#0), res: Def(Ctor(Struct, Const), DefId(0:10 ~ multistep[afa8]::TopType::{constructor#0})), segments: [PathSegment { ident: TopType#0, hir_id: HirId(DefId(0:50 ~ multistep[afa8]::mixed_coercion).11), res: Def(Ctor(Struct, Const), DefId(0:10 ~ multistep[afa8]::TopType::{constructor#0})), args: None, infer_args: true }] })), span: $DIR/multistep.rs:134:15: 134:22 (#0) }), span: $DIR/multistep.rs:134:14: 134:22 (#0) }, Ty { hir_id: HirId(DefId(0:50 ~ multistep[afa8]::mixed_coercion).15), span: $DIR/multistep.rs:134:31: 134:39 (#0), kind: Ref(Lifetime { hir_id: HirId(DefId(0:50 ~ multistep[afa8]::mixed_coercion).12), ident: '_#0, kind: Infer, source: Reference, syntax: Implicit }, MutTy { ty: Ty { hir_id: HirId(DefId(0:50 ~ multistep[afa8]::mixed_coercion).13), span: $DIR/multistep.rs:134:32: 134:39 (#0), kind: Path(Resolved(None, Path { span: $DIR/multistep.rs:134:32: 134:39 (#0), res: Def(Struct, DefId(0:9 ~ multistep[afa8]::TopType)), segments: [PathSegment { ident: TopType#0, hir_id: HirId(DefId(0:50 ~ multistep[afa8]::mixed_coercion).14), res: Def(Struct, DefId(0:9 ~ multistep[afa8]::TopType)), args: None, infer_args: false }] })) }, mutbl: Not }) }), span: $DIR/multistep.rs:134:14: 134:39 (#0) }, can't compose [Deref(None) -> TopType, Deref(Some(OverloadedDeref { mutbl: Not, span: $DIR/multistep.rs:135:14: 135:44 (#0) })) -> Wrap<[i32; 0]>, Borrow(Ref(Not)) -> &Wrap<[i32; 0]>] and [Deref(None) -> Wrap<[i32; 0]>, Borrow(Ref(Not)) -> &Wrap<[i32; 0]>, Pointer(Unsize) -> _] + --> $DIR/multistep.rs:134:14 + | +LL | 0 => &TopType as &TopType, + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: delayed at compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs:343:36 - disabled backtrace + --> $DIR/multistep.rs:134:14 + | +LL | 0 => &TopType as &TopType, + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: internal compiler error: while adjusting Expr { hir_id: HirId(DefId(0:50 ~ multistep[afa8]::mixed_coercion).8), kind: Cast(Expr { hir_id: HirId(DefId(0:50 ~ multistep[afa8]::mixed_coercion).9), kind: AddrOf(Ref, Not, Expr { hir_id: HirId(DefId(0:50 ~ multistep[afa8]::mixed_coercion).10), kind: Path(Resolved(None, Path { span: $DIR/multistep.rs:134:15: 134:22 (#0), res: Def(Ctor(Struct, Const), DefId(0:10 ~ multistep[afa8]::TopType::{constructor#0})), segments: [PathSegment { ident: TopType#0, hir_id: HirId(DefId(0:50 ~ multistep[afa8]::mixed_coercion).11), res: Def(Ctor(Struct, Const), DefId(0:10 ~ multistep[afa8]::TopType::{constructor#0})), args: None, infer_args: true }] })), span: $DIR/multistep.rs:134:15: 134:22 (#0) }), span: $DIR/multistep.rs:134:14: 134:22 (#0) }, Ty { hir_id: HirId(DefId(0:50 ~ multistep[afa8]::mixed_coercion).15), span: $DIR/multistep.rs:134:31: 134:39 (#0), kind: Ref(Lifetime { hir_id: HirId(DefId(0:50 ~ multistep[afa8]::mixed_coercion).12), ident: '_#0, kind: Infer, source: Reference, syntax: Implicit }, MutTy { ty: Ty { hir_id: HirId(DefId(0:50 ~ multistep[afa8]::mixed_coercion).13), span: $DIR/multistep.rs:134:32: 134:39 (#0), kind: Path(Resolved(None, Path { span: $DIR/multistep.rs:134:32: 134:39 (#0), res: Def(Struct, DefId(0:9 ~ multistep[afa8]::TopType)), segments: [PathSegment { ident: TopType#0, hir_id: HirId(DefId(0:50 ~ multistep[afa8]::mixed_coercion).14), res: Def(Struct, DefId(0:9 ~ multistep[afa8]::TopType)), args: None, infer_args: false }] })) }, mutbl: Not }) }), span: $DIR/multistep.rs:134:14: 134:39 (#0) }, can't compose [Deref(None) -> Wrap<[i32; 0]>, Borrow(Ref(Not)) -> &Wrap<[i32; 0]>, Pointer(Unsize) -> _] and [Deref(None) -> Wrap<[i32]>, Deref(Some(OverloadedDeref { mutbl: Not, span: $DIR/multistep.rs:138:14: 138:41 (#0) })) -> FinalType, Borrow(Ref(Not)) -> &FinalType] + --> $DIR/multistep.rs:134:14 + | +LL | 0 => &TopType as &TopType, + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: delayed at compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs:343:36 - disabled backtrace + --> $DIR/multistep.rs:134:14 + | +LL | 0 => &TopType as &TopType, + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: internal compiler error: while adjusting Expr { hir_id: HirId(DefId(0:50 ~ multistep[afa8]::mixed_coercion).19), kind: Cast(Expr { hir_id: HirId(DefId(0:50 ~ multistep[afa8]::mixed_coercion).20), kind: AddrOf(Ref, Not, Expr { hir_id: HirId(DefId(0:50 ~ multistep[afa8]::mixed_coercion).21), kind: Call(Expr { hir_id: HirId(DefId(0:50 ~ multistep[afa8]::mixed_coercion).22), kind: Path(Resolved(None, Path { span: $DIR/multistep.rs:135:15: 135:19 (#0), res: Def(Ctor(Struct, Fn), DefId(0:6 ~ multistep[afa8]::Wrap::{constructor#0})), segments: [PathSegment { ident: Wrap#0, hir_id: HirId(DefId(0:50 ~ multistep[afa8]::mixed_coercion).23), res: Def(Ctor(Struct, Fn), DefId(0:6 ~ multistep[afa8]::Wrap::{constructor#0})), args: None, infer_args: true }] })), span: $DIR/multistep.rs:135:15: 135:19 (#0) }, [Expr { hir_id: HirId(DefId(0:50 ~ multistep[afa8]::mixed_coercion).24), kind: Array([]), span: $DIR/multistep.rs:135:20: 135:22 (#0) }]), span: $DIR/multistep.rs:135:15: 135:23 (#0) }), span: $DIR/multistep.rs:135:14: 135:23 (#0) }, Ty { hir_id: HirId(DefId(0:50 ~ multistep[afa8]::mixed_coercion).28), span: $DIR/multistep.rs:135:31: 135:44 (#0), kind: Ref(Lifetime { hir_id: HirId(DefId(0:50 ~ multistep[afa8]::mixed_coercion).25), ident: '_#0, kind: Infer, source: Reference, syntax: Implicit }, MutTy { ty: Ty { hir_id: HirId(DefId(0:50 ~ multistep[afa8]::mixed_coercion).26), span: $DIR/multistep.rs:135:32: 135:44 (#0), kind: Path(Resolved(None, Path { span: $DIR/multistep.rs:135:32: 135:44 (#0), res: Def(TyAlias, DefId(0:11 ~ multistep[afa8]::ArrayWrapper)), segments: [PathSegment { ident: ArrayWrapper#0, hir_id: HirId(DefId(0:50 ~ multistep[afa8]::mixed_coercion).27), res: Def(TyAlias, DefId(0:11 ~ multistep[afa8]::ArrayWrapper)), args: None, infer_args: false }] })) }, mutbl: Not }) }), span: $DIR/multistep.rs:135:14: 135:44 (#0) }, can't compose [Deref(None) -> Wrap<[i32; 0]>, Borrow(Ref(Not)) -> &Wrap<[i32; 0]>, Pointer(Unsize) -> _] and [Deref(None) -> Wrap<[i32]>, Deref(Some(OverloadedDeref { mutbl: Not, span: $DIR/multistep.rs:138:14: 138:41 (#0) })) -> FinalType, Borrow(Ref(Not)) -> &FinalType] + --> $DIR/multistep.rs:135:14 + | +LL | 1 => &Wrap([]) as &ArrayWrapper, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: delayed at compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs:343:36 - disabled backtrace + --> $DIR/multistep.rs:135:14 + | +LL | 1 => &Wrap([]) as &ArrayWrapper, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: internal compiler error: while adjusting Expr { hir_id: HirId(DefId(0:51 ~ multistep[afa8]::order_dependence).8), kind: Cast(Expr { hir_id: HirId(DefId(0:51 ~ multistep[afa8]::order_dependence).9), kind: AddrOf(Ref, Not, Expr { hir_id: HirId(DefId(0:51 ~ multistep[afa8]::order_dependence).10), kind: Call(Expr { hir_id: HirId(DefId(0:51 ~ multistep[afa8]::order_dependence).11), kind: Path(Resolved(None, Path { span: $DIR/multistep.rs:153:15: 153:19 (#0), res: Def(Ctor(Struct, Fn), DefId(0:6 ~ multistep[afa8]::Wrap::{constructor#0})), segments: [PathSegment { ident: Wrap#0, hir_id: HirId(DefId(0:51 ~ multistep[afa8]::order_dependence).12), res: Def(Ctor(Struct, Fn), DefId(0:6 ~ multistep[afa8]::Wrap::{constructor#0})), args: None, infer_args: true }] })), span: $DIR/multistep.rs:153:15: 153:19 (#0) }, [Expr { hir_id: HirId(DefId(0:51 ~ multistep[afa8]::order_dependence).13), kind: Array([]), span: $DIR/multistep.rs:153:20: 153:22 (#0) }]), span: $DIR/multistep.rs:153:15: 153:23 (#0) }), span: $DIR/multistep.rs:153:14: 153:23 (#0) }, Ty { hir_id: HirId(DefId(0:51 ~ multistep[afa8]::order_dependence).17), span: $DIR/multistep.rs:153:29: 153:42 (#0), kind: Ref(Lifetime { hir_id: HirId(DefId(0:51 ~ multistep[afa8]::order_dependence).14), ident: '_#0, kind: Infer, source: Reference, syntax: Implicit }, MutTy { ty: Ty { hir_id: HirId(DefId(0:51 ~ multistep[afa8]::order_dependence).15), span: $DIR/multistep.rs:153:30: 153:42 (#0), kind: Path(Resolved(None, Path { span: $DIR/multistep.rs:153:30: 153:42 (#0), res: Def(TyAlias, DefId(0:11 ~ multistep[afa8]::ArrayWrapper)), segments: [PathSegment { ident: ArrayWrapper#0, hir_id: HirId(DefId(0:51 ~ multistep[afa8]::order_dependence).16), res: Def(TyAlias, DefId(0:11 ~ multistep[afa8]::ArrayWrapper)), args: None, infer_args: false }] })) }, mutbl: Not }) }), span: $DIR/multistep.rs:153:14: 153:42 (#0) }, can't compose [Deref(None) -> Wrap<[i32; 0]>, Deref(Some(OverloadedDeref { mutbl: Not, span: $DIR/multistep.rs:154:14: 154:40 (#0) })) -> IntWrapper, Borrow(Ref(Not)) -> &IntWrapper] and [Deref(None) -> IntWrapper, Deref(Some(OverloadedDeref { mutbl: Not, span: $DIR/multistep.rs:155:14: 155:42 (#0) })) -> Wrap<[i32]>, Borrow(Ref(Not)) -> &Wrap<[i32]>] + --> $DIR/multistep.rs:153:14 + | +LL | 0 => &Wrap([]) as &ArrayWrapper, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: delayed at compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs:343:36 - disabled backtrace + --> $DIR/multistep.rs:153:14 + | +LL | 0 => &Wrap([]) as &ArrayWrapper, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: internal compiler error: while adjusting Expr { hir_id: HirId(DefId(0:52 ~ multistep[afa8]::deref_to_dyn).8), kind: Cast(Expr { hir_id: HirId(DefId(0:52 ~ multistep[afa8]::deref_to_dyn).9), kind: AddrOf(Ref, Not, Expr { hir_id: HirId(DefId(0:52 ~ multistep[afa8]::deref_to_dyn).10), kind: Path(Resolved(None, Path { span: $DIR/multistep.rs:179:15: 179:29 (#0), res: Def(Ctor(Struct, Const), DefId(0:19 ~ multistep[afa8]::TopTypeNoTrait::{constructor#0})), segments: [PathSegment { ident: TopTypeNoTrait#0, hir_id: HirId(DefId(0:52 ~ multistep[afa8]::deref_to_dyn).11), res: Def(Ctor(Struct, Const), DefId(0:19 ~ multistep[afa8]::TopTypeNoTrait::{constructor#0})), args: None, infer_args: true }] })), span: $DIR/multistep.rs:179:15: 179:29 (#0) }), span: $DIR/multistep.rs:179:14: 179:29 (#0) }, Ty { hir_id: HirId(DefId(0:52 ~ multistep[afa8]::deref_to_dyn).15), span: $DIR/multistep.rs:179:33: 179:48 (#0), kind: Ref(Lifetime { hir_id: HirId(DefId(0:52 ~ multistep[afa8]::deref_to_dyn).12), ident: '_#0, kind: Infer, source: Reference, syntax: Implicit }, MutTy { ty: Ty { hir_id: HirId(DefId(0:52 ~ multistep[afa8]::deref_to_dyn).13), span: $DIR/multistep.rs:179:34: 179:48 (#0), kind: Path(Resolved(None, Path { span: $DIR/multistep.rs:179:34: 179:48 (#0), res: Def(Struct, DefId(0:18 ~ multistep[afa8]::TopTypeNoTrait)), segments: [PathSegment { ident: TopTypeNoTrait#0, hir_id: HirId(DefId(0:52 ~ multistep[afa8]::deref_to_dyn).14), res: Def(Struct, DefId(0:18 ~ multistep[afa8]::TopTypeNoTrait)), args: None, infer_args: false }] })) }, mutbl: Not }) }), span: $DIR/multistep.rs:179:14: 179:48 (#0) }, can't compose [Deref(None) -> TopTypeNoTrait, Deref(Some(OverloadedDeref { mutbl: Not, span: $DIR/multistep.rs:180:14: 180:43 (#0) })) -> Wrap<[i32; 0]>, Deref(Some(OverloadedDeref { mutbl: Not, span: $DIR/multistep.rs:180:14: 180:43 (#0) })) -> IntWrapper, Deref(Some(OverloadedDeref { mutbl: Not, span: $DIR/multistep.rs:180:14: 180:43 (#0) })) -> Wrap<[i32]>, Deref(Some(OverloadedDeref { mutbl: Not, span: $DIR/multistep.rs:180:14: 180:43 (#0) })) -> FinalType, Borrow(Ref(Not)) -> &FinalType] and [Deref(None) -> FinalType, Borrow(Ref(Not)) -> &FinalType, Pointer(Unsize) -> _] + --> $DIR/multistep.rs:179:14 + | +LL | 0 => &TopTypeNoTrait as &TopTypeNoTrait, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: delayed at compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs:343:36 - disabled backtrace + --> $DIR/multistep.rs:179:14 + | +LL | 0 => &TopTypeNoTrait as &TopTypeNoTrait, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: internal compiler error: broken MIR in DefId(0:49 ~ multistep[afa8]::long_chain) (_15 = &(*_16)): bad assignment (&'?79 Wrap<[i32]> = &'?23 IntWrapper): NoSolution + --> $DIR/multistep.rs:115:14 + | +LL | 2 => &IntWrapper as &IntWrapper, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: delayed at compiler/rustc_borrowck/src/type_check/mod.rs:676:21 - disabled backtrace + --> $DIR/multistep.rs:115:14 + | +LL | 2 => &IntWrapper as &IntWrapper, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: internal compiler error: broken MIR in DefId(0:49 ~ multistep[afa8]::long_chain) (_9 = &(*_10)): bad assignment (&'?75 Wrap<[i32]> = &'?27 Wrap<[i32; 0_usize]>): NoSolution + --> $DIR/multistep.rs:114:14 + | +LL | 1 => &Wrap([]) as &ArrayWrapper, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: delayed at compiler/rustc_borrowck/src/type_check/mod.rs:676:21 - disabled backtrace + --> $DIR/multistep.rs:114:14 + | +LL | 1 => &Wrap([]) as &ArrayWrapper, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: internal compiler error: broken MIR in DefId(0:49 ~ multistep[afa8]::long_chain) (_4 = &(*_5)): bad assignment (&'?71 Wrap<[i32]> = &'?31 TopType): NoSolution + --> $DIR/multistep.rs:113:14 + | +LL | 0 => &TopType as &TopType, + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: delayed at compiler/rustc_borrowck/src/type_check/mod.rs:676:21 - disabled backtrace + --> $DIR/multistep.rs:113:14 + | +LL | 0 => &TopType as &TopType, + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: internal compiler error: broken MIR in DefId(0:50 ~ multistep[afa8]::mixed_coercion) (_9 = &(*_10)): bad assignment (&'?64 Wrap<[i32]> = &'?21 Wrap<[i32; 0_usize]>): NoSolution + --> $DIR/multistep.rs:135:14 + | +LL | 1 => &Wrap([]) as &ArrayWrapper, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: delayed at compiler/rustc_borrowck/src/type_check/mod.rs:676:21 - disabled backtrace + --> $DIR/multistep.rs:135:14 + | +LL | 1 => &Wrap([]) as &ArrayWrapper, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: internal compiler error: broken MIR in DefId(0:50 ~ multistep[afa8]::mixed_coercion) (_4 = &(*_5)): bad assignment (&'?60 Wrap<[i32]> = &'?25 TopType): NoSolution + --> $DIR/multistep.rs:134:14 + | +LL | 0 => &TopType as &TopType, + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: delayed at compiler/rustc_borrowck/src/type_check/mod.rs:676:21 - disabled backtrace + --> $DIR/multistep.rs:134:14 + | +LL | 0 => &TopType as &TopType, + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: internal compiler error: broken MIR in DefId(0:51 ~ multistep[afa8]::order_dependence) (_4 = &(*_5)): bad assignment (&'?101 IntWrapper = &'?25 Wrap<[i32; 0_usize]>): NoSolution + --> $DIR/multistep.rs:153:14 + | +LL | 0 => &Wrap([]) as &ArrayWrapper, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: delayed at compiler/rustc_borrowck/src/type_check/mod.rs:676:21 - disabled backtrace + --> $DIR/multistep.rs:153:14 + | +LL | 0 => &Wrap([]) as &ArrayWrapper, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: internal compiler error: broken MIR in DefId(0:52 ~ multistep[afa8]::deref_to_dyn) (_3 = &(*_4)): bad assignment (&'?70 FinalType = &'?17 TopTypeNoTrait): NoSolution + --> $DIR/multistep.rs:179:14 + | +LL | 0 => &TopTypeNoTrait as &TopTypeNoTrait, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: delayed at compiler/rustc_borrowck/src/type_check/mod.rs:676:21 - disabled backtrace + --> $DIR/multistep.rs:179:14 + | +LL | 0 => &TopTypeNoTrait as &TopTypeNoTrait, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +note: we would appreciate a bug report: https://github.com/rust-lang/rust/issues/new?labels=C-bug%2C+I-ICE%2C+T-compiler&template=ice.md + +note: please make sure that you have updated to the latest nightly + +note: rustc 1.94.0-dev running on aarch64-unknown-linux-gnu + +note: compiler flags: -Z threads=1 -Z simulate-remapped-rust-src-base=/rustc/FAKE_PREFIX -Z translate-remapped-path-to-local-path=no -Z ignore-directory-in-diagnostics-source-blocks=/home/gh-jackh726/.cargo -Z ignore-directory-in-diagnostics-source-blocks=/home/gh-jackh726/rust2/vendor -C codegen-units=1 -Z ui-testing -Z deduplicate-diagnostics=no -Z write-long-types-to-disk=no -C strip=debuginfo -C prefer-dynamic -C rpath -C debuginfo=0 + +query stack during panic: +end of query stack From 6bae9c3132cee12a2da99d1394d82bde5f718494 Mon Sep 17 00:00:00 2001 From: jackh726 Date: Wed, 17 Dec 2025 15:48:58 +0000 Subject: [PATCH 3/3] Always use LUB for match arms --- compiler/rustc_hir_typeck/src/_match.rs | 1 + compiler/rustc_hir_typeck/src/coercion.rs | 16 +++++++++++----- .../coercion/coerce-loop-issue-122561.stderr | 6 ------ tests/ui/issues/issue-28839.rs | 14 +++++++++++--- tests/ui/issues/issue-28839.stderr | 15 +++++++++++++++ tests/ui/nll/issue-52213.rs | 2 +- tests/ui/nll/issue-52213.stderr | 18 ++++++++++-------- 7 files changed, 49 insertions(+), 23 deletions(-) create mode 100644 tests/ui/issues/issue-28839.stderr diff --git a/compiler/rustc_hir_typeck/src/_match.rs b/compiler/rustc_hir_typeck/src/_match.rs index 6467adb54dab0..c752f52d9c7cb 100644 --- a/compiler/rustc_hir_typeck/src/_match.rs +++ b/compiler/rustc_hir_typeck/src/_match.rs @@ -75,6 +75,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; CoerceMany::with_coercion_sites(coerce_first, arms) }; + coercion.force_lub(); let mut prior_non_diverging_arms = vec![]; // Used only for diagnostics. let mut prior_arm = None; diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index 93f500dc5dd82..af622ebd61746 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -1387,6 +1387,7 @@ pub(crate) struct CoerceMany<'tcx, 'exprs, E: AsCoercionSite> { final_ty: Option>, expressions: Expressions<'tcx, 'exprs, E>, pushed: usize, + force_lub: bool, } /// The type of a `CoerceMany` that is storing up the expressions into @@ -1416,7 +1417,13 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { } fn make(expected_ty: Ty<'tcx>, expressions: Expressions<'tcx, 'exprs, E>) -> Self { - CoerceMany { expected_ty, final_ty: None, expressions, pushed: 0 } + CoerceMany { expected_ty, final_ty: None, expressions, pushed: 0, force_lub: false } + } + + pub(crate) fn force_lub(&mut self) { + // Don't accidentally let someone switch this after coercing things + assert_eq!(self.pushed, 0); + self.force_lub = true; } /// Returns the "expected type" with which this coercion was @@ -1529,10 +1536,9 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { // Handle the actual type unification etc. let result = if let Some(expression) = expression { - if self.pushed == 0 { - // Special-case the first expression we are coercing. - // To be honest, I'm not entirely sure why we do this. - // We don't allow two-phase borrows, see comment in try_find_coercion_lub for why + if !self.force_lub && self.pushed == 0 { + // For this *first* expression, we do *not* use LUB + // (which `try_find_coercion_lub` does). fcx.coerce( expression, expression_ty, diff --git a/tests/ui/coercion/coerce-loop-issue-122561.stderr b/tests/ui/coercion/coerce-loop-issue-122561.stderr index 3fd6671565f18..39ea0bb6e6ea8 100644 --- a/tests/ui/coercion/coerce-loop-issue-122561.stderr +++ b/tests/ui/coercion/coerce-loop-issue-122561.stderr @@ -90,12 +90,6 @@ LL | | } | = note: expected type `!` found unit type `()` - = note: `for` loops evaluate to unit type `()` -help: consider adding a diverging expression here - | -LL ~ } -LL + /* `loop {}` or `panic!("...")` */ - | error[E0308]: mismatched types --> $DIR/coerce-loop-issue-122561.rs:35:32 diff --git a/tests/ui/issues/issue-28839.rs b/tests/ui/issues/issue-28839.rs index 76b0fa2d6e089..7c5960c0a70fc 100644 --- a/tests/ui/issues/issue-28839.rs +++ b/tests/ui/issues/issue-28839.rs @@ -1,12 +1,20 @@ -//@ run-pass +//@ check-fail pub struct Foo; -pub fn get_foo2<'a>(foo: &'a mut Option<&'a mut Foo>) -> &'a mut Foo { +pub fn get_foo1<'a>(foo: &'a mut Option<&'a mut Foo>) -> &'a mut Foo { match foo { - // Ensure that this is not considered a move, but rather a reborrow. &mut Some(ref mut x) => *x, + //~^ ERROR cannot move out of + &mut None => panic!(), + } +} + +pub fn get_foo2<'a>(foo: &'a mut Option<&'a mut Foo>) -> &'a mut Foo { + match foo { &mut None => panic!(), + &mut Some(ref mut x) => *x, + //~^ ERROR cannot move out of } } diff --git a/tests/ui/issues/issue-28839.stderr b/tests/ui/issues/issue-28839.stderr new file mode 100644 index 0000000000000..29bbada5673d7 --- /dev/null +++ b/tests/ui/issues/issue-28839.stderr @@ -0,0 +1,15 @@ +error[E0507]: cannot move out of `*x` which is behind a mutable reference + --> $DIR/issue-28839.rs:7:33 + | +LL | &mut Some(ref mut x) => *x, + | ^^ move occurs because `*x` has type `&mut Foo`, which does not implement the `Copy` trait + +error[E0507]: cannot move out of `*x` which is behind a mutable reference + --> $DIR/issue-28839.rs:16:33 + | +LL | &mut Some(ref mut x) => *x, + | ^^ move occurs because `*x` has type `&mut Foo`, which does not implement the `Copy` trait + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0507`. diff --git a/tests/ui/nll/issue-52213.rs b/tests/ui/nll/issue-52213.rs index a016924a869a8..2c8ffdca4df78 100644 --- a/tests/ui/nll/issue-52213.rs +++ b/tests/ui/nll/issue-52213.rs @@ -1,7 +1,7 @@ fn transmute_lifetime<'a, 'b, T>(t: &'a (T,)) -> &'b T { match (&t,) { - ((u,),) => u, //~^ ERROR lifetime may not live long enough + ((u,),) => u, } } diff --git a/tests/ui/nll/issue-52213.stderr b/tests/ui/nll/issue-52213.stderr index ed3723a7f03b0..2e6a0d81cba02 100644 --- a/tests/ui/nll/issue-52213.stderr +++ b/tests/ui/nll/issue-52213.stderr @@ -1,13 +1,15 @@ error: lifetime may not live long enough - --> $DIR/issue-52213.rs:3:20 + --> $DIR/issue-52213.rs:2:5 | -LL | fn transmute_lifetime<'a, 'b, T>(t: &'a (T,)) -> &'b T { - | -- -- lifetime `'b` defined here - | | - | lifetime `'a` defined here -LL | match (&t,) { -LL | ((u,),) => u, - | ^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a` +LL | fn transmute_lifetime<'a, 'b, T>(t: &'a (T,)) -> &'b T { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +LL | / match (&t,) { +LL | | +LL | | ((u,),) => u, +LL | | } + | |_____^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a` | = help: consider adding the following bound: `'a: 'b`