-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
[breaking change] Validate crate name in --extern
[MCP 650]
#116001
[breaking change] Validate crate name in --extern
[MCP 650]
#116001
Conversation
This comment has been minimized.
This comment has been minimized.
compiler/rustc_session/src/config.rs
Outdated
@@ -2451,6 +2451,19 @@ pub fn parse_externs( | |||
Some((opts, name)) => (Some(opts), name.to_string()), | |||
}; | |||
|
|||
if !rustc_lexer::is_ident(&name) { | |||
let mut error = handler.early_struct_error(format!( | |||
"crate name `{name}` passed to `--extern` is not a valid identifier" |
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 briefly considered Debug
-printing name
instead (via {:?}
or via .escape_debug()
) to escape line breaks but it looked confusing in the common case (backticks plus double quotes or \n
in backticks which the user didn't write).
@@ -1710,6 +1710,15 @@ impl EarlyErrorHandler { | |||
self.handler.struct_fatal(msg).emit() | |||
} | |||
|
|||
#[allow(rustc::untranslatable_diagnostic)] | |||
#[allow(rustc::diagnostic_outside_of_impl)] | |||
pub(crate) fn early_struct_error( |
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.
It's unfortunate that I had to introduce this method. I can get rid of it again at the cost of not showing the .help("replace dashes with underscores …")
.
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.
It's fine.
04de89d
to
c3e8204
Compare
These commits modify the If this was unintentional then you should revert the changes before this PR is merged. |
One thing that might want to be considered is that generally rustc requires crate names to be ASCII. That is, you cannot reference an extern crate with unicode characters. Should this also be checking |
Hmm, good point! That's very interesting since I'm gonna check if they're ASCII then 👍 |
This comment has been minimized.
This comment has been minimized.
c3e8204
to
192c353
Compare
@@ -15,7 +15,7 @@ INCR=$(TMPDIR)/incr | |||
all: | |||
cp first_crate.rs second_crate.rs $(TMPDIR) | |||
$(RUSTC) $(TMPDIR)/first_crate.rs -C incremental=$(INCR) --target $(TARGET) --crate-type lib | |||
$(RUSTC) $(TMPDIR)/second_crate.rs -C incremental=$(INCR) --target $(TARGET) --extern first-crate=$(TMPDIR) --crate-type lib | |||
$(RUSTC) $(TMPDIR)/second_crate.rs -C incremental=$(INCR) --target $(TARGET) --extern first_crate=$(TMPDIR)/libfirst_crate.rlib --crate-type lib |
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'm still baffled that this test used to work at all, can somebody enlighten me? If I manually follow the steps as taken by this Makefile, I correctly get the error can't find crate for first_crate
with a nightly rustc (since the name is first-crate on master). Is there any preprocessing going on here?
Apart from the incorrect crate name, --extern
can't point to a directory, which I've also fixed. What is going on?
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 weird indeed. I've checked the logs of recently successful runs and tests/run-make/incr-foreign-head-span
does succeed on master. Very weird.
192c353
to
58a610f
Compare
This comment has been minimized.
This comment has been minimized.
58a610f
to
8d81d5a
Compare
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 test has become obsolete since it would've triggered on the --extern
first, instead of on the use item. It's superseded by extern-flag/invalid-crate-name-non-ascii.rs
.
if !crate::utils::is_ascii_ident(&name) { | ||
let mut error = handler.early_struct_error(format!( | ||
"crate name `{name}` passed to `--extern` is not a valid ASCII identifier" | ||
)); | ||
let adjusted_name = name.replace("-", "_"); | ||
if crate::utils::is_ascii_ident(&adjusted_name) { | ||
error.help(format!( | ||
"consider replacing the dashes with underscores: `{adjusted_name}`" | ||
)); | ||
} | ||
error.emit(); | ||
} |
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.
Probably not worth it given how rare this error will be in practice, but on other non-ASCII errors we go beyond replacing -
with _
and try to provide more context on which chars were problematic and try to provide suggestions to similar ASCII chars when possible. This is particularly useful for homonyms, where someone is trying to sneak (on purpose or accidentally) a, for example, cyrillic char.
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 lints uncommon_codepoints
, mixed_script_confusables
and confusable_idents
are amazing for sure! I'd lean towards not doing that here since it'd mean moving the code from rustc_lint
here and adapting it to an environment that doesn't have a Session
yet, yuck! Not sure how easy that'd be, maybe it's not that bad. early_error
s can't even be translated right now.
Esp. since --extern
is not actually used directly as we've established (apart from rustc devs). Alternative Rust package managers should be able to figure out what to pass to --extern
relatively quickly.
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.
@fmease fair points 👍 . It can also be later work, too.
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.
My stance is always "don't block on improving a solution short of perfect as long as it improves over the status quo", and this PR comfortably glides over that bar.
@bors r+ |
☀️ Test successful - checks-actions |
Finished benchmarking commit (aadb571): comparison URL. Overall result: no relevant changes - no action needed@rustbot label: -perf-regression Instruction countThis benchmark run did not return any relevant results for this metric. Max RSS (memory usage)ResultsThis is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.
CyclesResultsThis is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.
Binary sizeThis benchmark run did not return any relevant results for this metric. Bootstrap: 635.567s -> 635.843s (0.04%) |
Pkgsrc changes: * Remove NetBSD-8 support (embedded LLVm requires newer C++ than what is in -8; it's conceivable that this could still build with an external LLVM) * undo powerpc 9.0 file naming tweak, since we no longer support -8. * Remove patch to LLVM for powerpc now included by upstream. * Minor adjustments, checksum changes etc. Upstream changes: Version 1.74.1 (2023-12-07) =========================== - [Resolved spurious STATUS_ACCESS_VIOLATIONs in LLVM] (rust-lang/rust#118464) - [Clarify guarantees for std::mem::discriminant] (rust-lang/rust#118006) - [Fix some subtyping-related regressions] (rust-lang/rust#116415) Version 1.74.0 (2023-11-16) ========================== Language -------- - [Codify that `std::mem::Discriminant<T>` does not depend on any lifetimes in T] (rust-lang/rust#104299) - [Replace `private_in_public` lint with `private_interfaces` and `private_bounds` per RFC 2145] (rust-lang/rust#113126) Read more in [RFC 2145](https://rust-lang.github.io/rfcs/2145-type-privacy.html). - [Allow explicit `#[repr(Rust)]`] (rust-lang/rust#114201) - [closure field capturing: don't depend on alignment of packed fields] (rust-lang/rust#115315) - [Enable MIR-based drop-tracking for `async` blocks] (rust-lang/rust#107421) Compiler -------- - [stabilize combining +bundle and +whole-archive link modifiers] (rust-lang/rust#113301) - [Stabilize `PATH` option for `--print KIND=PATH`] (rust-lang/rust#114183) - [Enable ASAN/LSAN/TSAN for `*-apple-ios-macabi`] (rust-lang/rust#115644) - [Promote loongarch64-unknown-none* to Tier 2] (rust-lang/rust#115368) - [Add `i686-pc-windows-gnullvm` as a tier 3 target] (rust-lang/rust#115687) Libraries --------- - [Implement `From<OwnedFd/Handle>` for ChildStdin/out/err] (rust-lang/rust#98704) - [Implement `From<{&,&mut} [T; N]>` for `Vec<T>` where `T: Clone`] (rust-lang/rust#111278) - [impl Step for IP addresses] (rust-lang/rust#113748) - [Implement `From<[T; N]>` for `Rc<[T]>` and `Arc<[T]>`] (rust-lang/rust#114041) - [`impl TryFrom<char> for u16`] (rust-lang/rust#114065) - [Stabilize `io_error_other` feature] (rust-lang/rust#115453) - [Stabilize the `Saturating` type] (rust-lang/rust#115477) - [Stabilize const_transmute_copy] (rust-lang/rust#115520) Stabilized APIs --------------- - [`core::num::Saturating`] (https://doc.rust-lang.org/stable/std/num/struct.Saturating.html) - [`impl From<io::Stdout> for std::process::Stdio`] (https://doc.rust-lang.org/stable/std/process/struct.Stdio.html#impl-From%3CStdout%3E-for-Stdio) - [`impl From<io::Stderr> for std::process::Stdio`] (https://doc.rust-lang.org/stable/std/process/struct.Stdio.html#impl-From%3CStderr%3E-for-Stdio) - [`impl From<OwnedHandle> for std::process::Child{Stdin, Stdout, Stderr}`] (https://doc.rust-lang.org/stable/std/process/struct.Stdio.html#impl-From%3CStderr%3E-for-Stdio) - [`impl From<OwnedFd> for std::process::Child{Stdin, Stdout, Stderr}`] (https://doc.rust-lang.org/stable/std/process/struct.Stdio.html#impl-From%3CStderr%3E-for-Stdio) - [`std::ffi::OsString::from_encoded_bytes_unchecked`] (https://doc.rust-lang.org/stable/std/ffi/struct.OsString.html#method.from_encoded_bytes_unchecked) - [`std::ffi::OsString::into_encoded_bytes`] (https://doc.rust-lang.org/stable/std/ffi/struct.OsString.html#method.into_encoded_bytes) - [`std::ffi::OsStr::from_encoded_bytes_unchecked`] (https://doc.rust-lang.org/stable/std/ffi/struct.OsStr.html#method.from_encoded_bytes_unchecked) - [`std::ffi::OsStr::as_encoded_bytes`] (https://doc.rust-lang.org/stable/std/ffi/struct.OsStr.html#method.as_encoded_bytes) - [`std::io::Error::other`] (https://doc.rust-lang.org/stable/std/io/struct.Error.html#method.other) - [`impl TryFrom<char> for u16`] (https://doc.rust-lang.org/stable/std/primitive.u16.html#impl-TryFrom%3Cchar%3E-for-u16) - [`impl<T: Clone, const N: usize> From<&[T; N]> for Vec<T>`] (https://doc.rust-lang.org/stable/std/vec/struct.Vec.html#impl-From%3C%26%5BT;+N%5D%3E-for-Vec%3CT,+Global%3E) - [`impl<T: Clone, const N: usize> From<&mut [T; N]> for Vec<T>`] (https://doc.rust-lang.org/stable/std/vec/struct.Vec.html#impl-From%3C%26mut+%5BT;+N%5D%3E-for-Vec%3CT,+Global%3E) - [`impl<T, const N: usize> From<[T; N]> for Arc<[T]>`] (https://doc.rust-lang.org/stable/std/sync/struct.Arc.html#impl-From%3C%5BT;+N%5D%3E-for-Arc%3C%5BT%5D,+Global%3E) - [`impl<T, const N: usize> From<[T; N]> for Rc<[T]>`] (https://doc.rust-lang.org/stable/std/rc/struct.Rc.html#impl-From%3C%5BT;+N%5D%3E-for-Rc%3C%5BT%5D,+Global%3E) These APIs are now stable in const contexts: - [`core::mem::transmute_copy`] (https://doc.rust-lang.org/beta/std/mem/fn.transmute_copy.html) - [`str::is_ascii`] (https://doc.rust-lang.org/beta/std/primitive.str.html#method.is_ascii) - [`[u8]::is_ascii`] (https://doc.rust-lang.org/beta/std/primitive.slice.html#method.is_ascii) Cargo ----- - [fix: Set MSRV for internal packages] (rust-lang/cargo#12381) - [config: merge lists in precedence order] (rust-lang/cargo#12515) - [fix(update): Clarify meaning of --aggressive as --recursive] (rust-lang/cargo#12544) - [fix(update): Make `-p` more convenient by being positional] (rust-lang/cargo#12545) - [feat(help): Add styling to help output ] (rust-lang/cargo#12578) - [feat(pkgid): Allow incomplete versions when unambigious] (rust-lang/cargo#12614) - [feat: stabilize credential-process and registry-auth] (rust-lang/cargo#12649) - [feat(cli): Add '-n' to dry-run] (rust-lang/cargo#12660) - [Add support for `target.'cfg(..)'.linker`] (rust-lang/cargo#12535) - [Stabilize `--keep-going`] (rust-lang/cargo#12568) - [feat: Stabilize lints] (rust-lang/cargo#12648) Rustdoc ------- - [Add warning block support in rustdoc] (rust-lang/rust#106561) - [Accept additional user-defined syntax classes in fenced code blocks] (rust-lang/rust#110800) - [rustdoc-search: add support for type parameters] (rust-lang/rust#112725) - [rustdoc: show inner enum and struct in type definition for concrete type] (rust-lang/rust#114855) Compatibility Notes ------------------- - [Raise minimum supported Apple OS versions] (rust-lang/rust#104385) - [make Cell::swap panic if the Cells partially overlap] (rust-lang/rust#114795) - [Reject invalid crate names in `--extern`] (rust-lang/rust#116001) - [Don't resolve generic impls that may be shadowed by dyn built-in impls] (rust-lang/rust#114941) Internal Changes ---------------- These changes do not affect any public interfaces of Rust, but they represent significant improvements to the performance or internals of rustc and related tools. None this cycle.
Reject non-ASCII-identifier crate names passed to the CLI option
--extern
(rustc
,rustdoc
).Implements MCP 650 (except that we only allow ASCII identifiers not arbitrary Rust identifiers).
Fixes #113035.
As mentioned on Zulip, doing a crater run probably doesn't make sense since it wouldn't yield anything. Most users don't interact with
rustc
directly but only ever through Cargo which always passes a valid crate name to--extern
when it invokesrustc
andrustdoc
. In any case, the user wouldn't be able to use such a crate name in the source code anyway.Note that I'm not using
rustc_session::output::validate_crate_name
(used for--crate-name
and#![crate_name]
) since the latter doesn't reject non-ASCII crate names and ones that start with a digit.As an aside, I've also thought about getting rid of
validate_crate_name
entirely in a separate PR (with another MCP) in favor ofis_ascii_ident
to reject more weird--crate-name
s,#![crate_name]
s and file names but I think that would lead to a lot of actual breakage, namely because of file names starting with a digit. Intests/ui
9 tests would be impacted for example.CC @estebank
r? @est31