@@ -13,6 +13,49 @@ use crate::errors::NonGenericOpaqueTypeParam;
1313use crate :: regions:: OutlivesEnvironmentBuildExt ;
1414use crate :: traits:: ObligationCtxt ;
1515
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+
1659/// Opaque type parameter validity check as documented in the [rustc-dev-guide chapter].
1760///
1861/// [rustc-dev-guide chapter]:
@@ -22,23 +65,19 @@ pub fn check_opaque_type_parameter_valid<'tcx>(
2265 opaque_type_key : OpaqueTypeKey < ' tcx > ,
2366 span : Span ,
2467 defining_scope_kind : DefiningScopeKind ,
25- ) -> Result < ( ) , ErrorGuaranteed > {
68+ ) -> Result < ( ) , InvalidOpaqueTypeArgs < ' tcx > > {
2669 let tcx = infcx. tcx ;
27- let opaque_generics = tcx. generics_of ( opaque_type_key. def_id ) ;
2870 let opaque_env = LazyOpaqueTyEnv :: new ( tcx, opaque_type_key. def_id ) ;
2971 let mut seen_params: FxIndexMap < _ , Vec < _ > > = FxIndexMap :: default ( ) ;
3072
3173 // Avoid duplicate errors in case the opaque has already been malformed in
3274 // HIR typeck.
3375 if let DefiningScopeKind :: MirBorrowck = defining_scope_kind {
34- if let Err ( guar ) = infcx
76+ infcx
3577 . tcx
3678 . type_of_opaque_hir_typeck ( opaque_type_key. def_id )
3779 . instantiate_identity ( )
38- . error_reported ( )
39- {
40- return Err ( guar) ;
41- }
80+ . error_reported ( ) ?;
4281 }
4382
4483 for ( i, arg) in opaque_type_key. iter_captured_args ( tcx) {
@@ -64,32 +103,18 @@ pub fn check_opaque_type_parameter_valid<'tcx>(
64103 }
65104 } else {
66105 // 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-
70106 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 } ) ;
78108 }
79109 }
80110
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+ } ) ;
93118 }
94119 }
95120
0 commit comments