1
+ use std:: assert_matches:: assert_matches;
2
+
1
3
use rustc_hir as hir;
4
+ use rustc_hir:: def:: DefKind ;
2
5
use rustc_middle:: bug;
3
- use rustc_middle:: ty:: { self , CanonicalUserType } ;
6
+ use rustc_middle:: ty:: { self , CanonicalUserType , TyCtxt } ;
4
7
use tracing:: debug;
5
8
6
9
/// Looks up the type associated with this hir-id and applies the
7
10
/// user-given generic parameters; the hir-id must map to a suitable
8
11
/// type.
9
12
pub ( crate ) fn user_args_applied_to_ty_of_hir_id < ' tcx > (
13
+ tcx : TyCtxt < ' tcx > ,
10
14
typeck_results : & ty:: TypeckResults < ' tcx > ,
11
15
hir_id : hir:: HirId ,
12
16
) -> Option < CanonicalUserType < ' tcx > > {
@@ -16,7 +20,23 @@ pub(crate) fn user_args_applied_to_ty_of_hir_id<'tcx>(
16
20
let ty = typeck_results. node_type ( hir_id) ;
17
21
match ty. kind ( ) {
18
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.
19
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
+ ) ;
20
40
* did = adt_def. did ( ) ;
21
41
}
22
42
Some ( user_ty)
0 commit comments