@@ -731,9 +731,32 @@ impl InferenceContext<'_> {
731731 & Pat :: Expr ( expr) => {
732732 Some ( self . infer_expr ( expr, & Expectation :: none ( ) , ExprIsRead :: No ) )
733733 }
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+ }
735757 _ => None ,
736758 } ;
759+ let is_destructuring_assignment = lhs_ty. is_none ( ) ;
737760
738761 if let Some ( lhs_ty) = lhs_ty {
739762 self . write_pat_ty ( target, lhs_ty. clone ( ) ) ;
@@ -747,7 +770,15 @@ impl InferenceContext<'_> {
747770 self . inside_assignment = false ;
748771 self . resolver . reset_to_guard ( resolver_guard) ;
749772 }
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+ }
751782 }
752783 Expr :: Range { lhs, rhs, range_type } => {
753784 let lhs_ty =
0 commit comments