@@ -13,6 +13,49 @@ use crate::errors::NonGenericOpaqueTypeParam;
13
13
use crate :: regions:: OutlivesEnvironmentBuildExt ;
14
14
use crate :: traits:: ObligationCtxt ;
15
15
16
+ pub enum InvalidOpaqueTypeArgs < ' tcx > {
17
+ AlreadyReported ( ErrorGuaranteed ) ,
18
+ NotAParam { opaque_type_key : OpaqueTypeKey < ' tcx > , param_index : usize , span : Span } ,
19
+ DuplicateParam { opaque_type_key : OpaqueTypeKey < ' tcx > , param_indices : Vec < usize > , span : Span } ,
20
+ }
21
+ impl From < ErrorGuaranteed > for InvalidOpaqueTypeArgs < ' _ > {
22
+ fn from ( guar : ErrorGuaranteed ) -> Self {
23
+ InvalidOpaqueTypeArgs :: AlreadyReported ( guar)
24
+ }
25
+ }
26
+ impl < ' tcx > InvalidOpaqueTypeArgs < ' tcx > {
27
+ pub fn report ( self , infcx : & InferCtxt < ' tcx > ) -> ErrorGuaranteed {
28
+ let tcx = infcx. tcx ;
29
+ match self {
30
+ InvalidOpaqueTypeArgs :: AlreadyReported ( guar) => guar,
31
+ InvalidOpaqueTypeArgs :: NotAParam { opaque_type_key, param_index, span } => {
32
+ let opaque_generics = tcx. generics_of ( opaque_type_key. def_id ) ;
33
+ let opaque_param = opaque_generics. param_at ( param_index, tcx) ;
34
+ let kind = opaque_param. kind . descr ( ) ;
35
+ infcx. dcx ( ) . emit_err ( NonGenericOpaqueTypeParam {
36
+ arg : opaque_type_key. args [ param_index] ,
37
+ kind,
38
+ span,
39
+ param_span : tcx. def_span ( opaque_param. def_id ) ,
40
+ } )
41
+ }
42
+ InvalidOpaqueTypeArgs :: DuplicateParam { opaque_type_key, param_indices, span } => {
43
+ let opaque_generics = tcx. generics_of ( opaque_type_key. def_id ) ;
44
+ let descr = opaque_generics. param_at ( param_indices[ 0 ] , tcx) . kind . descr ( ) ;
45
+ let spans: Vec < _ > = param_indices
46
+ . into_iter ( )
47
+ . map ( |i| tcx. def_span ( opaque_generics. param_at ( i, tcx) . def_id ) )
48
+ . collect ( ) ;
49
+ infcx
50
+ . dcx ( )
51
+ . struct_span_err ( span, "non-defining opaque type use in defining scope" )
52
+ . with_span_note ( spans, format ! ( "{descr} used multiple times" ) )
53
+ . emit ( )
54
+ }
55
+ }
56
+ }
57
+ }
58
+
16
59
/// Opaque type parameter validity check as documented in the [rustc-dev-guide chapter].
17
60
///
18
61
/// [rustc-dev-guide chapter]:
@@ -22,23 +65,19 @@ pub fn check_opaque_type_parameter_valid<'tcx>(
22
65
opaque_type_key : OpaqueTypeKey < ' tcx > ,
23
66
span : Span ,
24
67
defining_scope_kind : DefiningScopeKind ,
25
- ) -> Result < ( ) , ErrorGuaranteed > {
68
+ ) -> Result < ( ) , InvalidOpaqueTypeArgs < ' tcx > > {
26
69
let tcx = infcx. tcx ;
27
- let opaque_generics = tcx. generics_of ( opaque_type_key. def_id ) ;
28
70
let opaque_env = LazyOpaqueTyEnv :: new ( tcx, opaque_type_key. def_id ) ;
29
71
let mut seen_params: FxIndexMap < _ , Vec < _ > > = FxIndexMap :: default ( ) ;
30
72
31
73
// Avoid duplicate errors in case the opaque has already been malformed in
32
74
// HIR typeck.
33
75
if let DefiningScopeKind :: MirBorrowck = defining_scope_kind {
34
- if let Err ( guar ) = infcx
76
+ infcx
35
77
. tcx
36
78
. type_of_opaque_hir_typeck ( opaque_type_key. def_id )
37
79
. instantiate_identity ( )
38
- . error_reported ( )
39
- {
40
- return Err ( guar) ;
41
- }
80
+ . error_reported ( ) ?;
42
81
}
43
82
44
83
for ( i, arg) in opaque_type_key. iter_captured_args ( tcx) {
@@ -64,32 +103,18 @@ pub fn check_opaque_type_parameter_valid<'tcx>(
64
103
}
65
104
} else {
66
105
// Prevent `fn foo() -> Foo<u32>` from being defining.
67
- let opaque_param = opaque_generics. param_at ( i, tcx) ;
68
- let kind = opaque_param. kind . descr ( ) ;
69
-
70
106
opaque_env. param_is_error ( i) ?;
71
-
72
- return Err ( infcx. dcx ( ) . emit_err ( NonGenericOpaqueTypeParam {
73
- arg,
74
- kind,
75
- span,
76
- param_span : tcx. def_span ( opaque_param. def_id ) ,
77
- } ) ) ;
107
+ return Err ( InvalidOpaqueTypeArgs :: NotAParam { opaque_type_key, param_index : i, span } ) ;
78
108
}
79
109
}
80
110
81
- for ( _, indices) in seen_params {
82
- if indices. len ( ) > 1 {
83
- let descr = opaque_generics. param_at ( indices[ 0 ] , tcx) . kind . descr ( ) ;
84
- let spans: Vec < _ > = indices
85
- . into_iter ( )
86
- . map ( |i| tcx. def_span ( opaque_generics. param_at ( i, tcx) . def_id ) )
87
- . collect ( ) ;
88
- return Err ( infcx
89
- . dcx ( )
90
- . struct_span_err ( span, "non-defining opaque type use in defining scope" )
91
- . with_span_note ( spans, format ! ( "{descr} used multiple times" ) )
92
- . emit ( ) ) ;
111
+ for ( _, param_indices) in seen_params {
112
+ if param_indices. len ( ) > 1 {
113
+ return Err ( InvalidOpaqueTypeArgs :: DuplicateParam {
114
+ opaque_type_key,
115
+ param_indices,
116
+ span,
117
+ } ) ;
93
118
}
94
119
}
95
120
0 commit comments