rustc_mir_build/thir/
util.rs

1use std::assert_matches::assert_matches;
2
3use rustc_hir as hir;
4use rustc_hir::def::DefKind;
5use rustc_middle::bug;
6use rustc_middle::ty::{self, CanonicalUserType, TyCtxt};
7use tracing::debug;
8
9/// Looks up the type associated with this hir-id and applies the
10/// user-given generic parameters; the hir-id must map to a suitable
11/// type.
12pub(crate) fn user_args_applied_to_ty_of_hir_id<'tcx>(
13    tcx: TyCtxt<'tcx>,
14    typeck_results: &ty::TypeckResults<'tcx>,
15    hir_id: hir::HirId,
16) -> Option<CanonicalUserType<'tcx>> {
17    let user_provided_types = typeck_results.user_provided_types();
18    let mut user_ty = *user_provided_types.get(hir_id)?;
19    debug!("user_subts_applied_to_ty_of_hir_id: user_ty={:?}", user_ty);
20    let ty = typeck_results.node_type(hir_id);
21    match ty.kind() {
22        ty::Adt(adt_def, ..) => {
23            // This "fixes" user type annotations for tupled ctor patterns for ADTs.
24            // That's because `type_of(ctor_did)` returns a FnDef, but we actually
25            // want to be annotating the type of the ADT itself. It's a bit goofy,
26            // but it's easier to adjust this here rather than in the path lowering
27            // code for patterns in HIR.
28            if let ty::UserTypeKind::TypeOf(did, _) = &mut user_ty.value.kind {
29                // This is either already set up correctly (struct, union, enum, or variant),
30                // or needs adjusting (ctor). Make sure we don't start adjusting other
31                // user annotations like consts or fn calls.
32                assert_matches!(
33                    tcx.def_kind(*did),
34                    DefKind::Ctor(..)
35                        | DefKind::Struct
36                        | DefKind::Enum
37                        | DefKind::Union
38                        | DefKind::Variant
39                );
40                *did = adt_def.did();
41            }
42            Some(user_ty)
43        }
44        ty::FnDef(..) => Some(user_ty),
45        _ => bug!("ty: {:?} should not have user provided type {:?} recorded ", ty, user_ty),
46    }
47}