88//! specialization errors. These things can (and probably should) be 
99//! fixed, but for the moment it's easier to do these checks early. 
1010
11- use  crate :: constrained_generic_params as  cgp; 
11+ use  crate :: { constrained_generic_params as  cgp,  errors :: UnconstrainedGenericParameter } ; 
1212use  min_specialization:: check_min_specialization; 
1313
1414use  rustc_data_structures:: fx:: FxHashSet ; 
15- use  rustc_errors:: { codes:: * ,  struct_span_code_err } ; 
15+ use  rustc_errors:: codes:: * ; 
1616use  rustc_hir:: def:: DefKind ; 
1717use  rustc_hir:: def_id:: LocalDefId ; 
1818use  rustc_middle:: ty:: { self ,  TyCtxt ,  TypeVisitableExt } ; 
19- use  rustc_span:: { ErrorGuaranteed ,   Span ,   Symbol } ; 
19+ use  rustc_span:: ErrorGuaranteed ; 
2020
2121mod  min_specialization; 
2222
@@ -117,43 +117,34 @@ fn enforce_impl_params_are_constrained(
117117
118118    let  mut  res = Ok ( ( ) ) ; 
119119    for  param in  & impl_generics. own_params  { 
120-         match  param. kind  { 
120+         let  err =  match  param. kind  { 
121121            // Disallow ANY unconstrained type parameters. 
122122            ty:: GenericParamDefKind :: Type  {  .. }  => { 
123123                let  param_ty = ty:: ParamTy :: for_def ( param) ; 
124-                 if  !input_parameters. contains ( & cgp:: Parameter :: from ( param_ty) )  { 
125-                     res = Err ( report_unused_parameter ( 
126-                         tcx, 
127-                         tcx. def_span ( param. def_id ) , 
128-                         "type" , 
129-                         param_ty. name , 
130-                     ) ) ; 
131-                 } 
124+                 !input_parameters. contains ( & cgp:: Parameter :: from ( param_ty) ) 
132125            } 
133126            ty:: GenericParamDefKind :: Lifetime  => { 
134127                let  param_lt = cgp:: Parameter :: from ( param. to_early_bound_region_data ( ) ) ; 
135-                 if   lifetimes_in_associated_types. contains ( & param_lt)  && // (*) 
128+                 lifetimes_in_associated_types. contains ( & param_lt)  && // (*) 
136129                    !input_parameters. contains ( & param_lt) 
137-                 { 
138-                     res = Err ( report_unused_parameter ( 
139-                         tcx, 
140-                         tcx. def_span ( param. def_id ) , 
141-                         "lifetime" , 
142-                         param. name , 
143-                     ) ) ; 
144-                 } 
145130            } 
146131            ty:: GenericParamDefKind :: Const  {  .. }  => { 
147132                let  param_ct = ty:: ParamConst :: for_def ( param) ; 
148-                 if  !input_parameters. contains ( & cgp:: Parameter :: from ( param_ct) )  { 
149-                     res = Err ( report_unused_parameter ( 
150-                         tcx, 
151-                         tcx. def_span ( param. def_id ) , 
152-                         "const" , 
153-                         param_ct. name , 
154-                     ) ) ; 
155-                 } 
133+                 !input_parameters. contains ( & cgp:: Parameter :: from ( param_ct) ) 
156134            } 
135+         } ; 
136+         if  err { 
137+             let  const_param_note =
138+                 matches ! ( param. kind,  ty:: GenericParamDefKind :: Const  {  .. } ) . then_some ( ( ) ) ; 
139+             let  mut  diag = tcx. dcx ( ) . create_err ( UnconstrainedGenericParameter  { 
140+                 span :  tcx. def_span ( param. def_id ) , 
141+                 param_name :  param. name , 
142+                 param_def_kind :  tcx. def_descr ( param. def_id ) , 
143+                 const_param_note, 
144+                 const_param_note2 :  const_param_note, 
145+             } ) ; 
146+             diag. code ( E0207 ) ; 
147+             res = Err ( diag. emit ( ) ) ; 
157148        } 
158149    } 
159150    res
@@ -177,30 +168,3 @@ fn enforce_impl_params_are_constrained(
177168    // associated types. I believe this is sound, because lifetimes 
178169    // used elsewhere are not projected back out. 
179170} 
180- 
181- fn  report_unused_parameter ( 
182-     tcx :  TyCtxt < ' _ > , 
183-     span :  Span , 
184-     kind :  & str , 
185-     name :  Symbol , 
186- )  -> ErrorGuaranteed  { 
187-     let  mut  err = struct_span_code_err ! ( 
188-         tcx. dcx( ) , 
189-         span, 
190-         E0207 , 
191-         "the {} parameter `{}` is not constrained by the \  
192-          impl trait, self type, or predicates", 
193-         kind, 
194-         name
195-     ) ; 
196-     err. span_label ( span,  format ! ( "unconstrained {kind} parameter" ) ) ; 
197-     if  kind == "const"  { 
198-         err. note ( 
199-             "expressions using a const parameter must map each value to a distinct output value" , 
200-         ) ; 
201-         err. note ( 
202-             "proving the result of expressions other than the parameter are unique is not supported" , 
203-         ) ; 
204-     } 
205-     err. emit ( ) 
206- } 
0 commit comments