-
Notifications
You must be signed in to change notification settings - Fork 909
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fallback to dir_path when relative external mod resolution fails #5205
Conversation
using rustfmt build from rustfmt master with rust-lang/rustfmt#5205 applied
We only want to fall back if two conditions are met: 1) Initial module resolution is performed relative to some nested directory. 2) Module resolution fails because of a ModError::FileNotFound error. When these conditions are met we can try to fallback to searching for the module's file relative to the dir_path instead of the nested relative directory. Fixes 5198 As demonstrated by 5198, it's possible that a directory name conflicts with a rust file name. For example, src/lib/ and src/lib.rs. If src/lib.rs references an external module like ``mod foo;``, then module resolution will try to resolve ``foo`` to src/lib/foo.rs or src/lib/foo/mod.rs. Module resolution would fail with a file not found error if the ``foo`` module were defined at src/foo.rs. When encountering these kinds of module resolution issues we now fall back to the current directory and attempt to resolve the module again. Given the current example, this means that if we can't find the module ``foo`` at src/lib/foo.rs or src/lib/foo/mod.rs, we'll attempt to resolve the module to src/foo.rs.
Realize the follow ask is above and beyond the in-scope issue, but we have unfortunately had a history here of trading bug fixes where a fix for one reintroduces another. Whenever you get time, would you be up for checking how these changes handle some of the similar types of open issues? Think we've got things labeled sufficiently well enough that https://github.com/rust-lang/rustfmt/issues?q=is%3Aopen+is%3Aissue+label%3Aa-mods should include a few worthwhile ones |
@calebcartwright sure thig! I'd be happy to do a deep dive into the backlog to look and see if these changes resolve or change the behavior of some of the existing issues. Will probably have some time later this weekend to look into it! |
Awesome, thank you! My sense is that there might be an upstream issue causing this (e.g. bad dir path), but I'm okay with this approach since we're still letting the compiler drive resolution and just incorporating our own fallback behavior |
Did some digging:
I'm wondering if we'd benefit from making more of the compiler module resolution machinery public, for example mod_file_path? Looks like that ends up calling
I wonder if this dummy module has anything to do with what we're seeing here: |
This upstream comment gave me a good chuckle 😆
|
Feel free to look into it, but one thing to keep in mind is that we have to handle attributes a bit differently than the compiler, e.g. we need to follow all cfg_attrs whereas the compiler only cares about the relevant ones for a given platform/config/etc. |
Yeah I saw that one too and thought it was funny. Definitely something to keep in mind if someone opens up an issue about that weird case.
I don't necessarily know if I'll look into it right now, but I know you mentioned a while back (offline) that you want some help on improving the mod resolution in rustfmt. I think when we get started on that initiative it might be a better time for me to a do a deeper dive into what the compiler is doing and seeing if there's more that we can leverage. All that being said, is there anything else you'd like to see on this one? |
Nope! Was hoping it might've solved some others too, but sometimes we don't get that lucky. |
I have a fix for #5167 that should help improve the error message we're seeing in that case. I'll open that PR soon. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Couple minor non-block items left inline for your awareness, otherwise lgtm!
@@ -0,0 +1 @@ | |||
fn main( ) { println!("Hello World!") } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fully understand the utility of copy/pasta but for future reference I find it's helpful to make these types of files even subtly different (even just a different fn name) as it stands out more on the off chance we end up mapping the wrong files to modules.
Understand that wouldn't be caught by the particular test here given the nature of the test, just wanted to make a note
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I really appreciate you calling this out!
* mod c; | ||
|
||
Module resolution will fail if we look for './lib/a.rs' or './lib/a/mod.rs', | ||
so we should fall back to looking for './a.rs', which correctly finds the modlue that |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
minor typo fyi
so we should fall back to looking for './a.rs', which correctly finds the modlue that | |
so we should fall back to looking for './a.rs', which correctly finds the module that |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Aww man, I'm sorry about that. I totally would have gone back and fixed this before you merged had I had the opportunity to do so before the merge.
Unrelated to the typo, but was the explanation.txt
file helpful?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ha no worries. We've typos all over the place 😆
And yes I think the text file with explanatory commentary is helpful in cases like these as it lowers the barrier required to grok especially when trying to eyeball runtime module loading behavior
We only want to fall back if two conditions are met:
ModError::FileNotFound
error.When these conditions are met we can try to fallback to searching for the module's file relative to the
dir_path
instead of the nested relative directory.Fixes #5198
As demonstrated by 5198, it's possible that a directory name conflicts with a rust file name. For example,
src/lib/
andsrc/lib.rs
.If
src/lib.rs
references an external module likemod foo;
, then module resolution will try to resolvefoo
tosrc/lib/foo.rs
orsrc/lib/foo/mod.rs
. Module resolution would fail with a file not found error if thefoo
module were defined atsrc/foo.rs
.When encountering these kinds of module resolution issues we now fall back to the current directory and attempt to resolve the module again.
Given the current example, this means that if we can't find the module
foo
atsrc/lib/foo.rs
orsrc/lib/foo/mod.rs
, we'll attempt to resolve the module tosrc/foo.rs
.