@@ -731,9 +731,32 @@ impl InferenceContext<'_> {
731
731
& Pat :: Expr ( expr) => {
732
732
Some ( self . infer_expr ( expr, & Expectation :: none ( ) , ExprIsRead :: No ) )
733
733
}
734
- Pat :: Path ( path) => Some ( self . infer_expr_path ( path, target. into ( ) , tgt_expr) ) ,
734
+ Pat :: Path ( path) => {
735
+ let resolver_guard =
736
+ self . resolver . update_to_inner_scope ( self . db , self . owner , tgt_expr) ;
737
+ let resolution = self . resolver . resolve_path_in_value_ns_fully (
738
+ self . db ,
739
+ path,
740
+ self . body . pat_path_hygiene ( target) ,
741
+ ) ;
742
+ self . resolver . reset_to_guard ( resolver_guard) ;
743
+
744
+ if matches ! (
745
+ resolution,
746
+ Some (
747
+ ValueNs :: ConstId ( _)
748
+ | ValueNs :: StructId ( _)
749
+ | ValueNs :: EnumVariantId ( _)
750
+ )
751
+ ) {
752
+ None
753
+ } else {
754
+ Some ( self . infer_expr_path ( path, target. into ( ) , tgt_expr) )
755
+ }
756
+ }
735
757
_ => None ,
736
758
} ;
759
+ let is_destructuring_assignment = lhs_ty. is_none ( ) ;
737
760
738
761
if let Some ( lhs_ty) = lhs_ty {
739
762
self . write_pat_ty ( target, lhs_ty. clone ( ) ) ;
@@ -747,7 +770,15 @@ impl InferenceContext<'_> {
747
770
self . inside_assignment = false ;
748
771
self . resolver . reset_to_guard ( resolver_guard) ;
749
772
}
750
- self . result . standard_types . unit . clone ( )
773
+ if is_destructuring_assignment && self . diverges . is_always ( ) {
774
+ // Ordinary assignments always return `()`, even when they diverge.
775
+ // However, rustc lowers destructuring assignments into blocks, and blocks return `!` if they have no tail
776
+ // expression and they diverge. Therefore, we have to do the same here, even though we don't lower destructuring
777
+ // assignments into blocks.
778
+ self . table . new_maybe_never_var ( )
779
+ } else {
780
+ self . result . standard_types . unit . clone ( )
781
+ }
751
782
}
752
783
Expr :: Range { lhs, rhs, range_type } => {
753
784
let lhs_ty =
0 commit comments