@@ -333,7 +333,12 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
333333 find_opaque_ty_constraints_for_tait ( tcx, def_id)
334334 }
335335 // Opaque types desugared from `impl Trait`.
336- ItemKind :: OpaqueTy ( OpaqueTy { origin : hir:: OpaqueTyOrigin :: FnReturn ( owner) | hir:: OpaqueTyOrigin :: AsyncFn ( owner) , in_trait, .. } ) => {
336+ ItemKind :: OpaqueTy ( OpaqueTy {
337+ origin :
338+ hir:: OpaqueTyOrigin :: FnReturn ( owner) | hir:: OpaqueTyOrigin :: AsyncFn ( owner) ,
339+ in_trait,
340+ ..
341+ } ) => {
337342 if in_trait {
338343 span_bug ! ( item. span, "impl-trait in trait has no default" )
339344 } else {
@@ -378,7 +383,9 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
378383
379384 Node :: Field ( field) => icx. to_ty ( field. ty ) ,
380385
381- Node :: Expr ( & Expr { kind : ExprKind :: Closure { ..} , .. } ) => tcx. typeck ( def_id) . node_type ( hir_id) ,
386+ Node :: Expr ( & Expr { kind : ExprKind :: Closure { .. } , .. } ) => {
387+ tcx. typeck ( def_id) . node_type ( hir_id)
388+ }
382389
383390 Node :: AnonConst ( _) if let Some ( param) = tcx. opt_const_param_of ( def_id) => {
384391 // We defer to `type_of` of the corresponding parameter
@@ -410,40 +417,91 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
410417 | Node :: Item ( & Item { kind : ItemKind :: GlobalAsm ( asm) , .. } )
411418 if asm. operands . iter ( ) . any ( |( op, _op_sp) | match op {
412419 hir:: InlineAsmOperand :: Const { anon_const }
413- | hir:: InlineAsmOperand :: SymFn { anon_const } => anon_const. hir_id == hir_id,
420+ | hir:: InlineAsmOperand :: SymFn { anon_const } => {
421+ anon_const. hir_id == hir_id
422+ }
414423 _ => false ,
415424 } ) =>
416425 {
417426 tcx. typeck ( def_id) . node_type ( hir_id)
418427 }
419428
420- Node :: Variant ( Variant { disr_expr : Some ( ref e) , .. } ) if e. hir_id == hir_id => tcx
421- . adt_def ( tcx. hir ( ) . get_parent_item ( hir_id) )
422- . repr ( )
423- . discr_type ( )
424- . to_ty ( tcx) ,
429+ Node :: Variant ( Variant { disr_expr : Some ( ref e) , .. } ) if e. hir_id == hir_id => {
430+ tcx. adt_def ( tcx. hir ( ) . get_parent_item ( hir_id) ) . repr ( ) . discr_type ( ) . to_ty ( tcx)
431+ }
425432
426- Node :: TypeBinding ( binding @ & TypeBinding { hir_id : binding_id, .. } )
427- if let Node :: TraitRef ( trait_ref) = tcx. hir ( ) . get (
428- tcx. hir ( ) . get_parent_node ( binding_id)
429- ) =>
433+ Node :: TypeBinding (
434+ binding @ & TypeBinding {
435+ hir_id : binding_id,
436+ kind : TypeBindingKind :: Equality { term : Term :: Const ( ref e) } ,
437+ ..
438+ } ,
439+ ) if let Node :: TraitRef ( trait_ref) =
440+ tcx. hir ( ) . get ( tcx. hir ( ) . get_parent_node ( binding_id) )
441+ && e. hir_id == hir_id =>
430442 {
431- let Some ( trait_def_id) = trait_ref. trait_def_id ( ) else {
432- return tcx. ty_error_with_message ( DUMMY_SP , "Could not find trait" ) ;
433- } ;
434- let assoc_items = tcx. associated_items ( trait_def_id) ;
435- let assoc_item = assoc_items. find_by_name_and_kind (
436- tcx, binding. ident , ty:: AssocKind :: Const , def_id. to_def_id ( ) ,
437- ) ;
438- if let Some ( assoc_item) = assoc_item {
439- tcx. type_of ( assoc_item. def_id )
440- } else {
441- // FIXME(associated_const_equality): add a useful error message here.
442- tcx. ty_error_with_message (
443- DUMMY_SP ,
444- "Could not find associated const on trait" ,
445- )
446- }
443+ let Some ( trait_def_id) = trait_ref. trait_def_id ( ) else {
444+ return tcx. ty_error_with_message ( DUMMY_SP , "Could not find trait" ) ;
445+ } ;
446+ let assoc_items = tcx. associated_items ( trait_def_id) ;
447+ let assoc_item = assoc_items. find_by_name_and_kind (
448+ tcx,
449+ binding. ident ,
450+ ty:: AssocKind :: Const ,
451+ def_id. to_def_id ( ) ,
452+ ) ;
453+ if let Some ( assoc_item) = assoc_item {
454+ tcx. type_of ( assoc_item. def_id )
455+ } else {
456+ // FIXME(associated_const_equality): add a useful error message here.
457+ tcx. ty_error_with_message (
458+ DUMMY_SP ,
459+ "Could not find associated const on trait" ,
460+ )
461+ }
462+ }
463+
464+ Node :: TypeBinding (
465+ binding @ & TypeBinding { hir_id : binding_id, gen_args, ref kind, .. } ,
466+ ) if let Node :: TraitRef ( trait_ref) =
467+ tcx. hir ( ) . get ( tcx. hir ( ) . get_parent_node ( binding_id) )
468+ && let Some ( ( idx, _) ) =
469+ gen_args. args . iter ( ) . enumerate ( ) . find ( |( _, arg) | {
470+ if let GenericArg :: Const ( ct) = arg {
471+ ct. value . hir_id == hir_id
472+ } else {
473+ false
474+ }
475+ } ) =>
476+ {
477+ let Some ( trait_def_id) = trait_ref. trait_def_id ( ) else {
478+ return tcx. ty_error_with_message ( DUMMY_SP , "Could not find trait" ) ;
479+ } ;
480+ let assoc_items = tcx. associated_items ( trait_def_id) ;
481+ let assoc_item = assoc_items. find_by_name_and_kind (
482+ tcx,
483+ binding. ident ,
484+ match kind {
485+ // I think `<A: T>` type bindings requires that `A` is a type
486+ TypeBindingKind :: Constraint { .. }
487+ | TypeBindingKind :: Equality { term : Term :: Ty ( ..) } => {
488+ ty:: AssocKind :: Type
489+ }
490+ TypeBindingKind :: Equality { term : Term :: Const ( ..) } => {
491+ ty:: AssocKind :: Const
492+ }
493+ } ,
494+ def_id. to_def_id ( ) ,
495+ ) ;
496+ if let Some ( assoc_item) = assoc_item {
497+ tcx. type_of ( tcx. generics_of ( assoc_item. def_id ) . params [ idx] . def_id )
498+ } else {
499+ // FIXME(associated_const_equality): add a useful error message here.
500+ tcx. ty_error_with_message (
501+ DUMMY_SP ,
502+ "Could not find associated const on trait" ,
503+ )
504+ }
447505 }
448506
449507 Node :: GenericParam ( & GenericParam {
@@ -452,8 +510,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
452510 ..
453511 } ) if ct. hir_id == hir_id => tcx. type_of ( tcx. hir ( ) . local_def_id ( param_hir_id) ) ,
454512
455- x =>
456- tcx. ty_error_with_message (
513+ x => tcx. ty_error_with_message (
457514 DUMMY_SP ,
458515 & format ! ( "unexpected const parent in type_of(): {x:?}" ) ,
459516 ) ,
0 commit comments