@@ -1954,33 +1954,104 @@ impl<'tcx> TyCtxt<'tcx> {
1954
1954
if pred. kind ( ) != binder { self . mk_predicate ( binder) } else { pred }
1955
1955
}
1956
1956
1957
- #[ inline( always) ]
1958
- pub ( crate ) fn check_and_mk_args (
1957
+ pub fn check_args_compatible ( self , def_id : DefId , args : & ' tcx [ ty:: GenericArg < ' tcx > ] ) -> bool {
1958
+ self . check_args_compatible_inner ( def_id, args, false )
1959
+ }
1960
+
1961
+ fn check_args_compatible_inner (
1959
1962
self ,
1960
- _def_id : DefId ,
1961
- args : impl IntoIterator < Item : Into < GenericArg < ' tcx > > > ,
1962
- ) -> GenericArgsRef < ' tcx > {
1963
- let args = args. into_iter ( ) . map ( Into :: into) ;
1964
- #[ cfg( debug_assertions) ]
1963
+ def_id : DefId ,
1964
+ args : & ' tcx [ ty:: GenericArg < ' tcx > ] ,
1965
+ nested : bool ,
1966
+ ) -> bool {
1967
+ let generics = self . generics_of ( def_id) ;
1968
+
1969
+ // IATs themselves have a weird arg setup (self + own args), but nested items *in* IATs
1970
+ // (namely: opaques, i.e. ATPITs) do not.
1971
+ let own_args = if !nested
1972
+ && let DefKind :: AssocTy = self . def_kind ( def_id)
1973
+ && let DefKind :: Impl { of_trait : false } = self . def_kind ( self . parent ( def_id) )
1965
1974
{
1966
- let generics = self . generics_of ( _def_id) ;
1975
+ if generics. params . len ( ) + 1 != args. len ( ) {
1976
+ return false ;
1977
+ }
1967
1978
1968
- let n = if let DefKind :: AssocTy = self . def_kind ( _def_id)
1969
- && let DefKind :: Impl { of_trait : false } = self . def_kind ( self . parent ( _def_id) )
1979
+ if !matches ! ( args[ 0 ] . unpack( ) , ty:: GenericArgKind :: Type ( _) ) {
1980
+ return false ;
1981
+ }
1982
+
1983
+ & args[ 1 ..]
1984
+ } else {
1985
+ if generics. count ( ) != args. len ( ) {
1986
+ return false ;
1987
+ }
1988
+
1989
+ let ( parent_args, own_args) = args. split_at ( generics. parent_count ) ;
1990
+
1991
+ if let Some ( parent) = generics. parent
1992
+ && !self . check_args_compatible_inner ( parent, parent_args, true )
1970
1993
{
1971
- // If this is an inherent projection.
1972
- generics. params . len ( ) + 1
1973
- } else {
1974
- generics. count ( )
1975
- } ;
1976
- assert_eq ! (
1977
- ( n, Some ( n) ) ,
1978
- args. size_hint( ) ,
1979
- "wrong number of generic parameters for {_def_id:?}: {:?}" ,
1980
- args. collect:: <Vec <_>>( ) ,
1981
- ) ;
1994
+ return false ;
1995
+ }
1996
+
1997
+ own_args
1998
+ } ;
1999
+
2000
+ for ( param, arg) in std:: iter:: zip ( & generics. params , own_args) {
2001
+ match ( & param. kind , arg. unpack ( ) ) {
2002
+ ( ty:: GenericParamDefKind :: Type { .. } , ty:: GenericArgKind :: Type ( _) )
2003
+ | ( ty:: GenericParamDefKind :: Lifetime , ty:: GenericArgKind :: Lifetime ( _) )
2004
+ | ( ty:: GenericParamDefKind :: Const { .. } , ty:: GenericArgKind :: Const ( _) ) => { }
2005
+ _ => return false ,
2006
+ }
1982
2007
}
1983
- self . mk_args_from_iter ( args)
2008
+
2009
+ true
2010
+ }
2011
+
2012
+ /// With `cfg(debug_assertions)`, assert that args are compatible with their generics,
2013
+ /// and print out the args if not.
2014
+ pub fn debug_assert_args_compatible ( self , def_id : DefId , args : & ' tcx [ ty:: GenericArg < ' tcx > ] ) {
2015
+ if cfg ! ( debug_assertions) {
2016
+ if !self . check_args_compatible ( def_id, args) {
2017
+ if let DefKind :: AssocTy = self . def_kind ( def_id)
2018
+ && let DefKind :: Impl { of_trait : false } = self . def_kind ( self . parent ( def_id) )
2019
+ {
2020
+ bug ! (
2021
+ "args not compatible with generics for {}: args={:#?}, generics={:#?}" ,
2022
+ self . def_path_str( def_id) ,
2023
+ args,
2024
+ // Make `[Self, GAT_ARGS...]` (this could be simplified)
2025
+ self . mk_args_from_iter(
2026
+ [ self . types. self_param. into( ) ] . into_iter( ) . chain(
2027
+ self . generics_of( def_id)
2028
+ . own_args( ty:: GenericArgs :: identity_for_item( self , def_id) )
2029
+ . iter( )
2030
+ . copied( )
2031
+ )
2032
+ )
2033
+ ) ;
2034
+ } else {
2035
+ bug ! (
2036
+ "args not compatible with generics for {}: args={:#?}, generics={:#?}" ,
2037
+ self . def_path_str( def_id) ,
2038
+ args,
2039
+ ty:: GenericArgs :: identity_for_item( self , def_id)
2040
+ ) ;
2041
+ }
2042
+ }
2043
+ }
2044
+ }
2045
+
2046
+ #[ inline( always) ]
2047
+ pub ( crate ) fn check_and_mk_args (
2048
+ self ,
2049
+ def_id : DefId ,
2050
+ args : impl IntoIterator < Item : Into < GenericArg < ' tcx > > > ,
2051
+ ) -> GenericArgsRef < ' tcx > {
2052
+ let args = self . mk_args_from_iter ( args. into_iter ( ) . map ( Into :: into) ) ;
2053
+ self . debug_assert_args_compatible ( def_id, args) ;
2054
+ args
1984
2055
}
1985
2056
1986
2057
#[ inline]
0 commit comments