-
Notifications
You must be signed in to change notification settings - Fork 13k
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
Fix invalid module suggestion #38255
Fix invalid module suggestion #38255
Conversation
r? @nrc (rust_highfive has picked a reviewer for you, use r? to override) |
I have no idea why it failed. It seems there is no error. Or maybe I missed it? |
src/libsyntax/parse/parser.rs
Outdated
err.span_note(id_sp, | ||
&format!("maybe move this module `{0}` to its own directory \ | ||
via `{0}/mod.rs`", | ||
this_module)); | ||
paths.name)); |
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.
This is supposed to be the name of the file currently being parsed, not the name of the erroneous mod
.
For example, if we are parsing foo/bar.rs
and we encounter a non-inline module mod baz;
, we want to suggest moving foo/bar.rs
to foo/bar/mod.rs
. That way, bar
would be a directory owner (c.f. #37602), so mod baz;
would expect foo/bar/baz.rs
(or foo/bar/baz/mod.rs
) instead of being an error.
To get the name of the file currently being parsed, you could use self.root_module_name
(skipping the note if it is None
), or even better, remove the root_module_name
field entirely and instead use self.sess.codemap().span_to_filename(id_sp)
(skipping the note if id_sp
is DUMMY_SP
).
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.
Hum, the issue where I got this didn't reflect such a case. I'll need to take a different look. Thanks for the help!
@GuillaumeGomez Also, could you add a regression test?
Travis has been broken for a couple of days, not sure why. |
Sure. |
a598d84
to
67e321a
Compare
So, I updated the code but I now need to figure out how to add a compile fail test for it. I need to create a folder and 3 files for it in order to test it (no problem) but tests fail if no failing pattern is in the file. More to come when I figure all this out! |
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.
The field root_module_name
of Parser
is now unused and can be removed.
src/libsyntax/parse/parser.rs
Outdated
this_module)); | ||
if id_sp != syntax_pos::DUMMY_SP { | ||
let path = self.sess.codemap().span_to_filename(id_sp); | ||
let path = if path.ends_with(".rs") { |
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 think it would be better to always remove the extension here, e.g.
let path = Path::new(self.sess.codemap().span_to_filename(id_sp)).file_stem().unwrap();
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.
Would be better, indeed.
@GuillaumeGomez You can put the helper files in |
Thanks for the info @jseyfried! |
67e321a
to
6acb1ba
Compare
@jseyfried: Is it how you had it in mind? |
src/libsyntax/parse/parser.rs
Outdated
let parent = path.parent().unwrap_or(Path::new("")) | ||
.to_str().unwrap_or("").to_owned(); | ||
let path = format!("{}/{}", | ||
if parent.len() == 0 { "." } else { &parent }, |
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.
out of curiosity, can you construct an example where the parent.len()
is in fact equal to zero? I would have thought the context where this is arising will ensure that there is always a parent, but maybe I am missing a scenario.
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.
In case you're compiling a file at the same level of rustc I guess? I'm not sure if it's an absolute or a relative path so better be sure than sorry.
// except according to those terms. | ||
|
||
pub mod baz; //~ ERROR cannot declare a new module at this location | ||
//~ NOTE maybe move this module `src/test/compile-fail/foo/bar` to its own directory via `src/test/compile-fail/foo/bar/mod.rs` |
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.
if the suggestion is saying move foo/bar
to foo/bar/mod.rs
, wouldn't it make more sense for it to suggesting moving foo/bar.rs
(i.e. including the file extension) to foo/bar/mod.rs
, so that the source and destination look consistent?
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.
hmm I see that @jseyfried had earlier suggested removing the file extension.
If you're going to remove it from bar.rs
, then you should probably remove it from mod.rs
(again in the name of consistency between the origin and destination)
But I'm not so sure its clearer that way (versus having the .rs on both sides...)
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.
@GuillaumeGomez @pnkfelix
I was suggesting removing the file extension only to produce the bar
in foo/bar/mod.rs
.
That is, I think we should suggest moving foo/bar.rs
to foo/bar/mod.rs
.
If the file is not .rs
(possible via #[path]
), I think we should suggest moving e.g. foo/bar.txt
to foo/bar/mod.rs
.
Note that mod.rs
needs to be .rs
due to #37602.
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.
@GuillaumeGomez
I think the best way to do this is to
- Convert the
span_to_filename
String
into aPathBuf
- Remove the extension (
.rs
or other)- e.g.
let stem = path_buf.file_stem(); path_buf.set_file_name(stem);
- e.g.
- Push
"mod.rs"
to thePathBuf
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.
@jseyfried: I like this solution! I'll update in the evening.
84b83fd
to
1676314
Compare
Updated. |
ping @GuillaumeGomez -- could you fix the test as described here? |
Forgot this PR, sorry! |
Even with the explanations and the changes, I still get:
So completely useless... I think adding a test for this isn't this useful. Should I remove it? |
No, we definitely need a test for this ( Could you push what you have so far? For this use case, you don't want |
// ignore-tidy-linelength | ||
|
||
pub mod baz; //~ ERROR cannot declare a new module at this location | ||
//~ NOTE maybe move this module `src/test/compile-fail/foo/bar` to its own directory via `src/test/compile-fail/foo/bar/mod.rs` |
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.
Could this be
maybe move this module `src/test/compile-fail/foo/bar.rs` to its own directory via `src/test/compile-fail/foo/bar/mod.rs`
Pushed the changes into a second commit. |
ping @jseyfried, this look good to you now? |
@GuillaumeGomez looks like there may also be a failing test here that'll need fixing |
@alexcrichton: Indeed, I'll try to update it in the next days. |
@jseyfried: So I gave another try and I'm still completely unable to make it work. Any idea what I've done incorrectly (or missed)? |
7e2202a
to
4e090dd
Compare
@jseyfried: Updated. Thanks for all your help! |
src/libsyntax/parse/parser.rs
Outdated
full_path.push("mod.rs"); | ||
err.span_note(id_sp, | ||
&format!("maybe move this module `{0}` to its own directory \ | ||
via `{0}`", full_path.to_str().unwrap_or(""))); |
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.
Don't we want two paths here, e.g. maybe move this module `foo/bar.rs` to its own directory via `foo/bar/mod.rs`
?
Also, instead of unwrap_or("")
, I would use to_string_lossy
or just not emit the note if to_str
is None
.
// ignore-tidy-linelength | ||
|
||
// error-pattern: cannot declare a new module at this location | ||
// note-pattern: maybe move this module `src/test/compile-fail/auxiliary/foo/bar` to its own directory via `src/test/compile-fail/auxiliary/foo/bar/mod.rs` |
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.
// note-pattern
has no meaning to the compile-fail tests -- use // error-pattern
here instead (works just as well for notes).
Also, don't we want the pattern to be the following?
maybe move this module `src/test/compile-fail/auxiliary/foo/bar.rs` to its own directory via `src/test/compile-fail/auxiliary/foo/bar/mod.rs`
mod foo; | ||
} | ||
|
||
fn main() {} |
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.
nit: add trailing newline
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.
Done.
src/libsyntax/parse/parser.rs
Outdated
this_module)); | ||
if id_sp != syntax_pos::DUMMY_SP { | ||
let mut full_path = PathBuf::from(self.sess.codemap().span_to_filename(id_sp)); | ||
let full_path_copy = full_path.clone(); |
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.
Could we give these more descriptive names, e.g. source_path
/dest_path
, current_path
/owner_path
, etc.?
4e090dd
to
15cd2bc
Compare
Updated. |
src/libsyntax/parse/parser.rs
Outdated
if let Ok(cur_dir) = env::current_dir() { | ||
if let (Ok(src_path), Ok(dest_path)) = | ||
(Path::new(&src_path).strip_prefix(&cur_dir), | ||
Path::new(&dest_path).strip_prefix(&cur_dir)) { |
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 think we should fall back to the raw src_path
and dest_path
if env::current_dir()
is None
or strip_prefix
is Err
. That should fix the failing test.
I would mutate src_path
and/or dest_path
when strip_prefix
is Ok
and then err.span_note
unconditionally.
src/libsyntax/parse/parser.rs
Outdated
this_module)); | ||
if id_sp != syntax_pos::DUMMY_SP { | ||
let mut src_path = PathBuf::from(self.sess.codemap().span_to_filename(id_sp)); | ||
let src_path_copy = src_path.clone(); |
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.
We don't need src_path_copy
.
src/libsyntax/parse/parser.rs
Outdated
if id_sp != syntax_pos::DUMMY_SP { | ||
let mut src_path = PathBuf::from(self.sess.codemap().span_to_filename(id_sp)); | ||
let src_path_copy = src_path.clone(); | ||
let stem = src_path_copy.file_stem().unwrap_or(OsStr::new("")); |
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.
If there's no file_stem
, I think we should use the full file name or just not emit the note. I believe using ""
here would produce a very confusing suggestion.
src/libsyntax/parse/parser.rs
Outdated
let mut dest_path = src_path.clone(); | ||
dest_path.set_file_name(stem); | ||
dest_path.push("mod.rs"); | ||
src_path.set_extension("rs"); |
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.
Why do this? If the source path isn't .rs
, we'll be telling the user to move a file that doesn't exist.
15cd2bc
to
e2e758d
Compare
Updated. |
It seems it's now a path issue in the error checkup. Any idea how I could fix this issue @jseyfried? |
The issue is that we're producing I would just change the test to expect |
@jseyfried: It makes output more comfortable to read. |
☔ The latest upstream changes (presumably #39765) made this pull request unmergeable. Please resolve the merge conflicts. |
Does it?
If people use |
I think we should start with not doing |
As you prefer, I'd just like this change to get merge so I'll remove the path prefix. |
e2e758d
to
2316f38
Compare
2316f38
to
50461ef
Compare
And updated once again. |
this_module)); | ||
if id_sp != syntax_pos::DUMMY_SP { | ||
let src_path = PathBuf::from(self.sess.codemap().span_to_filename(id_sp)); | ||
if let Some(stem) = src_path.clone().file_stem() { |
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 don't think we need the .clone()
here.
// ignore-tidy-linelength | ||
|
||
// error-pattern: cannot declare a new module at this location | ||
// error-pattern: maybe move this module |
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.
Could you include the module paths here so that they are tested? It looks like this test would pass before the PR.
It doesn't matter if the paths are global and verbose here.
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.
As you asked, I removed the strip_prefix
, so now it's the full path starting from /
. Therefore, if I put it, it won't work because it'll be mine. Or am I missing something?
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 removed the
strip_prefix
, so now it's the full path starting from/
I believe it was the full path starting from /
even with strip_prefix
-- that is, the strip_prefix
stuff didn't make a difference in this case.
Therefore, if I put it, it won't work because it'll be mine
Good point -- the global path will depend on what platform is running the tests.
It looks like we'll need a ui
test, or if that doesn't work either a run-make
test.
☔ The latest upstream changes (presumably #40620) made this pull request unmergeable. Please resolve the merge conflicts. |
Closing due to inactivity, but feel free to resubmit with a rebase! |
I'll when the testing issue will be solved. |
Fixes #38110.