Explain weird quirk in user type annotation lowering

This commit is contained in:
Michael Goulet 2025-03-09 19:04:37 +00:00
parent 385970f0c1
commit 9067f7cad6
3 changed files with 23 additions and 3 deletions

View file

@ -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)
}
}

View file

@ -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

View file

@ -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)