Skip to content

(feature): Contextualized path for shorter and readable diagnostics#9265

Merged
eytan-starkware merged 2 commits intomainfrom
eytan_graphite/_feature_contextualized_path_for_shorter_and_readable_diagnostics
Dec 30, 2025
Merged

(feature): Contextualized path for shorter and readable diagnostics#9265
eytan-starkware merged 2 commits intomainfrom
eytan_graphite/_feature_contextualized_path_for_shorter_and_readable_diagnostics

Conversation

@eytan-starkware
Copy link
Contributor

@eytan-starkware eytan-starkware commented Dec 21, 2025

Summary

Added a new path module that provides functionality to find the shortest valid path to an item from a module context. This improves error messages by showing contextualized paths instead of full paths, making them more readable and relevant to the user's current module.


Type of change

Please check one:

  • Bug fix (fixes incorrect behavior)
  • New feature
  • Performance improvement
  • Documentation change with concrete technical impact
  • Style, wording, formatting, or typo-only change

Why is this change needed?

Error messages were showing full paths to types and traits (e.g., core::option::Option), which made them unnecessarily verbose and harder to read. This is especially problematic when the user has already imported the type or trait, as the full path is redundant and distracting.


What was the behavior or documentation before?

Error messages would show full paths to types and traits, even when shorter paths would be valid in the current context. For example:

error: Wrong enum in pattern. Expected: "core::option::Option". Got: "test::MyEnum".

What is the behavior or documentation after?

Error messages now show contextualized paths that are valid from the current module:

error: Wrong enum in pattern. Expected: "Option". Got: "MyEnum".

The system considers various access strategies (direct access, imports, relative paths, etc.) and chooses the shortest valid path.


Additional context

@reviewable-StarkWare
Copy link

This change is Reviewable

Copy link
Contributor Author

eytan-starkware commented Dec 21, 2025

@eytan-starkware eytan-starkware marked this pull request as ready for review December 21, 2025 14:38
Copy link
Collaborator

@orizi orizi left a comment

Choose a reason for hiding this comment

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

@orizi reviewed 1 of 14 files at r1, all commit messages.
Reviewable status: 1 of 14 files reviewed, 5 unresolved discussions (waiting on @eytan-starkware, @giladchase, and @TomerStarkware)


crates/cairo-lang-semantic/src/diagnostic.rs line 394 at r1 (raw file):

            }
            SemanticDiagnosticKind::AmbiguousTrait {
                context_module,

maybe we should go the other way - getting the context externally - as we collect the diagnostics per module to begin with.


crates/cairo-lang-defs/src/ids.rs line 73 at r1 (raw file):

    fn full_path(&self, db: &'db dyn Database) -> String {
        self.path_segments(db).iter().map(|s| s.to_string(db)).collect::<Vec<_>>().join("::")

this seems less efficient.


crates/cairo-lang-defs/src/ids.rs line 328 at r1 (raw file):

    pub fn full_path(&self, db: &'db dyn Database) -> String {
        self.path_segments(db).iter().map(|s| s.to_string(db)).collect::<Vec<_>>().join("::")

ditto.


crates/cairo-lang-defs/src/ids.rs line 512 at r1 (raw file):

impl<'db> ImportableId<'db> {
    pub fn parent_module(&self, db: &'db dyn Database) -> Option<ModuleId<'db>> {

doc


crates/cairo-lang-defs/src/ids.rs line 531 at r1 (raw file):

    }

    pub fn name(&self, db: &'db dyn Database) -> SmolStrId<'db> {

doc

@eytan-starkware eytan-starkware changed the base branch from main to graphite-base/9265 December 29, 2025 12:09
@eytan-starkware eytan-starkware force-pushed the eytan_graphite/_feature_contextualized_path_for_shorter_and_readable_diagnostics branch from 33ac7bc to 11b7298 Compare December 29, 2025 12:09
Copy link
Contributor Author

@eytan-starkware eytan-starkware left a comment

Choose a reason for hiding this comment

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

@eytan-starkware made 5 comments.
Reviewable status: 1 of 14 files reviewed, 5 unresolved discussions (waiting on @giladchase, @orizi, and @TomerStarkware).


crates/cairo-lang-defs/src/ids.rs line 73 at r1 (raw file):

Previously, orizi wrote…

this seems less efficient.

Done.


crates/cairo-lang-defs/src/ids.rs line 328 at r1 (raw file):

Previously, orizi wrote…

ditto.

Done.


crates/cairo-lang-defs/src/ids.rs line 512 at r1 (raw file):

Previously, orizi wrote…

doc

Done.


crates/cairo-lang-defs/src/ids.rs line 531 at r1 (raw file):

Previously, orizi wrote…

doc

Done.


crates/cairo-lang-semantic/src/diagnostic.rs line 394 at r1 (raw file):

Previously, orizi wrote…

maybe we should go the other way - getting the context externally - as we collect the diagnostics per module to begin with.

Moved on top of a new PR that puts module as part of the SemanticDiagnostic.

@eytan-starkware eytan-starkware changed the base branch from graphite-base/9265 to eytan_graphite/_feat_adding_module_as_context_to_diagnostic_reporting December 29, 2025 12:09
Copy link
Collaborator

@orizi orizi left a comment

Choose a reason for hiding this comment

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

@orizi reviewed 1 file and all commit messages, made 1 comment, and resolved 4 discussions.
Reviewable status: 1 of 17 files reviewed, 2 unresolved discussions (waiting on @eytan-starkware, @giladchase, and @TomerStarkware).


crates/cairo-lang-filesystem/src/ids.rs line 453 at r2 (raw file):

            result.push_str(&s.to_string(db));
        }
        result

my issue was the to-string and vector collection - you don't need them.

(and you probably don't need the function.

Suggestion:

        segments.iter().map(|s| s.long(db)).join(seperator)

Copy link
Collaborator

@orizi orizi left a comment

Choose a reason for hiding this comment

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

@orizi reviewed 4 files, made 1 comment, and resolved 1 discussion.
Reviewable status: 5 of 17 files reviewed, 2 unresolved discussions (waiting on @eytan-starkware, @giladchase, and @TomerStarkware).


crates/cairo-lang-semantic/src/expr/compute.rs line 2589 at r2 (raw file):

        TraitInferenceErrors<'db>,
    ) -> Option<SemanticDiagnosticKind<'db>>,
    multiple_trait_diagnostic: impl Fn(

still relevant?

@eytan-starkware eytan-starkware force-pushed the eytan_graphite/_feature_contextualized_path_for_shorter_and_readable_diagnostics branch from 11b7298 to ae380f9 Compare December 29, 2025 12:42
Copy link
Collaborator

@orizi orizi left a comment

Choose a reason for hiding this comment

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

@orizi reviewed 2 files and all commit messages, and made 5 comments.
Reviewable status: 5 of 24 files reviewed, 7 unresolved discussions (waiting on @eytan-starkware, @giladchase, and @TomerStarkware).


crates/cairo-lang-semantic/src/path.rs line 31 at r3 (raw file):

pub struct ItemAccessInfo<'db> {
    /// The shortest path segments to access the item from the context.
    pub path_segments: Vec<ImportableId<'db>>,

doc that it is reversed in relation to actual path (at least i assume so according to path())


crates/cairo-lang-semantic/src/path.rs line 57 at r3 (raw file):

            | ItemAccessKind::ViaGlobalUse
            | ItemAccessKind::FullPath(_) => "".to_string(),
        };

both are &' static - so no issue.

Suggestion:

        let prefix = match self.access_kind {
            ItemAccessKind::ViaCrate => "crate::",
            ItemAccessKind::DirectInModule
            | ItemAccessKind::ViaUse(_)
            | ItemAccessKind::ViaPrelude
            | ItemAccessKind::ViaGlobalUse
            | ItemAccessKind::FullPath(_) => "",
        };

crates/cairo-lang-semantic/src/path.rs line 58 at r3 (raw file):

            | ItemAccessKind::FullPath(_) => "".to_string(),
        };
        let mut path = self.path_segments.iter().rev().map(|id| id.name(db).long(db)).join("::");

comment about the rev.


crates/cairo-lang-semantic/src/path.rs line 63 at r3 (raw file):

        } else {
            path = format!("{path}::{}", self.name.long(db));
        }

Suggestion:

        let path = chain!(self.path_segments.iter().rev().map(|id|id.name(db)), [self.name]).map(|name| name.long(db)).join("::");

crates/cairo-lang-semantic/src/path.rs line 64 at r3 (raw file):

            path = format!("{path}::{}", self.name.long(db));
        }
        format!("{}{}", prefix, path)

Suggestion:

        format!("{prefix}{path}")

Copy link
Collaborator

@orizi orizi left a comment

Choose a reason for hiding this comment

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

@orizi made 6 comments.
Reviewable status: 5 of 24 files reviewed, 13 unresolved discussions (waiting on @eytan-starkware, @giladchase, and @TomerStarkware).


crates/cairo-lang-semantic/src/path.rs line 96 at r3 (raw file):

///
/// Access strategies tried:
/// 1. Direct access (item in current module)

isn't prelude first?


crates/cairo-lang-semantic/src/path.rs line 164 at r3 (raw file):

}

fn check_prelude<'db>(

doc


crates/cairo-lang-semantic/src/path.rs line 168 at r3 (raw file):

    item: ImportableId<'db>,
    context_module: ModuleId<'db>,
) -> Result<Option<ItemAccessInfo<'db>>, cairo_lang_diagnostics::DiagnosticAdded> {

Suggestion:

) -> Maybe<Option<ItemAccessInfo<'db>>> {

crates/cairo-lang-semantic/src/path.rs line 170 at r3 (raw file):

) -> Result<Option<ItemAccessInfo<'db>>, cairo_lang_diagnostics::DiagnosticAdded> {
    let settings = db.crate_config(context_module.owning_crate(db)).map(|c| c.settings.clone());
    if let Some(prelude_module) = db.get_prelude_submodule(&settings.unwrap_or_default())

feels like this clone can be avoided.

Code quote:

    let settings = db.crate_config(context_module.owning_crate(db)).map(|c| c.settings.clone());
    if let Some(prelude_module) = db.get_prelude_submodule(&settings.unwrap_or_default())

crates/cairo-lang-semantic/src/path.rs line 294 at r3 (raw file):

}

trait IntoImportableMarker<'db>: Into<ImportableId<'db>> {}

doc


crates/cairo-lang-semantic/src/path.rs line 300 at r3 (raw file):

    for<'a> &'a T: IntoImportableMarker<'db>,
{
    fn contextualized_path(

doc

Copy link
Collaborator

@orizi orizi left a comment

Choose a reason for hiding this comment

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

@orizi reviewed 19 files and resolved 1 discussion.
Reviewable status: all files reviewed, 12 unresolved discussions (waiting on @eytan-starkware, @giladchase, and @TomerStarkware).

@eytan-starkware eytan-starkware force-pushed the eytan_graphite/_feature_contextualized_path_for_shorter_and_readable_diagnostics branch from ae380f9 to 9095326 Compare December 29, 2025 13:39
@eytan-starkware eytan-starkware force-pushed the eytan_graphite/_feat_adding_module_as_context_to_diagnostic_reporting branch from a33d09b to 3d8fe56 Compare December 29, 2025 13:39
@eytan-starkware eytan-starkware force-pushed the eytan_graphite/_feature_contextualized_path_for_shorter_and_readable_diagnostics branch from 9095326 to 4981736 Compare December 29, 2025 14:20
Copy link
Contributor Author

@eytan-starkware eytan-starkware left a comment

Choose a reason for hiding this comment

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

@eytan-starkware made 13 comments.
Reviewable status: 20 of 24 files reviewed, 12 unresolved discussions (waiting on @giladchase, @orizi, and @TomerStarkware).


crates/cairo-lang-semantic/src/path.rs line 31 at r3 (raw file):

Previously, orizi wrote…

doc that it is reversed in relation to actual path (at least i assume so according to path())

Done.


crates/cairo-lang-semantic/src/path.rs line 57 at r3 (raw file):

Previously, orizi wrote…

both are &' static - so no issue.

Done.


crates/cairo-lang-semantic/src/path.rs line 58 at r3 (raw file):

Previously, orizi wrote…

comment about the rev.

Done.


crates/cairo-lang-semantic/src/path.rs line 96 at r3 (raw file):

Previously, orizi wrote…

isn't prelude first?

It definitely is, but this whole comment is wrong by now.


crates/cairo-lang-semantic/src/path.rs line 164 at r3 (raw file):

Previously, orizi wrote…

doc

Done.


crates/cairo-lang-semantic/src/path.rs line 170 at r3 (raw file):

Previously, orizi wrote…

feels like this clone can be avoided.

Yes, but we need to create a default value somewhere leading to allocations either way (or a query we had from before)


crates/cairo-lang-semantic/src/path.rs line 294 at r3 (raw file):

Previously, orizi wrote…

doc

Done.


crates/cairo-lang-semantic/src/path.rs line 300 at r3 (raw file):

Previously, orizi wrote…

doc

The trait function is documented in the definition of the trait


crates/cairo-lang-filesystem/src/ids.rs line 453 at r2 (raw file):

Previously, orizi wrote…

my issue was the to-string and vector collection - you don't need them.

(and you probably don't need the function.

Done


crates/cairo-lang-semantic/src/expr/compute.rs line 2589 at r2 (raw file):

Previously, orizi wrote…

still relevant?

Apparently not


crates/cairo-lang-semantic/src/path.rs line 63 at r3 (raw file):

        } else {
            path = format!("{path}::{}", self.name.long(db));
        }

Done.


crates/cairo-lang-semantic/src/path.rs line 64 at r3 (raw file):

            path = format!("{path}::{}", self.name.long(db));
        }
        format!("{}{}", prefix, path)

Done.


crates/cairo-lang-semantic/src/path.rs line 168 at r3 (raw file):

    item: ImportableId<'db>,
    context_module: ModuleId<'db>,
) -> Result<Option<ItemAccessInfo<'db>>, cairo_lang_diagnostics::DiagnosticAdded> {

Done.

Copy link
Collaborator

@orizi orizi left a comment

Choose a reason for hiding this comment

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

:lgtm:

@orizi reviewed 4 files and all commit messages, made 1 comment, and resolved 12 discussions.
Reviewable status: :shipit: complete! all files reviewed, all discussions resolved (waiting on @giladchase and @TomerStarkware).

@eytan-starkware eytan-starkware changed the base branch from eytan_graphite/_feat_adding_module_as_context_to_diagnostic_reporting to main December 30, 2025 07:09
@eytan-starkware eytan-starkware added this pull request to the merge queue Dec 30, 2025
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to no response for status checks Dec 30, 2025
@eytan-starkware eytan-starkware changed the title (feature): Dontextualized path for shorter and readable diagnostics (feature): Contextualized path for shorter and readable diagnostics Dec 30, 2025
@eytan-starkware eytan-starkware force-pushed the eytan_graphite/_feature_contextualized_path_for_shorter_and_readable_diagnostics branch from 4981736 to 311dfef Compare December 30, 2025 08:04
Copy link
Collaborator

@orizi orizi left a comment

Choose a reason for hiding this comment

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

@orizi reviewed 2 files and all commit messages.
Reviewable status: :shipit: complete! all files reviewed, all discussions resolved (waiting on @giladchase and @TomerStarkware).

@eytan-starkware eytan-starkware added this pull request to the merge queue Dec 30, 2025
Merged via the queue into main with commit 41461e7 Dec 30, 2025
55 checks passed
@orizi orizi deleted the eytan_graphite/_feature_contextualized_path_for_shorter_and_readable_diagnostics branch January 3, 2026 16:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants