@@ -10,92 +10,15 @@ use rustc_middle::ty::util::IntTypeExt;
1010use rustc_middle:: ty:: { self , DefiningScopeKind , IsSuggestable , Ty , TyCtxt , TypeVisitableExt } ;
1111use rustc_middle:: { bug, span_bug} ;
1212use rustc_span:: { DUMMY_SP , Ident , Span } ;
13+ use tracing:: instrument;
1314
1415use super :: { HirPlaceholderCollector , ItemCtxt , bad_placeholder} ;
1516use crate :: check:: wfcheck:: check_static_item;
1617use crate :: hir_ty_lowering:: HirTyLowerer ;
1718
1819mod opaque;
1920
20- fn anon_const_type_of < ' tcx > ( icx : & ItemCtxt < ' tcx > , def_id : LocalDefId ) -> Ty < ' tcx > {
21- use hir:: * ;
22- use rustc_middle:: ty:: Ty ;
23- let tcx = icx. tcx ;
24- let hir_id = tcx. local_def_id_to_hir_id ( def_id) ;
25-
26- let node = tcx. hir_node ( hir_id) ;
27- let Node :: AnonConst ( & AnonConst { span, .. } ) = node else {
28- span_bug ! (
29- tcx. def_span( def_id) ,
30- "expected anon const in `anon_const_type_of`, got {node:?}"
31- ) ;
32- } ;
33-
34- let parent_node_id = tcx. parent_hir_id ( hir_id) ;
35- let parent_node = tcx. hir_node ( parent_node_id) ;
36-
37- match parent_node {
38- // Anon consts "inside" the type system.
39- Node :: ConstArg ( & ConstArg {
40- hir_id : arg_hir_id,
41- kind : ConstArgKind :: Anon ( & AnonConst { hir_id : anon_hir_id, .. } ) ,
42- ..
43- } ) if anon_hir_id == hir_id => const_arg_anon_type_of ( icx, arg_hir_id, span) ,
44-
45- Node :: Variant ( Variant { disr_expr : Some ( e) , .. } ) if e. hir_id == hir_id => {
46- tcx. adt_def ( tcx. hir_get_parent_item ( hir_id) ) . repr ( ) . discr_type ( ) . to_ty ( tcx)
47- }
48-
49- Node :: Field ( & hir:: FieldDef { default : Some ( c) , def_id : field_def_id, .. } )
50- if c. hir_id == hir_id =>
51- {
52- tcx. type_of ( field_def_id) . instantiate_identity ( )
53- }
54-
55- _ => Ty :: new_error_with_message (
56- tcx,
57- span,
58- format ! ( "unexpected anon const parent in type_of(): {parent_node:?}" ) ,
59- ) ,
60- }
61- }
62-
63- fn const_arg_anon_type_of < ' tcx > ( icx : & ItemCtxt < ' tcx > , arg_hir_id : HirId , span : Span ) -> Ty < ' tcx > {
64- use hir:: * ;
65- use rustc_middle:: ty:: Ty ;
66-
67- let tcx = icx. tcx ;
68-
69- match tcx. parent_hir_node ( arg_hir_id) {
70- // Array length const arguments do not have `type_of` fed as there is never a corresponding
71- // generic parameter definition.
72- Node :: Ty ( & hir:: Ty { kind : TyKind :: Array ( _, ref constant) , .. } )
73- | Node :: Expr ( & Expr { kind : ExprKind :: Repeat ( _, ref constant) , .. } )
74- if constant. hir_id == arg_hir_id =>
75- {
76- tcx. types . usize
77- }
78-
79- Node :: TyPat ( pat) => {
80- let node = match tcx. parent_hir_node ( pat. hir_id ) {
81- // Or patterns can be nested one level deep
82- Node :: TyPat ( p) => tcx. parent_hir_node ( p. hir_id ) ,
83- other => other,
84- } ;
85- let hir:: TyKind :: Pat ( ty, _) = node. expect_ty ( ) . kind else { bug ! ( ) } ;
86- icx. lower_ty ( ty)
87- }
88-
89- // This is not a `bug!` as const arguments in path segments that did not resolve to anything
90- // will result in `type_of` never being fed.
91- _ => Ty :: new_error_with_message (
92- tcx,
93- span,
94- "`type_of` called on const argument's anon const before the const argument was lowered" ,
95- ) ,
96- }
97- }
98-
21+ #[ instrument( level = "debug" , skip( tcx) , ret) ]
9922pub ( super ) fn type_of ( tcx : TyCtxt < ' _ > , def_id : LocalDefId ) -> ty:: EarlyBinder < ' _ , Ty < ' _ > > {
10023 use rustc_hir:: * ;
10124 use rustc_middle:: ty:: Ty ;
@@ -408,6 +331,85 @@ pub(super) fn type_of_opaque_hir_typeck(
408331 }
409332}
410333
334+ fn anon_const_type_of < ' tcx > ( icx : & ItemCtxt < ' tcx > , def_id : LocalDefId ) -> Ty < ' tcx > {
335+ use hir:: * ;
336+ use rustc_middle:: ty:: Ty ;
337+ let tcx = icx. tcx ;
338+ let hir_id = tcx. local_def_id_to_hir_id ( def_id) ;
339+
340+ let node = tcx. hir_node ( hir_id) ;
341+ let Node :: AnonConst ( & AnonConst { span, .. } ) = node else {
342+ span_bug ! (
343+ tcx. def_span( def_id) ,
344+ "expected anon const in `anon_const_type_of`, got {node:?}"
345+ ) ;
346+ } ;
347+
348+ let parent_node_id = tcx. parent_hir_id ( hir_id) ;
349+ let parent_node = tcx. hir_node ( parent_node_id) ;
350+
351+ match parent_node {
352+ // Anon consts "inside" the type system.
353+ Node :: ConstArg ( & ConstArg {
354+ hir_id : arg_hir_id,
355+ kind : ConstArgKind :: Anon ( & AnonConst { hir_id : anon_hir_id, .. } ) ,
356+ ..
357+ } ) if anon_hir_id == hir_id => const_arg_anon_type_of ( icx, arg_hir_id, span) ,
358+
359+ Node :: Variant ( Variant { disr_expr : Some ( e) , .. } ) if e. hir_id == hir_id => {
360+ tcx. adt_def ( tcx. hir_get_parent_item ( hir_id) ) . repr ( ) . discr_type ( ) . to_ty ( tcx)
361+ }
362+
363+ Node :: Field ( & hir:: FieldDef { default : Some ( c) , def_id : field_def_id, .. } )
364+ if c. hir_id == hir_id =>
365+ {
366+ tcx. type_of ( field_def_id) . instantiate_identity ( )
367+ }
368+
369+ _ => Ty :: new_error_with_message (
370+ tcx,
371+ span,
372+ format ! ( "unexpected anon const parent in type_of(): {parent_node:?}" ) ,
373+ ) ,
374+ }
375+ }
376+
377+ fn const_arg_anon_type_of < ' tcx > ( icx : & ItemCtxt < ' tcx > , arg_hir_id : HirId , span : Span ) -> Ty < ' tcx > {
378+ use hir:: * ;
379+ use rustc_middle:: ty:: Ty ;
380+
381+ let tcx = icx. tcx ;
382+
383+ match tcx. parent_hir_node ( arg_hir_id) {
384+ // Array length const arguments do not have `type_of` fed as there is never a corresponding
385+ // generic parameter definition.
386+ Node :: Ty ( & hir:: Ty { kind : TyKind :: Array ( _, ref constant) , .. } )
387+ | Node :: Expr ( & Expr { kind : ExprKind :: Repeat ( _, ref constant) , .. } )
388+ if constant. hir_id == arg_hir_id =>
389+ {
390+ tcx. types . usize
391+ }
392+
393+ Node :: TyPat ( pat) => {
394+ let node = match tcx. parent_hir_node ( pat. hir_id ) {
395+ // Or patterns can be nested one level deep
396+ Node :: TyPat ( p) => tcx. parent_hir_node ( p. hir_id ) ,
397+ other => other,
398+ } ;
399+ let hir:: TyKind :: Pat ( ty, _) = node. expect_ty ( ) . kind else { bug ! ( ) } ;
400+ icx. lower_ty ( ty)
401+ }
402+
403+ // This is not a `bug!` as const arguments in path segments that did not resolve to anything
404+ // will result in `type_of` never being fed.
405+ _ => Ty :: new_error_with_message (
406+ tcx,
407+ span,
408+ "`type_of` called on const argument's anon const before the const argument was lowered" ,
409+ ) ,
410+ }
411+ }
412+
411413fn infer_placeholder_type < ' tcx > (
412414 cx : & dyn HirTyLowerer < ' tcx > ,
413415 def_id : LocalDefId ,
0 commit comments