Skip to content

Comments

[ty] Fix wrong inlay hints for overloaded function arguments#23179

Merged
charliermarsh merged 2 commits intomainfrom
charlie/overload-lsp
Feb 9, 2026
Merged

[ty] Fix wrong inlay hints for overloaded function arguments#23179
charliermarsh merged 2 commits intomainfrom
charlie/overload-lsp

Conversation

@charliermarsh
Copy link
Member

Summary

Inlay hints for function call arguments were showing parameter names from the wrong overload variant because they only performed arity-based matching.

Closes astral-sh/ty#1985.

@charliermarsh charliermarsh added server Related to the LSP server ty Multi-file analysis & type inference labels Feb 9, 2026
@astral-sh-bot
Copy link

astral-sh-bot bot commented Feb 9, 2026

Typing conformance results

No changes detected ✅

@astral-sh-bot
Copy link

astral-sh-bot bot commented Feb 9, 2026

mypy_primer results

Changes were detected when running on open source projects
Expression (https://github.com/cognitedata/Expression)
- tests/test_compose.py:21:16: error[invalid-assignment] Object of type `(Never, /) -> Never` is not assignable to `(int, /) -> int`
- Found 205 diagnostics
+ Found 204 diagnostics

setuptools (https://github.com/pypa/setuptools)
+ setuptools/_distutils/command/install.py:719:42: error[invalid-argument-type] Argument to function `__new__` is incorrect: Expected `Iterable[Never]`, found `map[str]`
- Found 1126 diagnostics
+ Found 1127 diagnostics

prefect (https://github.com/PrefectHQ/prefect)
- src/prefect/input/run_input.py:672:20: error[invalid-return-type] Return type does not match returned value: expected `T@GetAutomaticInputHandler | AutomaticRunInput[T@GetAutomaticInputHandler]`, found `T@GetAutomaticInputHandler | AutomaticRunInput[T@GetAutomaticInputHandler] | Coroutine[Any, Any, T@GetAutomaticInputHandler | AutomaticRunInput[T@GetAutomaticInputHandler]]`
+ src/prefect/input/run_input.py:672:20: error[invalid-return-type] Return type does not match returned value: expected `T@GetAutomaticInputHandler | AutomaticRunInput[T@GetAutomaticInputHandler]`, found `Unknown | Coroutine[Any, Any, Unknown]`

scikit-build-core (https://github.com/scikit-build/scikit-build-core)
+ src/scikit_build_core/build/wheel.py:99:20: error[no-matching-overload] No overload of bound method `__init__` matches arguments
- Found 49 diagnostics
+ Found 50 diagnostics

@charliermarsh charliermarsh marked this pull request as ready for review February 9, 2026 15:56
@AlexWaygood AlexWaygood self-assigned this Feb 9, 2026
Copy link
Member

@AlexWaygood AlexWaygood left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice

///
/// Falls back to arity-based matching if type-based resolution fails.
fn resolve_call_signature<'db>(
db: &'db dyn Db,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rather than passing in db as a separate argument, I think you can just add let db = model.db(); as the first line of the function

Comment on lines 811 to 813
let callable_type = func_type
.try_upcast_to_callable(model.db())
.map(|callables| callables.into_type(model.db()))?;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
let callable_type = func_type
.try_upcast_to_callable(model.db())
.map(|callables| callables.into_type(model.db()))?;
let callable_type = func_type.try_upcast_to_callable(db)?.into_type(db);

.bindings(model.db())
.match_parameters(model.db(), &call_arguments);

let db = model.db();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if you moved this assignment higher up in the function, you could replace four more model.db() calls with db

Comment on lines 825 to 828
let bindings = match &checked {
Ok(bindings) => bindings,
Err(err) => &err.1,
};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I'd use .unwrap_or_else() here

.try_upcast_to_callable(model.db())
.map(|callables| callables.into_type(model.db()))?;

let args = CallArguments::from_arguments_typed(&call_expr.arguments, |_, splatted_value| {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a pre-existing issue, but: I'm a bit confused about why the passed-in closure here needs to take 2 arguments. It looks like there are now two callsites of CallArguments::from_arguments_typed() on this PR branch, and both callsites pass in a closure that ignores the first argument passed into it

Comment on lines 821 to 828
let bindings = callable_type.bindings(db).match_parameters(db, &args);

// Extract the `Bindings` regardless of whether type checking succeeded or failed.
let checked = bindings.check_types(db, &args, TypeContext::default(), &[]);
let bindings = match &checked {
Ok(bindings) => bindings,
Err(err) => &err.1,
};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit

Suggested change
let bindings = callable_type.bindings(db).match_parameters(db, &args);
// Extract the `Bindings` regardless of whether type checking succeeded or failed.
let checked = bindings.check_types(db, &args, TypeContext::default(), &[]);
let bindings = match &checked {
Ok(bindings) => bindings,
Err(err) => &err.1,
};
let bindings = callable_type
.bindings(db)
.match_parameters(db, &args)
.check_types(db, &args, TypeContext::default(), &[])
.unwrap_or_else(|CallError(_, bindings)| *bindings);

@charliermarsh charliermarsh merged commit 11b6cfd into main Feb 9, 2026
49 checks passed
@charliermarsh charliermarsh deleted the charlie/overload-lsp branch February 9, 2026 20:27
carljm added a commit to Hugo-Polloli/ruff that referenced this pull request Feb 9, 2026
* main: (45 commits)
  [ty] Fix wrong inlay hints for overloaded function arguments (astral-sh#23179)
  [ty] Respect `@no_type_check` when combined with other decorators (astral-sh#23177)
  [ty] Use type context when inferring constructor argument types (astral-sh#23139)
  [`airflow`] Add ruff rules to catch deprecated attribute access from context key for Airflow 3.0 (`AIR301`) (astral-sh#22850)
  Support formatting `pycon` markdown code blocks (astral-sh#23112)
  Markdown formatting in LSP (astral-sh#23063)
  Instruct Claude to use comments more sparingly (astral-sh#23181)
  [`flake8-gettext`] Fix false negatives for plural argument of ngettext (`INT001`, `INT002`, `INT003`) (astral-sh#21078)
  [ty] Invoking goto-def on parentheses of a class constructor call takes you too constructor method
  [ty] Make goto definition on class constructor always go to class definition
  [ty] Assign lower completions ranking to deprecated functions and classes (astral-sh#23089)
  [ty] Fix parameter references across files via keyword args (astral-sh#23012)
  [ty] Exclude enclosing class for base completions (astral-sh#23141)
  [`pyupgrade`] Fix syntax error on string with newline escape and comment (`UP037`) (astral-sh#22968)
  [ty] Improve documentation for `expect_single_definition` method (astral-sh#23175)
  [ty] Configure check mode for all projects
  Add `home-assistant` to ecosystem projects (astral-sh#23132)
  Add tabbed shell completion documentation (astral-sh#23169)
  Bump typing conformance-suite pin (astral-sh#23174)
  [ty] Fix invalid diagnostic location for a sub-call to a specialized ParamSpec (astral-sh#23036)
  ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

server Related to the LSP server ty Multi-file analysis & type inference

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Wrong function argument inlay hint for overloaded function

2 participants