-
Notifications
You must be signed in to change notification settings - Fork 36
fix(const_path_join): Handle constant expressions in path joins #1574
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
base: master
Are you sure you want to change the base?
Changes from all commits
8acc127
661e930
b1b0b94
c383c69
fc46611
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
// run-rustfix | ||
|
||
fn main() { | ||
// Test env! expressions | ||
let _ = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("src/lib.rs"); | ||
|
||
// Test concat! expressions | ||
let _ = std::path::PathBuf::from(concat!("path", "/to/file")).join("filename.txt"); | ||
|
||
// Test nested expressions | ||
let dir = env!("CARGO_MANIFEST_DIR"); | ||
let _ = std::path::PathBuf::from(dir).join("tests/fixtures"); | ||
|
||
// Test with camino paths | ||
let _ = camino::Utf8PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("src"); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
// run-rustfix | ||
|
||
fn main() { | ||
// Test env! expressions | ||
let _ = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("src").join("lib.rs"); | ||
|
||
// Test concat! expressions | ||
let _ = std::path::PathBuf::from(concat!("path", "/to/file")).join("filename.txt"); | ||
|
||
// Test nested expressions | ||
let dir = env!("CARGO_MANIFEST_DIR"); | ||
let _ = std::path::PathBuf::from(dir).join("tests").join("fixtures"); | ||
|
||
// Test with camino paths | ||
let _ = camino::Utf8PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("src"); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
warning: path could be constructed from a string literal | ||
--> $DIR/const_expr.rs:5:65 | ||
| | ||
LL | let _ = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("src").join("lib.rs"); | ||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `.join("src/lib.rs")` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I really appreciate you tackling this difficult issue, but the tests show that the fix is not working. For this case, I would expect the suggestion to be: std::path::PathBuf::from(concat!(env!("CARGO_MANIFEST_DIR"), "/src/lib.rs")) The point is: the fix should suggest to use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Apologies. My earlier comment contained errors. I've since corrected it. |
||
| | ||
= note: `#[warn(const_path_join)]` on by default | ||
|
||
warning: path could be constructed from a string literal | ||
--> $DIR/const_expr.rs:12:42 | ||
| | ||
LL | let _ = std::path::PathBuf::from(dir).join("tests").join("fixtures"); | ||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `.join("tests/fixtures")` | ||
|
||
warning: 2 warnings emitted | ||
|
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 would expect
ComponentType
to look something like this. The way I think of it is: if an expression is constant but not a string literal, we're just going to pass it toconcat!
.ComponentType::Constant(..)
records the expression so that we have it to pass toconcat!
.Then, you'll need some logic to determine whether all of the components are string literals, etc., like I was suggesting in #1574 (comment).
And I see that you have something like that now.
For the case when all components are constant, but some are not string literals, that is when you will have to construct a
concat!
expression.That will involve constructing a string of the form:
If a component is of the form
ComponentType::Const
, you can use the expression it contains.I saw you were using
snippet_opt
earlier, but just to reinforce, you can usesnippet_opt(cx, expr.span)
to get the source text forexpr.
There are just two more small wrinkles.
First, all of the components need to be interspersed with "/". The easiest way to do that may be to insert a
ComponentType::Literal("/")
between each pair of adjacent components. In this way, if you collect n components initially, you will end up with n + n - 1 (= 2n - 1) components after putting the "/" between them.Second, adjacent string literals need to be combined.
In other words, rather than this:
we want this:
Note that when this step is done, the list of components should alternate
ComponentType::Constant(..)
,ComponentType::Literal(..)
,ComponentType::Constant(..)
, ...Does all that make sense?