Skip to content

Commit 9cc8506

Browse files
committed
Add recursion limit for find_all_typevars
1 parent 4dd7855 commit 9cc8506

File tree

3 files changed

+33
-20
lines changed

3 files changed

+33
-20
lines changed

Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ rust-version = "1.81.0"
88

99
[lib]
1010
name = "ante"
11-
edition = "2021"
1211

1312
[workspace]
1413
members = [ "ante-ls" ]

src/types/effects.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -242,16 +242,18 @@ impl EffectSet {
242242
a
243243
}
244244

245-
pub fn find_all_typevars(&self, polymorphic_only: bool, cache: &ModuleCache) -> Vec<super::TypeVariableId> {
245+
pub fn find_all_typevars(
246+
&self, polymorphic_only: bool, cache: &ModuleCache, fuel: u32,
247+
) -> Vec<super::TypeVariableId> {
246248
let this = self.flatten(cache);
247249
let mut vars = match this.extension {
248-
Some(extension) => typechecker::find_typevars_in_typevar_binding(extension, polymorphic_only, cache),
250+
Some(extension) => typechecker::find_typevars_in_typevar_binding(extension, polymorphic_only, cache, fuel),
249251
None => Vec::new(),
250252
};
251253

252254
for (_, args) in &this.effects {
253255
for arg in args {
254-
vars.append(&mut typechecker::find_all_typevars(arg, polymorphic_only, cache));
256+
vars.append(&mut typechecker::find_all_typevars_helper(arg, polymorphic_only, cache, fuel));
255257
}
256258
}
257259

src/types/typechecker.rs

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -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.
999999
pub 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.
10451051
pub(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

Comments
 (0)