@@ -3,10 +3,9 @@ use rustc_ast::ptr::P;
3
3
use rustc_ast:: visit:: AssocCtxt ;
4
4
use rustc_ast:: * ;
5
5
use rustc_errors:: ErrorGuaranteed ;
6
- use rustc_hir as hir;
7
- use rustc_hir:: PredicateOrigin ;
8
6
use rustc_hir:: def:: { DefKind , Res } ;
9
7
use rustc_hir:: def_id:: { CRATE_DEF_ID , LocalDefId } ;
8
+ use rustc_hir:: { self as hir, HirId , PredicateOrigin } ;
10
9
use rustc_index:: { IndexSlice , IndexVec } ;
11
10
use rustc_middle:: span_bug;
12
11
use rustc_middle:: ty:: { ResolverAstLowering , TyCtxt } ;
@@ -209,6 +208,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
209
208
generics,
210
209
body,
211
210
contract,
211
+ define_opaque,
212
212
..
213
213
} ) => {
214
214
self . with_new_scopes ( * fn_sig_span, |this| {
@@ -237,6 +237,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
237
237
header : this. lower_fn_header ( * header, hir:: Safety :: Safe , attrs) ,
238
238
span : this. lower_span ( * fn_sig_span) ,
239
239
} ;
240
+ this. lower_define_opaque ( hir_id, & define_opaque) ;
240
241
hir:: ItemKind :: Fn { sig, generics, body : body_id, has_body : body. is_some ( ) }
241
242
} )
242
243
}
@@ -779,7 +780,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
779
780
) ;
780
781
( generics, kind, expr. is_some ( ) )
781
782
}
782
- AssocItemKind :: Fn ( box Fn { sig, generics, body : None , .. } ) => {
783
+ AssocItemKind :: Fn ( box Fn { sig, generics, body : None , define_opaque , .. } ) => {
783
784
// FIXME(contracts): Deny contract here since it won't apply to
784
785
// any impl method or callees.
785
786
let names = self . lower_fn_params_to_names ( & sig. decl ) ;
@@ -791,9 +792,22 @@ impl<'hir> LoweringContext<'_, 'hir> {
791
792
sig. header . coroutine_kind ,
792
793
attrs,
793
794
) ;
795
+ if define_opaque. is_some ( ) {
796
+ self . dcx ( ) . span_err (
797
+ i. span ,
798
+ "only trait methods with default bodies can define opaque types" ,
799
+ ) ;
800
+ }
794
801
( generics, hir:: TraitItemKind :: Fn ( sig, hir:: TraitFn :: Required ( names) ) , false )
795
802
}
796
- AssocItemKind :: Fn ( box Fn { sig, generics, body : Some ( body) , contract, .. } ) => {
803
+ AssocItemKind :: Fn ( box Fn {
804
+ sig,
805
+ generics,
806
+ body : Some ( body) ,
807
+ contract,
808
+ define_opaque,
809
+ ..
810
+ } ) => {
797
811
let body_id = self . lower_maybe_coroutine_body (
798
812
sig. span ,
799
813
i. span ,
@@ -812,6 +826,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
812
826
sig. header . coroutine_kind ,
813
827
attrs,
814
828
) ;
829
+ self . lower_define_opaque ( hir_id, & define_opaque) ;
815
830
( generics, hir:: TraitItemKind :: Fn ( sig, hir:: TraitFn :: Provided ( body_id) ) , true )
816
831
}
817
832
AssocItemKind :: Type ( box TyAlias { generics, where_clauses, bounds, ty, .. } ) => {
@@ -911,7 +926,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
911
926
hir:: ImplItemKind :: Const ( ty, body)
912
927
} ,
913
928
) ,
914
- AssocItemKind :: Fn ( box Fn { sig, generics, body, contract, .. } ) => {
929
+ AssocItemKind :: Fn ( box Fn { sig, generics, body, contract, define_opaque , .. } ) => {
915
930
let body_id = self . lower_maybe_coroutine_body (
916
931
sig. span ,
917
932
i. span ,
@@ -930,6 +945,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
930
945
sig. header . coroutine_kind ,
931
946
attrs,
932
947
) ;
948
+ self . lower_define_opaque ( hir_id, & define_opaque) ;
933
949
934
950
( generics, hir:: ImplItemKind :: Fn ( sig, body_id) )
935
951
}
@@ -1657,6 +1673,31 @@ impl<'hir> LoweringContext<'_, 'hir> {
1657
1673
( lowered_generics, res)
1658
1674
}
1659
1675
1676
+ pub ( super ) fn lower_define_opaque (
1677
+ & mut self ,
1678
+ hir_id : HirId ,
1679
+ define_opaque : & Option < ThinVec < ( NodeId , Path ) > > ,
1680
+ ) {
1681
+ assert_eq ! ( self . define_opaque, None ) ;
1682
+ assert ! ( hir_id. is_owner( ) ) ;
1683
+ let Some ( define_opaque) = define_opaque. as_ref ( ) else {
1684
+ return ;
1685
+ } ;
1686
+ let define_opaque = define_opaque
1687
+ . iter ( )
1688
+ // TODO: error reporting for non-local items being mentioned and tests that go through these code paths
1689
+ . map ( |( id, _path) | {
1690
+ self . resolver
1691
+ . get_partial_res ( * id)
1692
+ . unwrap ( )
1693
+ . expect_full_res ( )
1694
+ . def_id ( )
1695
+ . expect_local ( )
1696
+ } ) ;
1697
+ let define_opaque = self . arena . alloc_from_iter ( define_opaque) ;
1698
+ self . define_opaque = Some ( define_opaque) ;
1699
+ }
1700
+
1660
1701
pub ( super ) fn lower_generic_bound_predicate (
1661
1702
& mut self ,
1662
1703
ident : Ident ,
0 commit comments