@@ -997,56 +997,68 @@ fn level_is_polymorphic(level: LetBindingLevel) -> bool {
997997/// should only be used with polymorphic_only = false outside of the typechecking pass.
998998/// Otherwise the decision of whether to propagate the variable would be incorrect.
999999pub fn find_all_typevars ( typ : & Type , polymorphic_only : bool , cache : & ModuleCache < ' _ > ) -> Vec < TypeVariableId > {
1000+ find_all_typevars_helper ( typ, polymorphic_only, cache, RECURSION_LIMIT )
1001+ }
1002+
1003+ pub ( super ) fn find_all_typevars_helper (
1004+ typ : & Type , polymorphic_only : bool , cache : & ModuleCache < ' _ > , fuel : u32 ,
1005+ ) -> Vec < TypeVariableId > {
10001006 match typ {
10011007 Primitive ( _) => vec ! [ ] ,
10021008 UserDefined ( _) => vec ! [ ] ,
10031009 Tag ( _) => vec ! [ ] ,
1004- TypeVariable ( id) => find_typevars_in_typevar_binding ( * id, polymorphic_only, cache) ,
1010+ TypeVariable ( id) => find_typevars_in_typevar_binding ( * id, polymorphic_only, cache, fuel ) ,
10051011 Function ( function) => {
10061012 let mut type_variables = vec ! [ ] ;
10071013 for parameter in & function. parameters {
1008- type_variables. append ( & mut find_all_typevars ( parameter, polymorphic_only, cache) ) ;
1014+ type_variables. append ( & mut find_all_typevars_helper ( parameter, polymorphic_only, cache, fuel ) ) ;
10091015 }
10101016
1011- type_variables. append ( & mut find_all_typevars ( & function. environment , polymorphic_only, cache) ) ;
1012- type_variables. append ( & mut find_all_typevars ( & function. return_type , polymorphic_only, cache) ) ;
1013- type_variables. append ( & mut find_all_typevars ( & function. effects , polymorphic_only, cache) ) ;
1017+ type_variables. append ( & mut find_all_typevars_helper ( & function. environment , polymorphic_only, cache, fuel ) ) ;
1018+ type_variables. append ( & mut find_all_typevars_helper ( & function. return_type , polymorphic_only, cache, fuel ) ) ;
1019+ type_variables. append ( & mut find_all_typevars_helper ( & function. effects , polymorphic_only, cache, fuel ) ) ;
10141020 type_variables
10151021 } ,
10161022 TypeApplication ( constructor, args) => {
1017- let mut type_variables = find_all_typevars ( constructor, polymorphic_only, cache) ;
1023+ let mut type_variables = find_all_typevars_helper ( constructor, polymorphic_only, cache, fuel ) ;
10181024 for arg in args {
1019- type_variables. append ( & mut find_all_typevars ( arg, polymorphic_only, cache) ) ;
1025+ type_variables. append ( & mut find_all_typevars_helper ( arg, polymorphic_only, cache, fuel ) ) ;
10201026 }
10211027 type_variables
10221028 } ,
10231029 Ref { sharedness, mutability, lifetime } => {
1024- let mut type_variables = find_all_typevars ( mutability, polymorphic_only, cache) ;
1025- type_variables. append ( & mut find_all_typevars ( sharedness, polymorphic_only, cache) ) ;
1026- type_variables. append ( & mut find_all_typevars ( lifetime, polymorphic_only, cache) ) ;
1030+ let mut type_variables = find_all_typevars_helper ( mutability, polymorphic_only, cache, fuel ) ;
1031+ type_variables. append ( & mut find_all_typevars_helper ( sharedness, polymorphic_only, cache, fuel ) ) ;
1032+ type_variables. append ( & mut find_all_typevars_helper ( lifetime, polymorphic_only, cache, fuel ) ) ;
10271033 type_variables
10281034 } ,
10291035 Struct ( fields, id) => match & cache. type_bindings [ id. 0 ] {
1030- Bound ( t) => find_all_typevars ( t, polymorphic_only, cache) ,
1036+ Bound ( t) => find_all_typevars_helper ( t, polymorphic_only, cache, fuel ) ,
10311037 Unbound ( ..) => {
1032- let mut vars = find_typevars_in_typevar_binding ( * id, polymorphic_only, cache) ;
1038+ let mut vars = find_typevars_in_typevar_binding ( * id, polymorphic_only, cache, fuel ) ;
10331039 for field in fields. values ( ) {
1034- vars. append ( & mut find_all_typevars ( field, polymorphic_only, cache) ) ;
1040+ vars. append ( & mut find_all_typevars_helper ( field, polymorphic_only, cache, fuel ) ) ;
10351041 }
10361042 vars
10371043 } ,
10381044 } ,
1039- Effects ( effects) => effects. find_all_typevars ( polymorphic_only, cache) ,
1045+ Effects ( effects) => effects. find_all_typevars ( polymorphic_only, cache, fuel ) ,
10401046 }
10411047}
10421048
10431049/// Helper for find_all_typevars which gets the TypeBinding for a given
10441050/// TypeVariableId and either recurses on it if it is bound or returns it.
10451051pub ( super ) fn find_typevars_in_typevar_binding (
1046- id : TypeVariableId , polymorphic_only : bool , cache : & ModuleCache ,
1052+ id : TypeVariableId , polymorphic_only : bool , cache : & ModuleCache , fuel : u32 ,
10471053) -> Vec < TypeVariableId > {
1054+ if fuel == 0 {
1055+ panic ! ( "Recursion limit hit in find_all_typevars" ) ;
1056+ }
1057+
1058+ let fuel = fuel - 1 ;
1059+
10481060 match & cache. type_bindings [ id. 0 ] {
1049- Bound ( t) => find_all_typevars ( t, polymorphic_only, cache) ,
1061+ Bound ( t) => find_all_typevars_helper ( t, polymorphic_only, cache, fuel ) ,
10501062 Unbound ( level, _) => {
10511063 if !polymorphic_only || level_is_polymorphic ( * level) {
10521064 vec ! [ id]
0 commit comments