Address PR comments, add syntax tests

This commit is contained in:
Sam Mohr 2024-10-21 03:06:43 -07:00
parent b3e60f9d3a
commit 7518a2c5ab
No known key found for this signature in database
GPG key ID: EA41D161A3C1BC99
28 changed files with 772 additions and 34 deletions

View file

@ -432,7 +432,8 @@ impl Scope {
self.aliases.contains_key(&name)
}
pub fn inner_scope<F, T>(&mut self, entering_function: bool, f: F) -> T
/// Enter an inner scope within a definition, e.g. a def or when block.
pub fn inner_def_scope<F, T>(&mut self, f: F) -> T
where
F: FnOnce(&mut Scope) -> T,
{
@ -449,11 +450,6 @@ impl Scope {
let locals_snapshot = self.locals.in_scope.len();
let imported_symbols_snapshot = self.imported_symbols.len();
let imported_modules_snapshot = self.modules.len();
let early_returns_snapshot = if entering_function {
std::mem::replace(&mut self.early_returns, Vec::new())
} else {
Vec::new()
};
let result = f(self);
@ -461,9 +457,6 @@ impl Scope {
self.ignored_locals.truncate(ignored_locals_count);
self.imported_symbols.truncate(imported_symbols_snapshot);
self.modules.truncate(imported_modules_snapshot);
if entering_function {
self.early_returns = early_returns_snapshot;
}
// anything added in the inner scope is no longer in scope now
for i in locals_snapshot..self.locals.in_scope.len() {
@ -473,6 +466,20 @@ impl Scope {
result
}
/// Enter an inner scope within a child function, e.g. a closure body.
pub fn inner_function_scope<F, T>(&mut self, f: F) -> T
where
F: FnOnce(&mut Scope) -> T,
{
let early_returns_snapshot = std::mem::replace(&mut self.early_returns, Vec::new());
let result = self.inner_def_scope(f);
self.early_returns = early_returns_snapshot;
result
}
pub fn register_debug_idents(&self) {
self.home.register_debug_idents(&self.locals.ident_ids)
}
@ -879,7 +886,7 @@ mod test {
}
#[test]
fn inner_scope_does_not_influence_outer() {
fn inner_def_scope_does_not_influence_outer() {
let _register_module_debug_names = ModuleIds::default();
let mut scope = Scope::new(
ModuleId::ATTR,
@ -893,7 +900,7 @@ mod test {
assert!(scope.lookup(&ident, region).is_err());
scope.inner_scope(false, |inner| {
scope.inner_def_scope(|inner| {
assert!(inner.introduce(ident.clone(), region).is_ok());
});
@ -919,7 +926,7 @@ mod test {
}
#[test]
fn idents_with_inner_scope() {
fn idents_with_inner_def_scope() {
let _register_module_debug_names = ModuleIds::default();
let mut scope = Scope::new(
ModuleId::ATTR,
@ -954,7 +961,7 @@ mod test {
&[ident1.clone(), ident2.clone(), ident3.clone(),]
);
scope.inner_scope(false, |inner| {
scope.inner_def_scope(|inner| {
let ident4 = Ident::from("Ångström");
let ident5 = Ident::from("Sirály");