[core] typecheck: Disallow redeclaration of var shadowing global
This commit is contained in:
parent
b538611cb0
commit
3afe69fcda
|
@ -34,6 +34,20 @@ impl<'a> Inferencer<'a> {
|
||||||
Err(HashSet::from([format!("cannot assign to a `none` (at {})", pattern.location)]))
|
Err(HashSet::from([format!("cannot assign to a `none` (at {})", pattern.location)]))
|
||||||
}
|
}
|
||||||
ExprKind::Name { id, .. } => {
|
ExprKind::Name { id, .. } => {
|
||||||
|
// If `id` refers to a declared symbol, reject this assignment if it is used in the
|
||||||
|
// context of an (implicit) global variable
|
||||||
|
if let Some(id_info) = self.defined_identifiers.get(id) {
|
||||||
|
if matches!(
|
||||||
|
id_info.source,
|
||||||
|
DeclarationSource::Global { is_explicit: Some(false) }
|
||||||
|
) {
|
||||||
|
return Err(HashSet::from([format!(
|
||||||
|
"cannot access local variable '{id}' before it is declared (at {})",
|
||||||
|
pattern.location
|
||||||
|
)]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if !defined_identifiers.contains_key(id) {
|
if !defined_identifiers.contains_key(id) {
|
||||||
defined_identifiers.insert(*id, IdentifierInfo::default());
|
defined_identifiers.insert(*id, IdentifierInfo::default());
|
||||||
}
|
}
|
||||||
|
@ -104,7 +118,7 @@ impl<'a> Inferencer<'a> {
|
||||||
*id,
|
*id,
|
||||||
) {
|
) {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
self.defined_identifiers.insert(*id, IdentifierInfo::default());
|
defined_identifiers.insert(*id, IdentifierInfo::default());
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
return Err(HashSet::from([format!(
|
return Err(HashSet::from([format!(
|
||||||
|
@ -370,7 +384,7 @@ impl<'a> Inferencer<'a> {
|
||||||
if let Some(id_info) = defined_identifiers.get(id) {
|
if let Some(id_info) = defined_identifiers.get(id) {
|
||||||
if id_info.source == DeclarationSource::Local {
|
if id_info.source == DeclarationSource::Local {
|
||||||
return Err(HashSet::from([format!(
|
return Err(HashSet::from([format!(
|
||||||
"name '{id}' is assigned to before global declaration at {}",
|
"name '{id}' is used prior to global declaration at {}",
|
||||||
stmt.location,
|
stmt.location,
|
||||||
)]));
|
)]));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue