Auto merge of #138901 - matthiaskrgr:rollup-qbbanhr, r=matthiaskrgr

Rollup of 7 pull requests

Successful merges:

 - #138662 (Implement some basics in UEFI fs)
 - #138800 (remove remnants of const_box feature)
 - #138821 (match lowering cleanup: remove unused unsizing logic from `non_scalar_compare`)
 - #138864 (Rework `--print` options documentation)
 - #138868 (Add do_not_recommend typo help)
 - #138882 (`with_scope` is only ever used for ast modules)
 - #138894 (Update books)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors
2025-03-24 19:43:42 +00:00
14 changed files with 342 additions and 190 deletions

View File

@@ -800,9 +800,9 @@ pub enum PatKind<'tcx> {
},
/// One of the following:
/// * `&str`/`&[u8]` (represented as a valtree), which will be handled as a string/slice pattern
/// and thus exhaustiveness checking will detect if you use the same string/slice twice in
/// different patterns.
/// * `&str` (represented as a valtree), which will be handled as a string pattern and thus
/// exhaustiveness checking will detect if you use the same string twice in different
/// patterns.
/// * integer, bool, char or float (represented as a valtree), which will be handled by
/// exhaustiveness to cover exactly its own value, similar to `&str`, but these values are
/// much simpler.

View File

@@ -1326,8 +1326,8 @@ enum TestKind<'tcx> {
Eq {
value: Const<'tcx>,
// Integer types are handled by `SwitchInt`, and constants with ADT
// types are converted back into patterns, so this can only be `&str`,
// `&[T]`, `f32` or `f64`.
// types and `&[T]` types are converted back into patterns, so this can
// only be `&str`, `f32` or `f64`.
ty: Ty<'tcx>,
},

View File

@@ -11,7 +11,6 @@ use std::sync::Arc;
use rustc_data_structures::fx::FxIndexMap;
use rustc_hir::{LangItem, RangeEnd};
use rustc_middle::mir::*;
use rustc_middle::ty::adjustment::PointerCoercion;
use rustc_middle::ty::util::IntTypeExt;
use rustc_middle::ty::{self, GenericArg, Ty, TyCtxt};
use rustc_middle::{bug, span_bug};
@@ -178,21 +177,30 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
_ => {}
}
assert_eq!(expect_ty, ty);
if !ty.is_scalar() {
// Use `PartialEq::eq` instead of `BinOp::Eq`
// (the binop can only handle primitives)
self.non_scalar_compare(
// Make sure that we do *not* call any user-defined code here.
// The only type that can end up here is string literals, which have their
// comparison defined in `core`.
// (Interestingly this means that exhaustiveness analysis relies, for soundness,
// on the `PartialEq` impl for `str` to b correct!)
match *ty.kind() {
ty::Ref(_, deref_ty, _) if deref_ty == self.tcx.types.str_ => {}
_ => {
span_bug!(source_info.span, "invalid type for non-scalar compare: {ty}")
}
};
self.string_compare(
block,
success_block,
fail_block,
source_info,
expect,
expect_ty,
Operand::Copy(place),
ty,
);
} else {
assert_eq!(expect_ty, ty);
self.compare(
block,
success_block,
@@ -370,97 +378,19 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
);
}
/// Compare two values using `<T as std::compare::PartialEq>::eq`.
/// If the values are already references, just call it directly, otherwise
/// take a reference to the values first and then call it.
fn non_scalar_compare(
/// Compare two values of type `&str` using `<str as std::cmp::PartialEq>::eq`.
fn string_compare(
&mut self,
block: BasicBlock,
success_block: BasicBlock,
fail_block: BasicBlock,
source_info: SourceInfo,
mut expect: Operand<'tcx>,
expect_ty: Ty<'tcx>,
mut val: Operand<'tcx>,
mut ty: Ty<'tcx>,
expect: Operand<'tcx>,
val: Operand<'tcx>,
) {
// If we're using `b"..."` as a pattern, we need to insert an
// unsizing coercion, as the byte string has the type `&[u8; N]`.
//
// We want to do this even when the scrutinee is a reference to an
// array, so we can call `<[u8]>::eq` rather than having to find an
// `<[u8; N]>::eq`.
let unsize = |ty: Ty<'tcx>| match ty.kind() {
ty::Ref(region, rty, _) => match rty.kind() {
ty::Array(inner_ty, n) => Some((region, inner_ty, n)),
_ => None,
},
_ => None,
};
let opt_ref_ty = unsize(ty);
let opt_ref_test_ty = unsize(expect_ty);
match (opt_ref_ty, opt_ref_test_ty) {
// nothing to do, neither is an array
(None, None) => {}
(Some((region, elem_ty, _)), _) | (None, Some((region, elem_ty, _))) => {
let tcx = self.tcx;
// make both a slice
ty = Ty::new_imm_ref(tcx, *region, Ty::new_slice(tcx, *elem_ty));
if opt_ref_ty.is_some() {
let temp = self.temp(ty, source_info.span);
self.cfg.push_assign(
block,
source_info,
temp,
Rvalue::Cast(
CastKind::PointerCoercion(
PointerCoercion::Unsize,
CoercionSource::Implicit,
),
val,
ty,
),
);
val = Operand::Copy(temp);
}
if opt_ref_test_ty.is_some() {
let slice = self.temp(ty, source_info.span);
self.cfg.push_assign(
block,
source_info,
slice,
Rvalue::Cast(
CastKind::PointerCoercion(
PointerCoercion::Unsize,
CoercionSource::Implicit,
),
expect,
ty,
),
);
expect = Operand::Move(slice);
}
}
}
// Figure out the type on which we are calling `PartialEq`. This involves an extra wrapping
// reference: we can only compare two `&T`, and then compare_ty will be `T`.
// Make sure that we do *not* call any user-defined code here.
// The only types that can end up here are string and byte literals,
// which have their comparison defined in `core`.
// (Interestingly this means that exhaustiveness analysis relies, for soundness,
// on the `PartialEq` impls for `str` and `[u8]` to b correct!)
let compare_ty = match *ty.kind() {
ty::Ref(_, deref_ty, _)
if deref_ty == self.tcx.types.str_ || deref_ty != self.tcx.types.u8 =>
{
deref_ty
}
_ => span_bug!(source_info.span, "invalid type for non-scalar compare: {}", ty),
};
let str_ty = self.tcx.types.str_;
let eq_def_id = self.tcx.require_lang_item(LangItem::PartialEq, Some(source_info.span));
let method = trait_method(self.tcx, eq_def_id, sym::eq, [compare_ty, compare_ty]);
let method = trait_method(self.tcx, eq_def_id, sym::eq, [str_ty, str_ty]);
let bool_ty = self.tcx.types.bool;
let eq_result = self.temp(bool_ty, source_info.span);

View File

@@ -1544,20 +1544,17 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
ret
}
fn with_scope<T>(&mut self, id: NodeId, f: impl FnOnce(&mut Self) -> T) -> T {
if let Some(module) = self.r.get_module(self.r.local_def_id(id).to_def_id()) {
// Move down in the graph.
let orig_module = replace(&mut self.parent_scope.module, module);
self.with_rib(ValueNS, RibKind::Module(module), |this| {
this.with_rib(TypeNS, RibKind::Module(module), |this| {
let ret = f(this);
this.parent_scope.module = orig_module;
ret
})
fn with_mod_rib<T>(&mut self, id: NodeId, f: impl FnOnce(&mut Self) -> T) -> T {
let module = self.r.expect_module(self.r.local_def_id(id).to_def_id());
// Move down in the graph.
let orig_module = replace(&mut self.parent_scope.module, module);
self.with_rib(ValueNS, RibKind::Module(module), |this| {
this.with_rib(TypeNS, RibKind::Module(module), |this| {
let ret = f(this);
this.parent_scope.module = orig_module;
ret
})
} else {
f(self)
}
})
}
fn visit_generic_params(&mut self, params: &'ast [GenericParam], add_self_upper: bool) {
@@ -2738,7 +2735,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
}
ItemKind::Mod(..) => {
self.with_scope(item.id, |this| {
self.with_mod_rib(item.id, |this| {
if mod_inner_docs {
this.resolve_doc_links(&item.attrs, MaybeExported::Ok(item.id));
}

View File

@@ -28,7 +28,7 @@ use rustc_session::lint::builtin::{
UNUSED_MACRO_RULES, UNUSED_MACROS,
};
use rustc_session::parse::feature_err;
use rustc_span::edit_distance::edit_distance;
use rustc_span::edit_distance::find_best_match_for_name;
use rustc_span::edition::Edition;
use rustc_span::hygiene::{self, AstPass, ExpnData, ExpnKind, LocalExpnId, MacroKind};
use rustc_span::{DUMMY_SP, Ident, Span, Symbol, kw, sym};
@@ -652,13 +652,13 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
if res == Res::NonMacroAttr(NonMacroAttrKind::Tool)
&& let [namespace, attribute, ..] = &*path.segments
&& namespace.ident.name == sym::diagnostic
&& !(attribute.ident.name == sym::on_unimplemented
|| attribute.ident.name == sym::do_not_recommend)
&& ![sym::on_unimplemented, sym::do_not_recommend].contains(&attribute.ident.name)
{
let distance =
edit_distance(attribute.ident.name.as_str(), sym::on_unimplemented.as_str(), 5);
let typo_name = distance.map(|_| sym::on_unimplemented);
let typo_name = find_best_match_for_name(
&[sym::on_unimplemented, sym::do_not_recommend],
attribute.ident.name,
Some(5),
);
self.tcx.sess.psess.buffer_lint(
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,

View File

@@ -1149,9 +1149,8 @@ impl<T: ?Sized, A: Allocator> Box<T, A> {
///
/// [memory layout]: self#memory-layout
#[unstable(feature = "allocator_api", issue = "32838")]
#[rustc_const_unstable(feature = "const_box", issue = "92521")]
#[inline]
pub const unsafe fn from_raw_in(raw: *mut T, alloc: A) -> Self {
pub unsafe fn from_raw_in(raw: *mut T, alloc: A) -> Self {
Box(unsafe { Unique::new_unchecked(raw) }, alloc)
}
@@ -1203,9 +1202,8 @@ impl<T: ?Sized, A: Allocator> Box<T, A> {
/// [memory layout]: self#memory-layout
#[unstable(feature = "allocator_api", issue = "32838")]
// #[unstable(feature = "box_vec_non_null", reason = "new API", issue = "130364")]
#[rustc_const_unstable(feature = "const_box", issue = "92521")]
#[inline]
pub const unsafe fn from_non_null_in(raw: NonNull<T>, alloc: A) -> Self {
pub unsafe fn from_non_null_in(raw: NonNull<T>, alloc: A) -> Self {
// SAFETY: guaranteed by the caller.
unsafe { Box::from_raw_in(raw.as_ptr(), alloc) }
}
@@ -1550,9 +1548,8 @@ impl<T: ?Sized, A: Allocator> Box<T, A> {
/// to call it as `Box::allocator(&b)` instead of `b.allocator()`. This
/// is so that there is no conflict with a method on the inner type.
#[unstable(feature = "allocator_api", issue = "32838")]
#[rustc_const_unstable(feature = "const_box", issue = "92521")]
#[inline]
pub const fn allocator(b: &Self) -> &A {
pub fn allocator(b: &Self) -> &A {
&b.1
}
@@ -1639,8 +1636,7 @@ impl<T: ?Sized, A: Allocator> Box<T, A> {
/// let bar = Pin::from(foo);
/// ```
#[stable(feature = "box_into_pin", since = "1.63.0")]
#[rustc_const_unstable(feature = "const_box", issue = "92521")]
pub const fn into_pin(boxed: Self) -> Pin<Self>
pub fn into_pin(boxed: Self) -> Pin<Self>
where
A: 'static,
{

View File

@@ -1,3 +1,5 @@
use r_efi::protocols::file;
use crate::ffi::OsString;
use crate::fmt;
use crate::hash::Hash;
@@ -22,7 +24,12 @@ pub struct ReadDir(!);
pub struct DirEntry(!);
#[derive(Clone, Debug)]
pub struct OpenOptions {}
pub struct OpenOptions {
mode: u64,
append: bool,
truncate: bool,
create_new: bool,
}
#[derive(Copy, Clone, Debug, Default)]
pub struct FileTimes {}
@@ -141,15 +148,58 @@ impl DirEntry {
impl OpenOptions {
pub fn new() -> OpenOptions {
OpenOptions {}
OpenOptions { mode: 0, append: false, create_new: false, truncate: false }
}
pub fn read(&mut self, _read: bool) {}
pub fn write(&mut self, _write: bool) {}
pub fn append(&mut self, _append: bool) {}
pub fn truncate(&mut self, _truncate: bool) {}
pub fn create(&mut self, _create: bool) {}
pub fn create_new(&mut self, _create_new: bool) {}
pub fn read(&mut self, read: bool) {
if read {
self.mode |= file::MODE_READ;
} else {
self.mode &= !file::MODE_READ;
}
}
pub fn write(&mut self, write: bool) {
if write {
// Valid Combinations: Read, Read/Write, Read/Write/Create
self.read(true);
self.mode |= file::MODE_WRITE;
} else {
self.mode &= !file::MODE_WRITE;
}
}
pub fn append(&mut self, append: bool) {
// Docs state that `.write(true).append(true)` has the same effect as `.append(true)`
if append {
self.write(true);
}
self.append = append;
}
pub fn truncate(&mut self, truncate: bool) {
self.truncate = truncate;
}
pub fn create(&mut self, create: bool) {
if create {
self.mode |= file::MODE_CREATE;
} else {
self.mode &= !file::MODE_CREATE;
}
}
pub fn create_new(&mut self, create_new: bool) {
self.create_new = create_new;
}
#[expect(dead_code)]
const fn is_mode_valid(&self) -> bool {
// Valid Combinations: Read, Read/Write, Read/Write/Create
self.mode == file::MODE_READ
|| self.mode == (file::MODE_READ | file::MODE_WRITE)
|| self.mode == (file::MODE_READ | file::MODE_WRITE | file::MODE_CREATE)
}
}
impl File {
@@ -311,12 +361,12 @@ pub fn stat(_p: &Path) -> io::Result<FileAttr> {
unsupported()
}
pub fn lstat(_p: &Path) -> io::Result<FileAttr> {
unsupported()
pub fn lstat(p: &Path) -> io::Result<FileAttr> {
stat(p)
}
pub fn canonicalize(_p: &Path) -> io::Result<PathBuf> {
unsupported()
pub fn canonicalize(p: &Path) -> io::Result<PathBuf> {
crate::path::absolute(p)
}
pub fn copy(_from: &Path, _to: &Path) -> io::Result<u64> {

View File

@@ -2,6 +2,7 @@
- [What is rustc?](what-is-rustc.md)
- [Command-line Arguments](command-line-arguments.md)
- [Print Options](command-line-arguments/print-options.md)
- [Codegen Options](codegen-options/index.md)
- [Jobserver](jobserver.md)
- [Lints](lints/index.md)

View File

@@ -247,58 +247,7 @@ types to stdout at the same time will result in an error.
<a id="option-print"></a>
## `--print`: print compiler information
This flag prints out various information about the compiler. This flag may be
specified multiple times, and the information is printed in the order the
flags are specified. Specifying a `--print` flag will usually disable the
[`--emit`](#option-emit) step and will only print the requested information.
The valid types of print values are:
- `crate-name` — The name of the crate.
- `file-names` — The names of the files created by the `link` emit kind.
- `sysroot` — Path to the sysroot.
- `target-libdir` — Path to the target libdir.
- `host-tuple` — The target-tuple string of the host compiler (e.g. `x86_64-unknown-linux-gnu`)
- `cfg` — List of cfg values. See [conditional compilation] for more
information about cfg values.
- `target-list` — List of known targets. The target may be selected with the
`--target` flag.
- `target-cpus` — List of available CPU values for the current target. The
target CPU may be selected with the [`-C target-cpu=val`
flag](codegen-options/index.md#target-cpu).
- `target-features` — List of available target features for the current
target. Target features may be enabled with the [`-C target-feature=val`
flag](codegen-options/index.md#target-feature). This flag is unsafe. See
[known issues](targets/known-issues.md) for more details.
- `relocation-models` — List of relocation models. Relocation models may be
selected with the [`-C relocation-model=val`
flag](codegen-options/index.md#relocation-model).
- `code-models` — List of code models. Code models may be selected with the
[`-C code-model=val` flag](codegen-options/index.md#code-model).
- `tls-models` — List of Thread Local Storage models supported. The model may
be selected with the `-Z tls-model=val` flag.
- `native-static-libs` — This may be used when creating a `staticlib` crate
type. If this is the only flag, it will perform a full compilation and
include a diagnostic note that indicates the linker flags to use when
linking the resulting static library. The note starts with the text
`native-static-libs:` to make it easier to fetch the output.
- `link-args` — This flag does not disable the `--emit` step. When linking,
this flag causes `rustc` to print the full linker invocation in a
human-readable form. This can be useful when debugging linker options. The
exact format of this debugging output is not a stable guarantee, other than
that it will include the linker executable and the text of each command-line
argument passed to the linker.
- `deployment-target` — The currently selected [deployment target] (or minimum OS version)
for the selected Apple platform target. This value can be used or passed along to other
components alongside a Rust build that need this information, such as C compilers.
This returns rustc's minimum supported deployment target if no `*_DEPLOYMENT_TARGET` variable
is present in the environment, or otherwise returns the variable's parsed value.
A filepath may optionally be specified for each requested information kind, in
the format `--print KIND=PATH`, just like for `--emit`. When a path is
specified, information will be written there instead of to stdout.
[conditional compilation]: ../reference/conditional-compilation.html
[deployment target]: https://developer.apple.com/library/archive/documentation/DeveloperTools/Conceptual/cross_development/Configuring/configuring.html
This flag will allow you to set [print options](command-line-arguments/print-options.md).
<a id="option-g-debug"></a>
## `-g`: include debug information

View File

@@ -0,0 +1,212 @@
# Print Options
All of these options are passed to `rustc` via the `--print` flag.
Those options prints out various information about the compiler. Multiple options can be
specified, and the information is printed in the order the options are specified.
Specifying an option will usually disable the [`--emit`](../command-line-arguments.md#option-emit)
step and will only print the requested information.
A filepath may optionally be specified for each requested information kind, in the format
`--print KIND=PATH`, just like for `--emit`. When a path is specified, information will be
written there instead of to stdout.
## `crate-name`
The name of the crate.
Generally coming from either from the `#![crate_name = "..."]` attribute,
[`--crate-name` flag](../command-line-arguments.md#option-crate-name) or the filename.
Example:
```bash
$ rustc --print crate-name --crate-name my_crate a.rs
my_crate
```
## `file-names`
The names of the files created by the `link` emit kind.
## `sysroot`
Abosulte path to the sysroot.
Example (with rustup and the stable toolchain):
```bash
$ rustc --print sysroot a.rs
/home/[REDACTED]/.rustup/toolchains/stable-x86_64-unknown-linux-gnu
```
## `target-libdir`
Path to the target libdir.
Example (with rustup and the stable toolchain):
```bash
$ rustc --print target-libdir a.rs
/home/[REDACTED]/.rustup/toolchains/beta-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib
```
## `host-tuple`
The target-tuple string of the host compiler.
Example:
```bash
$ rustc --print host-tuple a.rs
x86_64-unknown-linux-gnu
```
Example with the `--target` flag:
```bash
$ rustc --print host-tuple --target "armv7-unknown-linux-gnueabihf" a.rs
x86_64-unknown-linux-gnu
```
## `cfg`
List of cfg values. See [conditional compilation] for more information about cfg values.
Example (for `x86_64-unknown-linux-gnu`):
```bash
$ rustc --print cfg a.rs
debug_assertions
panic="unwind"
target_abi=""
target_arch="x86_64"
target_endian="little"
target_env="gnu"
target_family="unix"
target_feature="fxsr"
target_feature="sse"
target_feature="sse2"
target_has_atomic="16"
target_has_atomic="32"
target_has_atomic="64"
target_has_atomic="8"
target_has_atomic="ptr"
target_os="linux"
target_pointer_width="64"
target_vendor="unknown"
unix
```
## `target-list`
List of known targets. The target may be selected with the `--target` flag.
## `target-cpus`
List of available CPU values for the current target. The target CPU may be selected with
the [`-C target-cpu=val` flag](../codegen-options/index.md#target-cpu).
## `target-features`
List of available target features for the *current target*.
Target features may be enabled with the **unsafe**
[`-C target-feature=val` flag](../codegen-options/index.md#target-feature).
See [known issues](../targets/known-issues.md) for more details.
## `relocation-models`
List of relocation models. Relocation models may be selected with the
[`-C relocation-model=val` flag](../codegen-options/index.md#relocation-model).
Example:
```bash
$ rustc --print relocation-models a.rs
Available relocation models:
static
pic
pie
dynamic-no-pic
ropi
rwpi
ropi-rwpi
default
```
## `code-models`
List of code models. Code models may be selected with the
[`-C code-model=val` flag](../codegen-options/index.md#code-model).
Example:
```bash
$ rustc --print code-models a.rs
Available code models:
tiny
small
kernel
medium
large
```
## `tls-models`
List of Thread Local Storage models supported. The model may be selected with the
`-Z tls-model=val` flag.
Example:
```bash
$ rustc --print tls-models a.rs
Available TLS models:
global-dynamic
local-dynamic
initial-exec
local-exec
emulated
```
## `native-static-libs`
This may be used when creating a `staticlib` crate type.
If this is the only flag, it will perform a full compilation and include a diagnostic note
that indicates the linker flags to use when linking the resulting static library.
The note starts with the text `native-static-libs:` to make it easier to fetch the output.
Example:
```bash
$ rustc --print native-static-libs --crate-type staticlib a.rs
note: Link against the following native artifacts when linking against this static library. The order and any duplication can be significant on some platforms.
note: native-static-libs: -lgcc_s -lutil [REDACTED] -lpthread -lm -ldl -lc
```
## `link-args`
This flag does not disable the `--emit` step. This can be useful when debugging linker options.
When linking, this flag causes `rustc` to print the full linker invocation in a human-readable
form. The exact format of this debugging output is not a stable guarantee, other than that it
will include the linker executable and the text of each command-line argument passed to the
linker.
## `deployment-target`
The currently selected [deployment target] (or minimum OS version) for the selected Apple
platform target.
This value can be used or passed along to other components alongside a Rust build that need
this information, such as C compilers. This returns rustc's minimum supported deployment target
if no `*_DEPLOYMENT_TARGET` variable is present in the environment, or otherwise returns the
variable's parsed value.
[conditional compilation]: ../../reference/conditional-compilation.html
[deployment target]: https://developer.apple.com/library/archive/documentation/DeveloperTools/Conceptual/cross_development/Configuring/configuring.html

View File

@@ -16,4 +16,9 @@ trait Y{}
//~^^HELP an attribute with a similar name exists
trait Z{}
#[diagnostic::dont_recommend]
//~^ERROR unknown diagnostic attribute
//~^^HELP an attribute with a similar name exists
impl X for u8 {}
fn main(){}

View File

@@ -37,5 +37,17 @@ help: an attribute with a similar name exists
LL | #[diagnostic::on_unimplemented]
| ++
error: aborting due to 3 previous errors
error: unknown diagnostic attribute
--> $DIR/suggest_typos.rs:19:15
|
LL | #[diagnostic::dont_recommend]
| ^^^^^^^^^^^^^^
|
help: an attribute with a similar name exists
|
LL - #[diagnostic::dont_recommend]
LL + #[diagnostic::do_not_recommend]
|
error: aborting due to 4 previous errors