1616
1717use rustc_ast:: Recovered ;
1818use rustc_data_structures:: captures:: Captures ;
19- use rustc_data_structures:: fx:: { FxHashSet , FxIndexMap } ;
19+ use rustc_data_structures:: fx:: { FxHashMap , FxHashSet , FxIndexMap } ;
2020use rustc_data_structures:: unord:: UnordMap ;
2121use rustc_errors:: {
22- struct_span_code_err, Applicability , Diag , DiagCtxtHandle , ErrorGuaranteed , StashKey , E0228 ,
22+ struct_span_code_err, Applicability , Diag , DiagCtxtHandle , ErrorGuaranteed , StashKey , E0207 ,
23+ E0228 ,
2324} ;
2425use rustc_hir:: def:: DefKind ;
2526use rustc_hir:: def_id:: { DefId , LocalDefId } ;
@@ -31,7 +32,9 @@ use rustc_infer::traits::ObligationCause;
3132use rustc_middle:: hir:: nested_filter;
3233use rustc_middle:: query:: Providers ;
3334use rustc_middle:: ty:: util:: { Discr , IntTypeExt } ;
34- use rustc_middle:: ty:: { self , AdtKind , Const , IsSuggestable , Ty , TyCtxt , Upcast } ;
35+ use rustc_middle:: ty:: {
36+ self , AdtKind , Const , IsSuggestable , Ty , TyCtxt , TypeVisitableExt as _, Upcast ,
37+ } ;
3538use rustc_middle:: { bug, span_bug} ;
3639use rustc_span:: symbol:: { kw, sym, Ident , Symbol } ;
3740use rustc_span:: { Span , DUMMY_SP } ;
@@ -40,11 +43,13 @@ use rustc_trait_selection::error_reporting::traits::suggestions::NextTypeParamNa
4043use rustc_trait_selection:: infer:: InferCtxtExt ;
4144use rustc_trait_selection:: traits:: ObligationCtxt ;
4245use std:: cell:: Cell ;
46+ use std:: cell:: RefCell ;
4347use std:: iter;
4448use std:: ops:: Bound ;
4549
4650use crate :: check:: intrinsic:: intrinsic_operation_unsafety;
47- use crate :: errors;
51+ use crate :: constrained_generic_params:: { self as cgp, Parameter } ;
52+ use crate :: errors:: { self , UnconstrainedGenericParameter } ;
4853use crate :: hir_ty_lowering:: { HirTyLowerer , RegionInferReason } ;
4954
5055pub ( crate ) mod dump;
@@ -121,6 +126,7 @@ pub struct ItemCtxt<'tcx> {
121126 tcx : TyCtxt < ' tcx > ,
122127 item_def_id : LocalDefId ,
123128 tainted_by_errors : Cell < Option < ErrorGuaranteed > > ,
129+ pub forbidden_params : RefCell < FxHashMap < Parameter , ty:: GenericParamDef > > ,
124130}
125131
126132///////////////////////////////////////////////////////////////////////////
@@ -351,7 +357,12 @@ fn bad_placeholder<'cx, 'tcx>(
351357
352358impl < ' tcx > ItemCtxt < ' tcx > {
353359 pub fn new ( tcx : TyCtxt < ' tcx > , item_def_id : LocalDefId ) -> ItemCtxt < ' tcx > {
354- ItemCtxt { tcx, item_def_id, tainted_by_errors : Cell :: new ( None ) }
360+ ItemCtxt {
361+ tcx,
362+ item_def_id,
363+ tainted_by_errors : Cell :: new ( None ) ,
364+ forbidden_params : Default :: default ( ) ,
365+ }
355366 }
356367
357368 pub fn lower_ty ( & self , hir_ty : & hir:: Ty < ' tcx > ) -> Ty < ' tcx > {
@@ -372,6 +383,58 @@ impl<'tcx> ItemCtxt<'tcx> {
372383 None => Ok ( ( ) ) ,
373384 }
374385 }
386+
387+ fn forbid_unconstrained_lifetime_params_from_parent_impl ( & self ) -> Result < ( ) , ErrorGuaranteed > {
388+ let tcx = self . tcx ;
389+ let impl_def_id = tcx. hir ( ) . get_parent_item ( self . hir_id ( ) ) ;
390+ let impl_self_ty = tcx. type_of ( impl_def_id) . instantiate_identity ( ) ;
391+ impl_self_ty. error_reported ( ) ?;
392+ let impl_generics = tcx. generics_of ( impl_def_id) ;
393+ let impl_predicates = tcx. predicates_of ( impl_def_id) ;
394+ let impl_trait_ref =
395+ tcx. impl_trait_ref ( impl_def_id) . map ( ty:: EarlyBinder :: instantiate_identity) ;
396+
397+ impl_trait_ref. error_reported ( ) ?;
398+
399+ let mut input_parameters = cgp:: parameters_for_impl ( tcx, impl_self_ty, impl_trait_ref) ;
400+
401+ cgp:: identify_constrained_generic_params (
402+ tcx,
403+ impl_predicates,
404+ impl_trait_ref,
405+ & mut input_parameters,
406+ ) ;
407+
408+ for param in & impl_generics. own_params {
409+ let p = match param. kind {
410+ // This is a horrible concession to reality. It'd be
411+ // better to just ban unconstrained lifetimes outright, but in
412+ // practice people do non-hygienic macros like:
413+ //
414+ // ```
415+ // macro_rules! __impl_slice_eq1 {
416+ // ($Lhs: ty, $Rhs: ty, $Bound: ident) => {
417+ // impl<'a, 'b, A: $Bound, B> PartialEq<$Rhs> for $Lhs where A: PartialEq<B> {
418+ // ....
419+ // }
420+ // }
421+ // }
422+ // ```
423+ //
424+ // In a concession to backwards compatibility, we continue to
425+ // permit those, so long as the lifetimes aren't used in
426+ // associated types. This is sound, because lifetimes
427+ // used elsewhere are not projected back out.
428+ ty:: GenericParamDefKind :: Type { .. } => continue ,
429+ ty:: GenericParamDefKind :: Lifetime => param. to_early_bound_region_data ( ) . into ( ) ,
430+ ty:: GenericParamDefKind :: Const { .. } => continue ,
431+ } ;
432+ if !input_parameters. contains ( & p) {
433+ self . forbidden_params . borrow_mut ( ) . insert ( p, param. clone ( ) ) ;
434+ }
435+ }
436+ Ok ( ( ) )
437+ }
375438}
376439
377440impl < ' tcx > HirTyLowerer < ' tcx > for ItemCtxt < ' tcx > {
@@ -513,8 +576,25 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> {
513576 ty. ty_adt_def ( )
514577 }
515578
516- fn record_ty ( & self , _hir_id : hir:: HirId , _ty : Ty < ' tcx > , _span : Span ) {
517- // There's no place to record types from signatures?
579+ fn record_ty ( & self , _hir_id : hir:: HirId , ty : Ty < ' tcx > , span : Span ) {
580+ // There's no place to record types from signatures
581+
582+ if !self . forbidden_params . borrow ( ) . is_empty ( ) {
583+ for param in cgp:: parameters_for ( self . tcx , ty, true ) {
584+ if let Some ( param) = self . forbidden_params . borrow_mut ( ) . remove ( & param) {
585+ let mut diag = self . dcx ( ) . create_err ( UnconstrainedGenericParameter {
586+ span : self . tcx . def_span ( param. def_id ) ,
587+ param_name : param. name ,
588+ param_def_kind : self . tcx . def_descr ( param. def_id ) ,
589+ const_param_note : None ,
590+ const_param_note2 : None ,
591+ lifetime_help : Some ( span) ,
592+ } ) ;
593+ diag. code ( E0207 ) ;
594+ diag. emit ( ) ;
595+ }
596+ }
597+ }
518598 }
519599
520600 fn infcx ( & self ) -> Option < & InferCtxt < ' tcx > > {
0 commit comments