@@ -1961,33 +1961,90 @@ impl<'tcx> TyCtxt<'tcx> {
1961
1961
if pred. kind ( ) != binder { self . mk_predicate ( binder) } else { pred }
1962
1962
}
1963
1963
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
+
1964
2036
#[ inline( always) ]
1965
2037
pub ( crate ) fn check_and_mk_args (
1966
2038
self ,
1967
2039
_def_id : DefId ,
1968
2040
args : impl IntoIterator < Item : Into < GenericArg < ' tcx > > > ,
1969
2041
) -> 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) ) ;
1971
2043
#[ cfg( debug_assertions) ]
1972
2044
{
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) ;
1989
2046
}
1990
- self . mk_args_from_iter ( args)
2047
+ args
1991
2048
}
1992
2049
1993
2050
#[ inline]
0 commit comments