[ty] name is parameter and global is a syntax error (#21312)

Co-authored-by: Alex Waygood <alex.waygood@gmail.com>
Co-authored-by: Brent Westbrook <36778786+ntBre@users.noreply.github.com>
This commit is contained in:
Bhuminjay Soni
2025-11-14 23:45:34 +05:30
committed by GitHub
parent 8599c7e5b3
commit 8529d79a70
6 changed files with 194 additions and 18 deletions

View File

@@ -1165,6 +1165,9 @@ impl<'db, 'ast> SemanticIndexBuilder<'db, 'ast> {
}
if let Some(vararg) = parameters.vararg.as_ref() {
let symbol = self.add_symbol(vararg.name.id().clone());
self.current_place_table_mut()
.symbol_mut(symbol)
.mark_parameter();
self.add_definition(
symbol.into(),
DefinitionNodeRef::VariadicPositionalParameter(vararg),
@@ -1172,6 +1175,9 @@ impl<'db, 'ast> SemanticIndexBuilder<'db, 'ast> {
}
if let Some(kwarg) = parameters.kwarg.as_ref() {
let symbol = self.add_symbol(kwarg.name.id().clone());
self.current_place_table_mut()
.symbol_mut(symbol)
.mark_parameter();
self.add_definition(
symbol.into(),
DefinitionNodeRef::VariadicKeywordParameter(kwarg),
@@ -1184,6 +1190,10 @@ impl<'db, 'ast> SemanticIndexBuilder<'db, 'ast> {
let definition = self.add_definition(symbol.into(), parameter);
self.current_place_table_mut()
.symbol_mut(symbol)
.mark_parameter();
// Insert a mapping from the inner Parameter node to the same definition. This
// ensures that calling `HasType::inferred_type` on the inner parameter returns
// a valid type (and doesn't panic)
@@ -2248,7 +2258,9 @@ impl<'ast> Visitor<'ast> for SemanticIndexBuilder<'_, 'ast> {
let symbol_id = self.add_symbol(name.id.clone());
let symbol = self.current_place_table().symbol(symbol_id);
// Check whether the variable has already been accessed in this scope.
if symbol.is_bound() || symbol.is_declared() || symbol.is_used() {
if (symbol.is_bound() || symbol.is_declared() || symbol.is_used())
&& !symbol.is_parameter()
{
self.report_semantic_error(SemanticSyntaxError {
kind: SemanticSyntaxErrorKind::LoadBeforeGlobalDeclaration {
name: name.to_string(),
@@ -2892,8 +2904,12 @@ impl SemanticSyntaxContext for SemanticIndexBuilder<'_, '_> {
fn in_loop_context(&self) -> bool {
self.current_scope_info().current_loop.is_some()
}
fn is_bound_parameter(&self, _name: &str) -> bool {
false
fn is_bound_parameter(&self, name: &str) -> bool {
self.scopes[self.current_scope()]
.node()
.as_function()
.is_some_and(|func| func.node(self.module).parameters.includes(name))
}
}

View File

@@ -38,6 +38,7 @@ bitflags! {
const MARKED_NONLOCAL = 1 << 4;
/// true if the symbol is assigned more than once, or if it is assigned even though it is already in use
const IS_REASSIGNED = 1 << 5;
const IS_PARAMETER = 1 << 6;
}
}
@@ -116,6 +117,10 @@ impl Symbol {
self.flags.contains(SymbolFlags::IS_REASSIGNED)
}
pub(crate) fn is_parameter(&self) -> bool {
self.flags.contains(SymbolFlags::IS_PARAMETER)
}
pub(super) fn mark_global(&mut self) {
self.insert_flags(SymbolFlags::MARKED_GLOBAL);
}
@@ -140,6 +145,10 @@ impl Symbol {
self.insert_flags(SymbolFlags::IS_DECLARED);
}
pub(super) fn mark_parameter(&mut self) {
self.insert_flags(SymbolFlags::IS_PARAMETER);
}
fn insert_flags(&mut self, flags: SymbolFlags) {
self.flags.insert(flags);
}