[ty] Avoid overload errors when detecting dataclass-on-tuple#22687
[ty] Avoid overload errors when detecting dataclass-on-tuple#22687charliermarsh merged 2 commits intomainfrom
Conversation
Typing conformance resultsNo changes detected ✅ |
|
| // (possibly with semantic errors), report its errors directly instead | ||
| // of the generic "no matching overload" message. | ||
| if let MatchingOverloadIndex::Single(matching_overload_index) = | ||
| self.matching_overload_index() |
There was a problem hiding this comment.
I... think this was impossible on main? Because if we had exactly one matching overload without errors, we'd never call report_diagnostics? But now, we can have one overload that matches but still emits an error.
There was a problem hiding this comment.
Yeah, I think that's correct, I reached the same conclusion in #22688 (comment).
I think the body of this if branch is same as the one right above it, so both of these can be merged? Edit: Oh, merging that might be difficult but maybe we could extract out the logic into an inner function.
|
| Lint rule | Added | Removed | Changed |
|---|---|---|---|
invalid-parameter-default |
0 | 0 | 7 |
invalid-return-type |
0 | 1 | 6 |
invalid-argument-type |
0 | 1 | 4 |
invalid-assignment |
0 | 0 | 5 |
possibly-missing-attribute |
0 | 3 | 1 |
invalid-await |
0 | 2 | 0 |
unresolved-attribute |
0 | 0 | 2 |
unused-ignore-comment |
1 | 0 | 0 |
| Total | 1 | 7 | 25 |
|
So in But not the following: On main, we show both. |
|
I think that's actually... correct? Consider In this branch, we have |
ec73f1f to
6abafd1
Compare
|
I am going to see if I can fix that separately here. |
6abafd1 to
c008e7c
Compare
|
I moved that change into #22688. |
c008e7c to
6993da4
Compare
| // If any matching overload has errors, we have binding errors. | ||
| if !first_overload.errors.is_empty() { |
There was a problem hiding this comment.
These errors would be "semantic" errors as defined in affects_overload_resolution, right? If so, the comment could be updated
| fn as_result(&self) -> Result<(), CallErrorKind> { | ||
| if !self.errors.is_empty() { | ||
| if self | ||
| .errors | ||
| .iter() | ||
| .any(BindingError::affects_overload_resolution) | ||
| { | ||
| return Err(CallErrorKind::BindingError); | ||
| } | ||
| Ok(()) |
There was a problem hiding this comment.
The as_result name for this method seems a bit misleading now that we don't account for all errors here (only the ones that affect overload resolution), maybe we should rename this? e.g., has_errors_affecting_overload_resolution (too long), failed_overload_resolution, etc. This method is also only called in matching_overloads and matching_overloads_mut so it seems ok to rename it to be specific to this usage.
| // (possibly with semantic errors), report its errors directly instead | ||
| // of the generic "no matching overload" message. | ||
| if let MatchingOverloadIndex::Single(matching_overload_index) = | ||
| self.matching_overload_index() |
There was a problem hiding this comment.
Yeah, I think that's correct, I reached the same conclusion in #22688 (comment).
I think the body of this if branch is same as the one right above it, so both of these can be merged? Edit: Oh, merging that might be difficult but maybe we could extract out the logic into an inner function.
6993da4 to
fc557c5
Compare
Summary
Fixes some TODOs introduced in #22672 around cases like the following:
On main,
dataclass(NT)emits# error: [no-matching-overload]instead, which is wrong -- the overload does match! On main, the logic proceeds as follows:dataclasshas two overloads:dataclass(cls: type[_T], ...) -> type[_T]dataclass(cls: None = None, ...) -> Callable[[type[_T]], type[_T]]dataclass(NT)is called:NTmatchestype[_T]... but theninvalid_dataclass_target()runs and addsInvalidDataclassApplicationerrorNTdoesn't matchNone, so we have a type error.matching_overload_index()filters byoverload.as_result().is_ok(), which checks iferrors.is_empty(). Since both overloads have errors, neither matches...Instead, we now differentiate between non-matching errors, and errors that occur when we do match, but the call has some other semantic failure.