about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_mir_build/src/thir/cx/mod.rs2
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/mod.rs2
-rw-r--r--compiler/rustc_mir_build/src/thir/util.rs22
3 files changed, 23 insertions, 3 deletions
diff --git a/compiler/rustc_mir_build/src/thir/cx/mod.rs b/compiler/rustc_mir_build/src/thir/cx/mod.rs
index 2e069cae426..3d55c1401b6 100644
--- a/compiler/rustc_mir_build/src/thir/cx/mod.rs
+++ b/compiler/rustc_mir_build/src/thir/cx/mod.rs
@@ -207,7 +207,7 @@ impl<'tcx> ThirBuildCx<'tcx> {
         &self,
         hir_id: HirId,
     ) -> Option<ty::CanonicalUserType<'tcx>> {
-        crate::thir::util::user_args_applied_to_ty_of_hir_id(self.typeck_results, hir_id)
+        crate::thir::util::user_args_applied_to_ty_of_hir_id(self.tcx, self.typeck_results, hir_id)
     }
 }
 
diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
index 8dc3f998e09..4bfeab44bf4 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
@@ -539,7 +539,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
         &self,
         hir_id: hir::HirId,
     ) -> Option<ty::CanonicalUserType<'tcx>> {
-        crate::thir::util::user_args_applied_to_ty_of_hir_id(self.typeck_results, hir_id)
+        crate::thir::util::user_args_applied_to_ty_of_hir_id(self.tcx, self.typeck_results, hir_id)
     }
 
     /// Takes a HIR Path. If the path is a constant, evaluates it and feeds
diff --git a/compiler/rustc_mir_build/src/thir/util.rs b/compiler/rustc_mir_build/src/thir/util.rs
index 60a47a94e3a..457957f5fce 100644
--- a/compiler/rustc_mir_build/src/thir/util.rs
+++ b/compiler/rustc_mir_build/src/thir/util.rs
@@ -1,12 +1,16 @@
+use std::assert_matches::assert_matches;
+
 use rustc_hir as hir;
+use rustc_hir::def::DefKind;
 use rustc_middle::bug;
-use rustc_middle::ty::{self, CanonicalUserType};
+use rustc_middle::ty::{self, CanonicalUserType, TyCtxt};
 use tracing::debug;
 
 /// Looks up the type associated with this hir-id and applies the
 /// user-given generic parameters; the hir-id must map to a suitable
 /// type.
 pub(crate) fn user_args_applied_to_ty_of_hir_id<'tcx>(
+    tcx: TyCtxt<'tcx>,
     typeck_results: &ty::TypeckResults<'tcx>,
     hir_id: hir::HirId,
 ) -> Option<CanonicalUserType<'tcx>> {
@@ -16,7 +20,23 @@ pub(crate) fn user_args_applied_to_ty_of_hir_id<'tcx>(
     let ty = typeck_results.node_type(hir_id);
     match ty.kind() {
         ty::Adt(adt_def, ..) => {
+            // This "fixes" user type annotations for tupled ctor patterns for ADTs.
+            // That's because `type_of(ctor_did)` returns a FnDef, but we actually
+            // want to be annotating the type of the ADT itself. It's a bit goofy,
+            // but it's easier to adjust this here rather than in the path lowering
+            // code for patterns in HIR.
             if let ty::UserTypeKind::TypeOf(did, _) = &mut user_ty.value.kind {
+                // This is either already set up correctly (struct, union, enum, or variant),
+                // or needs adjusting (ctor). Make sure we don't start adjusting other
+                // user annotations like consts or fn calls.
+                assert_matches!(
+                    tcx.def_kind(*did),
+                    DefKind::Ctor(..)
+                        | DefKind::Struct
+                        | DefKind::Enum
+                        | DefKind::Union
+                        | DefKind::Variant
+                );
                 *did = adt_def.did();
             }
             Some(user_ty)