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