Skip to content

Conversation

AlexWaygood
Copy link
Member

Summary

ty's diagnostics are always sorted into a stable order when ty is executed on the command line. However, this sorting is not applied when the diagnostics are collected by mdtests, which can result in them being snapshotted in our tests in a different order than they would appear to users. That's quite confusing.

This PR fixes that by sorting the diagnostics collected by mdtest in the same way that we sort them when ty is actually executed on the command line.

Test Plan

  • cargo test -p ty_python_semantic
  • cargo test -p ty_project

@AlexWaygood AlexWaygood added the ty Multi-file analysis & type inference label May 7, 2025
@dhruvmanila
Copy link
Member

Thank you! I noticed this a couple of times and I was going to open an issue for it.

@dhruvmanila dhruvmanila requested a review from BurntSushi May 7, 2025 17:07
Copy link
Contributor

github-actions bot commented May 7, 2025

mypy_primer results

No ecosystem changes detected ✅

Copy link
Member

@MichaReiser MichaReiser left a comment

Choose a reason for hiding this comment

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

Nice, thank you

Comment on lines 236 to 246
/// Returns a key that can be used to sort two diagnostics into the canonical order
/// in which they should appear when rendered.
pub fn rendering_sort_key<'a, 'db>(&'a self, db: &'db dyn Db) -> impl Ord + 'a
where
'db: 'a,
{
RenderingSortKey {
db,
diagnostic: self,
}
}
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 sort of like how TextRange solved this. It has a ordering method. It could help reduce some complexity (no need for an extra struct, less lifetimes)

pub fn ordering(&self, db: &dyn Db, other: &Self) -> Ordering {
	if let (Some(span1), Some(span2)) = (
      self.primary_span(),
      other.primary_span(),
  ) {
      let order = span1
          .file()
          .path(self.db)
          .as_str()
          .cmp(span2.file().path(self.db).as_str());
      if order.is_ne() {
          return order;
      }

      if let (Some(range1), Some(range2)) = (span1.range(), span2.range()) {
          let order = range1.start().cmp(&range2.start());
          if order.is_ne() {
              return order;
          }
      }
  }
  // Reverse so that, e.g., Fatal sorts before Info.
  let order = self
      .severity()
      .cmp(&other.severity())
      .reverse();
  if order.is_ne() {
      return order;
  }
  self.id().cmp(&other.id())
}

Copy link
Member Author

Choose a reason for hiding this comment

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

I realised I could simplify it to a single lifetime (pushed the change). I weakly prefer encapsulating the sorting logic into a struct that represents the key (the way I have it now), but no strong opinion; happy to revisit this in a followup if others agree!

Copy link
Member

Choose a reason for hiding this comment

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

I don't feel too strongly personally. I'm fine with either approach given that these aren't semver boundaries.

@AlexWaygood AlexWaygood merged commit 74fe798 into main May 7, 2025
35 checks passed
@AlexWaygood AlexWaygood deleted the alex/mdtest-diagnostics-sorted branch May 7, 2025 17:23
dcreager added a commit that referenced this pull request May 7, 2025
…lass

* origin/main:
  [`pylint`] add fix safety section (`PLC2801`) (#17825)
  Add instructions on how to upgrade to a newer Rust version (#17928)
  [parser] Flag single unparenthesized generator expr with trailing comma in arguments. (#17893)
  [ty] Ensure that `T` is disjoint from `~T` even when `T` is a TypeVar (#17922)
  [ty] Sort collected diagnostics before snapshotting them in mdtest (#17926)
  [ty] Add basic file watching to server (#17912)
  Make completions an opt-in LSP feature (#17921)
  Add link to `ty` issue tracker (#17924)
  [ty] Add support for `__all__` (#17856)
  [ty] fix assigning a typevar to a union with itself (#17910)
  [ty] Improve UX for `[duplicate-base]` diagnostics (#17914)
  Clean up some Ruff references in the ty server (#17920)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ty Multi-file analysis & type inference
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants