@@ -1961,33 +1961,90 @@ impl<'tcx> TyCtxt<'tcx> {
19611961 if pred. kind ( ) != binder { self . mk_predicate ( binder) } else { pred }
19621962 }
19631963
1964+ pub fn check_args_compatible ( self , def_id : DefId , args : & ' tcx [ ty:: GenericArg < ' tcx > ] ) -> bool {
1965+ self . check_args_compatible_inner ( def_id, args, false )
1966+ }
1967+
1968+ fn check_args_compatible_inner (
1969+ self ,
1970+ def_id : DefId ,
1971+ args : & ' tcx [ ty:: GenericArg < ' tcx > ] ,
1972+ nested : bool ,
1973+ ) -> bool {
1974+ let generics = self . generics_of ( def_id) ;
1975+
1976+ // IATs themselves have a weird arg setup (self + own args), but nested items *in* IATs
1977+ // (namely: opaques, i.e. ATPITs) do not.
1978+ let own_args = if !nested
1979+ && let DefKind :: AssocTy = self . def_kind ( def_id)
1980+ && let DefKind :: Impl { of_trait : false } = self . def_kind ( self . parent ( def_id) )
1981+ {
1982+ if generics. params . len ( ) + 1 != args. len ( ) {
1983+ return false ;
1984+ }
1985+
1986+ if !matches ! ( args[ 0 ] . unpack( ) , ty:: GenericArgKind :: Type ( _) ) {
1987+ return false ;
1988+ }
1989+
1990+ & args[ 1 ..]
1991+ } else {
1992+ if generics. count ( ) != args. len ( ) {
1993+ return false ;
1994+ }
1995+
1996+ let ( parent_args, own_args) = args. split_at ( generics. parent_count ) ;
1997+
1998+ if let Some ( parent) = generics. parent
1999+ && !self . check_args_compatible_inner ( parent, parent_args, true )
2000+ {
2001+ return false ;
2002+ }
2003+
2004+ own_args
2005+ } ;
2006+
2007+ for ( param, arg) in std:: iter:: zip ( & generics. params , own_args) {
2008+ match ( & param. kind , arg. unpack ( ) ) {
2009+ ( ty:: GenericParamDefKind :: Type { .. } , ty:: GenericArgKind :: Type ( _) )
2010+ | ( ty:: GenericParamDefKind :: Lifetime , ty:: GenericArgKind :: Lifetime ( _) )
2011+ | ( ty:: GenericParamDefKind :: Const { .. } , ty:: GenericArgKind :: Const ( _) ) => { }
2012+ _ => return false ,
2013+ }
2014+ }
2015+
2016+ true
2017+ }
2018+
2019+ pub fn assert_args_compatible ( self , def_id : DefId , args : & ' tcx [ ty:: GenericArg < ' tcx > ] ) {
2020+ if !self . check_args_compatible ( def_id, args) {
2021+ if let DefKind :: AssocTy = self . def_kind ( def_id)
2022+ && let DefKind :: Impl { of_trait : false } = self . def_kind ( self . parent ( def_id) )
2023+ {
2024+ bug ! ( )
2025+ } else {
2026+ bug ! (
2027+ "args not compatible with generics for {}: args={:#?}, generics={:#?}" ,
2028+ self . def_path_str( def_id) ,
2029+ args,
2030+ ty:: GenericArgs :: identity_for_item( self , def_id)
2031+ ) ;
2032+ }
2033+ }
2034+ }
2035+
19642036 #[ inline( always) ]
19652037 pub ( crate ) fn check_and_mk_args (
19662038 self ,
19672039 _def_id : DefId ,
19682040 args : impl IntoIterator < Item : Into < GenericArg < ' tcx > > > ,
19692041 ) -> GenericArgsRef < ' tcx > {
1970- let args = args. into_iter ( ) . map ( Into :: into) ;
2042+ let args = self . mk_args_from_iter ( args. into_iter ( ) . map ( Into :: into) ) ;
19712043 #[ cfg( debug_assertions) ]
19722044 {
1973- let generics = self . generics_of ( _def_id) ;
1974-
1975- let n = if let DefKind :: AssocTy = self . def_kind ( _def_id)
1976- && let DefKind :: Impl { of_trait : false } = self . def_kind ( self . parent ( _def_id) )
1977- {
1978- // If this is an inherent projection.
1979- generics. params . len ( ) + 1
1980- } else {
1981- generics. count ( )
1982- } ;
1983- assert_eq ! (
1984- ( n, Some ( n) ) ,
1985- args. size_hint( ) ,
1986- "wrong number of generic parameters for {_def_id:?}: {:?}" ,
1987- args. collect:: <Vec <_>>( ) ,
1988- ) ;
2045+ self . assert_args_compatible ( _def_id, args) ;
19892046 }
1990- self . mk_args_from_iter ( args)
2047+ args
19912048 }
19922049
19932050 #[ inline]
0 commit comments