@@ -522,23 +522,33 @@ fn check_static_inhabited<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) {
522522
523523/// Checks that an opaque type does not contain cycles and does not use `Self` or `T::Foo`
524524/// projections that would result in "inheriting lifetimes".
525- pub ( super ) fn check_opaque < ' tcx > (
526- tcx : TyCtxt < ' tcx > ,
527- def_id : LocalDefId ,
528- substs : SubstsRef < ' tcx > ,
529- origin : & hir:: OpaqueTyOrigin ,
530- ) {
531- let span = tcx. def_span ( def_id) ;
532- check_opaque_for_inheriting_lifetimes ( tcx, def_id, span) ;
533- if tcx. type_of ( def_id) . references_error ( ) {
525+ fn check_opaque < ' tcx > ( tcx : TyCtxt < ' tcx > , id : hir:: ItemId ) {
526+ let item = tcx. hir ( ) . item ( id) ;
527+ let hir:: ItemKind :: OpaqueTy ( hir:: OpaqueTy { origin, .. } ) = item. kind else {
528+ tcx. sess . delay_span_bug ( tcx. hir ( ) . span ( id. hir_id ( ) ) , "expected opaque item" ) ;
529+ return ;
530+ } ;
531+
532+ // HACK(jynelson): trying to infer the type of `impl trait` breaks documenting
533+ // `async-std` (and `pub async fn` in general).
534+ // Since rustdoc doesn't care about the concrete type behind `impl Trait`, just don't look at it!
535+ // See https://github.com/rust-lang/rust/issues/75100
536+ if tcx. sess . opts . actually_rustdoc {
534537 return ;
535538 }
536- if check_opaque_for_cycles ( tcx, def_id, substs, span, origin) . is_err ( ) {
539+
540+ let substs = InternalSubsts :: identity_for_item ( tcx, item. def_id . to_def_id ( ) ) ;
541+ let span = tcx. def_span ( item. def_id . def_id ) ;
542+
543+ check_opaque_for_inheriting_lifetimes ( tcx, item. def_id . def_id , span) ;
544+ if tcx. type_of ( item. def_id . def_id ) . references_error ( ) {
545+ return ;
546+ }
547+ if check_opaque_for_cycles ( tcx, item. def_id . def_id , substs, span, & origin) . is_err ( ) {
537548 return ;
538549 }
539- check_opaque_meets_bounds ( tcx, def_id, substs, span, origin) ;
550+ check_opaque_meets_bounds ( tcx, item . def_id . def_id , substs, span, & origin) ;
540551}
541-
542552/// Checks that an opaque type does not use `Self` or `T::Foo` projections that would result
543553/// in "inheriting lifetimes".
544554#[ instrument( level = "debug" , skip( tcx, span) ) ]
@@ -857,17 +867,17 @@ fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, id: hir::ItemId) {
857867 check_union ( tcx, id. def_id . def_id ) ;
858868 }
859869 DefKind :: OpaqueTy => {
860- let item = tcx . hir ( ) . item ( id) ;
861- let hir :: ItemKind :: OpaqueTy ( hir :: OpaqueTy { origin , .. } ) = item . kind else {
862- return ;
863- } ;
864- // HACK(jynelson): trying to infer the type of `impl trait` breaks documenting
865- // `async-std` (and `pub async fn` in general).
866- // Since rustdoc doesn't care about the concrete type behind `impl Trait`, just don't look at it!
867- // See https://github.com/rust-lang/rust/issues/75100
868- if ! tcx. sess . opts . actually_rustdoc {
869- let substs = InternalSubsts :: identity_for_item ( tcx , item . def_id . to_def_id ( ) ) ;
870- check_opaque ( tcx, item . def_id . def_id , substs , & origin ) ;
870+ check_opaque ( tcx , id) ;
871+ }
872+ DefKind :: ImplTraitPlaceholder => {
873+ let parent = tcx . impl_trait_in_trait_parent ( id . def_id . to_def_id ( ) ) ;
874+ // Only check the validity of this opaque type if the function has a default body
875+ if let hir :: Node :: TraitItem ( hir :: TraitItem {
876+ kind : hir :: TraitItemKind :: Fn ( _ , hir :: TraitFn :: Provided ( _ ) ) ,
877+ ..
878+ } ) = tcx. hir ( ) . get_by_def_id ( parent . expect_local ( ) )
879+ {
880+ check_opaque ( tcx, id ) ;
871881 }
872882 }
873883 DefKind :: TyAlias => {
0 commit comments