Skip to content

Commit

Permalink
Rename Overloads and Signature
Browse files Browse the repository at this point in the history
  • Loading branch information
dcreager committed Mar 11, 2025
1 parent 5937f24 commit fdc67f9
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 34 deletions.
28 changes: 14 additions & 14 deletions crates/red_knot_python_semantic/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ pub(crate) use self::infer::{
infer_scope_types,
};
pub use self::narrow::KnownConstraintFunction;
pub(crate) use self::signatures::{Overloads, Signature};
pub(crate) use self::signatures::{CallableSignature, Signature};
pub use self::subclass_of::SubclassOfType;
use crate::module_name::ModuleName;
use crate::module_resolver::{file_to_module, resolve_module, KnownModule};
Expand Down Expand Up @@ -2316,9 +2316,9 @@ impl<'db> Type<'db> {
// ```

#[salsa::tracked(return_ref)]
fn overloads<'db>(db: &'db dyn Db) -> Overloads<'db> {
fn overloads<'db>(db: &'db dyn Db) -> CallableSignature<'db> {
let not_none = Type::none(db).negate(db);
Overloads::from_overloads([
CallableSignature::from_overloads([
Signature::new(
Parameters::new([
Parameter::new(
Expand Down Expand Up @@ -2396,9 +2396,9 @@ impl<'db> Type<'db> {
// since the previous one is just this signature with the `self` parameters
// removed.
#[salsa::tracked(return_ref)]
fn overloads<'db>(db: &'db dyn Db) -> Overloads<'db> {
fn overloads<'db>(db: &'db dyn Db) -> CallableSignature<'db> {
let not_none = Type::none(db).negate(db);
Overloads::from_overloads([
CallableSignature::from_overloads([
Signature::new(
Parameters::new([
Parameter::new(
Expand Down Expand Up @@ -2655,7 +2655,7 @@ impl<'db> Type<'db> {
// def __new__(cls, o: object = ..., /) -> Self: ...
// ```
#[salsa::tracked(return_ref)]
fn overloads<'db>(db: &'db dyn Db) -> Overloads<'db> {
fn overloads<'db>(db: &'db dyn Db) -> CallableSignature<'db> {
Signature::new(
Parameters::new([Parameter::new(
Some(Name::new_static("o")),
Expand Down Expand Up @@ -2693,8 +2693,8 @@ impl<'db> Type<'db> {
// def __new__(cls, object: ReadableBuffer, encoding: str = ..., errors: str = ...) -> Self: ...
// ```
#[salsa::tracked(return_ref)]
fn overloads<'db>(db: &'db dyn Db) -> Overloads<'db> {
Overloads::from_overloads([
fn overloads<'db>(db: &'db dyn Db) -> CallableSignature<'db> {
CallableSignature::from_overloads([
Signature::new(
Parameters::new([Parameter::new(
Some(Name::new_static("o")),
Expand Down Expand Up @@ -2754,8 +2754,8 @@ impl<'db> Type<'db> {
// def __init__(self, name: str, bases: tuple[type, ...], dict: dict[str, Any], /, **kwds: Any) -> None: ...
// ```
#[salsa::tracked(return_ref)]
fn overloads<'db>(db: &'db dyn Db) -> Overloads<'db> {
Overloads::from_overloads([
fn overloads<'db>(db: &'db dyn Db) -> CallableSignature<'db> {
CallableSignature::from_overloads([
Signature::new(
Parameters::new([Parameter::new(
Some(Name::new_static("o")),
Expand Down Expand Up @@ -2856,7 +2856,7 @@ impl<'db> Type<'db> {
// Dynamic types are callable, and the return type is the same dynamic type. Similarly,
// `Never` is always callable and returns `Never`.
Type::Dynamic(_) | Type::Never => {
let overloads = Overloads::dynamic(self);
let overloads = CallableSignature::dynamic(self);
let binding = bind_call(db, arguments, &overloads, self);
binding.into_outcome()
}
Expand All @@ -2866,7 +2866,7 @@ impl<'db> Type<'db> {
}

Type::Intersection(_) => {
let overloads = Overloads::todo("Type::Intersection.call()");
let overloads = CallableSignature::todo("Type::Intersection.call()");
let binding = bind_call(db, arguments, &overloads, self);
binding.into_outcome()
}
Expand Down Expand Up @@ -4310,7 +4310,7 @@ impl<'db> FunctionType<'db> {
/// Were this not a salsa query, then the calling query
/// would depend on the function's AST and rerun for every change in that file.
#[salsa::tracked(return_ref)]
pub fn signature(self, db: &'db dyn Db) -> Overloads<'db> {
pub fn signature(self, db: &'db dyn Db) -> CallableSignature<'db> {
let internal_signature = self.internal_signature(db).into();

let decorators = self.decorators(db);
Expand All @@ -4323,7 +4323,7 @@ impl<'db> FunctionType<'db> {
{
internal_signature
} else {
Overloads::todo("return type of decorated function")
CallableSignature::todo("return type of decorated function")
}
} else {
internal_signature
Expand Down
2 changes: 1 addition & 1 deletion crates/red_knot_python_semantic/src/types/call.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use super::context::InferContext;
use super::{Overloads, Signature, Type};
use super::{CallableSignature, Signature, Type};
use crate::types::UnionType;
use crate::Db;

Expand Down
7 changes: 4 additions & 3 deletions crates/red_knot_python_semantic/src/types/call/bind.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use super::{
Argument, CallArguments, CallError, CallOutcome, InferContext, Overloads, Signature, Type,
Argument, CallArguments, CallError, CallOutcome, CallableSignature, InferContext, Signature,
Type,
};
use crate::db::Db;
use crate::types::diagnostic::{
Expand All @@ -12,14 +13,14 @@ use ruff_db::diagnostic::{OldSecondaryDiagnosticMessage, Span};
use ruff_python_ast as ast;
use ruff_text_size::Ranged;

/// Bind a [`CallArguments`] against a callable [`Signature`].
/// Bind a [`CallArguments`] against a [`CallableSignature`].
///
/// The returned [`CallBinding`] provides the return type of the call, the bound types for all
/// parameters, and any errors resulting from binding the call.
pub(crate) fn bind_call<'db>(
db: &'db dyn Db,
arguments: &CallArguments<'_, 'db>,
overloads: &Overloads<'db>,
overloads: &CallableSignature<'db>,
callable_ty: Type<'db>,
) -> CallBinding<'db> {
// TODO: This checks every overload. In the proposed more detailed call checking spec [1],
Expand Down
4 changes: 2 additions & 2 deletions crates/red_knot_python_semantic/src/types/infer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6057,8 +6057,8 @@ impl<'db> TypeInferenceBuilder<'db> {
Signature::new(parameters, Some(return_type)),
)));

// `Signature` / `Parameters` are not a `Type` variant, so we're storing the outer
// callable type on the these expressions instead.
// `Signature` / `Parameters` are not a `Type` variant, so we're storing
// the outer callable type on the these expressions instead.
self.store_expression_type(arguments_slice, callable_type);
self.store_expression_type(first_argument, callable_type);

Expand Down
40 changes: 26 additions & 14 deletions crates/red_knot_python_semantic/src/types/signatures.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,31 @@
//! _Signatures_ describe the expected parameters and return type of a function or other callable.
//! Overloads and unions add complexity to this simple description.
//!
//! In a call expression, the type of the callable might be a union of several types. The call must
//! be compatible with _all_ of these types, since at runtime the callable might be an instance of
//! any of them.
//!
//! Each of the atomic types in the union must be callable. Each callable might be _overloaded_,
//! containing multiple _overload signatures_, each of which describes a different combination of
//! argument types and return types. For each callable type in the union, the call expression's
//! arguments must match _at least one_ overload.
use super::{definition_expression_type, DynamicType, Type};
use crate::Db;
use crate::{semantic_index::definition::Definition, types::todo_type};
use ruff_python_ast::{self as ast, name::Name};

/// A collection of overloads for a callable.
/// The signature of a single callable. If the callable is overloaded, there is a separate
/// [`Signature`] for each overload.
#[derive(Clone, Debug, PartialEq, Eq, Hash, salsa::Update)]
pub enum Overloads<'db> {
pub enum CallableSignature<'db> {
Single(Signature<'db>),
Overloaded(Box<[Signature<'db>]>),
}

impl<'db> Overloads<'db> {
/// Creates a new `Overloads` from an non-empty iterator of [`Signature`]s. Panics if the
/// iterator is empty.
impl<'db> CallableSignature<'db> {
/// Creates a new `CallableSignature` from an non-empty iterator of [`Signature`]s.
/// Panics if the iterator is empty.
pub(crate) fn from_overloads<I>(overloads: I) -> Self
where
I: IntoIterator,
Expand All @@ -21,17 +34,17 @@ impl<'db> Overloads<'db> {
let mut iter = overloads.into_iter();
let first_overload = iter.next().expect("overloads should not be empty");
let Some(second_overload) = iter.next() else {
return Overloads::Single(first_overload);
return CallableSignature::Single(first_overload);
};
let mut overloads = vec![first_overload, second_overload];
overloads.extend(iter);
Overloads::Overloaded(overloads.into())
CallableSignature::Overloaded(overloads.into())
}

pub(crate) fn iter(&self) -> std::slice::Iter<Signature<'db>> {
match self {
Overloads::Single(signature) => std::slice::from_ref(signature).iter(),
Overloads::Overloaded(signatures) => signatures.iter(),
CallableSignature::Single(signature) => std::slice::from_ref(signature).iter(),
CallableSignature::Overloaded(signatures) => signatures.iter(),
}
}

Expand All @@ -55,14 +68,13 @@ impl<'db> Overloads<'db> {
}
}

impl<'db> From<Signature<'db>> for Overloads<'db> {
impl<'db> From<Signature<'db>> for CallableSignature<'db> {
fn from(signature: Signature<'db>) -> Self {
Overloads::Single(signature)
CallableSignature::Single(signature)
}
}

/// A typed callable signature. If a callable is overloaded, there will be one of these for each
/// possible overload.
/// The signature of one of the overloads of a callable.
#[derive(Clone, Debug, PartialEq, Eq, Hash, salsa::Update)]
pub struct Signature<'db> {
/// Parameters, in source order.
Expand Down Expand Up @@ -785,7 +797,7 @@ mod tests {
.unwrap();
let func = get_function_f(&db, "/src/a.py");

let expected_sig = Overloads::todo("return type of decorated function");
let expected_sig = CallableSignature::todo("return type of decorated function");

// With no decorators, internal and external signature are the same
assert_eq!(func.signature(&db), &expected_sig);
Expand Down

0 comments on commit fdc67f9

Please sign in to comment.