mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-04 02:38:25 +00:00
Refine SemanticModel lifetime bounds (#10221)
## Summary Corrects/refines some semantic model and related lifetime bounds. ## Test Plan `cargo check`
This commit is contained in:
parent
4eac9baf43
commit
64f66cd8fe
7 changed files with 46 additions and 40 deletions
|
@ -110,7 +110,7 @@ impl<'a> Binding<'a> {
|
|||
|
||||
/// Return `true` if this binding "redefines" the given binding, as per Pyflake's definition of
|
||||
/// redefinition.
|
||||
pub fn redefines(&self, existing: &'a Binding) -> bool {
|
||||
pub fn redefines(&self, existing: &Binding) -> bool {
|
||||
match &self.kind {
|
||||
// Submodule imports are only considered redefinitions if they import the same
|
||||
// submodule. For example, this is a redefinition:
|
||||
|
@ -184,12 +184,12 @@ impl<'a> Binding<'a> {
|
|||
}
|
||||
|
||||
/// Returns the name of the binding (e.g., `x` in `x = 1`).
|
||||
pub fn name<'b>(&self, locator: &'b Locator) -> &'b str {
|
||||
pub fn name<'b>(&self, locator: &Locator<'b>) -> &'b str {
|
||||
locator.slice(self.range)
|
||||
}
|
||||
|
||||
/// Returns the statement in which the binding was defined.
|
||||
pub fn statement<'b>(&self, semantic: &'b SemanticModel) -> Option<&'b Stmt> {
|
||||
pub fn statement<'b>(&self, semantic: &SemanticModel<'b>) -> Option<&'b Stmt> {
|
||||
self.source
|
||||
.map(|statement_id| semantic.statement(statement_id))
|
||||
}
|
||||
|
@ -205,7 +205,7 @@ impl<'a> Binding<'a> {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn as_any_import(&'a self) -> Option<AnyImport<'a>> {
|
||||
pub fn as_any_import(&self) -> Option<AnyImport<'_, 'a>> {
|
||||
match &self.kind {
|
||||
BindingKind::Import(import) => Some(AnyImport::Import(import)),
|
||||
BindingKind::SubmoduleImport(import) => Some(AnyImport::SubmoduleImport(import)),
|
||||
|
@ -549,10 +549,10 @@ bitflags! {
|
|||
/// A trait for imported symbols.
|
||||
pub trait Imported<'a> {
|
||||
/// Returns the call path to the imported symbol.
|
||||
fn call_path(&self) -> &[&str];
|
||||
fn call_path(&self) -> &[&'a str];
|
||||
|
||||
/// Returns the module name of the imported symbol.
|
||||
fn module_name(&self) -> &[&str];
|
||||
fn module_name(&self) -> &[&'a str];
|
||||
|
||||
/// Returns the member name of the imported symbol. For a straight import, this is equivalent
|
||||
/// to the qualified name; for a `from` import, this is the name of the imported symbol.
|
||||
|
@ -568,12 +568,12 @@ pub trait Imported<'a> {
|
|||
|
||||
impl<'a> Imported<'a> for Import<'a> {
|
||||
/// For example, given `import foo`, returns `["foo"]`.
|
||||
fn call_path(&self) -> &[&str] {
|
||||
fn call_path(&self) -> &[&'a str] {
|
||||
self.call_path.as_ref()
|
||||
}
|
||||
|
||||
/// For example, given `import foo`, returns `["foo"]`.
|
||||
fn module_name(&self) -> &[&str] {
|
||||
fn module_name(&self) -> &[&'a str] {
|
||||
&self.call_path[..1]
|
||||
}
|
||||
|
||||
|
@ -585,12 +585,12 @@ impl<'a> Imported<'a> for Import<'a> {
|
|||
|
||||
impl<'a> Imported<'a> for SubmoduleImport<'a> {
|
||||
/// For example, given `import foo.bar`, returns `["foo", "bar"]`.
|
||||
fn call_path(&self) -> &[&str] {
|
||||
fn call_path(&self) -> &[&'a str] {
|
||||
self.call_path.as_ref()
|
||||
}
|
||||
|
||||
/// For example, given `import foo.bar`, returns `["foo"]`.
|
||||
fn module_name(&self) -> &[&str] {
|
||||
fn module_name(&self) -> &[&'a str] {
|
||||
&self.call_path[..1]
|
||||
}
|
||||
|
||||
|
@ -602,12 +602,12 @@ impl<'a> Imported<'a> for SubmoduleImport<'a> {
|
|||
|
||||
impl<'a> Imported<'a> for FromImport<'a> {
|
||||
/// For example, given `from foo import bar`, returns `["foo", "bar"]`.
|
||||
fn call_path(&self) -> &[&str] {
|
||||
fn call_path(&self) -> &[&'a str] {
|
||||
&self.call_path
|
||||
}
|
||||
|
||||
/// For example, given `from foo import bar`, returns `["foo"]`.
|
||||
fn module_name(&self) -> &[&str] {
|
||||
fn module_name(&self) -> &[&'a str] {
|
||||
&self.call_path[..self.call_path.len() - 1]
|
||||
}
|
||||
|
||||
|
@ -619,14 +619,14 @@ impl<'a> Imported<'a> for FromImport<'a> {
|
|||
|
||||
/// A wrapper around an import [`BindingKind`] that can be any of the three types of imports.
|
||||
#[derive(Debug, Clone, is_macro::Is)]
|
||||
pub enum AnyImport<'a> {
|
||||
Import(&'a Import<'a>),
|
||||
SubmoduleImport(&'a SubmoduleImport<'a>),
|
||||
FromImport(&'a FromImport<'a>),
|
||||
pub enum AnyImport<'a, 'ast> {
|
||||
Import(&'a Import<'ast>),
|
||||
SubmoduleImport(&'a SubmoduleImport<'ast>),
|
||||
FromImport(&'a FromImport<'ast>),
|
||||
}
|
||||
|
||||
impl<'a> Imported<'a> for AnyImport<'a> {
|
||||
fn call_path(&self) -> &[&str] {
|
||||
impl<'a, 'ast> Imported<'ast> for AnyImport<'a, 'ast> {
|
||||
fn call_path(&self) -> &[&'ast str] {
|
||||
match self {
|
||||
Self::Import(import) => import.call_path(),
|
||||
Self::SubmoduleImport(import) => import.call_path(),
|
||||
|
@ -634,7 +634,7 @@ impl<'a> Imported<'a> for AnyImport<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn module_name(&self) -> &[&str] {
|
||||
fn module_name(&self) -> &[&'ast str] {
|
||||
match self {
|
||||
Self::Import(import) => import.module_name(),
|
||||
Self::SubmoduleImport(import) => import.module_name(),
|
||||
|
@ -642,7 +642,7 @@ impl<'a> Imported<'a> for AnyImport<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn member_name(&self) -> Cow<'a, str> {
|
||||
fn member_name(&self) -> Cow<'ast, str> {
|
||||
match self {
|
||||
Self::Import(import) => import.member_name(),
|
||||
Self::SubmoduleImport(import) => import.member_name(),
|
||||
|
|
|
@ -81,7 +81,7 @@ pub struct Member<'a> {
|
|||
|
||||
impl<'a> Member<'a> {
|
||||
/// Return the name of the member.
|
||||
pub fn name(&self) -> &str {
|
||||
pub fn name(&self) -> &'a str {
|
||||
match self.kind {
|
||||
MemberKind::Class(class) => &class.name,
|
||||
MemberKind::NestedClass(class) => &class.name,
|
||||
|
@ -92,7 +92,7 @@ impl<'a> Member<'a> {
|
|||
}
|
||||
|
||||
/// Return the body of the member.
|
||||
pub fn body(&self) -> &[Stmt] {
|
||||
pub fn body(&self) -> &'a [Stmt] {
|
||||
match self.kind {
|
||||
MemberKind::Class(class) => &class.body,
|
||||
MemberKind::NestedClass(class) => &class.body,
|
||||
|
@ -123,7 +123,7 @@ pub enum Definition<'a> {
|
|||
Member(Member<'a>),
|
||||
}
|
||||
|
||||
impl Definition<'_> {
|
||||
impl<'a> Definition<'a> {
|
||||
/// Returns `true` if the [`Definition`] is a method definition.
|
||||
pub const fn is_method(&self) -> bool {
|
||||
matches!(
|
||||
|
@ -136,7 +136,7 @@ impl Definition<'_> {
|
|||
}
|
||||
|
||||
/// Return the name of the definition.
|
||||
pub fn name(&self) -> Option<&str> {
|
||||
pub fn name(&self) -> Option<&'a str> {
|
||||
match self {
|
||||
Definition::Module(module) => module.name(),
|
||||
Definition::Member(member) => Some(member.name()),
|
||||
|
@ -144,7 +144,7 @@ impl Definition<'_> {
|
|||
}
|
||||
|
||||
/// Return the [`ast::StmtFunctionDef`] of the definition, if it's a function definition.
|
||||
pub fn as_function_def(&self) -> Option<&ast::StmtFunctionDef> {
|
||||
pub fn as_function_def(&self) -> Option<&'a ast::StmtFunctionDef> {
|
||||
match self {
|
||||
Definition::Member(Member {
|
||||
kind:
|
||||
|
@ -158,7 +158,7 @@ impl Definition<'_> {
|
|||
}
|
||||
|
||||
/// Return the [`ast::StmtClassDef`] of the definition, if it's a class definition.
|
||||
pub fn as_class_def(&self) -> Option<&ast::StmtClassDef> {
|
||||
pub fn as_class_def(&self) -> Option<&'a ast::StmtClassDef> {
|
||||
match self {
|
||||
Definition::Member(Member {
|
||||
kind: MemberKind::Class(class) | MemberKind::NestedClass(class),
|
||||
|
|
|
@ -48,8 +48,8 @@ impl<'a> Globals<'a> {
|
|||
builder.finish()
|
||||
}
|
||||
|
||||
pub(crate) fn get(&self, name: &str) -> Option<&TextRange> {
|
||||
self.0.get(name)
|
||||
pub(crate) fn get(&self, name: &str) -> Option<TextRange> {
|
||||
self.0.get(name).copied()
|
||||
}
|
||||
|
||||
pub(crate) fn iter(&self) -> impl Iterator<Item = (&&'a str, &TextRange)> + '_ {
|
||||
|
|
|
@ -131,7 +131,7 @@ pub struct SemanticModel<'a> {
|
|||
}
|
||||
|
||||
impl<'a> SemanticModel<'a> {
|
||||
pub fn new(typing_modules: &'a [String], path: &'a Path, module: Module<'a>) -> Self {
|
||||
pub fn new(typing_modules: &'a [String], path: &Path, module: Module<'a>) -> Self {
|
||||
Self {
|
||||
typing_modules,
|
||||
module_path: module.path(),
|
||||
|
@ -159,7 +159,7 @@ impl<'a> SemanticModel<'a> {
|
|||
|
||||
/// Return the [`Binding`] for the given [`BindingId`].
|
||||
#[inline]
|
||||
pub fn binding(&self, id: BindingId) -> &Binding {
|
||||
pub fn binding(&self, id: BindingId) -> &Binding<'a> {
|
||||
&self.bindings[id]
|
||||
}
|
||||
|
||||
|
@ -200,7 +200,7 @@ impl<'a> SemanticModel<'a> {
|
|||
}
|
||||
|
||||
/// Return an iterator over the set of `typing` modules allowed in the semantic model.
|
||||
pub fn typing_modules(&self) -> impl Iterator<Item = &str> {
|
||||
pub fn typing_modules(&self) -> impl Iterator<Item = &'a str> {
|
||||
["typing", "_typeshed", "typing_extensions"]
|
||||
.iter()
|
||||
.copied()
|
||||
|
@ -567,7 +567,7 @@ impl<'a> SemanticModel<'a> {
|
|||
/// For example, given `["Class", "method"`], resolve the `BindingKind::ClassDefinition`
|
||||
/// associated with `Class`, then the `BindingKind::FunctionDefinition` associated with
|
||||
/// `Class.method`.
|
||||
pub fn lookup_attribute(&'a self, value: &'a Expr) -> Option<BindingId> {
|
||||
pub fn lookup_attribute(&self, value: &Expr) -> Option<BindingId> {
|
||||
let call_path = CallPath::from_expr(value)?;
|
||||
|
||||
// Find the symbol in the current scope.
|
||||
|
@ -659,7 +659,13 @@ impl<'a> SemanticModel<'a> {
|
|||
/// ```
|
||||
///
|
||||
/// ...then `resolve_call_path(${python_version})` will resolve to `sys.version_info`.
|
||||
pub fn resolve_call_path(&'a self, value: &'a Expr) -> Option<CallPath<'a>> {
|
||||
pub fn resolve_call_path<'name, 'expr: 'name>(
|
||||
&self,
|
||||
value: &'expr Expr,
|
||||
) -> Option<CallPath<'name>>
|
||||
where
|
||||
'a: 'name,
|
||||
{
|
||||
/// Return the [`ast::ExprName`] at the head of the expression, if any.
|
||||
const fn match_head(value: &Expr) -> Option<&ast::ExprName> {
|
||||
match value {
|
||||
|
@ -974,7 +980,7 @@ impl<'a> SemanticModel<'a> {
|
|||
}
|
||||
|
||||
/// Returns an iterator over all scopes, starting from the current [`Scope`].
|
||||
pub fn current_scopes(&self) -> impl Iterator<Item = &Scope> {
|
||||
pub fn current_scopes(&self) -> impl Iterator<Item = &Scope<'a>> {
|
||||
self.scopes.ancestors(self.scope_id)
|
||||
}
|
||||
|
||||
|
@ -1154,7 +1160,7 @@ impl<'a> SemanticModel<'a> {
|
|||
/// Return the [`TextRange`] at which a name is declared as global in the current [`Scope`].
|
||||
pub fn global(&self, name: &str) -> Option<TextRange> {
|
||||
let global_id = self.scopes[self.scope_id].globals_id()?;
|
||||
self.globals[global_id].get(name).copied()
|
||||
self.globals[global_id].get(name)
|
||||
}
|
||||
|
||||
/// Given a `name` that has been declared `nonlocal`, return the [`ScopeId`] and [`BindingId`]
|
||||
|
@ -1998,7 +2004,7 @@ impl ImportedName {
|
|||
self.context
|
||||
}
|
||||
|
||||
pub fn statement<'a>(&self, semantic: &'a SemanticModel) -> &'a Stmt {
|
||||
pub fn statement<'a>(&self, semantic: &SemanticModel<'a>) -> &'a Stmt {
|
||||
semantic.statement(self.source)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -95,7 +95,7 @@ impl<'a> Scope<'a> {
|
|||
}
|
||||
|
||||
/// Returns a tuple of the name and ID of all bindings defined in this scope.
|
||||
pub fn bindings(&self) -> impl Iterator<Item = (&str, BindingId)> + '_ {
|
||||
pub fn bindings(&self) -> impl Iterator<Item = (&'a str, BindingId)> + '_ {
|
||||
self.bindings.iter().map(|(&name, &id)| (name, id))
|
||||
}
|
||||
|
||||
|
@ -238,7 +238,7 @@ impl<'a> Scopes<'a> {
|
|||
}
|
||||
|
||||
/// Returns an iterator over all [`Scope`] ancestors, starting from the given [`ScopeId`].
|
||||
pub fn ancestors(&self, scope_id: ScopeId) -> impl Iterator<Item = &Scope> + '_ {
|
||||
pub fn ancestors(&self, scope_id: ScopeId) -> impl Iterator<Item = &Scope<'a>> + '_ {
|
||||
std::iter::successors(Some(&self[scope_id]), |&scope| {
|
||||
scope.parent.map(|scope_id| &self[scope_id])
|
||||
})
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue