diff --git a/.github/workflows/post-merge.yml b/.github/workflows/post-merge.yml index b4848a8cf099..d38cc0e8a17f 100644 --- a/.github/workflows/post-merge.yml +++ b/.github/workflows/post-merge.yml @@ -6,7 +6,7 @@ name: Post merge analysis on: push: branches: - - master + - main jobs: analysis: diff --git a/Cargo.lock b/Cargo.lock index d2b96e6d1027..5c095e0eefa8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -600,6 +600,7 @@ dependencies = [ "serde_json", "tempfile", "termize", + "tikv-jemalloc-sys", "toml 0.9.7", "ui_test", "walkdir", @@ -4806,6 +4807,7 @@ dependencies = [ "stringdex", "tempfile", "threadpool", + "tikv-jemalloc-sys", "tracing", "tracing-subscriber", "tracing-tree", @@ -5537,9 +5539,9 @@ version = "0.1.0" [[package]] name = "tikv-jemalloc-sys" -version = "0.6.0+5.3.0-1-ge13ca993e8ccb9ba9847cc330696e02839f328f7" +version = "0.6.1+5.3.0-1-ge13ca993e8ccb9ba9847cc330696e02839f328f7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd3c60906412afa9c2b5b5a48ca6a5abe5736aec9eb48ad05037a677e52e4e2d" +checksum = "cd8aa5b2ab86a2cefa406d889139c162cbb230092f7d1d7cbc1716405d852a3b" dependencies = [ "cc", "libc", diff --git a/bootstrap.example.toml b/bootstrap.example.toml index 6f37e51a47de..0d0f5e405d1f 100644 --- a/bootstrap.example.toml +++ b/bootstrap.example.toml @@ -320,7 +320,7 @@ #build.npm = "npm" # Python interpreter to use for various tasks throughout the build, notably -# rustdoc tests, the lldb python interpreter, and some dist bits and pieces. +# rustdoc tests, and some dist bits and pieces. # # Defaults to the Python interpreter used to execute x.py. #build.python = "python" diff --git a/compiler/rustc/Cargo.toml b/compiler/rustc/Cargo.toml index 9ef8fa75062a..d2ab70895eb3 100644 --- a/compiler/rustc/Cargo.toml +++ b/compiler/rustc/Cargo.toml @@ -21,9 +21,9 @@ rustc_public_bridge = { path = "../rustc_public_bridge" } # tidy-alphabetical-end [dependencies.tikv-jemalloc-sys] -version = "0.6.0" +version = "0.6.1" optional = true -features = ['unprefixed_malloc_on_supported_platforms'] +features = ['override_allocator_on_supported_platforms'] [features] # tidy-alphabetical-start diff --git a/compiler/rustc/src/main.rs b/compiler/rustc/src/main.rs index ca1bb59e59d6..89c61cdf00a5 100644 --- a/compiler/rustc/src/main.rs +++ b/compiler/rustc/src/main.rs @@ -7,26 +7,25 @@ // distribution. The obvious way to do this is with the `#[global_allocator]` // mechanism. However, for complicated reasons (see // https://github.com/rust-lang/rust/pull/81782#issuecomment-784438001 for some -// details) that mechanism doesn't work here. Also, we must use a consistent -// allocator across the rustc <-> llvm boundary, and `#[global_allocator]` -// wouldn't provide that. +// details) that mechanism doesn't work here. Also, we'd like to use a +// consistent allocator across the rustc <-> llvm boundary, and +// `#[global_allocator]` wouldn't provide that. // -// Instead, we use a lower-level mechanism. rustc is linked with jemalloc in a -// way such that jemalloc's implementation of `malloc`, `free`, etc., override -// the libc allocator's implementation. This means that Rust's `System` -// allocator, which calls `libc::malloc()` et al., is actually calling into -// jemalloc. +// Instead, we use a lower-level mechanism, namely the +// `"override_allocator_on_supported_platforms"` Cargo feature of jemalloc-sys. +// +// This makes jemalloc-sys override the libc/system allocator's implementation +// of `malloc`, `free`, etc.. This means that Rust's `System` allocator, which +// calls `libc::malloc()` et al., is actually calling into jemalloc. // // A consequence of not using `GlobalAlloc` (and the `tikv-jemallocator` crate // provides an impl of that trait, which is called `Jemalloc`) is that we // cannot use the sized deallocation APIs (`sdallocx`) that jemalloc provides. // It's unclear how much performance is lost because of this. // -// As for the symbol overrides in `main` below: we're pulling in a static copy -// of jemalloc. We need to actually reference its symbols for it to get linked. -// The two crates we link to here, `std` and `rustc_driver`, are both dynamic -// libraries. So we must reference jemalloc symbols one way or another, because -// this file is the only object code in the rustc executable. +// NOTE: Even though Cargo passes `--extern` with `tikv_jemalloc_sys`, we still need to `use` the +// crate for the compiler to see the `#[used]`, see https://github.com/rust-lang/rust/issues/64402. +// This is similarly required if we used a crate with `#[global_allocator]`. // // NOTE: if you are reading this comment because you want to set a custom `global_allocator` for // benchmarking, consider using the benchmarks in the `rustc-perf` collector suite instead: @@ -36,43 +35,9 @@ // to compare their performance, see // https://github.com/rust-lang/rust/commit/b90cfc887c31c3e7a9e6d462e2464db1fe506175#diff-43914724af6e464c1da2171e4a9b6c7e607d5bc1203fa95c0ab85be4122605ef // for an example of how to do so. +#[cfg(feature = "jemalloc")] +use tikv_jemalloc_sys as _; fn main() { - // See the comment at the top of this file for an explanation of this. - #[cfg(feature = "jemalloc")] - { - use std::os::raw::{c_int, c_void}; - - use tikv_jemalloc_sys as jemalloc_sys; - - #[used] - static _F1: unsafe extern "C" fn(usize, usize) -> *mut c_void = jemalloc_sys::calloc; - #[used] - static _F2: unsafe extern "C" fn(*mut *mut c_void, usize, usize) -> c_int = - jemalloc_sys::posix_memalign; - #[used] - static _F3: unsafe extern "C" fn(usize, usize) -> *mut c_void = jemalloc_sys::aligned_alloc; - #[used] - static _F4: unsafe extern "C" fn(usize) -> *mut c_void = jemalloc_sys::malloc; - #[used] - static _F5: unsafe extern "C" fn(*mut c_void, usize) -> *mut c_void = jemalloc_sys::realloc; - #[used] - static _F6: unsafe extern "C" fn(*mut c_void) = jemalloc_sys::free; - - // On OSX, jemalloc doesn't directly override malloc/free, but instead - // registers itself with the allocator's zone APIs in a ctor. However, - // the linker doesn't seem to consider ctors as "used" when statically - // linking, so we need to explicitly depend on the function. - #[cfg(target_os = "macos")] - { - unsafe extern "C" { - fn _rjem_je_zone_register(); - } - - #[used] - static _F7: unsafe extern "C" fn() = _rjem_je_zone_register; - } - } - rustc_driver::main() } diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index e65688f3532e..4de9d61e7f75 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -648,9 +648,10 @@ impl Pat { PatKind::Path(qself, path) => TyKind::Path(qself.clone(), path.clone()), PatKind::MacCall(mac) => TyKind::MacCall(mac.clone()), // `&mut? P` can be reinterpreted as `&mut? T` where `T` is `P` reparsed as a type. - PatKind::Ref(pat, mutbl) => { - pat.to_ty().map(|ty| TyKind::Ref(None, MutTy { ty, mutbl: *mutbl }))? - } + PatKind::Ref(pat, pinned, mutbl) => pat.to_ty().map(|ty| match pinned { + Pinnedness::Not => TyKind::Ref(None, MutTy { ty, mutbl: *mutbl }), + Pinnedness::Pinned => TyKind::PinnedRef(None, MutTy { ty, mutbl: *mutbl }), + })?, // A slice/array pattern `[P]` can be reparsed as `[T]`, an unsized array, // when `P` can be reparsed as a type `T`. PatKind::Slice(pats) if let [pat] = pats.as_slice() => { @@ -696,7 +697,7 @@ impl Pat { // Trivial wrappers over inner patterns. PatKind::Box(s) | PatKind::Deref(s) - | PatKind::Ref(s, _) + | PatKind::Ref(s, _, _) | PatKind::Paren(s) | PatKind::Guard(s, _) => s.walk(it), @@ -717,7 +718,7 @@ impl Pat { /// Strip off all reference patterns (`&`, `&mut`) and return the inner pattern. pub fn peel_refs(&self) -> &Pat { let mut current = self; - while let PatKind::Ref(inner, _) = ¤t.kind { + while let PatKind::Ref(inner, _, _) = ¤t.kind { current = inner; } current @@ -765,7 +766,9 @@ impl Pat { PatKind::Missing => unreachable!(), PatKind::Wild => Some("_".to_string()), PatKind::Ident(BindingMode::NONE, ident, None) => Some(format!("{ident}")), - PatKind::Ref(pat, mutbl) => pat.descr().map(|d| format!("&{}{d}", mutbl.prefix_str())), + PatKind::Ref(pat, pinned, mutbl) => { + pat.descr().map(|d| format!("&{}{d}", pinned.prefix_str(*mutbl))) + } _ => None, } } @@ -913,7 +916,7 @@ pub enum PatKind { Deref(Box), /// A reference pattern (e.g., `&mut (a, b)`). - Ref(Box, Mutability), + Ref(Box, Pinnedness, Mutability), /// A literal, const block or path. Expr(Box), diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index 4ae193a42ff2..094875f38d74 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -645,8 +645,9 @@ macro_rules! common_visitor_and_walkers { fn visit_fn( &mut self, fk: FnKind<$($lt)? $(${ignore($mut)} '_)?>, + _: &AttrVec, _: Span, - _: NodeId + _: NodeId, ) -> Self::Result { walk_fn(self, fk) } @@ -740,6 +741,7 @@ macro_rules! common_visitor_and_walkers { type Ctxt; fn walk<$($lt,)? V: $Visitor$(<$lt>)?>( &$($lt)? $($mut)? self, + attrs: &AttrVec, span: Span, id: NodeId, visibility: &$($lt)? $($mut)? Visibility, @@ -773,7 +775,7 @@ macro_rules! common_visitor_and_walkers { ) -> V::Result { let Item { attrs, id, kind, vis, span, tokens: _ } = item; visit_visitable!($($mut)? visitor, id, attrs, vis); - try_visit!(kind.walk(*span, *id, vis, ctxt, visitor)); + try_visit!(kind.walk(attrs, *span, *id, vis, ctxt, visitor)); visit_visitable!($($mut)? visitor, span); V::Result::output() } @@ -799,6 +801,7 @@ macro_rules! common_visitor_and_walkers { type Ctxt = (); fn walk<$($lt,)? V: $Visitor$(<$lt>)?>( &$($lt)? $($mut)? self, + attrs: &AttrVec, span: Span, id: NodeId, visibility: &$($lt)? $($mut)? Visibility, @@ -808,7 +811,7 @@ macro_rules! common_visitor_and_walkers { match self { ItemKind::Fn(func) => { let kind = FnKind::Fn(FnCtxt::Free, visibility, &$($mut)? *func); - try_visit!(vis.visit_fn(kind, span, id)); + try_visit!(vis.visit_fn(kind, attrs, span, id)); } ItemKind::ExternCrate(orig_name, ident) => visit_visitable!($($mut)? vis, orig_name, ident), @@ -856,6 +859,7 @@ macro_rules! common_visitor_and_walkers { type Ctxt = AssocCtxt; fn walk<$($lt,)? V: $Visitor$(<$lt>)?>( &$($lt)? $($mut)? self, + attrs: &AttrVec, span: Span, id: NodeId, visibility: &$($lt)? $($mut)? Visibility, @@ -867,7 +871,7 @@ macro_rules! common_visitor_and_walkers { visit_visitable!($($mut)? vis, item), AssocItemKind::Fn(func) => { let kind = FnKind::Fn(FnCtxt::Assoc(ctxt), visibility, &$($mut)? *func); - try_visit!(vis.visit_fn(kind, span, id)) + try_visit!(vis.visit_fn(kind, attrs, span, id)) } AssocItemKind::Type(alias) => visit_visitable!($($mut)? vis, alias), @@ -886,6 +890,7 @@ macro_rules! common_visitor_and_walkers { type Ctxt = (); fn walk<$($lt,)? V: $Visitor$(<$lt>)?>( &$($lt)? $($mut)? self, + attrs: &AttrVec, span: Span, id: NodeId, visibility: &$($lt)? $($mut)? Visibility, @@ -897,7 +902,7 @@ macro_rules! common_visitor_and_walkers { visit_visitable!($($mut)? vis, item), ForeignItemKind::Fn(func) => { let kind = FnKind::Fn(FnCtxt::Foreign, visibility, &$($mut)?*func); - try_visit!(vis.visit_fn(kind, span, id)) + try_visit!(vis.visit_fn(kind, attrs, span, id)) } ForeignItemKind::TyAlias(alias) => visit_visitable!($($mut)? vis, alias), @@ -999,7 +1004,7 @@ macro_rules! common_visitor_and_walkers { }) => { visit_visitable!($($mut)? vis, constness, movability, capture_clause); let kind = FnKind::Closure(binder, coroutine_kind, fn_decl, body); - try_visit!(vis.visit_fn(kind, *span, *id)); + try_visit!(vis.visit_fn(kind, attrs, *span, *id)); visit_visitable!($($mut)? vis, fn_decl_span, fn_arg_span); } ExprKind::Block(block, opt_label) => diff --git a/compiler/rustc_ast_ir/src/lib.rs b/compiler/rustc_ast_ir/src/lib.rs index 0f63fad15743..fb00f5d9b623 100644 --- a/compiler/rustc_ast_ir/src/lib.rs +++ b/compiler/rustc_ast_ir/src/lib.rs @@ -317,4 +317,15 @@ impl Pinnedness { pub fn is_pinned(self) -> bool { matches!(self, Self::Pinned) } + + /// Returns `""` (empty string), "mut", `"pin mut "` or `"pin const "` depending + /// on the pinnedness and mutability. + pub fn prefix_str(self, mutbl: Mutability) -> &'static str { + match (self, mutbl) { + (Pinnedness::Pinned, Mutability::Mut) => "pin mut ", + (Pinnedness::Pinned, Mutability::Not) => "pin const ", + (Pinnedness::Not, Mutability::Mut) => "mut ", + (Pinnedness::Not, Mutability::Not) => "", + } + } } diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 2be2fca87c3c..c6f24c1a19b4 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -1771,8 +1771,14 @@ impl<'hir> LoweringContext<'_, 'hir> { let pat = self.lower_pat(pat); let for_span = self.mark_span_with_reason(DesugaringKind::ForLoop, self.lower_span(e.span), None); - let head_span = self.mark_span_with_reason(DesugaringKind::ForLoop, head.span, None); - let pat_span = self.mark_span_with_reason(DesugaringKind::ForLoop, pat.span, None); + let for_ctxt = for_span.ctxt(); + + // Try to point both the head and pat spans to their position in the for loop + // rather than inside a macro. + let head_span = + head.span.find_ancestor_in_same_ctxt(e.span).unwrap_or(head.span).with_ctxt(for_ctxt); + let pat_span = + pat.span.find_ancestor_in_same_ctxt(e.span).unwrap_or(pat.span).with_ctxt(for_ctxt); let loop_hir_id = self.lower_node_id(e.id); let label = self.lower_label(opt_label, e.id, loop_hir_id); diff --git a/compiler/rustc_ast_lowering/src/index.rs b/compiler/rustc_ast_lowering/src/index.rs index 5f8933aa2beb..8d7351d3a510 100644 --- a/compiler/rustc_ast_lowering/src/index.rs +++ b/compiler/rustc_ast_lowering/src/index.rs @@ -125,9 +125,9 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> { } impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> { - /// Because we want to track parent items and so forth, enable - /// deep walking so that we walk nested items in the context of - /// their outer items. + // Because we want to track parent items and so forth, enable + // deep walking so that we walk nested items in the context of + // their outer items. fn visit_nested_item(&mut self, item: ItemId) { debug!("visit_nested_item: {:?}", item); diff --git a/compiler/rustc_ast_lowering/src/pat.rs b/compiler/rustc_ast_lowering/src/pat.rs index 815338c84fa6..3571fd652397 100644 --- a/compiler/rustc_ast_lowering/src/pat.rs +++ b/compiler/rustc_ast_lowering/src/pat.rs @@ -124,8 +124,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { PatKind::Deref(inner) => { break hir::PatKind::Deref(self.lower_pat(inner)); } - PatKind::Ref(inner, mutbl) => { - break hir::PatKind::Ref(self.lower_pat(inner), *mutbl); + PatKind::Ref(inner, pinned, mutbl) => { + break hir::PatKind::Ref(self.lower_pat(inner), *pinned, *mutbl); } PatKind::Range(e1, e2, Spanned { node: end, .. }) => { break hir::PatKind::Range( diff --git a/compiler/rustc_ast_passes/messages.ftl b/compiler/rustc_ast_passes/messages.ftl index 7d618f16b26e..1bfe4b07551f 100644 --- a/compiler/rustc_ast_passes/messages.ftl +++ b/compiler/rustc_ast_passes/messages.ftl @@ -68,6 +68,10 @@ ast_passes_c_variadic_bad_extern = `...` is not supported for `extern "{$abi}"` .label = `extern "{$abi}"` because of this .help = only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list +ast_passes_c_variadic_bad_naked_extern = `...` is not supported for `extern "{$abi}"` naked functions + .label = `extern "{$abi}"` because of this + .help = C-variadic function must have a compatible calling convention + ast_passes_c_variadic_must_be_unsafe = functions with a C variable argument list must be unsafe .suggestion = add the `unsafe` keyword to this definition diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index c203e5426b1e..37e40bd6e94d 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -21,7 +21,7 @@ use std::ops::{Deref, DerefMut}; use std::str::FromStr; use itertools::{Either, Itertools}; -use rustc_abi::{CanonAbi, ExternAbi, InterruptKind}; +use rustc_abi::{CVariadicStatus, CanonAbi, ExternAbi, InterruptKind}; use rustc_ast::visit::{AssocCtxt, BoundKind, FnCtxt, FnKind, Visitor, walk_list}; use rustc_ast::*; use rustc_ast_pretty::pprust::{self, State}; @@ -35,6 +35,7 @@ use rustc_session::lint::builtin::{ DEPRECATED_WHERE_CLAUSE_LOCATION, MISSING_ABI, MISSING_UNSAFE_ON_EXTERN, PATTERNS_IN_FNS_WITHOUT_BODY, }; +use rustc_session::parse::feature_err; use rustc_span::{Ident, Span, kw, sym}; use rustc_target::spec::{AbiMap, AbiMapping}; use thin_vec::thin_vec; @@ -661,7 +662,7 @@ impl<'a> AstValidator<'a> { /// C-variadics must be: /// - Non-const /// - Either foreign, or free and `unsafe extern "C"` semantically - fn check_c_variadic_type(&self, fk: FnKind<'a>) { + fn check_c_variadic_type(&self, fk: FnKind<'a>, attrs: &'a AttrVec) { // `...` is already rejected when it is not the final parameter. let variadic_param = match fk.decl().inputs.last() { Some(param) if matches!(param.ty.kind, TyKind::CVarArgs) => param, @@ -693,36 +694,92 @@ impl<'a> AstValidator<'a> { match fn_ctxt { FnCtxt::Foreign => return, - FnCtxt::Free | FnCtxt::Assoc(_) => match sig.header.ext { - Extern::Implicit(_) => { - if !matches!(sig.header.safety, Safety::Unsafe(_)) { - self.dcx().emit_err(errors::CVariadicMustBeUnsafe { - span: variadic_param.span, - unsafe_span: sig.safety_span(), - }); + FnCtxt::Free | FnCtxt::Assoc(_) => { + match sig.header.ext { + Extern::Implicit(_) => { + if !matches!(sig.header.safety, Safety::Unsafe(_)) { + self.dcx().emit_err(errors::CVariadicMustBeUnsafe { + span: variadic_param.span, + unsafe_span: sig.safety_span(), + }); + } + } + Extern::Explicit(StrLit { symbol_unescaped, .. }, _) => { + // Just bail if the ABI is not even recognized. + let Ok(abi) = ExternAbi::from_str(symbol_unescaped.as_str()) else { + return; + }; + + self.check_c_variadic_abi(abi, attrs, variadic_param.span, sig); + + if !matches!(sig.header.safety, Safety::Unsafe(_)) { + self.dcx().emit_err(errors::CVariadicMustBeUnsafe { + span: variadic_param.span, + unsafe_span: sig.safety_span(), + }); + } + } + Extern::None => { + let err = errors::CVariadicNoExtern { span: variadic_param.span }; + self.dcx().emit_err(err); } } - Extern::Explicit(StrLit { symbol_unescaped, .. }, _) => { - if !matches!(symbol_unescaped, sym::C | sym::C_dash_unwind) { - self.dcx().emit_err(errors::CVariadicBadExtern { - span: variadic_param.span, - abi: symbol_unescaped, - extern_span: sig.extern_span(), - }); + } + } + } + + fn check_c_variadic_abi( + &self, + abi: ExternAbi, + attrs: &'a AttrVec, + dotdotdot_span: Span, + sig: &FnSig, + ) { + // For naked functions we accept any ABI that is accepted on c-variadic + // foreign functions, if the c_variadic_naked_functions feature is enabled. + if attr::contains_name(attrs, sym::naked) { + match abi.supports_c_variadic() { + CVariadicStatus::Stable if let ExternAbi::C { .. } = abi => { + // With `c_variadic` naked c-variadic `extern "C"` functions are allowed. + } + CVariadicStatus::Stable => { + // For e.g. aapcs or sysv64 `c_variadic_naked_functions` must also be enabled. + if !self.features.enabled(sym::c_variadic_naked_functions) { + let msg = format!("Naked c-variadic `extern {abi}` functions are unstable"); + feature_err(&self.sess, sym::c_variadic_naked_functions, sig.span, msg) + .emit(); + } + } + CVariadicStatus::Unstable { feature } => { + // Some ABIs need additional features. + if !self.features.enabled(sym::c_variadic_naked_functions) { + let msg = format!("Naked c-variadic `extern {abi}` functions are unstable"); + feature_err(&self.sess, sym::c_variadic_naked_functions, sig.span, msg) + .emit(); } - if !matches!(sig.header.safety, Safety::Unsafe(_)) { - self.dcx().emit_err(errors::CVariadicMustBeUnsafe { - span: variadic_param.span, - unsafe_span: sig.safety_span(), - }); + if !self.features.enabled(feature) { + let msg = format!( + "C-variadic functions with the {abi} calling convention are unstable" + ); + feature_err(&self.sess, feature, sig.span, msg).emit(); } } - Extern::None => { - let err = errors::CVariadicNoExtern { span: variadic_param.span }; - self.dcx().emit_err(err); + CVariadicStatus::NotSupported => { + // Some ABIs, e.g. `extern "Rust"`, never support c-variadic functions. + self.dcx().emit_err(errors::CVariadicBadNakedExtern { + span: dotdotdot_span, + abi: abi.as_str(), + extern_span: sig.extern_span(), + }); } - }, + } + } else if !matches!(abi, ExternAbi::C { .. }) { + self.dcx().emit_err(errors::CVariadicBadExtern { + span: dotdotdot_span, + abi: abi.as_str(), + extern_span: sig.extern_span(), + }); } } @@ -1106,7 +1163,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { } let kind = FnKind::Fn(FnCtxt::Free, &item.vis, &*func); - self.visit_fn(kind, item.span, item.id); + self.visit_fn(kind, &item.attrs, item.span, item.id); } ItemKind::ForeignMod(ForeignMod { extern_span, abi, safety, .. }) => { let old_item = mem::replace(&mut self.extern_mod_span, Some(item.span)); @@ -1473,7 +1530,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { visit::walk_param_bound(self, bound) } - fn visit_fn(&mut self, fk: FnKind<'a>, span: Span, id: NodeId) { + fn visit_fn(&mut self, fk: FnKind<'a>, attrs: &AttrVec, span: Span, id: NodeId) { // Only associated `fn`s can have `self` parameters. let self_semantic = match fk.ctxt() { Some(FnCtxt::Assoc(_)) => SelfSemantic::Yes, @@ -1492,7 +1549,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { self.check_extern_fn_signature(abi, ctxt, &fun.ident, &fun.sig); } - self.check_c_variadic_type(fk); + self.check_c_variadic_type(fk, attrs); // Functions cannot both be `const async` or `const gen` if let Some(&FnHeader { @@ -1643,7 +1700,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { { self.visit_attrs_vis_ident(&item.attrs, &item.vis, &func.ident); let kind = FnKind::Fn(FnCtxt::Assoc(ctxt), &item.vis, &*func); - self.visit_fn(kind, item.span, item.id); + self.visit_fn(kind, &item.attrs, item.span, item.id); } AssocItemKind::Type(_) => { let disallowed = (!parent_is_const).then(|| match self.outer_trait_or_trait_impl { diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs index 7c63b8e35999..20813d936c00 100644 --- a/compiler/rustc_ast_passes/src/errors.rs +++ b/compiler/rustc_ast_passes/src/errors.rs @@ -347,7 +347,18 @@ pub(crate) struct CVariadicMustBeUnsafe { pub(crate) struct CVariadicBadExtern { #[primary_span] pub span: Span, - pub abi: Symbol, + pub abi: &'static str, + #[label] + pub extern_span: Span, +} + +#[derive(Diagnostic)] +#[diag(ast_passes_c_variadic_bad_naked_extern)] +#[help] +pub(crate) struct CVariadicBadNakedExtern { + #[primary_span] + pub span: Span, + pub abi: &'static str, #[label] pub extern_span: Span, } diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index b8a29a9a08f4..2d87d8c84d7c 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -1,6 +1,5 @@ -use rustc_ast as ast; use rustc_ast::visit::{self, AssocCtxt, FnCtxt, FnKind, Visitor}; -use rustc_ast::{NodeId, PatKind, attr, token}; +use rustc_ast::{self as ast, AttrVec, NodeId, PatKind, attr, token}; use rustc_feature::{AttributeGate, BUILTIN_ATTRIBUTE_MAP, BuiltinAttribute, Features}; use rustc_session::Session; use rustc_session::parse::{feature_err, feature_warn}; @@ -392,7 +391,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { visit::walk_poly_trait_ref(self, t); } - fn visit_fn(&mut self, fn_kind: FnKind<'a>, span: Span, _: NodeId) { + fn visit_fn(&mut self, fn_kind: FnKind<'a>, _: &AttrVec, span: Span, _: NodeId) { if let Some(_header) = fn_kind.header() { // Stability of const fn methods are covered in `visit_assoc_item` below. } diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index 93f4e47342f1..21b14f161077 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -1807,8 +1807,14 @@ impl<'a> State<'a> { self.print_pat(inner); self.pclose(); } - PatKind::Ref(inner, mutbl) => { + PatKind::Ref(inner, pinned, mutbl) => { self.word("&"); + if pinned.is_pinned() { + self.word("pin "); + if mutbl.is_not() { + self.word("const "); + } + } if mutbl.is_mut() { self.word("mut "); } diff --git a/compiler/rustc_attr_parsing/src/attributes/cfg_select.rs b/compiler/rustc_attr_parsing/src/attributes/cfg_select.rs new file mode 100644 index 000000000000..8006fb963b19 --- /dev/null +++ b/compiler/rustc_attr_parsing/src/attributes/cfg_select.rs @@ -0,0 +1,89 @@ +use rustc_ast::token::Token; +use rustc_ast::tokenstream::TokenStream; +use rustc_ast::{AttrStyle, NodeId, token}; +use rustc_feature::{AttributeTemplate, Features}; +use rustc_hir::AttrPath; +use rustc_hir::attrs::CfgEntry; +use rustc_parse::exp; +use rustc_parse::parser::Parser; +use rustc_session::Session; +use rustc_span::{ErrorGuaranteed, Ident, Span}; + +use crate::parser::MetaItemOrLitParser; +use crate::{AttributeParser, ParsedDescription, ShouldEmit, parse_cfg_entry}; + +pub enum CfgSelectPredicate { + Cfg(CfgEntry), + Wildcard(Token), +} + +#[derive(Default)] +pub struct CfgSelectBranches { + /// All the conditional branches. + pub reachable: Vec<(CfgEntry, TokenStream, Span)>, + /// The first wildcard `_ => { ... }` branch. + pub wildcard: Option<(Token, TokenStream, Span)>, + /// All branches after the first wildcard, including further wildcards. + /// These branches are kept for formatting. + pub unreachable: Vec<(CfgSelectPredicate, TokenStream, Span)>, +} + +pub fn parse_cfg_select( + p: &mut Parser<'_>, + sess: &Session, + features: Option<&Features>, + lint_node_id: NodeId, +) -> Result { + let mut branches = CfgSelectBranches::default(); + + while p.token != token::Eof { + if p.eat_keyword(exp!(Underscore)) { + let underscore = p.prev_token; + p.expect(exp!(FatArrow)).map_err(|e| e.emit())?; + + let tts = p.parse_delimited_token_tree().map_err(|e| e.emit())?; + let span = underscore.span.to(p.token.span); + + match branches.wildcard { + None => branches.wildcard = Some((underscore, tts, span)), + Some(_) => { + branches.unreachable.push((CfgSelectPredicate::Wildcard(underscore), tts, span)) + } + } + } else { + let meta = MetaItemOrLitParser::parse_single(p, ShouldEmit::ErrorsAndLints) + .map_err(|diag| diag.emit())?; + let cfg_span = meta.span(); + let cfg = AttributeParser::parse_single_args( + sess, + cfg_span, + cfg_span, + AttrStyle::Inner, + AttrPath { + segments: vec![Ident::from_str("cfg_select")].into_boxed_slice(), + span: cfg_span, + }, + ParsedDescription::Macro, + cfg_span, + lint_node_id, + features, + ShouldEmit::ErrorsAndLints, + &meta, + parse_cfg_entry, + &AttributeTemplate::default(), + )?; + + p.expect(exp!(FatArrow)).map_err(|e| e.emit())?; + + let tts = p.parse_delimited_token_tree().map_err(|e| e.emit())?; + let span = cfg_span.to(p.token.span); + + match branches.wildcard { + None => branches.reachable.push((cfg, tts, span)), + Some(_) => branches.unreachable.push((CfgSelectPredicate::Cfg(cfg), tts, span)), + } + } + } + + Ok(branches) +} diff --git a/compiler/rustc_attr_parsing/src/attributes/mod.rs b/compiler/rustc_attr_parsing/src/attributes/mod.rs index 093969586596..65e0957ca900 100644 --- a/compiler/rustc_attr_parsing/src/attributes/mod.rs +++ b/compiler/rustc_attr_parsing/src/attributes/mod.rs @@ -33,6 +33,7 @@ pub(crate) mod allow_unstable; pub(crate) mod body; pub(crate) mod cfg; pub(crate) mod cfg_old; +pub(crate) mod cfg_select; pub(crate) mod codegen_attrs; pub(crate) mod confusables; pub(crate) mod crate_level; diff --git a/compiler/rustc_attr_parsing/src/lib.rs b/compiler/rustc_attr_parsing/src/lib.rs index 473935abdcd5..046cca4c742b 100644 --- a/compiler/rustc_attr_parsing/src/lib.rs +++ b/compiler/rustc_attr_parsing/src/lib.rs @@ -106,6 +106,7 @@ pub use attributes::cfg::{ CFG_TEMPLATE, EvalConfigResult, eval_config_entry, parse_cfg, parse_cfg_attr, parse_cfg_entry, }; pub use attributes::cfg_old::*; +pub use attributes::cfg_select::*; pub use attributes::util::{is_builtin_attr, is_doc_alias_attrs_contain_symbol, parse_version}; pub use context::{Early, Late, OmitDoc, ShouldEmit}; pub use interface::AttributeParser; diff --git a/compiler/rustc_attr_parsing/src/validate_attr.rs b/compiler/rustc_attr_parsing/src/validate_attr.rs index 927417f89f8c..4065fe7ce173 100644 --- a/compiler/rustc_attr_parsing/src/validate_attr.rs +++ b/compiler/rustc_attr_parsing/src/validate_attr.rs @@ -209,7 +209,7 @@ pub fn check_attribute_safety( // - Normal builtin attribute // - Writing `#[unsafe(..)]` is not permitted on normal builtin attributes - (Some(AttributeSafety::Normal), Safety::Unsafe(unsafe_span)) => { + (None | Some(AttributeSafety::Normal), Safety::Unsafe(unsafe_span)) => { psess.dcx().emit_err(errors::InvalidAttrUnsafe { span: unsafe_span, name: attr_item.path.clone(), @@ -218,15 +218,10 @@ pub fn check_attribute_safety( // - Normal builtin attribute // - No explicit `#[unsafe(..)]` written. - (Some(AttributeSafety::Normal), Safety::Default) => { + (None | Some(AttributeSafety::Normal), Safety::Default) => { // OK } - // - Non-builtin attribute - (None, Safety::Unsafe(_) | Safety::Default) => { - // OK (not checked here) - } - ( Some(AttributeSafety::Unsafe { .. } | AttributeSafety::Normal) | None, Safety::Safe(..), diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index f84ed64e036e..9a8927c10297 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -3087,6 +3087,39 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { }); explanation.add_explanation_to_diagnostic(&self, &mut err, "", Some(borrow_span), None); + + // Detect buffer reuse pattern + if let BorrowExplanation::UsedLater(_dropped_local, _, _, _) = explanation { + // Check all locals at the borrow location to find Vec<&T> types + for (local, local_decl) in self.body.local_decls.iter_enumerated() { + if let ty::Adt(adt_def, args) = local_decl.ty.kind() + && self.infcx.tcx.is_diagnostic_item(sym::Vec, adt_def.did()) + && args.len() > 0 + { + let vec_inner_ty = args.type_at(0); + // Check if Vec contains references + if vec_inner_ty.is_ref() { + let local_place = local.into(); + if let Some(local_name) = self.describe_place(local_place) { + err.span_label( + local_decl.source_info.span, + format!("variable `{local_name}` declared here"), + ); + err.note( + format!( + "`{local_name}` is a collection that stores borrowed references, \ + but {name} does not live long enough to be stored in it" + ) + ); + err.help( + "buffer reuse with borrowed references requires unsafe code or restructuring" + ); + break; + } + } + } + } + } } err diff --git a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs index be2a5b1ebe22..3322c590a6ce 100644 --- a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs @@ -867,11 +867,12 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { for (binding_span, opt_ref_pat) in finder.ref_pat_for_binding { if let Some(ref_pat) = opt_ref_pat && !finder.cannot_remove.contains(&ref_pat.hir_id) - && let hir::PatKind::Ref(subpat, mutbl) = ref_pat.kind + && let hir::PatKind::Ref(subpat, pinned, mutbl) = ref_pat.kind && let Some(ref_span) = ref_pat.span.trim_end(subpat.span) { + let pinned_str = if pinned.is_pinned() { "pinned " } else { "" }; let mutable_str = if mutbl.is_mut() { "mutable " } else { "" }; - let msg = format!("consider removing the {mutable_str}borrow"); + let msg = format!("consider removing the {pinned_str}{mutable_str}borrow"); suggestions.push((ref_span, msg, "".to_string())); } else { let msg = "consider borrowing the pattern binding".to_string(); diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index 2f011dba60b1..c06e3c8b3c17 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -213,7 +213,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { AccessKind::Mutate => { err = self.cannot_assign(span, &(item_msg + &reason)); act = "assign"; - acted_on = "written"; + acted_on = "written to"; span } AccessKind::MutableBorrow => { @@ -518,8 +518,8 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { err.span_label( span, format!( - "`{name}` is a `{pointer_sigil}` {pointer_desc}, \ - so the data it refers to cannot be {acted_on}", + "`{name}` is a `{pointer_sigil}` {pointer_desc}, so it cannot be \ + {acted_on}", ), ); @@ -542,7 +542,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { self.expected_fn_found_fn_mut_call(&mut err, span, act); } - PlaceRef { local: _, projection: [.., ProjectionElem::Deref] } => { + PlaceRef { local, projection: [.., ProjectionElem::Deref] } => { err.span_label(span, format!("cannot {act}")); match opt_source { @@ -559,11 +559,36 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { )); self.suggest_map_index_mut_alternatives(ty, &mut err, span); } - _ => (), + _ => { + let local = &self.body.local_decls[local]; + match local.local_info() { + LocalInfo::StaticRef { def_id, .. } => { + let span = self.infcx.tcx.def_span(def_id); + err.span_label(span, format!("this `static` cannot be {acted_on}")); + } + LocalInfo::ConstRef { def_id } => { + let span = self.infcx.tcx.def_span(def_id); + err.span_label(span, format!("this `const` cannot be {acted_on}")); + } + LocalInfo::BlockTailTemp(_) | LocalInfo::Boring + if !local.source_info.span.overlaps(span) => + { + err.span_label( + local.source_info.span, + format!("this cannot be {acted_on}"), + ); + } + _ => {} + } + } } } - _ => { + PlaceRef { local, .. } => { + let local = &self.body.local_decls[local]; + if !local.source_info.span.overlaps(span) { + err.span_label(local.source_info.span, format!("this cannot be {acted_on}")); + } err.span_label(span, format!("cannot {act}")); } } @@ -772,11 +797,11 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { && let Some(hir_id) = (BindingFinder { span: pat_span }).visit_body(&body).break_value() && let node = self.infcx.tcx.hir_node(hir_id) && let hir::Node::LetStmt(hir::LetStmt { - pat: hir::Pat { kind: hir::PatKind::Ref(_, _), .. }, + pat: hir::Pat { kind: hir::PatKind::Ref(_, _, _), .. }, .. }) | hir::Node::Param(Param { - pat: hir::Pat { kind: hir::PatKind::Ref(_, _), .. }, + pat: hir::Pat { kind: hir::PatKind::Ref(_, _, _), .. }, .. }) = node { @@ -1494,7 +1519,7 @@ impl<'tcx> Visitor<'tcx> for BindingFinder { } fn visit_param(&mut self, param: &'tcx hir::Param<'tcx>) -> Self::Result { - if let hir::Pat { kind: hir::PatKind::Ref(_, _), span, .. } = param.pat + if let hir::Pat { kind: hir::PatKind::Ref(_, _, _), span, .. } = param.pat && *span == self.span { ControlFlow::Break(param.hir_id) diff --git a/compiler/rustc_builtin_macros/src/cfg_select.rs b/compiler/rustc_builtin_macros/src/cfg_select.rs index f22d5f255c29..f2e454c3d437 100644 --- a/compiler/rustc_builtin_macros/src/cfg_select.rs +++ b/compiler/rustc_builtin_macros/src/cfg_select.rs @@ -1,7 +1,9 @@ use rustc_ast::tokenstream::TokenStream; use rustc_attr_parsing as attr; +use rustc_attr_parsing::{ + CfgSelectBranches, CfgSelectPredicate, EvalConfigResult, ShouldEmit, parse_cfg_select, +}; use rustc_expand::base::{DummyResult, ExpandResult, ExtCtxt, MacroExpanderResult}; -use rustc_parse::parser::cfg_select::{CfgSelectBranches, CfgSelectPredicate, parse_cfg_select}; use rustc_span::{Ident, Span, sym}; use crate::errors::{CfgSelectNoMatches, CfgSelectUnreachable}; @@ -9,11 +11,11 @@ use crate::errors::{CfgSelectNoMatches, CfgSelectUnreachable}; /// Selects the first arm whose predicate evaluates to true. fn select_arm(ecx: &ExtCtxt<'_>, branches: CfgSelectBranches) -> Option<(TokenStream, Span)> { for (cfg, tt, arm_span) in branches.reachable { - if attr::cfg_matches( - &cfg, + if let EvalConfigResult::True = attr::eval_config_entry( &ecx.sess, + &cfg, ecx.current_expansion.lint_node_id, - Some(ecx.ecfg.features), + ShouldEmit::ErrorsAndLints, ) { return Some((tt, arm_span)); } @@ -27,37 +29,41 @@ pub(super) fn expand_cfg_select<'cx>( sp: Span, tts: TokenStream, ) -> MacroExpanderResult<'cx> { - ExpandResult::Ready(match parse_cfg_select(&mut ecx.new_parser_from_tts(tts)) { - Ok(branches) => { - if let Some((underscore, _, _)) = branches.wildcard { - // Warn for every unreachable predicate. We store the fully parsed branch for rustfmt. - for (predicate, _, _) in &branches.unreachable { - let span = match predicate { - CfgSelectPredicate::Wildcard(underscore) => underscore.span, - CfgSelectPredicate::Cfg(cfg) => cfg.span(), - }; - let err = CfgSelectUnreachable { span, wildcard_span: underscore.span }; - ecx.dcx().emit_warn(err); + ExpandResult::Ready( + match parse_cfg_select( + &mut ecx.new_parser_from_tts(tts), + ecx.sess, + Some(ecx.ecfg.features), + ecx.current_expansion.lint_node_id, + ) { + Ok(branches) => { + if let Some((underscore, _, _)) = branches.wildcard { + // Warn for every unreachable predicate. We store the fully parsed branch for rustfmt. + for (predicate, _, _) in &branches.unreachable { + let span = match predicate { + CfgSelectPredicate::Wildcard(underscore) => underscore.span, + CfgSelectPredicate::Cfg(cfg) => cfg.span(), + }; + let err = CfgSelectUnreachable { span, wildcard_span: underscore.span }; + ecx.dcx().emit_warn(err); + } + } + + if let Some((tts, arm_span)) = select_arm(ecx, branches) { + return ExpandResult::from_tts( + ecx, + tts, + sp, + arm_span, + Ident::with_dummy_span(sym::cfg_select), + ); + } else { + // Emit a compiler error when none of the predicates matched. + let guar = ecx.dcx().emit_err(CfgSelectNoMatches { span: sp }); + DummyResult::any(sp, guar) } } - - if let Some((tts, arm_span)) = select_arm(ecx, branches) { - return ExpandResult::from_tts( - ecx, - tts, - sp, - arm_span, - Ident::with_dummy_span(sym::cfg_select), - ); - } else { - // Emit a compiler error when none of the predicates matched. - let guar = ecx.dcx().emit_err(CfgSelectNoMatches { span: sp }); - DummyResult::any(sp, guar) - } - } - Err(err) => { - let guar = err.emit(); - DummyResult::any(sp, guar) - } - }) + Err(guar) => DummyResult::any(sp, guar), + }, + ) } diff --git a/compiler/rustc_builtin_macros/src/deriving/bounds.rs b/compiler/rustc_builtin_macros/src/deriving/bounds.rs index 63342880b094..06b0d0512e70 100644 --- a/compiler/rustc_builtin_macros/src/deriving/bounds.rs +++ b/compiler/rustc_builtin_macros/src/deriving/bounds.rs @@ -1,4 +1,4 @@ -use rustc_ast::MetaItem; +use rustc_ast::{MetaItem, Safety}; use rustc_expand::base::{Annotatable, ExtCtxt}; use rustc_span::Span; @@ -24,6 +24,8 @@ pub(crate) fn expand_deriving_copy( associated_types: Vec::new(), is_const, is_staged_api_crate: cx.ecfg.features.staged_api(), + safety: Safety::Default, + document: true, }; trait_def.expand(cx, mitem, item, push); @@ -48,6 +50,8 @@ pub(crate) fn expand_deriving_const_param_ty( associated_types: Vec::new(), is_const, is_staged_api_crate: cx.ecfg.features.staged_api(), + safety: Safety::Default, + document: true, }; trait_def.expand(cx, mitem, item, push); diff --git a/compiler/rustc_builtin_macros/src/deriving/clone.rs b/compiler/rustc_builtin_macros/src/deriving/clone.rs index 3c78f53c5cb0..af3db65bd0a6 100644 --- a/compiler/rustc_builtin_macros/src/deriving/clone.rs +++ b/compiler/rustc_builtin_macros/src/deriving/clone.rs @@ -1,7 +1,7 @@ -use rustc_ast::{self as ast, Generics, ItemKind, MetaItem, VariantData}; +use rustc_ast::{self as ast, Generics, ItemKind, MetaItem, Safety, VariantData}; use rustc_data_structures::fx::FxHashSet; use rustc_expand::base::{Annotatable, ExtCtxt}; -use rustc_span::{Ident, Span, kw, sym}; +use rustc_span::{DUMMY_SP, Ident, Span, kw, sym}; use thin_vec::{ThinVec, thin_vec}; use crate::deriving::generic::ty::*; @@ -68,6 +68,29 @@ pub(crate) fn expand_deriving_clone( _ => cx.dcx().span_bug(span, "`#[derive(Clone)]` on trait item or impl item"), } + // If the clone method is just copying the value, also mark the type as + // `TrivialClone` to allow some library optimizations. + if is_simple { + let trivial_def = TraitDef { + span, + path: path_std!(clone::TrivialClone), + skip_path_as_bound: false, + needs_copy_as_bound_if_packed: true, + additional_bounds: bounds.clone(), + supports_unions: true, + methods: Vec::new(), + associated_types: Vec::new(), + is_const, + is_staged_api_crate: cx.ecfg.features.staged_api(), + safety: Safety::Unsafe(DUMMY_SP), + // `TrivialClone` is not part of an API guarantee, so it shouldn't + // appear in rustdoc output. + document: false, + }; + + trivial_def.expand_ext(cx, mitem, item, push, true); + } + let trait_def = TraitDef { span, path: path_std!(clone::Clone), @@ -88,6 +111,8 @@ pub(crate) fn expand_deriving_clone( associated_types: Vec::new(), is_const, is_staged_api_crate: cx.ecfg.features.staged_api(), + safety: Safety::Default, + document: true, }; trait_def.expand_ext(cx, mitem, item, push, is_simple) diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs index 29d531219a69..d9b82e97cb46 100644 --- a/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs +++ b/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs @@ -1,4 +1,4 @@ -use rustc_ast::{self as ast, MetaItem}; +use rustc_ast::{self as ast, MetaItem, Safety}; use rustc_data_structures::fx::FxHashSet; use rustc_expand::base::{Annotatable, ExtCtxt}; use rustc_span::{Span, sym}; @@ -44,6 +44,8 @@ pub(crate) fn expand_deriving_eq( associated_types: Vec::new(), is_const, is_staged_api_crate: cx.ecfg.features.staged_api(), + safety: Safety::Default, + document: true, }; trait_def.expand_ext(cx, mitem, item, push, true) } diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs index 0e1ecf3118ac..4a8e4e07942b 100644 --- a/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs +++ b/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs @@ -1,4 +1,4 @@ -use rustc_ast::MetaItem; +use rustc_ast::{MetaItem, Safety}; use rustc_expand::base::{Annotatable, ExtCtxt}; use rustc_span::{Ident, Span, sym}; use thin_vec::thin_vec; @@ -35,6 +35,8 @@ pub(crate) fn expand_deriving_ord( associated_types: Vec::new(), is_const, is_staged_api_crate: cx.ecfg.features.staged_api(), + safety: Safety::Default, + document: true, }; trait_def.expand(cx, mitem, item, push) diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs index a0f71a1868b5..03ee270d66ba 100644 --- a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs +++ b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs @@ -1,4 +1,4 @@ -use rustc_ast::{BinOpKind, BorrowKind, Expr, ExprKind, MetaItem, Mutability}; +use rustc_ast::{BinOpKind, BorrowKind, Expr, ExprKind, MetaItem, Mutability, Safety}; use rustc_expand::base::{Annotatable, ExtCtxt}; use rustc_span::{Span, sym}; use thin_vec::thin_vec; @@ -30,6 +30,8 @@ pub(crate) fn expand_deriving_partial_eq( associated_types: Vec::new(), is_const: false, is_staged_api_crate: cx.ecfg.features.staged_api(), + safety: Safety::Default, + document: true, }; structural_trait_def.expand(cx, mitem, item, push); @@ -59,6 +61,8 @@ pub(crate) fn expand_deriving_partial_eq( associated_types: Vec::new(), is_const, is_staged_api_crate: cx.ecfg.features.staged_api(), + safety: Safety::Default, + document: true, }; trait_def.expand(cx, mitem, item, push) } diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs index f5d262ece36e..d9d7dd9c3620 100644 --- a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs +++ b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs @@ -1,4 +1,4 @@ -use rustc_ast::{ExprKind, ItemKind, MetaItem, PatKind}; +use rustc_ast::{ExprKind, ItemKind, MetaItem, PatKind, Safety}; use rustc_expand::base::{Annotatable, ExtCtxt}; use rustc_span::{Ident, Span, sym}; use thin_vec::thin_vec; @@ -65,6 +65,8 @@ pub(crate) fn expand_deriving_partial_ord( associated_types: Vec::new(), is_const, is_staged_api_crate: cx.ecfg.features.staged_api(), + safety: Safety::Default, + document: true, }; trait_def.expand(cx, mitem, item, push) } diff --git a/compiler/rustc_builtin_macros/src/deriving/debug.rs b/compiler/rustc_builtin_macros/src/deriving/debug.rs index 597af0e09c06..48a2f19261f6 100644 --- a/compiler/rustc_builtin_macros/src/deriving/debug.rs +++ b/compiler/rustc_builtin_macros/src/deriving/debug.rs @@ -1,4 +1,4 @@ -use rustc_ast::{self as ast, EnumDef, MetaItem}; +use rustc_ast::{self as ast, EnumDef, MetaItem, Safety}; use rustc_expand::base::{Annotatable, ExtCtxt}; use rustc_session::config::FmtDebug; use rustc_span::{Ident, Span, Symbol, sym}; @@ -42,6 +42,8 @@ pub(crate) fn expand_deriving_debug( associated_types: Vec::new(), is_const, is_staged_api_crate: cx.ecfg.features.staged_api(), + safety: Safety::Default, + document: true, }; trait_def.expand(cx, mitem, item, push) } diff --git a/compiler/rustc_builtin_macros/src/deriving/default.rs b/compiler/rustc_builtin_macros/src/deriving/default.rs index 2462114ec24a..86d53b23e1f1 100644 --- a/compiler/rustc_builtin_macros/src/deriving/default.rs +++ b/compiler/rustc_builtin_macros/src/deriving/default.rs @@ -1,8 +1,7 @@ use core::ops::ControlFlow; -use rustc_ast as ast; use rustc_ast::visit::visit_opt; -use rustc_ast::{EnumDef, VariantData, attr}; +use rustc_ast::{self as ast, EnumDef, Safety, VariantData, attr}; use rustc_expand::base::{Annotatable, DummyResult, ExtCtxt}; use rustc_span::{ErrorGuaranteed, Ident, Span, kw, sym}; use smallvec::SmallVec; @@ -52,6 +51,8 @@ pub(crate) fn expand_deriving_default( associated_types: Vec::new(), is_const, is_staged_api_crate: cx.ecfg.features.staged_api(), + safety: Safety::Default, + document: true, }; trait_def.expand(cx, mitem, item, push) } diff --git a/compiler/rustc_builtin_macros/src/deriving/from.rs b/compiler/rustc_builtin_macros/src/deriving/from.rs index ab25de7c9175..2e4369f3bb1c 100644 --- a/compiler/rustc_builtin_macros/src/deriving/from.rs +++ b/compiler/rustc_builtin_macros/src/deriving/from.rs @@ -1,5 +1,5 @@ use rustc_ast as ast; -use rustc_ast::{ItemKind, VariantData}; +use rustc_ast::{ItemKind, Safety, VariantData}; use rustc_errors::MultiSpan; use rustc_expand::base::{Annotatable, DummyResult, ExtCtxt}; use rustc_span::{Ident, Span, kw, sym}; @@ -127,6 +127,8 @@ pub(crate) fn expand_deriving_from( associated_types: Vec::new(), is_const, is_staged_api_crate: cx.ecfg.features.staged_api(), + safety: Safety::Default, + document: true, }; from_trait_def.expand(cx, mitem, annotatable, push); diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs index 24a71ae94389..2b1e10120a0d 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs @@ -225,6 +225,12 @@ pub(crate) struct TraitDef<'a> { pub is_const: bool, pub is_staged_api_crate: bool, + + /// The safety of the `impl`. + pub safety: Safety, + + /// Whether the added `impl` should appear in rustdoc output. + pub document: bool, } pub(crate) struct MethodDef<'a> { @@ -826,13 +832,17 @@ impl<'a> TraitDef<'a> { ) } + if !self.document { + attrs.push(cx.attr_nested_word(sym::doc, sym::hidden, self.span)); + } + cx.item( self.span, attrs, ast::ItemKind::Impl(ast::Impl { generics: trait_generics, of_trait: Some(Box::new(ast::TraitImplHeader { - safety: ast::Safety::Default, + safety: self.safety, polarity: ast::ImplPolarity::Positive, defaultness: ast::Defaultness::Final, constness: if self.is_const { diff --git a/compiler/rustc_builtin_macros/src/deriving/hash.rs b/compiler/rustc_builtin_macros/src/deriving/hash.rs index 78534449895c..e18c8e1750d8 100644 --- a/compiler/rustc_builtin_macros/src/deriving/hash.rs +++ b/compiler/rustc_builtin_macros/src/deriving/hash.rs @@ -1,4 +1,4 @@ -use rustc_ast::{MetaItem, Mutability}; +use rustc_ast::{MetaItem, Mutability, Safety}; use rustc_expand::base::{Annotatable, ExtCtxt}; use rustc_span::{Span, sym}; use thin_vec::thin_vec; @@ -42,6 +42,8 @@ pub(crate) fn expand_deriving_hash( associated_types: Vec::new(), is_const, is_staged_api_crate: cx.ecfg.features.staged_api(), + safety: Safety::Default, + document: true, }; hash_trait_def.expand(cx, mitem, item, push); diff --git a/compiler/rustc_codegen_cranelift/src/abi/mod.rs b/compiler/rustc_codegen_cranelift/src/abi/mod.rs index 9ac282df5b5e..09d71f5dd557 100644 --- a/compiler/rustc_codegen_cranelift/src/abi/mod.rs +++ b/compiler/rustc_codegen_cranelift/src/abi/mod.rs @@ -916,8 +916,8 @@ pub(crate) fn codegen_call_with_unwind_action( pub(crate) fn lib_call_arg_param(tcx: TyCtxt<'_>, ty: Type, is_signed: bool) -> AbiParam { let param = AbiParam::new(ty); if ty.is_int() && u64::from(ty.bits()) < tcx.data_layout.pointer_size().bits() { - match (&tcx.sess.target.arch, tcx.sess.target.vendor.as_ref()) { - (Arch::X86_64, _) | (Arch::AArch64, "apple") => match (ty, is_signed) { + match (&tcx.sess.target.arch, tcx.sess.target.is_like_darwin) { + (Arch::X86_64, _) | (Arch::AArch64, true) => match (ty, is_signed) { (types::I8 | types::I16, true) => param.sext(), (types::I8 | types::I16, false) => param.uext(), _ => param, diff --git a/compiler/rustc_codegen_cranelift/src/codegen_f16_f128.rs b/compiler/rustc_codegen_cranelift/src/codegen_f16_f128.rs index 91f7220667ff..86bff32dc623 100644 --- a/compiler/rustc_codegen_cranelift/src/codegen_f16_f128.rs +++ b/compiler/rustc_codegen_cranelift/src/codegen_f16_f128.rs @@ -5,7 +5,7 @@ use crate::prelude::*; pub(crate) fn f16_to_f32(fx: &mut FunctionCx<'_, '_, '_>, value: Value) -> Value { let (value, arg_ty) = - if fx.tcx.sess.target.vendor == "apple" && fx.tcx.sess.target.arch == Arch::X86_64 { + if fx.tcx.sess.target.is_like_darwin && fx.tcx.sess.target.arch == Arch::X86_64 { ( fx.bcx.ins().bitcast(types::I16, MemFlags::new(), value), lib_call_arg_param(fx.tcx, types::I16, false), @@ -22,8 +22,7 @@ fn f16_to_f64(fx: &mut FunctionCx<'_, '_, '_>, value: Value) -> Value { } pub(crate) fn f32_to_f16(fx: &mut FunctionCx<'_, '_, '_>, value: Value) -> Value { - let ret_ty = if fx.tcx.sess.target.vendor == "apple" && fx.tcx.sess.target.arch == Arch::X86_64 - { + let ret_ty = if fx.tcx.sess.target.is_like_darwin && fx.tcx.sess.target.arch == Arch::X86_64 { types::I16 } else { types::F16 @@ -38,8 +37,7 @@ pub(crate) fn f32_to_f16(fx: &mut FunctionCx<'_, '_, '_>, value: Value) -> Value } fn f64_to_f16(fx: &mut FunctionCx<'_, '_, '_>, value: Value) -> Value { - let ret_ty = if fx.tcx.sess.target.vendor == "apple" && fx.tcx.sess.target.arch == Arch::X86_64 - { + let ret_ty = if fx.tcx.sess.target.is_like_darwin && fx.tcx.sess.target.arch == Arch::X86_64 { types::I16 } else { types::F16 diff --git a/compiler/rustc_codegen_cranelift/src/lib.rs b/compiler/rustc_codegen_cranelift/src/lib.rs index 4745243a6eab..5fdecd014ac0 100644 --- a/compiler/rustc_codegen_cranelift/src/lib.rs +++ b/compiler/rustc_codegen_cranelift/src/lib.rs @@ -49,7 +49,7 @@ use rustc_middle::dep_graph::{WorkProduct, WorkProductId}; use rustc_session::Session; use rustc_session::config::OutputFilenames; use rustc_span::{Symbol, sym}; -use rustc_target::spec::Arch; +use rustc_target::spec::{Abi, Arch, Env, Os}; pub use crate::config::*; use crate::prelude::*; @@ -163,15 +163,15 @@ impl CodegenBackend for CraneliftCodegenBackend { fn target_config(&self, sess: &Session) -> TargetConfig { // FIXME return the actually used target features. this is necessary for #[cfg(target_feature)] let target_features = match sess.target.arch { - Arch::X86_64 if sess.target.os != "none" => { + Arch::X86_64 if sess.target.os != Os::None => { // x86_64 mandates SSE2 support and rustc requires the x87 feature to be enabled vec![sym::fxsr, sym::sse, sym::sse2, Symbol::intern("x87")] } - Arch::AArch64 => match &*sess.target.os { - "none" => vec![], + Arch::AArch64 => match &sess.target.os { + Os::None => vec![], // On macOS the aes, sha2 and sha3 features are enabled by default and ring // fails to compile on macOS when they are not present. - "macos" => vec![sym::neon, sym::aes, sym::sha2, sym::sha3], + Os::MacOs => vec![sym::neon, sym::aes, sym::sha2, sym::sha3], // AArch64 mandates Neon support _ => vec![sym::neon], }, @@ -184,9 +184,9 @@ impl CodegenBackend for CraneliftCodegenBackend { // targets due to GCC using a different ABI than LLVM. Therefore `f16` and `f128` // won't be available when using a LLVM-built sysroot. let has_reliable_f16_f128 = !(sess.target.arch == Arch::X86_64 - && sess.target.os == "windows" - && sess.target.env == "gnu" - && sess.target.abi != "llvm"); + && sess.target.os == Os::Windows + && sess.target.env == Env::Gnu + && sess.target.abi != Abi::Llvm); TargetConfig { target_features, diff --git a/compiler/rustc_codegen_llvm/src/callee.rs b/compiler/rustc_codegen_llvm/src/callee.rs index f0d4c546e986..9215273eed17 100644 --- a/compiler/rustc_codegen_llvm/src/callee.rs +++ b/compiler/rustc_codegen_llvm/src/callee.rs @@ -7,7 +7,7 @@ use rustc_codegen_ssa::common; use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, HasTypingEnv}; use rustc_middle::ty::{self, Instance, TypeVisitableExt}; -use rustc_target::spec::Arch; +use rustc_target::spec::{Arch, Env}; use tracing::debug; use crate::context::CodegenCx; @@ -145,7 +145,7 @@ pub(crate) fn get_fn<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'t if cx.use_dll_storage_attrs && let Some(library) = tcx.native_library(instance_def_id) && library.kind.is_dllimport() - && !matches!(tcx.sess.target.env.as_ref(), "gnu" | "uclibc") + && !matches!(tcx.sess.target.env, Env::Gnu | Env::Uclibc) { llvm::set_dllimport_storage_class(llfn); } diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs index c01f163f2ee1..b60c8a7d3719 100644 --- a/compiler/rustc_codegen_llvm/src/context.rs +++ b/compiler/rustc_codegen_llvm/src/context.rs @@ -29,7 +29,7 @@ use rustc_span::source_map::Spanned; use rustc_span::{DUMMY_SP, Span, Symbol}; use rustc_symbol_mangling::mangle_internal_symbol; use rustc_target::spec::{ - Arch, HasTargetSpec, RelocModel, SmallDataThresholdSupport, Target, TlsModel, + Abi, Arch, Env, HasTargetSpec, Os, RelocModel, SmallDataThresholdSupport, Target, TlsModel, }; use smallvec::SmallVec; @@ -335,9 +335,9 @@ pub(crate) unsafe fn create_module<'ll>( // Control Flow Guard is currently only supported by MSVC and LLVM on Windows. if sess.target.is_like_msvc - || (sess.target.options.os == "windows" - && sess.target.options.env == "gnu" - && sess.target.options.abi == "llvm") + || (sess.target.options.os == Os::Windows + && sess.target.options.env == Env::Gnu + && sess.target.options.abi == Abi::Llvm) { match sess.opts.cg.control_flow_guard { CFGuard::Disabled => {} @@ -669,7 +669,7 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> { /// This corresponds to the `-fobjc-abi-version=` flag in Clang / GCC. pub(crate) fn objc_abi_version(&self) -> u32 { assert!(self.tcx.sess.target.is_like_darwin); - if self.tcx.sess.target.arch == Arch::X86 && self.tcx.sess.target.os == "macos" { + if self.tcx.sess.target.arch == Arch::X86 && self.tcx.sess.target.os == Os::MacOs { // 32-bit x86 macOS uses ABI version 1 (a.k.a. the "fragile ABI"). 1 } else { @@ -710,7 +710,7 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> { }, ); - if self.tcx.sess.target.env == "sim" { + if self.tcx.sess.target.env == Env::Sim { llvm::add_module_flag_u32( self.llmod, llvm::ModuleFlagMergeBehavior::Error, @@ -963,7 +963,7 @@ impl<'ll> CodegenCx<'ll, '_> { return eh_catch_typeinfo; } let tcx = self.tcx; - assert!(self.sess().target.os == "emscripten"); + assert!(self.sess().target.os == Os::Emscripten); let eh_catch_typeinfo = match tcx.lang_items().eh_catch_typeinfo() { Some(def_id) => self.get_static(def_id), _ => { diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index 0626cb3f2f16..739b33f34962 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -18,6 +18,7 @@ use rustc_middle::{bug, span_bug}; use rustc_span::{Span, Symbol, sym}; use rustc_symbol_mangling::{mangle_internal_symbol, symbol_name_for_instance_in_crate}; use rustc_target::callconv::PassMode; +use rustc_target::spec::Os; use tracing::debug; use crate::abi::FnAbiLlvmExt; @@ -681,7 +682,7 @@ fn catch_unwind_intrinsic<'ll, 'tcx>( codegen_msvc_try(bx, try_func, data, catch_func, dest); } else if wants_wasm_eh(bx.sess()) { codegen_wasm_try(bx, try_func, data, catch_func, dest); - } else if bx.sess().target.os == "emscripten" { + } else if bx.sess().target.os == Os::Emscripten { codegen_emcc_try(bx, try_func, data, catch_func, dest); } else { codegen_gnu_try(bx, try_func, data, catch_func, dest); diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs index 3714049c3231..b498448417f5 100644 --- a/compiler/rustc_codegen_llvm/src/llvm_util.rs +++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs @@ -15,7 +15,9 @@ use rustc_fs_util::path_to_c_string; use rustc_middle::bug; use rustc_session::Session; use rustc_session::config::{PrintKind, PrintRequest}; -use rustc_target::spec::{Arch, MergeFunctions, PanicStrategy, SmallDataThresholdSupport}; +use rustc_target::spec::{ + Abi, Arch, Env, MergeFunctions, Os, PanicStrategy, SmallDataThresholdSupport, +}; use smallvec::{SmallVec, smallvec}; use crate::back::write::create_informational_target_machine; @@ -104,7 +106,7 @@ unsafe fn configure_llvm(sess: &Session) { add("-wasm-enable-eh", false); } - if sess.target.os == "emscripten" + if sess.target.os == Os::Emscripten && !sess.opts.unstable_opts.emscripten_wasm_eh && sess.panic_strategy().unwinds() { @@ -351,9 +353,9 @@ pub(crate) fn target_config(sess: &Session) -> TargetConfig { /// Determine whether or not experimental float types are reliable based on known bugs. fn update_target_reliable_float_cfg(sess: &Session, cfg: &mut TargetConfig) { let target_arch = &sess.target.arch; - let target_os = sess.target.options.os.as_ref(); - let target_env = sess.target.options.env.as_ref(); - let target_abi = sess.target.options.abi.as_ref(); + let target_os = &sess.target.options.os; + let target_env = &sess.target.options.env; + let target_abi = &sess.target.options.abi; let target_pointer_width = sess.target.pointer_width; let version = get_version(); let lt_20_1_1 = version < (20, 1, 1); @@ -371,7 +373,7 @@ fn update_target_reliable_float_cfg(sess: &Session, cfg: &mut TargetConfig) { // Selection failure (fixed in llvm21) (Arch::S390x, _) if lt_21_0_0 => false, // MinGW ABI bugs - (Arch::X86_64, "windows") if target_env == "gnu" && target_abi != "llvm" => false, + (Arch::X86_64, Os::Windows) if *target_env == Env::Gnu && *target_abi != Abi::Llvm => false, // Infinite recursion (Arch::CSky, _) => false, (Arch::Hexagon, _) if lt_21_0_0 => false, // (fixed in llvm21) @@ -403,7 +405,7 @@ fn update_target_reliable_float_cfg(sess: &Session, cfg: &mut TargetConfig) { // not fail if our compiler-builtins is linked. (fixed in llvm21) (Arch::X86, _) if lt_21_0_0 => false, // MinGW ABI bugs - (Arch::X86_64, "windows") if target_env == "gnu" && target_abi != "llvm" => false, + (Arch::X86_64, Os::Windows) if *target_env == Env::Gnu && *target_abi != Abi::Llvm => false, // There are no known problems on other platforms, so the only requirement is that symbols // are available. `compiler-builtins` provides all symbols required for core `f128` // support, so this should work for everything else. @@ -424,9 +426,9 @@ fn update_target_reliable_float_cfg(sess: &Session, cfg: &mut TargetConfig) { // (ld is 80-bit extended precision). // // musl does not implement the symbols required for f128 math at all. - _ if target_env == "musl" => false, + _ if *target_env == Env::Musl => false, (Arch::X86_64, _) => false, - (_, "linux") if target_pointer_width == 64 => true, + (_, Os::Linux) if target_pointer_width == 64 => true, _ => false, } && cfg.has_reliable_f128; } diff --git a/compiler/rustc_codegen_llvm/src/va_arg.rs b/compiler/rustc_codegen_llvm/src/va_arg.rs index 115d96d9baf6..add25da025b2 100644 --- a/compiler/rustc_codegen_llvm/src/va_arg.rs +++ b/compiler/rustc_codegen_llvm/src/va_arg.rs @@ -7,7 +7,7 @@ use rustc_codegen_ssa::traits::{ }; use rustc_middle::ty::Ty; use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf}; -use rustc_target::spec::Arch; +use rustc_target::spec::{Abi, Arch}; use crate::builder::Builder; use crate::llvm::{Type, Value}; @@ -270,7 +270,7 @@ fn emit_powerpc_va_arg<'ll, 'tcx>( // Rust does not currently support any powerpc softfloat targets. let target = &bx.cx.tcx.sess.target; - let is_soft_float_abi = target.abi == "softfloat"; + let is_soft_float_abi = target.abi == Abi::SoftFloat; assert!(!is_soft_float_abi); // All instances of VaArgSafe are passed directly. diff --git a/compiler/rustc_codegen_ssa/src/back/apple.rs b/compiler/rustc_codegen_ssa/src/back/apple.rs index 3b29ddeadc7f..23808ade6c85 100644 --- a/compiler/rustc_codegen_ssa/src/back/apple.rs +++ b/compiler/rustc_codegen_ssa/src/back/apple.rs @@ -6,7 +6,7 @@ use itertools::Itertools; use rustc_middle::middle::exported_symbols::SymbolExportKind; use rustc_session::Session; pub(super) use rustc_target::spec::apple::OSVersion; -use rustc_target::spec::{Arch, Target}; +use rustc_target::spec::{Arch, Env, Os, Target}; use tracing::debug; use crate::errors::{XcrunError, XcrunSdkPathWarning}; @@ -17,35 +17,35 @@ mod tests; /// The canonical name of the desired SDK for a given target. pub(super) fn sdk_name(target: &Target) -> &'static str { - match (&*target.os, &*target.env) { - ("macos", "") => "MacOSX", - ("ios", "") => "iPhoneOS", - ("ios", "sim") => "iPhoneSimulator", + match (&target.os, &target.env) { + (Os::MacOs, Env::Unspecified) => "MacOSX", + (Os::IOs, Env::Unspecified) => "iPhoneOS", + (Os::IOs, Env::Sim) => "iPhoneSimulator", // Mac Catalyst uses the macOS SDK - ("ios", "macabi") => "MacOSX", - ("tvos", "") => "AppleTVOS", - ("tvos", "sim") => "AppleTVSimulator", - ("visionos", "") => "XROS", - ("visionos", "sim") => "XRSimulator", - ("watchos", "") => "WatchOS", - ("watchos", "sim") => "WatchSimulator", + (Os::IOs, Env::MacAbi) => "MacOSX", + (Os::TvOs, Env::Unspecified) => "AppleTVOS", + (Os::TvOs, Env::Sim) => "AppleTVSimulator", + (Os::VisionOs, Env::Unspecified) => "XROS", + (Os::VisionOs, Env::Sim) => "XRSimulator", + (Os::WatchOs, Env::Unspecified) => "WatchOS", + (Os::WatchOs, Env::Sim) => "WatchSimulator", (os, abi) => unreachable!("invalid os '{os}' / abi '{abi}' combination for Apple target"), } } pub(super) fn macho_platform(target: &Target) -> u32 { - match (&*target.os, &*target.env) { - ("macos", _) => object::macho::PLATFORM_MACOS, - ("ios", "macabi") => object::macho::PLATFORM_MACCATALYST, - ("ios", "sim") => object::macho::PLATFORM_IOSSIMULATOR, - ("ios", _) => object::macho::PLATFORM_IOS, - ("watchos", "sim") => object::macho::PLATFORM_WATCHOSSIMULATOR, - ("watchos", _) => object::macho::PLATFORM_WATCHOS, - ("tvos", "sim") => object::macho::PLATFORM_TVOSSIMULATOR, - ("tvos", _) => object::macho::PLATFORM_TVOS, - ("visionos", "sim") => object::macho::PLATFORM_XROSSIMULATOR, - ("visionos", _) => object::macho::PLATFORM_XROS, - _ => unreachable!("tried to get Mach-O platform for non-Apple target"), + match (&target.os, &target.env) { + (Os::MacOs, _) => object::macho::PLATFORM_MACOS, + (Os::IOs, Env::MacAbi) => object::macho::PLATFORM_MACCATALYST, + (Os::IOs, Env::Sim) => object::macho::PLATFORM_IOSSIMULATOR, + (Os::IOs, _) => object::macho::PLATFORM_IOS, + (Os::WatchOs, Env::Sim) => object::macho::PLATFORM_WATCHOSSIMULATOR, + (Os::WatchOs, _) => object::macho::PLATFORM_WATCHOS, + (Os::TvOs, Env::Sim) => object::macho::PLATFORM_TVOSSIMULATOR, + (Os::TvOs, _) => object::macho::PLATFORM_TVOS, + (Os::VisionOs, Env::Sim) => object::macho::PLATFORM_XROSSIMULATOR, + (Os::VisionOs, _) => object::macho::PLATFORM_XROS, + (os, env) => unreachable!("invalid os '{os}' / env '{env}' combination for Apple target"), } } diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index c5724c20b216..820f7ba4a6f2 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -46,9 +46,9 @@ use rustc_session::{Session, filesearch}; use rustc_span::Symbol; use rustc_target::spec::crt_objects::CrtObjects; use rustc_target::spec::{ - BinaryFormat, Cc, LinkOutputKind, LinkSelfContainedComponents, LinkSelfContainedDefault, - LinkerFeatures, LinkerFlavor, LinkerFlavorCli, Lld, RelocModel, RelroLevel, SanitizerSet, - SplitDebuginfo, + Abi, BinaryFormat, Cc, Env, LinkOutputKind, LinkSelfContainedComponents, + LinkSelfContainedDefault, LinkerFeatures, LinkerFlavor, LinkerFlavorCli, Lld, Os, RelocModel, + RelroLevel, SanitizerSet, SplitDebuginfo, }; use tracing::{debug, info, warn}; @@ -1407,11 +1407,9 @@ pub fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) { Some(LinkerFlavorCli::Llbc) => Some(LinkerFlavor::Llbc), Some(LinkerFlavorCli::Ptx) => Some(LinkerFlavor::Ptx), // The linker flavors that corresponds to targets needs logic that keeps the base LinkerFlavor - _ => sess - .opts - .cg - .linker_flavor - .map(|flavor| sess.target.linker_flavor.with_cli_hints(flavor)), + linker_flavor => { + linker_flavor.map(|flavor| sess.target.linker_flavor.with_cli_hints(flavor)) + } }; if let Some(ret) = infer_from(sess, sess.opts.cg.linker.clone(), linker_flavor, features) { return ret; @@ -1819,7 +1817,7 @@ fn self_contained_components( LinkSelfContainedDefault::InferredForMusl => sess.crt_static(Some(crate_type)), LinkSelfContainedDefault::InferredForMingw => { sess.host == sess.target - && sess.target.vendor != "uwp" + && sess.target.abi != Abi::Uwp && detect_self_contained_mingw(sess, linker) } } @@ -1845,7 +1843,7 @@ fn add_pre_link_objects( let empty = Default::default(); let objects = if self_contained { &opts.pre_link_objects_self_contained - } else if !(sess.target.os == "fuchsia" && matches!(flavor, LinkerFlavor::Gnu(Cc::Yes, _))) { + } else if !(sess.target.os == Os::Fuchsia && matches!(flavor, LinkerFlavor::Gnu(Cc::Yes, _))) { &opts.pre_link_objects } else { &empty @@ -2496,7 +2494,7 @@ fn add_order_independent_options( let apple_sdk_root = add_apple_sdk(cmd, sess, flavor); - if sess.target.os == "fuchsia" + if sess.target.os == Os::Fuchsia && crate_type == CrateType::Executable && !matches!(flavor, LinkerFlavor::Gnu(Cc::Yes, _)) { @@ -2515,7 +2513,7 @@ fn add_order_independent_options( cmd.no_crt_objects(); } - if sess.target.os == "emscripten" { + if sess.target.os == Os::Emscripten { cmd.cc_arg(if sess.opts.unstable_opts.emscripten_wasm_eh { "-fwasm-exceptions" } else if sess.panic_strategy().unwinds() { @@ -3070,8 +3068,8 @@ fn add_apple_link_args(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavo // `sess.target.arch` (`target_arch`) is not detailed enough. let llvm_arch = sess.target.llvm_target.split_once('-').expect("LLVM target must have arch").0; - let target_os = &*sess.target.os; - let target_env = &*sess.target.env; + let target_os = &sess.target.os; + let target_env = &sess.target.env; // The architecture name to forward to the linker. // @@ -3123,12 +3121,12 @@ fn add_apple_link_args(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavo // > - xros-simulator // > - driverkit let platform_name = match (target_os, target_env) { - (os, "") => os, - ("ios", "macabi") => "mac-catalyst", - ("ios", "sim") => "ios-simulator", - ("tvos", "sim") => "tvos-simulator", - ("watchos", "sim") => "watchos-simulator", - ("visionos", "sim") => "visionos-simulator", + (os, Env::Unspecified) => os.desc(), + (Os::IOs, Env::MacAbi) => "mac-catalyst", + (Os::IOs, Env::Sim) => "ios-simulator", + (Os::TvOs, Env::Sim) => "tvos-simulator", + (Os::WatchOs, Env::Sim) => "watchos-simulator", + (Os::VisionOs, Env::Sim) => "visionos-simulator", _ => bug!("invalid OS/env combination for Apple target: {target_os}, {target_env}"), }; @@ -3192,7 +3190,7 @@ fn add_apple_link_args(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavo // fairly safely use `-target`. See also the following, where it is // made explicit that the recommendation by LLVM developers is to use // `-target`: - if target_os == "macos" { + if *target_os == Os::MacOs { // `-arch` communicates the architecture. // // CC forwards the `-arch` to the linker, so we use the same value diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs index eb2740d59b4b..f4225b2d764b 100644 --- a/compiler/rustc_codegen_ssa/src/back/linker.rs +++ b/compiler/rustc_codegen_ssa/src/back/linker.rs @@ -17,7 +17,7 @@ use rustc_middle::middle::exported_symbols::{ use rustc_middle::ty::TyCtxt; use rustc_session::Session; use rustc_session::config::{self, CrateType, DebugInfo, LinkerPluginLto, Lto, OptLevel, Strip}; -use rustc_target::spec::{Arch, Cc, LinkOutputKind, LinkerFlavor, Lld}; +use rustc_target::spec::{Abi, Arch, Cc, LinkOutputKind, LinkerFlavor, Lld, Os}; use tracing::{debug, warn}; use super::command::Command; @@ -83,7 +83,7 @@ pub(crate) fn get_linker<'a>( // To comply with the Windows App Certification Kit, // MSVC needs to link with the Store versions of the runtime libraries (vcruntime, msvcrt, etc). let t = &sess.target; - if matches!(flavor, LinkerFlavor::Msvc(..)) && t.vendor == "uwp" { + if matches!(flavor, LinkerFlavor::Msvc(..)) && t.abi == Abi::Uwp { if let Some(ref tool) = msvc_tool { let original_path = tool.path(); if let Some(root_lib_path) = original_path.ancestors().nth(4) { @@ -134,12 +134,12 @@ pub(crate) fn get_linker<'a>( // FIXME: Move `/LIBPATH` addition for uwp targets from the linker construction // to the linker args construction. - assert!(cmd.get_args().is_empty() || sess.target.vendor == "uwp"); + assert!(cmd.get_args().is_empty() || sess.target.abi == Abi::Uwp); match flavor { - LinkerFlavor::Unix(Cc::No) if sess.target.os == "l4re" => { + LinkerFlavor::Unix(Cc::No) if sess.target.os == Os::L4Re => { Box::new(L4Bender::new(cmd, sess)) as Box } - LinkerFlavor::Unix(Cc::No) if sess.target.os == "aix" => { + LinkerFlavor::Unix(Cc::No) if sess.target.os == Os::Aix => { Box::new(AixLinker::new(cmd, sess)) as Box } LinkerFlavor::WasmLld(Cc::No) => Box::new(WasmLd::new(cmd, sess)) as Box, @@ -573,7 +573,7 @@ impl<'a> Linker for GccLinker<'a> { // any `#[link]` attributes in the `libc` crate, see #72782 for details. // FIXME: Switch to using `#[link]` attributes in the `libc` crate // similarly to other targets. - if self.sess.target.os == "vxworks" + if self.sess.target.os == Os::VxWorks && matches!( output_kind, LinkOutputKind::StaticNoPicExe @@ -595,7 +595,7 @@ impl<'a> Linker for GccLinker<'a> { } fn link_dylib_by_name(&mut self, name: &str, verbatim: bool, as_needed: bool) { - if self.sess.target.os == "illumos" && name == "c" { + if self.sess.target.os == Os::Illumos && name == "c" { // libc will be added via late_link_args on illumos so that it will // appear last in the library search order. // FIXME: This should be replaced by a more complete and generic @@ -1439,7 +1439,7 @@ impl<'a> Linker for WasmLd<'a> { // symbols explicitly passed via the `--export` flags above and hides all // others. Various bits and pieces of wasm32-unknown-unknown tooling use // this, so be sure these symbols make their way out of the linker as well. - if self.sess.target.os == "unknown" || self.sess.target.os == "none" { + if matches!(self.sess.target.os, Os::Unknown | Os::None) { self.link_args(&["--export=__heap_base", "--export=__data_end"]); } } diff --git a/compiler/rustc_codegen_ssa/src/back/metadata.rs b/compiler/rustc_codegen_ssa/src/back/metadata.rs index 10aaadd5688a..6dff79374f20 100644 --- a/compiler/rustc_codegen_ssa/src/back/metadata.rs +++ b/compiler/rustc_codegen_ssa/src/back/metadata.rs @@ -20,7 +20,7 @@ use rustc_metadata::fs::METADATA_FILENAME; use rustc_middle::bug; use rustc_session::Session; use rustc_span::sym; -use rustc_target::spec::{RelocModel, Target, ef_avr_arch}; +use rustc_target::spec::{Abi, Os, RelocModel, Target, ef_avr_arch}; use tracing::debug; use super::apple; @@ -260,10 +260,10 @@ pub(crate) fn create_object_file(sess: &Session) -> Option u8 { - match sess.target.options.os.as_ref() { - "hermit" => elf::ELFOSABI_STANDALONE, - "freebsd" => elf::ELFOSABI_FREEBSD, - "solaris" => elf::ELFOSABI_SOLARIS, + match sess.target.options.os { + Os::Hermit => elf::ELFOSABI_STANDALONE, + Os::FreeBsd => elf::ELFOSABI_FREEBSD, + Os::Solaris => elf::ELFOSABI_SOLARIS, _ => elf::ELFOSABI_NONE, } } @@ -379,11 +379,11 @@ pub(super) fn elf_e_flags(architecture: Architecture, sess: &Session) -> u32 { } } Architecture::Csky => { - let e_flags = match sess.target.options.abi.as_ref() { - "abiv2" => elf::EF_CSKY_ABIV2, - _ => elf::EF_CSKY_ABIV1, - }; - e_flags + if matches!(sess.target.options.abi, Abi::AbiV2) { + elf::EF_CSKY_ABIV2 + } else { + elf::EF_CSKY_ABIV1 + } } Architecture::PowerPc64 => { const EF_PPC64_ABI_UNKNOWN: u32 = 0; diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs index 6fa8725a7871..a80976fad02a 100644 --- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs +++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs @@ -17,7 +17,7 @@ use rustc_middle::ty::{self, GenericArgKind, GenericArgsRef, Instance, SymbolNam use rustc_middle::util::Providers; use rustc_session::config::{CrateType, OomStrategy}; use rustc_symbol_mangling::mangle_internal_symbol; -use rustc_target::spec::{Arch, TlsModel}; +use rustc_target::spec::{Arch, Os, TlsModel}; use tracing::debug; use crate::back::symbol_export; @@ -711,7 +711,7 @@ pub(crate) fn extend_exported_symbols<'tcx>( ) { let (callconv, _) = calling_convention_for_symbol(tcx, symbol); - if callconv != CanonAbi::GpuKernel || tcx.sess.target.os != "amdhsa" { + if callconv != CanonAbi::GpuKernel || tcx.sess.target.os != Os::AmdHsa { return; } diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index ed2815b06c18..414e9ce1c821 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -33,7 +33,7 @@ use rustc_session::Session; use rustc_session::config::{self, CrateType, EntryFnType}; use rustc_span::{DUMMY_SP, Symbol, sym}; use rustc_symbol_mangling::mangle_internal_symbol; -use rustc_target::spec::Arch; +use rustc_target::spec::{Arch, Os}; use rustc_trait_selection::infer::{BoundRegionConversionTime, TyCtxtInferExt}; use rustc_trait_selection::traits::{ObligationCause, ObligationCtxt}; use tracing::{debug, info}; @@ -366,7 +366,7 @@ pub(crate) fn build_shift_expr_rhs<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( // us pub fn wants_wasm_eh(sess: &Session) -> bool { sess.target.is_like_wasm - && (sess.target.os != "emscripten" || sess.opts.unstable_opts.emscripten_wasm_eh) + && (sess.target.os != Os::Emscripten || sess.opts.unstable_opts.emscripten_wasm_eh) } /// Returns `true` if this session's target will use SEH-based unwinding. @@ -500,7 +500,7 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( ) -> Bx::Function { // The entry function is either `int main(void)` or `int main(int argc, char **argv)`, or // `usize efi_main(void *handle, void *system_table)` depending on the target. - let llfty = if cx.sess().target.os.contains("uefi") { + let llfty = if cx.sess().target.os == Os::Uefi { cx.type_func(&[cx.type_ptr(), cx.type_ptr()], cx.type_isize()) } else if cx.sess().target.main_needs_argc_argv { cx.type_func(&[cx.type_int(), cx.type_ptr()], cx.type_int()) @@ -562,7 +562,7 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( }; let result = bx.call(start_ty, None, None, start_fn, &args, None, instance); - if cx.sess().target.os.contains("uefi") { + if cx.sess().target.os == Os::Uefi { bx.ret(result); } else { let cast = bx.intcast(result, cx.type_int(), true); @@ -576,7 +576,7 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( /// Obtain the `argc` and `argv` values to pass to the rust start function /// (i.e., the "start" lang item). fn get_argc_argv<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(bx: &mut Bx) -> (Bx::Value, Bx::Value) { - if bx.cx().sess().target.os.contains("uefi") { + if bx.cx().sess().target.os == Os::Uefi { // Params for UEFI let param_handle = bx.get_param(0); let param_system_table = bx.get_param(1); diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index 720f8061c4e6..c59e04c07b21 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -16,6 +16,7 @@ use rustc_middle::ty::{self as ty, TyCtxt}; use rustc_session::lint; use rustc_session::parse::feature_err; use rustc_span::{Ident, Span, sym}; +use rustc_target::spec::Os; use crate::errors; use crate::target_features::{ @@ -258,7 +259,7 @@ fn process_builtin_attrs( UsedBy::Compiler => codegen_fn_attrs.flags |= CodegenFnAttrFlags::USED_COMPILER, UsedBy::Linker => codegen_fn_attrs.flags |= CodegenFnAttrFlags::USED_LINKER, UsedBy::Default => { - let used_form = if tcx.sess.target.os == "illumos" { + let used_form = if tcx.sess.target.os == Os::Illumos { // illumos' `ld` doesn't support a section header that would represent // `#[used(linker)]`, see // https://github.com/rust-lang/rust/issues/146169. For that target, diff --git a/compiler/rustc_codegen_ssa/src/common.rs b/compiler/rustc_codegen_ssa/src/common.rs index 08e2f3559533..89a3f8061a8c 100644 --- a/compiler/rustc_codegen_ssa/src/common.rs +++ b/compiler/rustc_codegen_ssa/src/common.rs @@ -7,7 +7,7 @@ use rustc_middle::ty::{self, Instance, TyCtxt}; use rustc_middle::{bug, mir, span_bug}; use rustc_session::cstore::{DllCallingConvention, DllImport}; use rustc_span::Span; -use rustc_target::spec::Target; +use rustc_target::spec::{Abi, Env, Os, Target}; use crate::traits::*; @@ -171,7 +171,7 @@ pub fn asm_const_to_str<'tcx>( } pub fn is_mingw_gnu_toolchain(target: &Target) -> bool { - target.vendor == "pc" && target.os == "windows" && target.env == "gnu" && target.abi.is_empty() + target.os == Os::Windows && target.env == Env::Gnu && target.abi == Abi::Unspecified } pub fn i686_decorated_name( diff --git a/compiler/rustc_data_structures/src/marker.rs b/compiler/rustc_data_structures/src/marker.rs index 2be9ba292f97..0ef3bb319ff8 100644 --- a/compiler/rustc_data_structures/src/marker.rs +++ b/compiler/rustc_data_structures/src/marker.rs @@ -53,13 +53,13 @@ impl !DynSend for std::env::VarsOs {} macro_rules! already_send { ($([$ty: ty])*) => { - $(unsafe impl DynSend for $ty where $ty: Send {})* + $(unsafe impl DynSend for $ty where Self: Send {})* }; } // These structures are already `Send`. already_send!( - [std::backtrace::Backtrace][std::io::Stdout][std::io::Stderr][std::io::Error][std::fs::File] + [std::backtrace::Backtrace][std::io::Stdout][std::io::Stderr][std::io::Error][std::fs::File][std::panic::Location<'_>] [rustc_arena::DroplessArena][jobserver_crate::Client][jobserver_crate::HelperThread] [crate::memmap::Mmap][crate::profiling::SelfProfiler][crate::owned_slice::OwnedSlice] ); @@ -127,14 +127,14 @@ impl !DynSync for std::env::VarsOs {} macro_rules! already_sync { ($([$ty: ty])*) => { - $(unsafe impl DynSync for $ty where $ty: Sync {})* + $(unsafe impl DynSync for $ty where Self: Sync {})* }; } // These structures are already `Sync`. already_sync!( [std::sync::atomic::AtomicBool][std::sync::atomic::AtomicUsize][std::sync::atomic::AtomicU8] - [std::sync::atomic::AtomicU32][std::backtrace::Backtrace][std::io::Error][std::fs::File] + [std::sync::atomic::AtomicU32][std::backtrace::Backtrace][std::io::Error][std::fs::File][std::panic::Location<'_>] [jobserver_crate::Client][jobserver_crate::HelperThread][crate::memmap::Mmap] [crate::profiling::SelfProfiler][crate::owned_slice::OwnedSlice] ); diff --git a/compiler/rustc_data_structures/src/steal.rs b/compiler/rustc_data_structures/src/steal.rs index 0d79d98b5d96..afa9bc36f2c5 100644 --- a/compiler/rustc_data_structures/src/steal.rs +++ b/compiler/rustc_data_structures/src/steal.rs @@ -1,5 +1,5 @@ use crate::stable_hasher::{HashStable, StableHasher}; -use crate::sync::{MappedReadGuard, ReadGuard, RwLock}; +use crate::sync::{MappedReadGuard, MappedWriteGuard, ReadGuard, RwLock, WriteGuard}; /// The `Steal` struct is intended to used as the value for a query. /// Specifically, we sometimes have queries (*cough* MIR *cough*) @@ -40,9 +40,17 @@ impl Steal { ReadGuard::map(borrow, |opt| opt.as_ref().unwrap()) } + /// An escape hatch for rustc drivers to mutate `Steal` caches. + /// + /// Use at your own risk. This can badly break incremental compilation + /// and anything else that relies on the immutability of query caches. #[track_caller] - pub fn get_mut(&mut self) -> &mut T { - self.value.get_mut().as_mut().expect("attempt to read from stolen value") + pub fn risky_hack_borrow_mut(&self) -> MappedWriteGuard<'_, T> { + let borrow = self.value.borrow_mut(); + if borrow.is_none() { + panic!("attempted to read from stolen value: {}", std::any::type_name::()); + } + WriteGuard::map(borrow, |opt| opt.as_mut().unwrap()) } #[track_caller] diff --git a/compiler/rustc_driver_impl/src/signal_handler.rs b/compiler/rustc_driver_impl/src/signal_handler.rs index e7bc57c9749b..3d5df19bf67e 100644 --- a/compiler/rustc_driver_impl/src/signal_handler.rs +++ b/compiler/rustc_driver_impl/src/signal_handler.rs @@ -152,7 +152,8 @@ pub(super) fn install() { libc::sigaltstack(&alt_stack, ptr::null_mut()); let mut sa: libc::sigaction = mem::zeroed(); - sa.sa_sigaction = print_stack_trace as libc::sighandler_t; + sa.sa_sigaction = + print_stack_trace as unsafe extern "C" fn(libc::c_int) as libc::sighandler_t; sa.sa_flags = libc::SA_NODEFER | libc::SA_RESETHAND | libc::SA_ONSTACK; libc::sigemptyset(&mut sa.sa_mask); for (signum, _signame) in KILL_SIGNALS { diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index 81a7ee1ff45f..4cab7e407eec 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -1704,7 +1704,7 @@ impl HumanEmitter { } // print out the span location and spacer before we print the annotated source // to do this, we need to know if this span will be primary - let is_primary = primary_lo.file.name == annotated_file.file.name; + let is_primary = primary_lo.file.stable_id == annotated_file.file.stable_id; if is_primary { let loc = primary_lo.clone(); if !self.short_message { @@ -2322,11 +2322,6 @@ impl HumanEmitter { show_code_change { for part in parts { - let snippet = if let Ok(snippet) = sm.span_to_snippet(part.span) { - snippet - } else { - String::new() - }; let span_start_pos = sm.lookup_char_pos(part.span.lo()).col_display; let span_end_pos = sm.lookup_char_pos(part.span.hi()).col_display; @@ -2402,7 +2397,7 @@ impl HumanEmitter { // LL - REMOVED <- row_num - 2 - (newlines - first_i - 1) // LL + NEWER // | <- row_num - + let snippet = sm.span_to_snippet(part.span).unwrap_or_default(); let newlines = snippet.lines().count(); if newlines > 0 && row_num > newlines { // Account for removals where the part being removed spans multiple @@ -3108,7 +3103,7 @@ impl FileWithAnnotatedLines { ) { for slot in file_vec.iter_mut() { // Look through each of our files for the one we're adding to - if slot.file.name == file.name { + if slot.file.stable_id == file.stable_id { // See if we already have a line for it for line_slot in &mut slot.lines { if line_slot.line_index == line_index { @@ -3471,14 +3466,9 @@ impl Drop for Buffy { pub fn stderr_destination(color: ColorConfig) -> Destination { let buffer_writer = std::io::stderr(); - let choice = color.to_color_choice(); // We need to resolve `ColorChoice::Auto` before `Box`ing since // `ColorChoice::Auto` on `dyn Write` will always resolve to `Never` - let choice = if matches!(choice, ColorChoice::Auto) { - AutoStream::choice(&buffer_writer) - } else { - choice - }; + let choice = get_stderr_color_choice(color, &buffer_writer); // On Windows we'll be performing global synchronization on the entire // system for emitting rustc errors, so there's no need to buffer // anything. @@ -3493,6 +3483,11 @@ pub fn stderr_destination(color: ColorConfig) -> Destination { } } +pub fn get_stderr_color_choice(color: ColorConfig, stderr: &std::io::Stderr) -> ColorChoice { + let choice = color.to_color_choice(); + if matches!(choice, ColorChoice::Auto) { AutoStream::choice(stderr) } else { choice } +} + /// On Windows, BRIGHT_BLUE is hard to read on black. Use cyan instead. /// /// See #36178. diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index 276490bc0c9d..1dbf7b472649 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -886,9 +886,6 @@ impl<'a, 'b> MacroExpander<'a, 'b> { } } } else if let SyntaxExtensionKind::NonMacroAttr = ext { - if let ast::Safety::Unsafe(span) = attr.get_normal_item().unsafety { - self.cx.dcx().span_err(span, "unnecessary `unsafe` on safe attribute"); - } // `-Zmacro-stats` ignores these because they don't do any real expansion. self.cx.expanded_inert_attrs.mark(&attr); item.visit_attrs(|attrs| attrs.insert(pos, attr)); diff --git a/compiler/rustc_expand/src/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs index 295573f44926..0e063011eea4 100644 --- a/compiler/rustc_expand/src/proc_macro_server.rs +++ b/compiler/rustc_expand/src/proc_macro_server.rs @@ -749,7 +749,7 @@ impl server::Span for Rustc<'_, '_> { let self_loc = self.psess().source_map().lookup_char_pos(first.lo()); let other_loc = self.psess().source_map().lookup_char_pos(second.lo()); - if self_loc.file.name != other_loc.file.name { + if self_loc.file.stable_id != other_loc.file.stable_id { return None; } diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 8397cd294e0a..f51bc7031c31 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -410,6 +410,9 @@ declare_features! ( (unstable, avx10_target_feature, "1.88.0", Some(138843)), /// Allows using C-variadics. (unstable, c_variadic, "1.34.0", Some(44930)), + /// Allows defining c-variadic naked functions with any extern ABI that is allowed + /// on c-variadic foreign functions. + (unstable, c_variadic_naked_functions, "CURRENT_RUSTC_VERSION", Some(148767)), /// Allows the use of `#[cfg(contract_checks)` to check if contract checks are enabled. (unstable, cfg_contract_checks, "1.86.0", Some(128044)), /// Allows the use of `#[cfg(overflow_checks)` to check if integer overflow behaviour. diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index 7ddd71c34600..4ba64b240ac0 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -194,6 +194,18 @@ pub enum CfgEntry { Version(Option, Span), } +impl CfgEntry { + pub fn span(&self) -> Span { + let (CfgEntry::All(_, span) + | CfgEntry::Any(_, span) + | CfgEntry::Not(_, span) + | CfgEntry::Bool(_, span) + | CfgEntry::NameValue { span, .. } + | CfgEntry::Version(_, span)) = self; + *span + } +} + /// Possible values for the `#[linkage]` attribute, allowing to specify the /// linkage type for a `MonoItem`. /// diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 4cdfc752d989..786280c24c11 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -1722,7 +1722,9 @@ impl<'hir> Pat<'hir> { match self.kind { Missing => unreachable!(), Wild | Never | Expr(_) | Range(..) | Binding(.., None) | Err(_) => true, - Box(s) | Deref(s) | Ref(s, _) | Binding(.., Some(s)) | Guard(s, _) => s.walk_short_(it), + Box(s) | Deref(s) | Ref(s, _, _) | Binding(.., Some(s)) | Guard(s, _) => { + s.walk_short_(it) + } Struct(_, fields, _) => fields.iter().all(|field| field.pat.walk_short_(it)), TupleStruct(_, s, _) | Tuple(s, _) | Or(s) => s.iter().all(|p| p.walk_short_(it)), Slice(before, slice, after) => { @@ -1749,7 +1751,7 @@ impl<'hir> Pat<'hir> { use PatKind::*; match self.kind { Missing | Wild | Never | Expr(_) | Range(..) | Binding(.., None) | Err(_) => {} - Box(s) | Deref(s) | Ref(s, _) | Binding(.., Some(s)) | Guard(s, _) => s.walk_(it), + Box(s) | Deref(s) | Ref(s, _, _) | Binding(.., Some(s)) | Guard(s, _) => s.walk_(it), Struct(_, fields, _) => fields.iter().for_each(|field| field.pat.walk_(it)), TupleStruct(_, s, _) | Tuple(s, _) | Or(s) => s.iter().for_each(|p| p.walk_(it)), Slice(before, slice, after) => { @@ -1938,7 +1940,7 @@ pub enum PatKind<'hir> { Deref(&'hir Pat<'hir>), /// A reference pattern (e.g., `&mut (a, b)`). - Ref(&'hir Pat<'hir>, Mutability), + Ref(&'hir Pat<'hir>, Pinnedness, Mutability), /// A literal, const block or path. Expr(&'hir PatExpr<'hir>), diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index 9328ffad1c9a..2f45636a883d 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -752,7 +752,7 @@ pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat<'v>) -> V: } PatKind::Box(ref subpattern) | PatKind::Deref(ref subpattern) - | PatKind::Ref(ref subpattern, _) => { + | PatKind::Ref(ref subpattern, _, _) => { try_visit!(visitor.visit_pat(subpattern)); } PatKind::Binding(_, _hir_id, ident, ref optional_subpattern) => { diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs index e454ed58699c..20bf742e7fc7 100644 --- a/compiler/rustc_hir/src/lang_items.rs +++ b/compiler/rustc_hir/src/lang_items.rs @@ -176,6 +176,7 @@ language_item_table! { Clone, sym::clone, clone_trait, Target::Trait, GenericRequirement::None; CloneFn, sym::clone_fn, clone_fn, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::None; UseCloned, sym::use_cloned, use_cloned_trait, Target::Trait, GenericRequirement::None; + TrivialClone, sym::trivial_clone, trivial_clone_trait, Target::Trait, GenericRequirement::None; Sync, sym::sync, sync_trait, Target::Trait, GenericRequirement::Exact(0); DiscriminantKind, sym::discriminant_kind, discriminant_kind_trait, Target::Trait, GenericRequirement::None; /// The associated item of the `DiscriminantKind` trait. diff --git a/compiler/rustc_hir_analysis/src/check/region.rs b/compiler/rustc_hir_analysis/src/check/region.rs index bac34454b3b7..4e605ef62519 100644 --- a/compiler/rustc_hir_analysis/src/check/region.rs +++ b/compiler/rustc_hir_analysis/src/check/region.rs @@ -516,12 +516,10 @@ fn resolve_local<'tcx>( if let Some(pat) = pat { if is_binding_pat(pat) { - visitor.scope_tree.record_rvalue_candidate( - expr.hir_id, - RvalueCandidate { - target: expr.hir_id.local_id, - lifetime: visitor.cx.var_parent, - }, + record_subexpr_extended_temp_scopes( + &mut visitor.scope_tree, + expr, + visitor.cx.var_parent, ); } } @@ -593,7 +591,7 @@ fn resolve_local<'tcx>( is_binding_pat(subpat) } - PatKind::Ref(_, _) + PatKind::Ref(_, _, _) | PatKind::Binding(hir::BindingMode(hir::ByRef::No, _), ..) | PatKind::Missing | PatKind::Wild @@ -604,7 +602,7 @@ fn resolve_local<'tcx>( } } - /// If `expr` matches the `E&` grammar, then records an extended rvalue scope as appropriate: + /// If `expr` matches the `E&` grammar, then records an extended temporary scope as appropriate: /// /// ```text /// E& = & ET @@ -627,10 +625,7 @@ fn resolve_local<'tcx>( match expr.kind { hir::ExprKind::AddrOf(_, _, subexpr) => { record_rvalue_scope_if_borrow_expr(visitor, subexpr, blk_id); - visitor.scope_tree.record_rvalue_candidate( - subexpr.hir_id, - RvalueCandidate { target: subexpr.hir_id.local_id, lifetime: blk_id }, - ); + record_subexpr_extended_temp_scopes(&mut visitor.scope_tree, subexpr, blk_id); } hir::ExprKind::Struct(_, fields, _) => { for field in fields { @@ -687,6 +682,53 @@ fn resolve_local<'tcx>( } } +/// Applied to an expression `expr` if `expr` -- or something owned or partially owned by +/// `expr` -- is going to be indirectly referenced by a variable in a let statement. In that +/// case, the "temporary lifetime" of `expr` is extended to be the block enclosing the `let` +/// statement. +/// +/// More formally, if `expr` matches the grammar `ET`, record the temporary scope of the matching +/// `` as `lifetime`: +/// +/// ```text +/// ET = *ET +/// | ET[...] +/// | ET.f +/// | (ET) +/// | +/// ``` +/// +/// Note: ET is intended to match "rvalues or places based on rvalues". +fn record_subexpr_extended_temp_scopes( + scope_tree: &mut ScopeTree, + mut expr: &hir::Expr<'_>, + lifetime: Option, +) { + debug!(?expr, ?lifetime); + + loop { + // Note: give all the expressions matching `ET` with the + // extended temporary lifetime, not just the innermost rvalue, + // because in MIR building if we must compile e.g., `*rvalue()` + // into a temporary, we request the temporary scope of the + // outer expression. + + scope_tree.record_extended_temp_scope(expr.hir_id.local_id, lifetime); + + match expr.kind { + hir::ExprKind::AddrOf(_, _, subexpr) + | hir::ExprKind::Unary(hir::UnOp::Deref, subexpr) + | hir::ExprKind::Field(subexpr, _) + | hir::ExprKind::Index(subexpr, _, _) => { + expr = subexpr; + } + _ => { + return; + } + } + } +} + impl<'tcx> ScopeResolutionVisitor<'tcx> { /// Records the current parent (if any) as the parent of `child_scope`. fn record_child_scope(&mut self, child_scope: Scope) { diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index 79f3d7f2ff8f..c881c77f38f1 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -1487,11 +1487,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { match assoc_tag { // Don't attempt to look up inherent associated types when the feature is not // enabled. Theoretically it'd be fine to do so since we feature-gate their - // definition site. However, due to current limitations of the implementation - // (caused by us performing selection during HIR ty lowering instead of in the - // trait solver), IATs can lead to cycle errors (#108491) which mask the - // feature-gate error, needlessly confusing users who use IATs by accident - // (#113265). + // definition site. However, the current implementation of inherent associated + // items is somewhat brittle, so let's not run it by default. ty::AssocTag::Type => return Ok(None), ty::AssocTag::Const => { // We also gate the mgca codepath for type-level uses of inherent consts @@ -1520,9 +1517,18 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { }) .collect(); + // At the moment, we actually bail out with a hard error if the selection of an inherent + // associated item fails (see below). This means we never consider trait associated items + // as potential fallback candidates (#142006). To temporarily mask that issue, let's not + // select at all if there are no early inherent candidates. + if candidates.is_empty() { + return Ok(None); + } + let (applicable_candidates, fulfillment_errors) = self.select_inherent_assoc_candidates(span, self_ty, candidates.clone()); + // FIXME(#142006): Don't eagerly error here, there might be applicable trait candidates. let InherentAssocCandidate { impl_, assoc_item, scope: def_scope } = match &applicable_candidates[..] { &[] => Err(self.report_unresolved_inherent_assoc_item( @@ -1543,6 +1549,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { )), }?; + // FIXME(#142006): Don't eagerly validate here, there might be trait candidates that are + // accessible (visible and stable) contrary to the inherent candidate. self.check_assoc_item(assoc_item, name, def_scope, block, span); // FIXME(fmease): Currently creating throwaway `parent_args` to please diff --git a/compiler/rustc_hir_analysis/src/variance/terms.rs b/compiler/rustc_hir_analysis/src/variance/terms.rs index cf38957bf24a..9c7680b92120 100644 --- a/compiler/rustc_hir_analysis/src/variance/terms.rs +++ b/compiler/rustc_hir_analysis/src/variance/terms.rs @@ -44,7 +44,7 @@ impl<'a> fmt::Debug for VarianceTerm<'a> { } } -/// The first pass over the crate simply builds up the set of inferreds. +// The first pass over the crate simply builds up the set of inferreds. pub(crate) struct TermsContext<'a, 'tcx> { pub tcx: TyCtxt<'tcx>, diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 2ff651df0d3d..308e604deb40 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -2028,9 +2028,15 @@ impl<'a> State<'a> { self.print_pat(inner); self.pclose(); } - PatKind::Ref(inner, mutbl) => { + PatKind::Ref(inner, pinned, mutbl) => { let is_range_inner = matches!(inner.kind, PatKind::Range(..)); self.word("&"); + if pinned.is_pinned() { + self.word("pin "); + if mutbl.is_not() { + self.word("const "); + } + } self.word(mutbl.prefix_str()); if is_range_inner { self.popen(); diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index e533ee78cc82..d7df23f92f05 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -523,7 +523,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { | hir::PatKind::TupleStruct(_, _, _) | hir::PatKind::Tuple(_, _) | hir::PatKind::Box(_) - | hir::PatKind::Ref(_, _) + | hir::PatKind::Ref(_, _, _) | hir::PatKind::Deref(_) | hir::PatKind::Expr(_) | hir::PatKind::Range(_, _, _) diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs index b9f1463d8007..561230c193ce 100644 --- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs @@ -1231,7 +1231,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx debug!("pat_ty(pat={:?}) found adjustment `{:?}`", pat, first_adjust); return Ok(first_adjust.source); } - } else if let PatKind::Ref(subpat, _) = pat.kind + } else if let PatKind::Ref(subpat, _, _) = pat.kind && self.cx.typeck_results().skipped_ref_pats().contains(pat.hir_id) { return self.pat_ty_adjusted(subpat); @@ -1817,13 +1817,13 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx self.cat_pattern(place_with_id, subpat, op)?; } - PatKind::Ref(subpat, _) + PatKind::Ref(subpat, _, _) if self.cx.typeck_results().skipped_ref_pats().contains(pat.hir_id) => { self.cat_pattern(place_with_id, subpat, op)?; } - PatKind::Box(subpat) | PatKind::Ref(subpat, _) => { + PatKind::Box(subpat) | PatKind::Ref(subpat, _, _) => { // box p1, &p1, &mut p1. we can ignore the mutability of // PatKind::Ref since that information is already contained // in the type. diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 38586c844445..da719e615fd7 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -40,7 +40,7 @@ use tracing::{debug, instrument}; use crate::callee::{self, DeferredCallResolution}; use crate::errors::{self, CtorIsPrivate}; use crate::method::{self, MethodCallee}; -use crate::{BreakableCtxt, Diverges, Expectation, FnCtxt, LoweredTy, rvalue_scopes}; +use crate::{BreakableCtxt, Diverges, Expectation, FnCtxt, LoweredTy}; impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// Produces warning on the given node, if the current point in the @@ -604,13 +604,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.normalize(span, field.ty(self.tcx, args)) } - pub(crate) fn resolve_rvalue_scopes(&self, def_id: DefId) { - let scope_tree = self.tcx.region_scope_tree(def_id); - let rvalue_scopes = { rvalue_scopes::resolve_rvalue_scopes(self, scope_tree, def_id) }; - let mut typeck_results = self.typeck_results.borrow_mut(); - typeck_results.rvalue_scopes = rvalue_scopes; - } - /// Drain all obligations that are stalled on coroutines defined in this body. #[instrument(level = "debug", skip(self))] pub(crate) fn drain_stalled_coroutine_obligations(&self) { diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index b4264e999331..d090eb633828 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -37,7 +37,6 @@ mod op; mod opaque_types; mod pat; mod place_op; -mod rvalue_scopes; mod typeck_root_ctxt; mod upvar; mod writeback; @@ -237,9 +236,6 @@ fn typeck_with_inspect<'tcx>( // because they don't constrain other type variables. fcx.closure_analyze(body); assert!(fcx.deferred_call_resolutions.borrow().is_empty()); - // Before the coroutine analysis, temporary scopes shall be marked to provide more - // precise information on types to be captured. - fcx.resolve_rvalue_scopes(def_id.to_def_id()); for (ty, span, code) in fcx.deferred_sized_obligations.borrow_mut().drain(..) { let ty = fcx.normalize(span, ty); diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 7d6982cb024c..6beaac9d3828 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -1079,6 +1079,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } self.note_derefed_ty_has_method(&mut err, source, rcvr_ty, item_ident, expected); + self.suggest_bounds_for_range_to_method(&mut err, source, item_ident); err.emit() } @@ -2610,7 +2611,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let mut current_node = parent_node; while let Node::Pat(parent_pat) = current_node { - if let hir::PatKind::Ref(_, mutability) = parent_pat.kind { + if let hir::PatKind::Ref(_, _, mutability) = parent_pat.kind { ref_muts.push(mutability); current_node = self.tcx.parent_hir_node(parent_pat.hir_id); } else { @@ -3260,6 +3261,71 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } + fn suggest_bounds_for_range_to_method( + &self, + err: &mut Diag<'_>, + source: SelfSource<'tcx>, + item_ident: Ident, + ) { + let SelfSource::MethodCall(rcvr_expr) = source else { return }; + let hir::ExprKind::Struct(qpath, fields, _) = rcvr_expr.kind else { return }; + let Some(lang_item) = self.tcx.qpath_lang_item(*qpath) else { + return; + }; + let is_inclusive = match lang_item { + hir::LangItem::RangeTo => false, + hir::LangItem::RangeToInclusive | hir::LangItem::RangeInclusiveCopy => true, + _ => return, + }; + + let Some(iterator_trait) = self.tcx.get_diagnostic_item(sym::Iterator) else { return }; + let Some(_) = self + .tcx + .associated_items(iterator_trait) + .filter_by_name_unhygienic(item_ident.name) + .next() + else { + return; + }; + + let source_map = self.tcx.sess.source_map(); + let range_type = if is_inclusive { "RangeInclusive" } else { "Range" }; + let Some(end_field) = fields.iter().find(|f| f.ident.name == rustc_span::sym::end) else { + return; + }; + + let element_ty = self.typeck_results.borrow().expr_ty_opt(end_field.expr); + let is_integral = element_ty.is_some_and(|ty| ty.is_integral()); + let end_is_negative = is_integral + && matches!(end_field.expr.kind, hir::ExprKind::Unary(rustc_ast::UnOp::Neg, _)); + + let Ok(snippet) = source_map.span_to_snippet(rcvr_expr.span) else { return }; + + let offset = snippet + .chars() + .take_while(|&c| c == '(' || c.is_whitespace()) + .map(|c| c.len_utf8()) + .sum::(); + + let insert_span = rcvr_expr + .span + .with_lo(rcvr_expr.span.lo() + rustc_span::BytePos(offset as u32)) + .shrink_to_lo(); + + let (value, appl) = if is_integral && !end_is_negative { + ("0", Applicability::MachineApplicable) + } else { + ("/* start */", Applicability::HasPlaceholders) + }; + + err.span_suggestion_verbose( + insert_span, + format!("consider using a bounded `{range_type}` by adding a concrete starting value"), + value, + appl, + ); + } + /// Print out the type for use in value namespace. fn ty_to_value_string(&self, ty: Ty<'tcx>) -> String { match ty.kind() { @@ -4212,7 +4278,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err: &mut Diag<'_>, item_def_id: DefId, hir_id: hir::HirId, - rcvr_ty: Option>, + rcvr_ty: Option>, ) -> bool { let hir_id = self.tcx.parent_hir_id(hir_id); let Some(traits) = self.tcx.in_scope_traits(hir_id) else { return false }; @@ -4223,49 +4289,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if !self.tcx.is_trait(trait_def_id) { return false; } - let krate = self.tcx.crate_name(trait_def_id.krate); - let name = self.tcx.item_name(trait_def_id); - let candidates: Vec<_> = traits - .iter() - .filter(|c| { - c.def_id.krate != trait_def_id.krate - && self.tcx.crate_name(c.def_id.krate) == krate - && self.tcx.item_name(c.def_id) == name - }) - .map(|c| (c.def_id, c.import_ids.get(0).cloned())) - .collect(); - if candidates.is_empty() { + let hir::Node::Expr(rcvr) = self.tcx.hir_node(hir_id) else { return false; - } - let item_span = self.tcx.def_span(item_def_id); - let msg = format!( - "there are multiple different versions of crate `{krate}` in the dependency graph", - ); - let trait_span = self.tcx.def_span(trait_def_id); - let mut multi_span: MultiSpan = trait_span.into(); - multi_span.push_span_label(trait_span, "this is the trait that is needed".to_string()); - let descr = self.tcx.associated_item(item_def_id).descr(); - let rcvr_ty = - rcvr_ty.map(|t| format!("`{t}`")).unwrap_or_else(|| "the receiver".to_string()); - multi_span - .push_span_label(item_span, format!("the {descr} is available for {rcvr_ty} here")); - for (def_id, import_def_id) in candidates { - if let Some(import_def_id) = import_def_id { - multi_span.push_span_label( - self.tcx.def_span(import_def_id), - format!( - "`{name}` imported here doesn't correspond to the right version of crate \ - `{krate}`", - ), - ); - } - multi_span.push_span_label( - self.tcx.def_span(def_id), - "this is the trait that was imported".to_string(), - ); - } - err.span_note(multi_span, msg); - true + }; + let trait_ref = ty::TraitRef::new(self.tcx, trait_def_id, rcvr_ty.into_iter()); + let trait_pred = ty::Binder::dummy(ty::TraitPredicate { + trait_ref, + polarity: ty::PredicatePolarity::Positive, + }); + let obligation = Obligation::new(self.tcx, self.misc(rcvr.span), self.param_env, trait_ref); + self.err_ctxt().note_different_trait_with_same_name(err, &obligation, trait_pred) } /// issue #102320, for `unwrap_or` with closure as argument, suggest `unwrap_or_else` diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 88f6077c2ef5..0e9ff962435f 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -91,6 +91,7 @@ struct TopInfo<'tcx> { #[derive(Copy, Clone)] struct PatInfo<'tcx> { binding_mode: ByRef, + max_pinnedness: PinnednessCap, max_ref_mutbl: MutblCap, top_info: TopInfo<'tcx>, decl_origin: Option>, @@ -241,6 +242,19 @@ impl MutblCap { } } +/// `ref` or `ref mut` bindings (not pinned, explicitly or match-ergonomics) are only allowed behind +/// an `&pin` reference if the binding's type is `Unpin`. +/// +/// Normally, the borrow checker enforces this (not implemented yet), but we track it here for better +/// diagnostics. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +enum PinnednessCap { + /// No restriction on pinnedness. + Not, + /// Pinnedness restricted to pinned. + Pinned, +} + /// Variations on RFC 3627's Rule 4: when do reference patterns match against inherited references? /// /// "Inherited reference" designates the `&`/`&mut` types that arise from using match ergonomics, i.e. @@ -374,6 +388,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let top_info = TopInfo { expected, origin_expr, span, hir_id: pat.hir_id }; let pat_info = PatInfo { binding_mode: ByRef::No, + max_pinnedness: PinnednessCap::Not, max_ref_mutbl: MutblCap::Mut, top_info, decl_origin, @@ -489,22 +504,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let old_pat_info = pat_info; let pat_info = PatInfo { current_depth: old_pat_info.current_depth + 1, ..old_pat_info }; - let adjust_binding_mode = |inner_pinnedness, inner_mutability| { - match pat_info.binding_mode { - // If default binding mode is by value, make it `ref`, `ref mut`, `ref pin const` - // or `ref pin mut` (depending on whether we observe `&`, `&mut`, `&pin const` or - // `&pin mut`). - ByRef::No => ByRef::Yes(inner_pinnedness, inner_mutability), - // When `ref mut`, stay a `ref mut` (on `&mut`) or downgrade to `ref` (on `&`). - // Pinnedness is preserved. - ByRef::Yes(pinnedness, Mutability::Mut) => ByRef::Yes(pinnedness, inner_mutability), - // Once a `ref`, always a `ref`. - // This is because a `& &mut` cannot mutate the underlying value. - // Pinnedness is preserved. - ByRef::Yes(pinnedness, Mutability::Not) => ByRef::Yes(pinnedness, Mutability::Not), - } - }; - match pat.kind { // Peel off a `&` or `&mut`from the scrutinee type. See the examples in // `tests/ui/rfcs/rfc-2005-default-binding-mode`. @@ -524,19 +523,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .or_default() .push(PatAdjustment { kind: PatAdjust::BuiltinDeref, source: expected }); - let mut binding_mode = adjust_binding_mode(Pinnedness::Not, inner_mutability); - - let mut max_ref_mutbl = pat_info.max_ref_mutbl; - if self.downgrade_mut_inside_shared() { - binding_mode = binding_mode.cap_ref_mutability(max_ref_mutbl.as_mutbl()); - } - if matches!(binding_mode, ByRef::Yes(_, Mutability::Not)) { - max_ref_mutbl = MutblCap::Not; - } - debug!("default binding mode is now {:?}", binding_mode); - // Use the old pat info to keep `current_depth` to its old value. - let new_pat_info = PatInfo { binding_mode, max_ref_mutbl, ..old_pat_info }; + let new_pat_info = + self.adjust_pat_info(Pinnedness::Not, inner_mutability, old_pat_info); + // Recurse with the new expected type. self.check_pat_inner(pat, opt_path_res, adjust_mode, inner_ty, new_pat_info) } @@ -569,20 +559,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }); } - let binding_mode = adjust_binding_mode(Pinnedness::Pinned, inner_mutability); - // If the pinnedness is `Not`, it means the pattern is unpinned - // and thus requires an `Unpin` bound. - if matches!(binding_mode, ByRef::Yes(Pinnedness::Not, _)) { - self.register_bound( - inner_ty, - self.tcx.require_lang_item(hir::LangItem::Unpin, pat.span), - self.misc(pat.span), - ) - } - debug!("default binding mode is now {:?}", binding_mode); - // Use the old pat info to keep `current_depth` to its old value. - let new_pat_info = PatInfo { binding_mode, ..old_pat_info }; + let new_pat_info = + self.adjust_pat_info(Pinnedness::Pinned, inner_mutability, old_pat_info); self.check_deref_pattern( pat, @@ -689,13 +668,62 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } PatKind::Box(inner) => self.check_pat_box(pat.span, inner, expected, pat_info), PatKind::Deref(inner) => self.check_pat_deref(pat.span, inner, expected, pat_info), - PatKind::Ref(inner, mutbl) => self.check_pat_ref(pat, inner, mutbl, expected, pat_info), + PatKind::Ref(inner, pinned, mutbl) => { + self.check_pat_ref(pat, inner, pinned, mutbl, expected, pat_info) + } PatKind::Slice(before, slice, after) => { self.check_pat_slice(pat.span, before, slice, after, expected, pat_info) } } } + fn adjust_pat_info( + &self, + inner_pinnedness: Pinnedness, + inner_mutability: Mutability, + pat_info: PatInfo<'tcx>, + ) -> PatInfo<'tcx> { + let mut binding_mode = match pat_info.binding_mode { + // If default binding mode is by value, make it `ref`, `ref mut`, `ref pin const` + // or `ref pin mut` (depending on whether we observe `&`, `&mut`, `&pin const` or + // `&pin mut`). + ByRef::No => ByRef::Yes(inner_pinnedness, inner_mutability), + ByRef::Yes(pinnedness, mutability) => { + let pinnedness = match pinnedness { + // When `ref`, stay a `ref` (on `&`) or downgrade to `ref pin` (on `&pin`). + Pinnedness::Not => inner_pinnedness, + // When `ref pin`, stay a `ref pin`. + // This is because we cannot get an `&mut T` from `&mut &pin mut T` unless `T: Unpin`. + // Note that `&T` and `&mut T` are `Unpin`, which implies + // `& &pin const T` <-> `&pin const &T` and `&mut &pin mut T` <-> `&pin mut &mut T` + // (i.e. mutually coercible). + Pinnedness::Pinned => Pinnedness::Pinned, + }; + + let mutability = match mutability { + // When `ref mut`, stay a `ref mut` (on `&mut`) or downgrade to `ref` (on `&`). + Mutability::Mut => inner_mutability, + // Once a `ref`, always a `ref`. + // This is because a `& &mut` cannot mutate the underlying value. + Mutability::Not => Mutability::Not, + }; + ByRef::Yes(pinnedness, mutability) + } + }; + + let PatInfo { mut max_ref_mutbl, mut max_pinnedness, .. } = pat_info; + if self.downgrade_mut_inside_shared() { + binding_mode = binding_mode.cap_ref_mutability(max_ref_mutbl.as_mutbl()); + } + match binding_mode { + ByRef::Yes(_, Mutability::Not) => max_ref_mutbl = MutblCap::Not, + ByRef::Yes(Pinnedness::Pinned, _) => max_pinnedness = PinnednessCap::Pinned, + _ => {} + } + debug!("default binding mode is now {:?}", binding_mode); + PatInfo { binding_mode, max_pinnedness, max_ref_mutbl, ..pat_info } + } + fn check_deref_pattern( &self, pat: &'tcx Pat<'tcx>, @@ -1195,6 +1223,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } }; + // If there exists a pinned reference in the pattern but the binding is not pinned, + // it means the binding is unpinned and thus requires an `Unpin` bound. + if pat_info.max_pinnedness == PinnednessCap::Pinned + && matches!(bm.0, ByRef::Yes(Pinnedness::Not, _)) + { + self.register_bound( + expected, + self.tcx.require_lang_item(hir::LangItem::Unpin, pat.span), + self.misc(pat.span), + ) + } + if matches!(bm.0, ByRef::Yes(_, Mutability::Mut)) && let MutblCap::WeaklyNot(and_pat_span) = pat_info.max_ref_mutbl { @@ -1223,22 +1263,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let local_ty = self.local_ty(pat.span, pat.hir_id); let eq_ty = match bm.0 { - ByRef::Yes(Pinnedness::Not, mutbl) => { + ByRef::Yes(pinnedness, mutbl) => { // If the binding is like `ref x | ref mut x`, // then `x` is assigned a value of type `&M T` where M is the // mutability and T is the expected type. // + // Under pin ergonomics, if the binding is like `ref pin const|mut x`, + // then `x` is assigned a value of type `&pin M T` where M is the + // mutability and T is the expected type. + // // `x` is assigned a value of type `&M T`, hence `&M T <: typeof(x)` // is required. However, we use equality, which is stronger. // See (note_1) for an explanation. - self.new_ref_ty(pat.span, mutbl, expected) + self.new_ref_ty(pat.span, pinnedness, mutbl, expected) } - // Wrapping the type into `Pin` if the binding is like `ref pin const|mut x` - ByRef::Yes(Pinnedness::Pinned, mutbl) => Ty::new_adt( - self.tcx, - self.tcx.adt_def(self.tcx.require_lang_item(hir::LangItem::Pin, pat.span)), - self.tcx.mk_args(&[self.new_ref_ty(pat.span, mutbl, expected).into()]), - ), // Otherwise, the type of x is the expected type `T`. ByRef::No => expected, // As above, `T <: typeof(x)` is required, but we use equality, see (note_1). }; @@ -1331,18 +1369,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } /// Precondition: pat is a `Ref(_)` pattern + // FIXME(pin_ergonomics): add suggestions for `&pin mut` or `&pin const` patterns fn borrow_pat_suggestion(&self, err: &mut Diag<'_>, pat: &Pat<'_>) { let tcx = self.tcx; - if let PatKind::Ref(inner, mutbl) = pat.kind + if let PatKind::Ref(inner, pinned, mutbl) = pat.kind && let PatKind::Binding(_, _, binding, ..) = inner.kind { let binding_parent = tcx.parent_hir_node(pat.hir_id); debug!(?inner, ?pat, ?binding_parent); - let mutability = match mutbl { - ast::Mutability::Mut => "mut", - ast::Mutability::Not => "", - }; + let pin_and_mut = pinned.prefix_str(mutbl).trim_end(); let mut_var_suggestion = 'block: { if mutbl.is_not() { @@ -1392,7 +1428,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // so we don't suggest moving something to the type that does not exist hir::Node::Param(hir::Param { ty_span, pat, .. }) if pat.span != *ty_span => { err.multipart_suggestion_verbose( - format!("to take parameter `{binding}` by reference, move `&{mutability}` to the type"), + format!("to take parameter `{binding}` by reference, move `&{pin_and_mut}` to the type"), vec![ (pat.span.until(inner.span), "".to_owned()), (ty_span.shrink_to_lo(), mutbl.ref_prefix_str().to_owned()), @@ -1406,13 +1442,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } hir::Node::Pat(pt) if let PatKind::TupleStruct(_, pat_arr, _) = pt.kind => { for i in pat_arr.iter() { - if let PatKind::Ref(the_ref, _) = i.kind + if let PatKind::Ref(the_ref, _, _) = i.kind && let PatKind::Binding(mt, _, ident, _) = the_ref.kind { let BindingMode(_, mtblty) = mt; err.span_suggestion_verbose( i.span, - format!("consider removing `&{mutability}` from the pattern"), + format!("consider removing `&{pin_and_mut}` from the pattern"), mtblty.prefix_str().to_string() + &ident.name.to_string(), Applicability::MaybeIncorrect, ); @@ -1426,7 +1462,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // rely on match ergonomics or it might be nested `&&pat` err.span_suggestion_verbose( pat.span.until(inner.span), - format!("consider removing `&{mutability}` from the pattern"), + format!("consider removing `&{pin_and_mut}` from the pattern"), "", Applicability::MaybeIncorrect, ); @@ -2677,6 +2713,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { &self, pat: &'tcx Pat<'tcx>, inner: &'tcx Pat<'tcx>, + pat_pinned: Pinnedness, pat_mutbl: Mutability, mut expected: Ty<'tcx>, mut pat_info: PatInfo<'tcx>, @@ -2699,9 +2736,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Determine whether we're consuming an inherited reference and resetting the default // binding mode, based on edition and enabled experimental features. if let ByRef::Yes(inh_pin, inh_mut) = pat_info.binding_mode - // FIXME(pin_ergonomics): since `&pin` pattern is supported, the condition here - // should be adjusted to `pat_pin == inh_pin` - && (!self.tcx.features().pin_ergonomics() || inh_pin == Pinnedness::Not) + && pat_pinned == inh_pin { match self.ref_pat_matches_inherited_ref(pat.span.edition()) { InheritedRefMatchRule::EatOuter => { @@ -2821,21 +2856,24 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // to avoid creating needless variables. This also helps with // the bad interactions of the given hack detailed in (note_1). debug!("check_pat_ref: expected={:?}", expected); - match *expected.kind() { - ty::Ref(_, r_ty, r_mutbl) - if (ref_pat_matches_mut_ref && r_mutbl >= pat_mutbl) - || r_mutbl == pat_mutbl => + match expected.maybe_pinned_ref() { + Some((r_ty, r_pinned, r_mutbl)) + if ((ref_pat_matches_mut_ref && r_mutbl >= pat_mutbl) + || r_mutbl == pat_mutbl) + && pat_pinned == r_pinned => { if r_mutbl == Mutability::Not { pat_info.max_ref_mutbl = MutblCap::Not; } + if r_pinned == Pinnedness::Pinned { + pat_info.max_pinnedness = PinnednessCap::Pinned; + } (expected, r_ty) } - _ => { let inner_ty = self.next_ty_var(inner.span); - let ref_ty = self.new_ref_ty(pat.span, pat_mutbl, inner_ty); + let ref_ty = self.new_ref_ty(pat.span, pat_pinned, pat_mutbl, inner_ty); debug!("check_pat_ref: demanding {:?} = {:?}", expected, ref_ty); let err = self.demand_eqtype_pat_diag( pat.span, @@ -2864,10 +2902,29 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ref_ty } - /// Create a reference type with a fresh region variable. - fn new_ref_ty(&self, span: Span, mutbl: Mutability, ty: Ty<'tcx>) -> Ty<'tcx> { + /// Create a reference or pinned reference type with a fresh region variable. + fn new_ref_ty( + &self, + span: Span, + pinnedness: Pinnedness, + mutbl: Mutability, + ty: Ty<'tcx>, + ) -> Ty<'tcx> { let region = self.next_region_var(RegionVariableOrigin::PatternRegion(span)); - Ty::new_ref(self.tcx, region, ty, mutbl) + let ref_ty = Ty::new_ref(self.tcx, region, ty, mutbl); + if pinnedness.is_pinned() { + return self.new_pinned_ty(span, ref_ty); + } + ref_ty + } + + /// Create a pinned type. + fn new_pinned_ty(&self, span: Span, ty: Ty<'tcx>) -> Ty<'tcx> { + Ty::new_adt( + self.tcx, + self.tcx.adt_def(self.tcx.require_lang_item(LangItem::Pin, span)), + self.tcx.mk_args(&[ty.into()]), + ) } fn error_inherited_ref_mutability_mismatch( diff --git a/compiler/rustc_hir_typeck/src/rvalue_scopes.rs b/compiler/rustc_hir_typeck/src/rvalue_scopes.rs deleted file mode 100644 index 973dc7141e64..000000000000 --- a/compiler/rustc_hir_typeck/src/rvalue_scopes.rs +++ /dev/null @@ -1,79 +0,0 @@ -use hir::Node; -use hir::def_id::DefId; -use rustc_hir as hir; -use rustc_middle::bug; -use rustc_middle::middle::region::{RvalueCandidate, Scope, ScopeTree}; -use rustc_middle::ty::RvalueScopes; -use tracing::debug; - -use super::FnCtxt; - -/// Applied to an expression `expr` if `expr` -- or something owned or partially owned by -/// `expr` -- is going to be indirectly referenced by a variable in a let statement. In that -/// case, the "temporary lifetime" or `expr` is extended to be the block enclosing the `let` -/// statement. -/// -/// More formally, if `expr` matches the grammar `ET`, record the rvalue scope of the matching -/// `` as `blk_id`: -/// -/// ```text -/// ET = *ET -/// | ET[...] -/// | ET.f -/// | (ET) -/// | -/// ``` -/// -/// Note: ET is intended to match "rvalues or places based on rvalues". -fn record_rvalue_scope_rec( - rvalue_scopes: &mut RvalueScopes, - mut expr: &hir::Expr<'_>, - lifetime: Option, -) { - loop { - // Note: give all the expressions matching `ET` with the - // extended temporary lifetime, not just the innermost rvalue, - // because in codegen if we must compile e.g., `*rvalue()` - // into a temporary, we request the temporary scope of the - // outer expression. - - rvalue_scopes.record_rvalue_scope(expr.hir_id.local_id, lifetime); - - match expr.kind { - hir::ExprKind::AddrOf(_, _, subexpr) - | hir::ExprKind::Unary(hir::UnOp::Deref, subexpr) - | hir::ExprKind::Field(subexpr, _) - | hir::ExprKind::Index(subexpr, _, _) => { - expr = subexpr; - } - _ => { - return; - } - } - } -} -fn record_rvalue_scope( - rvalue_scopes: &mut RvalueScopes, - expr: &hir::Expr<'_>, - candidate: &RvalueCandidate, -) { - debug!("resolve_rvalue_scope(expr={expr:?}, candidate={candidate:?})"); - record_rvalue_scope_rec(rvalue_scopes, expr, candidate.lifetime) - // FIXME(@dingxiangfei2009): handle the candidates in the function call arguments -} - -pub(crate) fn resolve_rvalue_scopes<'a, 'tcx>( - fcx: &'a FnCtxt<'a, 'tcx>, - scope_tree: &'a ScopeTree, - def_id: DefId, -) -> RvalueScopes { - let tcx = &fcx.tcx; - let mut rvalue_scopes = RvalueScopes::new(); - debug!("start resolving rvalue scopes, def_id={def_id:?}"); - debug!("rvalue_scope: rvalue_candidates={:?}", scope_tree.rvalue_candidates); - for (&hir_id, candidate) in &scope_tree.rvalue_candidates { - let Node::Expr(expr) = tcx.hir_node(hir_id) else { bug!("hir node does not exist") }; - record_rvalue_scope(&mut rvalue_scopes, expr, candidate); - } - rvalue_scopes -} diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs index 3235aa396df4..ec4e7cd6c82a 100644 --- a/compiler/rustc_hir_typeck/src/writeback.rs +++ b/compiler/rustc_hir_typeck/src/writeback.rs @@ -79,9 +79,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { wbcx.visit_offset_of_container_types(); wbcx.visit_potentially_region_dependent_goals(); - wbcx.typeck_results.rvalue_scopes = - mem::take(&mut self.typeck_results.borrow_mut().rvalue_scopes); - let used_trait_imports = mem::take(&mut self.typeck_results.borrow_mut().used_trait_imports); debug!("used_trait_imports({:?}) = {:?}", item_def_id, used_trait_imports); diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index 8aa90c070acd..c996181354b9 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -265,6 +265,9 @@ lint_forgetting_copy_types = calls to `std::mem::forget` with a value that imple lint_forgetting_references = calls to `std::mem::forget` with a reference instead of an owned value does nothing .label = argument has type `{$arg_ty}` +lint_function_casts_as_integer = direct cast of function item into an integer + .cast_as_fn = first cast to a pointer `as *const ()` + lint_hidden_glob_reexport = private item shadows public glob re-export .note_glob_reexport = the name `{$name}` in the {$namespace} namespace is supposed to be publicly re-exported here .note_private_item = but the private item here shadows it diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 83de7d389231..4e9ecb9006ab 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -1705,7 +1705,7 @@ impl EarlyLintPass for EllipsisInclusiveRangePatterns { } let (parentheses, endpoints) = match &pat.kind { - PatKind::Ref(subpat, _) => (true, matches_ellipsis_pat(subpat)), + PatKind::Ref(subpat, _, _) => (true, matches_ellipsis_pat(subpat)), _ => (false, matches_ellipsis_pat(pat)), }; diff --git a/compiler/rustc_lint/src/early.rs b/compiler/rustc_lint/src/early.rs index dff1fc436702..6cb5aea79840 100644 --- a/compiler/rustc_lint/src/early.rs +++ b/compiler/rustc_lint/src/early.rs @@ -5,7 +5,7 @@ //! syntactical lints. use rustc_ast::visit::{self as ast_visit, Visitor, walk_list}; -use rustc_ast::{self as ast, HasAttrs}; +use rustc_ast::{self as ast, AttrVec, HasAttrs}; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_errors::{BufferedEarlyLint, DecorateDiagCompat, LintBuffer}; use rustc_feature::Features; @@ -135,7 +135,7 @@ impl<'ast, 'ecx, 'tcx, T: EarlyLintPass> ast_visit::Visitor<'ast> }); } - fn visit_fn(&mut self, fk: ast_visit::FnKind<'ast>, span: Span, id: ast::NodeId) { + fn visit_fn(&mut self, fk: ast_visit::FnKind<'ast>, _: &AttrVec, span: Span, id: ast::NodeId) { lint_callback!(self, check_fn, fk, span, id); ast_visit::walk_fn(self, fk); } diff --git a/compiler/rustc_lint/src/function_cast_as_integer.rs b/compiler/rustc_lint/src/function_cast_as_integer.rs new file mode 100644 index 000000000000..2a4ff1f63db5 --- /dev/null +++ b/compiler/rustc_lint/src/function_cast_as_integer.rs @@ -0,0 +1,63 @@ +use rustc_hir as hir; +use rustc_middle::ty; +use rustc_session::{declare_lint, declare_lint_pass}; +use rustc_span::BytePos; + +use crate::lints::{FunctionCastsAsIntegerDiag, FunctionCastsAsIntegerSugg}; +use crate::{LateContext, LateLintPass}; + +declare_lint! { + /// The `function_casts_as_integer` lint detects cases where a function item is cast + /// to an integer. + /// + /// ### Example + /// + /// ```rust + /// fn foo() {} + /// let x = foo as usize; + /// ``` + /// + /// {{produces}} + /// + /// ### Explanation + /// + /// When casting a function item to an integer, it implicitly creates a + /// function pointer that will in turn be cast to an integer. By making + /// it explicit, it improves readability of the code and prevents bugs. + pub FUNCTION_CASTS_AS_INTEGER, + Warn, + "casting a function into an integer", +} + +declare_lint_pass!( + /// Lint for casts of functions into integers. + FunctionCastsAsInteger => [FUNCTION_CASTS_AS_INTEGER] +); + +impl<'tcx> LateLintPass<'tcx> for FunctionCastsAsInteger { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>) { + let hir::ExprKind::Cast(cast_from_expr, cast_to_expr) = expr.kind else { return }; + let cast_to_ty = cx.typeck_results().expr_ty(expr); + // Casting to a function (pointer?), so all good. + // + // Normally, only casts to integers is possible, but if it ever changed, this condition + // will likely need to be updated. + if matches!(cast_to_ty.kind(), ty::FnDef(..) | ty::FnPtr(..) | ty::RawPtr(..)) { + return; + } + let cast_from_ty = cx.typeck_results().expr_ty(cast_from_expr); + if matches!(cast_from_ty.kind(), ty::FnDef(..)) { + cx.tcx.emit_node_span_lint( + FUNCTION_CASTS_AS_INTEGER, + expr.hir_id, + cast_to_expr.span.with_lo(cast_from_expr.span.hi() + BytePos(1)), + FunctionCastsAsIntegerDiag { + sugg: FunctionCastsAsIntegerSugg { + suggestion: cast_from_expr.span.shrink_to_hi(), + cast_to_ty, + }, + }, + ); + } + } +} diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index 8a83434e10c1..7c3a81e89130 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -45,6 +45,7 @@ mod errors; mod expect; mod for_loops_over_fallibles; mod foreign_modules; +mod function_cast_as_integer; mod if_let_rescope; mod impl_trait_overcaptures; mod internal; @@ -89,6 +90,7 @@ use deref_into_dyn_supertrait::*; use drop_forget_useless::*; use enum_intrinsics_non_enums::EnumIntrinsicsNonEnums; use for_loops_over_fallibles::*; +use function_cast_as_integer::*; use if_let_rescope::IfLetRescope; use impl_trait_overcaptures::ImplTraitOvercaptures; use internal::*; @@ -241,6 +243,7 @@ late_lint_methods!( IfLetRescope: IfLetRescope::default(), StaticMutRefs: StaticMutRefs, UnqualifiedLocalImports: UnqualifiedLocalImports, + FunctionCastsAsInteger: FunctionCastsAsInteger, CheckTransmutes: CheckTransmutes, LifetimeSyntax: LifetimeSyntax, ] diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index c55f2b9dd6f2..dc50f61f741d 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -3019,6 +3019,26 @@ pub(crate) struct ReservedMultihash { pub suggestion: Span, } +#[derive(LintDiagnostic)] +#[diag(lint_function_casts_as_integer)] +pub(crate) struct FunctionCastsAsIntegerDiag<'tcx> { + #[subdiagnostic] + pub(crate) sugg: FunctionCastsAsIntegerSugg<'tcx>, +} + +#[derive(Subdiagnostic)] +#[suggestion( + lint_cast_as_fn, + code = " as *const ()", + applicability = "machine-applicable", + style = "verbose" +)] +pub(crate) struct FunctionCastsAsIntegerSugg<'tcx> { + #[primary_span] + pub suggestion: Span, + pub cast_to_ty: Ty<'tcx>, +} + #[derive(Debug)] pub(crate) struct MismatchedLifetimeSyntaxes { pub inputs: LifetimeSyntaxCategories>, diff --git a/compiler/rustc_lint/src/passes.rs b/compiler/rustc_lint/src/passes.rs index 191eb721b347..ae145543e70d 100644 --- a/compiler/rustc_lint/src/passes.rs +++ b/compiler/rustc_lint/src/passes.rs @@ -55,10 +55,10 @@ macro_rules! late_lint_methods { /// Each `check` method checks a single syntax node, and should not /// invoke methods recursively (unlike `Visitor`). By default they /// do nothing. -// +/// // FIXME: eliminate the duplication with `Visitor`. But this also // contains a few lint-specific methods with no equivalent in `Visitor`. - +// macro_rules! declare_late_lint_pass { ([], [$($(#[$attr:meta])* fn $name:ident($($param:ident: $arg:ty),*);)*]) => ( pub trait LateLintPass<'tcx>: LintPass { diff --git a/compiler/rustc_lint/src/types/improper_ctypes.rs b/compiler/rustc_lint/src/types/improper_ctypes.rs index 2c8839708669..9e38ea6b685b 100644 --- a/compiler/rustc_lint/src/types/improper_ctypes.rs +++ b/compiler/rustc_lint/src/types/improper_ctypes.rs @@ -16,6 +16,7 @@ use rustc_middle::ty::{ use rustc_session::{declare_lint, declare_lint_pass}; use rustc_span::def_id::LocalDefId; use rustc_span::{Span, sym}; +use rustc_target::spec::Os; use tracing::debug; use super::repr_nullable_ptr; @@ -177,7 +178,7 @@ fn variant_has_complex_ctor(variant: &ty::VariantDef) -> bool { /// the Power alignment Rule (see the `check_struct_for_power_alignment` function). fn check_arg_for_power_alignment<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool { let tcx = cx.tcx; - assert!(tcx.sess.target.os == "aix"); + assert!(tcx.sess.target.os == Os::Aix); // Structs (under repr(C)) follow the power alignment rule if: // - the first field of the struct is a floating-point type that // is greater than 4-bytes, or @@ -222,7 +223,7 @@ fn check_struct_for_power_alignment<'tcx>( let tcx = cx.tcx; // Only consider structs (not enums or unions) on AIX. - if tcx.sess.target.os != "aix" || !adt_def.is_struct() { + if tcx.sess.target.os != Os::Aix || !adt_def.is_struct() { return; } diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs index 40df5ecb0f3c..4842615409f3 100644 --- a/compiler/rustc_lint/src/unused.rs +++ b/compiler/rustc_lint/src/unused.rs @@ -1307,7 +1307,8 @@ impl EarlyLintPass for UnusedParens { Ident(.., Some(p)) | Box(p) | Deref(p) | Guard(p, _) => self.check_unused_parens_pat(cx, p, true, false, keep_space), // Avoid linting on `&(mut x)` as `&mut x` has a different meaning, #55342. // Also avoid linting on `& mut? (p0 | .. | pn)`, #64106. - Ref(p, m) => self.check_unused_parens_pat(cx, p, true, *m == Mutability::Not, keep_space), + // FIXME(pin_ergonomics): check pinned patterns + Ref(p, _, m) => self.check_unused_parens_pat(cx, p, true, *m == Mutability::Not, keep_space), } } diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 7e762a878078..899632b9d4b7 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -144,6 +144,7 @@ declare_lint_pass! { UNUSED_UNSAFE, UNUSED_VARIABLES, USELESS_DEPRECATED, + VARARGS_WITHOUT_PATTERN, WARNINGS, // tidy-alphabetical-end ] @@ -5295,3 +5296,50 @@ declare_lint! { report_in_deps: false, }; } + +declare_lint! { + /// The `varargs_without_pattern` lint detects when `...` is used as an argument to a + /// non-foreign function without any pattern being specified. + /// + /// ### Example + /// + /// ```rust + /// // Using `...` in non-foreign function definitions is unstable, however stability is + /// // currently only checked after attributes are expanded, so using `#[cfg(false)]` here will + /// // allow this to compile on stable Rust. + /// #[cfg(false)] + /// fn foo(...) { + /// + /// } + /// ``` + /// + /// {{produces}} + /// + /// ### Explanation + /// + /// Patterns are currently required for all non-`...` arguments in function definitions (with + /// some exceptions in the 2015 edition). Requiring `...` arguments to have patterns in + /// non-foreign function definitions makes the language more consistent, and removes a source of + /// confusion for the unstable C variadic feature. `...` arguments without a pattern are already + /// stable and widely used in foreign function definitions; this lint only affects non-foreign + /// function definitions. + /// + /// Using `...` (C varargs) in a non-foreign function definition is currently unstable. However, + /// stability checking for the `...` syntax in non-foreign function definitions is currently + /// implemented after attributes have been expanded, meaning that if the attribute removes the + /// use of the unstable syntax (e.g. `#[cfg(false)]`, or a procedural macro), the code will + /// compile on stable Rust; this is the only situation where this lint affects code that + /// compiles on stable Rust. + /// + /// This is a [future-incompatible] lint to transition this to a hard error in the future. + /// + /// [future-incompatible]: ../index.md#future-incompatible-lints + pub VARARGS_WITHOUT_PATTERN, + Warn, + "detects usage of `...` arguments without a pattern in non-foreign items", + @future_incompatible = FutureIncompatibleInfo { + reason: FutureIncompatibilityReason::FutureReleaseError, + reference: "issue #145544 ", + report_in_deps: false, + }; +} diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs index 291f5c65dfa2..250657bc6806 100644 --- a/compiler/rustc_metadata/src/native_libs.rs +++ b/compiler/rustc_metadata/src/native_libs.rs @@ -15,7 +15,7 @@ use rustc_session::cstore::{DllCallingConvention, DllImport, ForeignModule, Nati use rustc_session::search_paths::PathKind; use rustc_span::Symbol; use rustc_span::def_id::{DefId, LOCAL_CRATE}; -use rustc_target::spec::{Arch, BinaryFormat, LinkSelfContainedComponents}; +use rustc_target::spec::{Abi, Arch, BinaryFormat, Env, LinkSelfContainedComponents, Os}; use crate::errors; @@ -67,9 +67,9 @@ pub fn walk_native_lib_search_dirs( // FIXME: On AIX this also has the side-effect of making the list of library search paths // non-empty, which is needed or the linker may decide to record the LIBPATH env, if // defined, as the search path instead of appending the default search paths. - if sess.target.vendor == "fortanix" - || sess.target.os == "linux" - || sess.target.os == "fuchsia" + if sess.target.abi == Abi::Fortanix + || sess.target.os == Os::Linux + || sess.target.os == Os::Fuchsia || sess.target.is_like_aix || sess.target.is_like_darwin && !sess.sanitizers().is_empty() { @@ -79,7 +79,7 @@ pub fn walk_native_lib_search_dirs( // Mac Catalyst uses the macOS SDK, but to link to iOS-specific frameworks // we must have the support library stubs in the library search path (#121430). if let Some(sdk_root) = apple_sdk_root - && sess.target.env == "macabi" + && sess.target.env == Env::MacAbi { f(&sdk_root.join("System/iOSSupport/usr/lib"), false)?; f(&sdk_root.join("System/iOSSupport/System/Library/Frameworks"), true)?; diff --git a/compiler/rustc_middle/src/middle/region.rs b/compiler/rustc_middle/src/middle/region.rs index 3ed8d9a36e10..c0e443b5ead8 100644 --- a/compiler/rustc_middle/src/middle/region.rs +++ b/compiler/rustc_middle/src/middle/region.rs @@ -11,7 +11,7 @@ use std::fmt; use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::unord::UnordMap; use rustc_hir as hir; -use rustc_hir::{HirId, HirIdMap, Node}; +use rustc_hir::{HirId, ItemLocalMap, Node}; use rustc_macros::{HashStable, TyDecodable, TyEncodable}; use rustc_span::{DUMMY_SP, Span}; use tracing::debug; @@ -221,12 +221,12 @@ pub struct ScopeTree { /// variable is declared. var_map: FxIndexMap, - /// Identifies expressions which, if captured into a temporary, ought to - /// have a temporary whose lifetime extends to the end of the enclosing *block*, - /// and not the enclosing *statement*. Expressions that are not present in this - /// table are not rvalue candidates. The set of rvalue candidates is computed - /// during type check based on a traversal of the AST. - pub rvalue_candidates: HirIdMap, + /// Tracks expressions with extended temporary scopes, based on the syntactic rules for + /// temporary lifetime extension. Further details may be found in + /// `rustc_hir_analysis::check::region` and in the [Reference]. + /// + /// [Reference]: https://doc.rust-lang.org/nightly/reference/destructors.html#temporary-lifetime-extension + extended_temp_scopes: ItemLocalMap>, /// Backwards incompatible scoping that will be introduced in future editions. /// This information is used later for linting to identify locals and @@ -234,16 +234,6 @@ pub struct ScopeTree { pub backwards_incompatible_scope: UnordMap, } -/// See the `rvalue_candidates` field for more information on rvalue -/// candidates in general. -/// The `lifetime` field is None to indicate that certain expressions escape -/// into 'static and should have no local cleanup scope. -#[derive(Debug, Copy, Clone, HashStable)] -pub struct RvalueCandidate { - pub target: hir::ItemLocalId, - pub lifetime: Option, -} - impl ScopeTree { pub fn record_scope_parent(&mut self, child: Scope, parent: Option) { debug!("{:?}.parent = {:?}", child, parent); @@ -260,12 +250,13 @@ impl ScopeTree { self.var_map.insert(var, lifetime); } - pub fn record_rvalue_candidate(&mut self, var: HirId, candidate: RvalueCandidate) { - debug!("record_rvalue_candidate(var={var:?}, candidate={candidate:?})"); - if let Some(lifetime) = &candidate.lifetime { - assert!(var.local_id != lifetime.local_id) + /// Make an association between a sub-expression and an extended lifetime + pub fn record_extended_temp_scope(&mut self, var: hir::ItemLocalId, lifetime: Option) { + debug!(?var, ?lifetime); + if let Some(lifetime) = lifetime { + assert!(var != lifetime.local_id); } - self.rvalue_candidates.insert(var, candidate); + self.extended_temp_scopes.insert(var, lifetime); } /// Returns the narrowest scope that encloses `id`, if any. @@ -337,4 +328,20 @@ impl ScopeTree { span_bug!(ty::tls::with(|tcx| inner.span(tcx, self)), "no enclosing temporary scope") } + + /// Returns the scope when the temp created by `expr_id` will be cleaned up. + /// It also emits a lint on potential backwards incompatible change to the temporary scope + /// which is *for now* always shortening. + pub fn temporary_scope(&self, expr_id: hir::ItemLocalId) -> (Option, Option) { + // Check for a designated extended temporary scope. + if let Some(&s) = self.extended_temp_scopes.get(&expr_id) { + debug!("temporary_scope({expr_id:?}) = {s:?} [custom]"); + return (s, None); + } + + // Otherwise, locate the innermost terminating scope. + let (scope, backward_incompatible) = + self.default_temporary_scope(Scope { local_id: expr_id, data: ScopeData::Node }); + (Some(scope), backward_incompatible) + } } diff --git a/compiler/rustc_middle/src/mir/consts.rs b/compiler/rustc_middle/src/mir/consts.rs index 5764a9c84eea..6985cc7ddcfa 100644 --- a/compiler/rustc_middle/src/mir/consts.rs +++ b/compiler/rustc_middle/src/mir/consts.rs @@ -16,7 +16,7 @@ use crate::ty::{self, ConstKind, GenericArgsRef, ScalarInt, Ty, TyCtxt}; /////////////////////////////////////////////////////////////////////////// /// Evaluated Constants - +/// /// Represents the result of const evaluation via the `eval_to_allocation` query. /// Not to be confused with `ConstAllocation`, which directly refers to the underlying data! /// Here we indirect via an `AllocId`. diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 802adceb063e..a1f99de9165b 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -11,7 +11,7 @@ pub use basic_blocks::{BasicBlocks, SwitchTargetValue}; use either::Either; use polonius_engine::Atom; use rustc_abi::{FieldIdx, VariantIdx}; -pub use rustc_ast::Mutability; +pub use rustc_ast::{Mutability, Pinnedness}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::graph::dominators::Dominators; use rustc_errors::{DiagArgName, DiagArgValue, DiagMessage, ErrorGuaranteed, IntoDiagArg}; diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index ae83e98f37d2..d7c161a6a609 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -856,6 +856,7 @@ bidirectional_lang_item_map! { PointeeTrait, Sized, TransmuteTrait, + TrivialClone, Tuple, Unpin, Unsize, diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index faa8420c20d0..5eb8f1713a13 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -97,7 +97,6 @@ pub use self::region::{ BoundRegion, BoundRegionKind, EarlyParamRegion, LateParamRegion, LateParamRegionKind, Region, RegionKind, RegionVid, }; -pub use self::rvalue_scopes::RvalueScopes; pub use self::sty::{ AliasTy, Article, Binder, BoundTy, BoundTyKind, BoundVariableKind, CanonicalPolyFnSig, CoroutineArgsExt, EarlyBinder, FnSig, InlineConstArgs, InlineConstArgsParts, ParamConst, @@ -156,7 +155,6 @@ mod list; mod opaque_types; mod predicate; mod region; -mod rvalue_scopes; mod structural_impls; #[allow(hidden_glob_reexports)] mod sty; diff --git a/compiler/rustc_middle/src/ty/rvalue_scopes.rs b/compiler/rustc_middle/src/ty/rvalue_scopes.rs deleted file mode 100644 index df4e29d45754..000000000000 --- a/compiler/rustc_middle/src/ty/rvalue_scopes.rs +++ /dev/null @@ -1,48 +0,0 @@ -use rustc_hir as hir; -use rustc_hir::ItemLocalMap; -use rustc_macros::{HashStable, TyDecodable, TyEncodable}; -use tracing::debug; - -use crate::middle::region::{Scope, ScopeData, ScopeTree}; - -/// `RvalueScopes` is a mapping from sub-expressions to _extended_ lifetime as determined by -/// rules laid out in `rustc_hir_analysis::check::rvalue_scopes`. -#[derive(TyEncodable, TyDecodable, Clone, Debug, Default, Eq, PartialEq, HashStable)] -pub struct RvalueScopes { - map: ItemLocalMap>, -} - -impl RvalueScopes { - pub fn new() -> Self { - Self { map: <_>::default() } - } - - /// Returns the scope when the temp created by `expr_id` will be cleaned up. - /// It also emits a lint on potential backwards incompatible change to the temporary scope - /// which is *for now* always shortening. - pub fn temporary_scope( - &self, - region_scope_tree: &ScopeTree, - expr_id: hir::ItemLocalId, - ) -> (Option, Option) { - // Check for a designated rvalue scope. - if let Some(&s) = self.map.get(&expr_id) { - debug!("temporary_scope({expr_id:?}) = {s:?} [custom]"); - return (s, None); - } - - // Otherwise, locate the innermost terminating scope. - let (scope, backward_incompatible) = region_scope_tree - .default_temporary_scope(Scope { local_id: expr_id, data: ScopeData::Node }); - (Some(scope), backward_incompatible) - } - - /// Make an association between a sub-expression and an extended lifetime - pub fn record_rvalue_scope(&mut self, var: hir::ItemLocalId, lifetime: Option) { - debug!("record_rvalue_scope(var={var:?}, lifetime={lifetime:?})"); - if let Some(lifetime) = lifetime { - assert!(var != lifetime.local_id); - } - self.map.insert(var, lifetime); - } -} diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 953c806658ae..d8f16ef5561d 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -1366,6 +1366,19 @@ impl<'tcx> Ty<'tcx> { None } + pub fn maybe_pinned_ref(self) -> Option<(Ty<'tcx>, ty::Pinnedness, ty::Mutability)> { + match *self.kind() { + Adt(def, args) + if def.is_pin() + && let ty::Ref(_, ty, mutbl) = *args.type_at(0).kind() => + { + Some((ty, ty::Pinnedness::Pinned, mutbl)) + } + ty::Ref(_, ty, mutbl) => Some((ty, ty::Pinnedness::Not, mutbl)), + _ => None, + } + } + /// Panics if called on any type other than `Box`. pub fn expect_boxed_ty(self) -> Ty<'tcx> { self.boxed_ty() diff --git a/compiler/rustc_middle/src/ty/typeck_results.rs b/compiler/rustc_middle/src/ty/typeck_results.rs index 5300be58f04e..55b738a0a34f 100644 --- a/compiler/rustc_middle/src/ty/typeck_results.rs +++ b/compiler/rustc_middle/src/ty/typeck_results.rs @@ -18,7 +18,6 @@ use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisit use rustc_session::Session; use rustc_span::Span; -use super::RvalueScopes; use crate::hir::place::Place as HirPlace; use crate::infer::canonical::Canonical; use crate::mir::FakeReadCause; @@ -198,11 +197,6 @@ pub struct TypeckResults<'tcx> { /// issue by fake reading `t`. pub closure_fake_reads: LocalDefIdMap, FakeReadCause, HirId)>>, - /// Tracks the rvalue scoping rules which defines finer scoping for rvalue expressions - /// by applying extended parameter rules. - /// Details may be found in `rustc_hir_analysis::check::rvalue_scopes`. - pub rvalue_scopes: RvalueScopes, - /// Stores the predicates that apply on coroutine witness types. /// formatting modified file tests/ui/coroutine/retain-resume-ref.rs pub coroutine_stalled_predicates: FxIndexSet<(ty::Predicate<'tcx>, ObligationCause<'tcx>)>, @@ -254,7 +248,6 @@ impl<'tcx> TypeckResults<'tcx> { hidden_types: Default::default(), closure_min_captures: Default::default(), closure_fake_reads: Default::default(), - rvalue_scopes: Default::default(), coroutine_stalled_predicates: Default::default(), potentially_region_dependent_goals: Default::default(), closure_size_eval: Default::default(), diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index a4422abc6883..782ea3906ef1 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -607,9 +607,9 @@ impl<'tcx> TyCtxt<'tcx> { /// have the same `DefKind`. /// /// Note that closures have a `DefId`, but the closure *expression* also has a - // `HirId` that is located within the context where the closure appears (and, sadly, - // a corresponding `NodeId`, since those are not yet phased out). The parent of - // the closure's `DefId` will also be the context where it appears. + /// `HirId` that is located within the context where the closure appears (and, sadly, + /// a corresponding `NodeId`, since those are not yet phased out). The parent of + /// the closure's `DefId` will also be the context where it appears. pub fn is_closure_like(self, def_id: DefId) -> bool { matches!(self.def_kind(def_id), DefKind::Closure) } diff --git a/compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs index 552f8c66784e..546bfc8ea547 100644 --- a/compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs +++ b/compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs @@ -779,8 +779,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { Rvalue::Ref(this.tcx.lifetimes.re_erased, borrow_kind, arg_place), ); - // See the comment in `expr_as_temp` and on the `rvalue_scopes` field for why - // this can be `None`. + // This can be `None` if the expression's temporary scope was extended so that it can be + // borrowed by a `const` or `static`. In that case, it's never dropped. if let Some(temp_lifetime) = temp_lifetime { this.schedule_drop_storage_and_value(upvar_span, temp_lifetime, temp); } diff --git a/compiler/rustc_mir_build/src/builder/matches/match_pair.rs b/compiler/rustc_mir_build/src/builder/matches/match_pair.rs index af565ef63699..a0d54354a9c6 100644 --- a/compiler/rustc_mir_build/src/builder/matches/match_pair.rs +++ b/compiler/rustc_mir_build/src/builder/matches/match_pair.rs @@ -284,14 +284,12 @@ impl<'tcx> MatchPairTree<'tcx> { } PatKind::Deref { ref subpattern } - | PatKind::DerefPattern { ref subpattern, borrow: ByRef::No } => { - if cfg!(debug_assertions) && matches!(pattern.kind, PatKind::DerefPattern { .. }) { - // Only deref patterns on boxes can be lowered using a built-in deref. - debug_assert!(pattern.ty.is_box()); - } - + | PatKind::DerefPattern { ref subpattern, borrow: ByRef::Yes(Pinnedness::Pinned, _) } + if let Some(ref_ty) = pattern.ty.pinned_ty() + && ref_ty.is_ref() => + { MatchPairTree::for_pattern( - place_builder.deref(), + place_builder.field(FieldIdx::ZERO, ref_ty).deref(), subpattern, cx, &mut subpairs, @@ -300,12 +298,14 @@ impl<'tcx> MatchPairTree<'tcx> { None } - PatKind::DerefPattern { ref subpattern, borrow: ByRef::Yes(Pinnedness::Pinned, _) } => { - let Some(ref_ty) = pattern.ty.pinned_ty() else { - rustc_middle::bug!("RefPin pattern on non-`Pin` type {:?}", pattern.ty); - }; + PatKind::DerefPattern { borrow: ByRef::Yes(Pinnedness::Pinned, _), .. } => { + rustc_middle::bug!("RefPin pattern on non-`Pin` type {:?}", pattern.ty) + } + + PatKind::Deref { ref subpattern } + | PatKind::DerefPattern { ref subpattern, borrow: ByRef::No } => { MatchPairTree::for_pattern( - place_builder.field(FieldIdx::ZERO, ref_ty).deref(), + place_builder.deref(), subpattern, cx, &mut subpairs, diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs index 8ce0b73e47e3..6ac935d3901e 100644 --- a/compiler/rustc_mir_build/src/thir/cx/expr.rs +++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs @@ -337,7 +337,7 @@ impl<'tcx> ThirBuildCx<'tcx> { let tcx = self.tcx; let expr_ty = self.typeck_results.expr_ty(expr); let (temp_lifetime, backwards_incompatible) = - self.rvalue_scopes.temporary_scope(self.region_scope_tree, expr.hir_id.local_id); + self.region_scope_tree.temporary_scope(expr.hir_id.local_id); let kind = match expr.kind { // Here comes the interesting stuff: @@ -502,9 +502,8 @@ impl<'tcx> ThirBuildCx<'tcx> { expr: Some(arg), safety_mode: BlockSafety::Safe, }); - let (temp_lifetime, backwards_incompatible) = self - .rvalue_scopes - .temporary_scope(self.region_scope_tree, arg_expr.hir_id.local_id); + let (temp_lifetime, backwards_incompatible) = + self.region_scope_tree.temporary_scope(arg_expr.hir_id.local_id); arg = self.thir.exprs.push(Expr { temp_lifetime: TempLifetime { temp_lifetime, backwards_incompatible }, ty: arg_ty, @@ -996,9 +995,8 @@ impl<'tcx> ThirBuildCx<'tcx> { } } else { let block_ty = self.typeck_results.node_type(body.hir_id); - let (temp_lifetime, backwards_incompatible) = self - .rvalue_scopes - .temporary_scope(self.region_scope_tree, body.hir_id.local_id); + let (temp_lifetime, backwards_incompatible) = + self.region_scope_tree.temporary_scope(body.hir_id.local_id); let block = self.mirror_block(body); let body = self.thir.exprs.push(Expr { ty: block_ty, @@ -1143,7 +1141,7 @@ impl<'tcx> ThirBuildCx<'tcx> { overloaded_callee: Option>, ) -> Expr<'tcx> { let (temp_lifetime, backwards_incompatible) = - self.rvalue_scopes.temporary_scope(self.region_scope_tree, expr.hir_id.local_id); + self.region_scope_tree.temporary_scope(expr.hir_id.local_id); let (ty, user_ty) = match overloaded_callee { Some(fn_def) => (fn_def, None), None => { @@ -1237,9 +1235,8 @@ impl<'tcx> ThirBuildCx<'tcx> { Res::Def(DefKind::Static { .. }, id) => { // this is &raw for extern static or static mut, and & for other statics let ty = self.tcx.static_ptr_ty(id, self.typing_env); - let (temp_lifetime, backwards_incompatible) = self - .rvalue_scopes - .temporary_scope(self.region_scope_tree, expr.hir_id.local_id); + let (temp_lifetime, backwards_incompatible) = + self.region_scope_tree.temporary_scope(expr.hir_id.local_id); let kind = if self.tcx.is_thread_local_static(id) { ExprKind::ThreadLocalRef(id) } else { @@ -1321,7 +1318,7 @@ impl<'tcx> ThirBuildCx<'tcx> { // construct the complete expression `foo()` for the overloaded call, // which will yield the &T type let (temp_lifetime, backwards_incompatible) = - self.rvalue_scopes.temporary_scope(self.region_scope_tree, expr.hir_id.local_id); + self.region_scope_tree.temporary_scope(expr.hir_id.local_id); let fun = self.method_callee(expr, span, overloaded_callee); let fun = self.thir.exprs.push(fun); let fun_ty = self.thir[fun].ty; @@ -1341,9 +1338,8 @@ impl<'tcx> ThirBuildCx<'tcx> { closure_expr: &'tcx hir::Expr<'tcx>, place: HirPlace<'tcx>, ) -> Expr<'tcx> { - let (temp_lifetime, backwards_incompatible) = self - .rvalue_scopes - .temporary_scope(self.region_scope_tree, closure_expr.hir_id.local_id); + let (temp_lifetime, backwards_incompatible) = + self.region_scope_tree.temporary_scope(closure_expr.hir_id.local_id); let var_ty = place.base_ty; // The result of capture analysis in `rustc_hir_typeck/src/upvar.rs` represents a captured path @@ -1405,9 +1401,8 @@ impl<'tcx> ThirBuildCx<'tcx> { let upvar_capture = captured_place.info.capture_kind; let captured_place_expr = self.convert_captured_hir_place(closure_expr, captured_place.place.clone()); - let (temp_lifetime, backwards_incompatible) = self - .rvalue_scopes - .temporary_scope(self.region_scope_tree, closure_expr.hir_id.local_id); + let (temp_lifetime, backwards_incompatible) = + self.region_scope_tree.temporary_scope(closure_expr.hir_id.local_id); match upvar_capture { ty::UpvarCapture::ByValue => captured_place_expr, diff --git a/compiler/rustc_mir_build/src/thir/cx/mod.rs b/compiler/rustc_mir_build/src/thir/cx/mod.rs index 9657c4dc839d..65b05a0e6a98 100644 --- a/compiler/rustc_mir_build/src/thir/cx/mod.rs +++ b/compiler/rustc_mir_build/src/thir/cx/mod.rs @@ -12,7 +12,7 @@ use rustc_hir::{self as hir, HirId, find_attr}; use rustc_middle::bug; use rustc_middle::middle::region; use rustc_middle::thir::*; -use rustc_middle::ty::{self, RvalueScopes, TyCtxt}; +use rustc_middle::ty::{self, TyCtxt}; use tracing::instrument; use crate::thir::pattern::pat_from_hir; @@ -62,7 +62,6 @@ struct ThirBuildCx<'tcx> { region_scope_tree: &'tcx region::ScopeTree, typeck_results: &'tcx ty::TypeckResults<'tcx>, - rvalue_scopes: &'tcx RvalueScopes, /// False to indicate that adjustments should not be applied. Only used for `custom_mir` apply_adjustments: bool, @@ -109,7 +108,6 @@ impl<'tcx> ThirBuildCx<'tcx> { typing_env: ty::TypingEnv::non_body_analysis(tcx, def), region_scope_tree: tcx.region_scope_tree(def), typeck_results, - rvalue_scopes: &typeck_results.rvalue_scopes, body_owner: def.to_def_id(), apply_adjustments: !find_attr!(tcx.hir_attrs(hir_id), AttributeKind::CustomMir(..) => ()).is_some(), diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index 404f410e2219..8531c5f39f84 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -97,7 +97,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { // adjustments in *reverse order* (last-in-first-out, so that the last `Deref` inserted // gets the least-dereferenced type). let unadjusted_pat = match pat.kind { - hir::PatKind::Ref(inner, _) + hir::PatKind::Ref(inner, _, _) if self.typeck_results.skipped_ref_pats().contains(pat.hir_id) => { self.lower_pattern(inner) @@ -319,7 +319,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { let borrow = self.typeck_results.deref_pat_borrow_mode(ty, subpattern); PatKind::DerefPattern { subpattern: self.lower_pattern(subpattern), borrow } } - hir::PatKind::Ref(subpattern, _) => { + hir::PatKind::Ref(subpattern, _, _) => { // Track the default binding mode for the Rust 2024 migration suggestion. let opt_old_mode_span = self.rust_2024_migration.as_mut().and_then(|s| s.visit_explicit_deref()); @@ -370,10 +370,6 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { if let Some(pty) = ty.pinned_ty() && let &ty::Ref(_, rty, _) = pty.kind() => { - debug_assert!( - self.tcx.features().pin_ergonomics(), - "`pin_ergonomics` must be enabled to have a by-pin-ref binding" - ); ty = rty; } hir::Pinnedness::Not if let &ty::Ref(_, rty, _) = ty.kind() => { diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs index 221593d6eadb..57c36a0030aa 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs @@ -547,9 +547,11 @@ where Some(SolverTraitLangItem::PointeeSized) => { unreachable!("`PointeeSized` is removed during lowering"); } - Some(SolverTraitLangItem::Copy | SolverTraitLangItem::Clone) => { - G::consider_builtin_copy_clone_candidate(self, goal) - } + Some( + SolverTraitLangItem::Copy + | SolverTraitLangItem::Clone + | SolverTraitLangItem::TrivialClone, + ) => G::consider_builtin_copy_clone_candidate(self, goal), Some(SolverTraitLangItem::Fn) => { G::consider_builtin_fn_trait_candidates(self, goal, ty::ClosureKind::Fn) } diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs index 110cc30e740b..8da4289bf185 100644 --- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs @@ -235,8 +235,9 @@ where // See . ecx.try_evaluate_added_goals()?; - // Add GAT where clauses from the trait's definition. - // FIXME: We don't need these, since these are the type's own WF obligations. + // Add GAT where clauses from the trait's definition. This is necessary + // for soundness until we properly handle implied bounds on binders, + // see tests/ui/generic-associated-types/must-prove-where-clauses-on-norm.rs. ecx.add_goals( GoalSource::AliasWellFormed, cx.own_predicates_of(goal.predicate.def_id()) diff --git a/compiler/rustc_parse/messages.ftl b/compiler/rustc_parse/messages.ftl index 1862900077f0..c74333f5655a 100644 --- a/compiler/rustc_parse/messages.ftl +++ b/compiler/rustc_parse/messages.ftl @@ -1004,6 +1004,9 @@ parse_use_if_else = use an `if-else` expression instead parse_use_let_not_auto = write `let` instead of `auto` to introduce a new variable parse_use_let_not_var = write `let` instead of `var` to introduce a new variable +parse_varargs_without_pattern = missing pattern for `...` argument + .suggestion = name the argument, or use `_` to continue ignoring it + parse_visibility_not_followed_by_item = visibility `{$vis}` is not followed by an item .label = the visibility .help = you likely meant to define an item, e.g., `{$vis} fn foo() {"{}"}` diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index a35c5c304d95..bde179c9438f 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -3645,3 +3645,10 @@ impl Subdiagnostic for HiddenUnicodeCodepointsDiagSub { } } } + +#[derive(LintDiagnostic)] +#[diag(parse_varargs_without_pattern)] +pub(crate) struct VarargsWithoutPattern { + #[suggestion(code = "_: ...", applicability = "machine-applicable")] + pub span: Span, +} diff --git a/compiler/rustc_parse/src/parser/attr.rs b/compiler/rustc_parse/src/parser/attr.rs index 5725f4c36679..63109c7ba5cb 100644 --- a/compiler/rustc_parse/src/parser/attr.rs +++ b/compiler/rustc_parse/src/parser/attr.rs @@ -201,7 +201,7 @@ impl<'a> Parser<'a> { AttrWrapper::empty(), true, false, - FnParseMode { req_name: |_| true, context: FnContext::Free, req_body: true }, + FnParseMode { req_name: |_, _| true, context: FnContext::Free, req_body: true }, ForceCollect::No, ) { Ok(Some(item)) => { diff --git a/compiler/rustc_parse/src/parser/cfg_select.rs b/compiler/rustc_parse/src/parser/cfg_select.rs index 08a71db4de85..9692d2c70893 100644 --- a/compiler/rustc_parse/src/parser/cfg_select.rs +++ b/compiler/rustc_parse/src/parser/cfg_select.rs @@ -1,83 +1,34 @@ -use rustc_ast::token::Token; +use rustc_ast::token; use rustc_ast::tokenstream::{TokenStream, TokenTree}; use rustc_ast::util::classify; -use rustc_ast::{MetaItemInner, token}; use rustc_errors::PResult; -use rustc_span::Span; use crate::exp; use crate::parser::{AttrWrapper, ForceCollect, Parser, Restrictions, Trailing, UsePreAttrPos}; -pub enum CfgSelectPredicate { - Cfg(MetaItemInner), - Wildcard(Token), -} - -#[derive(Default)] -pub struct CfgSelectBranches { - /// All the conditional branches. - pub reachable: Vec<(MetaItemInner, TokenStream, Span)>, - /// The first wildcard `_ => { ... }` branch. - pub wildcard: Option<(Token, TokenStream, Span)>, - /// All branches after the first wildcard, including further wildcards. - /// These branches are kept for formatting. - pub unreachable: Vec<(CfgSelectPredicate, TokenStream, Span)>, -} - -/// Parses a `TokenTree` consisting either of `{ /* ... */ }` (and strip the braces) or an -/// expression followed by a comma (and strip the comma). -fn parse_token_tree<'a>(p: &mut Parser<'a>) -> PResult<'a, TokenStream> { - if p.token == token::OpenBrace { - // Strip the outer '{' and '}'. - match p.parse_token_tree() { - TokenTree::Token(..) => unreachable!("because of the expect above"), - TokenTree::Delimited(.., tts) => return Ok(tts), - } - } - let expr = p.collect_tokens(None, AttrWrapper::empty(), ForceCollect::Yes, |p, _| { - p.parse_expr_res(Restrictions::STMT_EXPR, AttrWrapper::empty()) - .map(|(expr, _)| (expr, Trailing::No, UsePreAttrPos::No)) - })?; - if !classify::expr_is_complete(&expr) && p.token != token::CloseBrace && p.token != token::Eof { - p.expect(exp!(Comma))?; - } else { - let _ = p.eat(exp!(Comma)); - } - Ok(TokenStream::from_ast(&expr)) -} - -pub fn parse_cfg_select<'a>(p: &mut Parser<'a>) -> PResult<'a, CfgSelectBranches> { - let mut branches = CfgSelectBranches::default(); - - while p.token != token::Eof { - if p.eat_keyword(exp!(Underscore)) { - let underscore = p.prev_token; - p.expect(exp!(FatArrow))?; - - let tts = parse_token_tree(p)?; - let span = underscore.span.to(p.token.span); - - match branches.wildcard { - None => branches.wildcard = Some((underscore, tts, span)), - Some(_) => { - branches.unreachable.push((CfgSelectPredicate::Wildcard(underscore), tts, span)) - } +impl<'a> Parser<'a> { + /// Parses a `TokenTree` consisting either of `{ /* ... */ }` (and strip the braces) or an + /// expression followed by a comma (and strip the comma). + pub fn parse_delimited_token_tree(&mut self) -> PResult<'a, TokenStream> { + if self.token == token::OpenBrace { + // Strip the outer '{' and '}'. + match self.parse_token_tree() { + TokenTree::Token(..) => unreachable!("because of the expect above"), + TokenTree::Delimited(.., tts) => return Ok(tts), } + } + let expr = self.collect_tokens(None, AttrWrapper::empty(), ForceCollect::Yes, |p, _| { + p.parse_expr_res(Restrictions::STMT_EXPR, AttrWrapper::empty()) + .map(|(expr, _)| (expr, Trailing::No, UsePreAttrPos::No)) + })?; + if !classify::expr_is_complete(&expr) + && self.token != token::CloseBrace + && self.token != token::Eof + { + self.expect(exp!(Comma))?; } else { - let meta_item = p.parse_meta_item_inner()?; - p.expect(exp!(FatArrow))?; - - let tts = parse_token_tree(p)?; - let span = meta_item.span().to(p.token.span); - - match branches.wildcard { - None => branches.reachable.push((meta_item, tts, span)), - Some(_) => { - branches.unreachable.push((CfgSelectPredicate::Cfg(meta_item), tts, span)) - } - } + let _ = self.eat(exp!(Comma)); } + Ok(TokenStream::from_ast(&expr)) } - - Ok(branches) } diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index bc08faabece4..bd495f6ec1ac 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -45,6 +45,7 @@ use crate::errors::{ }; use crate::parser::FnContext; use crate::parser::attr::InnerAttrPolicy; +use crate::parser::item::IsDotDotDot; use crate::{exp, fluent_generated as fluent}; /// Creates a placeholder argument. @@ -2284,7 +2285,7 @@ impl<'a> Parser<'a> { let maybe_emit_anon_params_note = |this: &mut Self, err: &mut Diag<'_>| { let ed = this.token.span.with_neighbor(this.prev_token.span).edition(); if matches!(fn_parse_mode.context, crate::parser::item::FnContext::Trait) - && (fn_parse_mode.req_name)(ed) + && (fn_parse_mode.req_name)(ed, IsDotDotDot::No) { err.note("anonymous parameters are removed in the 2018 edition (see RFC 1685)"); } @@ -2301,10 +2302,10 @@ impl<'a> Parser<'a> { pat.span.shrink_to_hi(), pat.span.shrink_to_lo(), ), - PatKind::Ref(ref inner_pat, _) + PatKind::Ref(ref inner_pat, _, _) // Fix suggestions for multi-reference `self` parameters (e.g. `&&&self`) // cc: https://github.com/rust-lang/rust/pull/146305 - if let PatKind::Ref(_, _) = &inner_pat.kind + if let PatKind::Ref(_, _, _) = &inner_pat.kind && let PatKind::Path(_, path) = &pat.peel_refs().kind && let [a, ..] = path.segments.as_slice() && a.ident.name == kw::SelfLower => @@ -2312,7 +2313,7 @@ impl<'a> Parser<'a> { let mut inner = inner_pat; let mut span_vec = vec![pat.span]; - while let PatKind::Ref(ref inner_type, _) = inner.kind { + while let PatKind::Ref(ref inner_type, _, _) = inner.kind { inner = inner_type; span_vec.push(inner.span.shrink_to_lo()); } @@ -2334,10 +2335,10 @@ impl<'a> Parser<'a> { return None; } // Also catches `fn foo(&a)`. - PatKind::Ref(ref inner_pat, mutab) + PatKind::Ref(ref inner_pat, pinned, mutab) if let PatKind::Ident(_, ident, _) = inner_pat.clone().kind => { - let mutab = mutab.prefix_str(); + let mutab = pinned.prefix_str(mutab); ( ident, "self: ", diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index e7c89f079622..9e7d4bca37d0 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -863,14 +863,15 @@ impl<'a> Parser<'a> { assert!(found_raw); let mutability = self.parse_const_or_mut().unwrap(); (ast::BorrowKind::Raw, mutability) - } else if let Some((ast::Pinnedness::Pinned, mutbl)) = self.parse_pin_and_mut() { - // `pin [ const | mut ]`. - // `pin` has been gated in `self.parse_pin_and_mut()` so we don't - // need to gate it here. - (ast::BorrowKind::Pin, mutbl) } else { - // `mut?` - (ast::BorrowKind::Ref, self.parse_mutability()) + match self.parse_pin_and_mut() { + // `mut?` + (ast::Pinnedness::Not, mutbl) => (ast::BorrowKind::Ref, mutbl), + // `pin [ const | mut ]`. + // `pin` has been gated in `self.parse_pin_and_mut()` so we don't + // need to gate it here. + (ast::Pinnedness::Pinned, mutbl) => (ast::BorrowKind::Pin, mutbl), + } } } diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 599ec80e0a38..a4fadb029f5c 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -12,6 +12,7 @@ use rustc_ast::{ use rustc_ast_pretty::pprust; use rustc_errors::codes::*; use rustc_errors::{Applicability, PResult, StashKey, struct_span_code_err}; +use rustc_session::lint::builtin::VARARGS_WITHOUT_PATTERN; use rustc_span::edit_distance::edit_distance; use rustc_span::edition::Edition; use rustc_span::{DUMMY_SP, ErrorGuaranteed, Ident, Span, Symbol, kw, source_map, sym}; @@ -119,7 +120,7 @@ impl<'a> Parser<'a> { impl<'a> Parser<'a> { pub fn parse_item(&mut self, force_collect: ForceCollect) -> PResult<'a, Option>> { let fn_parse_mode = - FnParseMode { req_name: |_| true, context: FnContext::Free, req_body: true }; + FnParseMode { req_name: |_, _| true, context: FnContext::Free, req_body: true }; self.parse_item_(fn_parse_mode, force_collect).map(|i| i.map(Box::new)) } @@ -976,7 +977,7 @@ impl<'a> Parser<'a> { force_collect: ForceCollect, ) -> PResult<'a, Option>>> { let fn_parse_mode = - FnParseMode { req_name: |_| true, context: FnContext::Impl, req_body: true }; + FnParseMode { req_name: |_, _| true, context: FnContext::Impl, req_body: true }; self.parse_assoc_item(fn_parse_mode, force_collect) } @@ -985,7 +986,7 @@ impl<'a> Parser<'a> { force_collect: ForceCollect, ) -> PResult<'a, Option>>> { let fn_parse_mode = FnParseMode { - req_name: |edition| edition >= Edition::Edition2018, + req_name: |edition, _| edition >= Edition::Edition2018, context: FnContext::Trait, req_body: false, }; @@ -1245,8 +1246,11 @@ impl<'a> Parser<'a> { &mut self, force_collect: ForceCollect, ) -> PResult<'a, Option>>> { - let fn_parse_mode = - FnParseMode { req_name: |_| true, context: FnContext::Free, req_body: false }; + let fn_parse_mode = FnParseMode { + req_name: |_, is_dot_dot_dot| is_dot_dot_dot == IsDotDotDot::No, + context: FnContext::Free, + req_body: false, + }; Ok(self.parse_item_(fn_parse_mode, force_collect)?.map( |Item { attrs, id, span, vis, kind, tokens }| { let kind = match ForeignItemKind::try_from(kind) { @@ -2133,7 +2137,7 @@ impl<'a> Parser<'a> { Visibility { span: DUMMY_SP, kind: VisibilityKind::Inherited, tokens: None }; // We use `parse_fn` to get a span for the function let fn_parse_mode = - FnParseMode { req_name: |_| true, context: FnContext::Free, req_body: true }; + FnParseMode { req_name: |_, _| true, context: FnContext::Free, req_body: true }; match self.parse_fn( &mut AttrVec::new(), fn_parse_mode, @@ -2366,8 +2370,16 @@ impl<'a> Parser<'a> { /// The function decides if, per-parameter `p`, `p` must have a pattern or just a type. /// /// This function pointer accepts an edition, because in edition 2015, trait declarations -/// were allowed to omit parameter names. In 2018, they became required. -type ReqName = fn(Edition) -> bool; +/// were allowed to omit parameter names. In 2018, they became required. It also accepts an +/// `IsDotDotDot` parameter, as `extern` function declarations and function pointer types are +/// allowed to omit the name of the `...` but regular function items are not. +type ReqName = fn(Edition, IsDotDotDot) -> bool; + +#[derive(Copy, Clone, PartialEq)] +pub(crate) enum IsDotDotDot { + Yes, + No, +} /// Parsing configuration for functions. /// @@ -2400,6 +2412,9 @@ pub(crate) struct FnParseMode { /// to true. /// * The span is from Edition 2015. In particular, you can get a /// 2015 span inside a 2021 crate using macros. + /// + /// Or if `IsDotDotDot::Yes`, this function will also return `false` if the item being parsed + /// is inside an `extern` block. pub(super) req_name: ReqName, /// The context in which this function is parsed, used for diagnostics. /// This indicates the fn is a free function or method and so on. @@ -3049,11 +3064,25 @@ impl<'a> Parser<'a> { return Ok((res?, Trailing::No, UsePreAttrPos::No)); } - let is_name_required = match this.token.kind { - token::DotDotDot => false, - _ => (fn_parse_mode.req_name)( - this.token.span.with_neighbor(this.prev_token.span).edition(), - ), + let is_dot_dot_dot = if this.token.kind == token::DotDotDot { + IsDotDotDot::Yes + } else { + IsDotDotDot::No + }; + let is_name_required = (fn_parse_mode.req_name)( + this.token.span.with_neighbor(this.prev_token.span).edition(), + is_dot_dot_dot, + ); + let is_name_required = if is_name_required && is_dot_dot_dot == IsDotDotDot::Yes { + this.psess.buffer_lint( + VARARGS_WITHOUT_PATTERN, + this.token.span, + ast::CRATE_NODE_ID, + errors::VarargsWithoutPattern { span: this.token.span }, + ); + false + } else { + is_name_required }; let (pat, ty) = if is_name_required || this.is_named_param() { debug!("parse_param_general parse_pat (is_name_required:{})", is_name_required); diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index 30870c810942..203a93b52012 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -36,8 +36,8 @@ use rustc_ast::tokenstream::{ use rustc_ast::util::case::Case; use rustc_ast::{ self as ast, AnonConst, AttrArgs, AttrId, ByRef, Const, CoroutineKind, DUMMY_NODE_ID, - DelimArgs, Expr, ExprKind, Extern, HasAttrs, HasTokens, Mutability, Pinnedness, Recovered, - Safety, StrLit, Visibility, VisibilityKind, + DelimArgs, Expr, ExprKind, Extern, HasAttrs, HasTokens, Mutability, Recovered, Safety, StrLit, + Visibility, VisibilityKind, }; use rustc_ast_pretty::pprust; use rustc_data_structures::fx::FxHashMap; @@ -1315,11 +1315,11 @@ impl<'a> Parser<'a> { if self.eat_keyword(exp!(Mut)) { Mutability::Mut } else { Mutability::Not } } - /// Parses reference binding mode (`ref`, `ref mut`, or nothing). + /// Parses reference binding mode (`ref`, `ref mut`, `ref pin const`, `ref pin mut`, or nothing). fn parse_byref(&mut self) -> ByRef { if self.eat_keyword(exp!(Ref)) { - // FIXME(pin_ergonomics): support `ref pin const|mut` bindings - ByRef::Yes(Pinnedness::Not, self.parse_mutability()) + let (pinnedness, mutability) = self.parse_pin_and_mut(); + ByRef::Yes(pinnedness, mutability) } else { ByRef::No } diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs index f964ecb90326..0e9796c04c8a 100644 --- a/compiler/rustc_parse/src/parser/pat.rs +++ b/compiler/rustc_parse/src/parser/pat.rs @@ -7,8 +7,7 @@ use rustc_ast::util::parser::ExprPrecedence; use rustc_ast::visit::{self, Visitor}; use rustc_ast::{ self as ast, Arm, AttrVec, BindingMode, ByRef, Expr, ExprKind, LocalKind, MacCall, Mutability, - Pat, PatField, PatFieldsRest, PatKind, Path, Pinnedness, QSelf, RangeEnd, RangeSyntax, Stmt, - StmtKind, + Pat, PatField, PatFieldsRest, PatKind, Path, QSelf, RangeEnd, RangeSyntax, Stmt, StmtKind, }; use rustc_ast_pretty::pprust; use rustc_errors::{Applicability, Diag, DiagArgValue, PResult, StashKey}; @@ -661,7 +660,7 @@ impl<'a> Parser<'a> { // Sub-patterns // FIXME: this doesn't work with recursive subpats (`&mut &mut `) - PatKind::Box(subpat) | PatKind::Ref(subpat, _) + PatKind::Box(subpat) | PatKind::Ref(subpat, _, _) if matches!(subpat.kind, PatKind::Err(_) | PatKind::Expr(_)) => { self.maybe_add_suggestions_then_emit(subpat.span, p.span, false) @@ -777,11 +776,10 @@ impl<'a> Parser<'a> { self.bump(); self.dcx().emit_err(SwitchRefBoxOrder { span }); } - // Parse ref ident @ pat / ref mut ident @ pat - let mutbl = self.parse_mutability(); + // Parse ref ident @ pat / ref mut ident @ pat / ref pin const|mut ident @ pat + let (pinned, mutbl) = self.parse_pin_and_mut(); self.parse_pat_ident( - // FIXME(pin_ergonomics): support `ref pin const|mut` bindings - BindingMode(ByRef::Yes(Pinnedness::Not, mutbl), Mutability::Not), + BindingMode(ByRef::Yes(pinned, mutbl), Mutability::Not), syntax_loc, )? } else if self.eat_keyword(exp!(Box)) { @@ -982,7 +980,7 @@ impl<'a> Parser<'a> { }); } - /// Parse `&pat` / `&mut pat`. + /// Parse `&pat` / `&mut pat` / `&pin const pat` / `&pin mut pat`. fn parse_pat_deref(&mut self, expected: Option) -> PResult<'a, PatKind> { self.expect_and()?; if let Some((lifetime, _)) = self.token.lifetime() { @@ -995,9 +993,9 @@ impl<'a> Parser<'a> { }); } - let mutbl = self.parse_mutability(); + let (pinned, mutbl) = self.parse_pin_and_mut(); let subpat = self.parse_pat_with_range_pat(false, expected, None)?; - Ok(PatKind::Ref(Box::new(subpat), mutbl)) + Ok(PatKind::Ref(Box::new(subpat), pinned, mutbl)) } /// Parse a tuple or parenthesis pattern. diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs index f7757921cd42..437f6da67b74 100644 --- a/compiler/rustc_parse/src/parser/path.rs +++ b/compiler/rustc_parse/src/parser/path.rs @@ -404,7 +404,7 @@ impl<'a> Parser<'a> { // Inside parenthesized type arguments, we want types only, not names. let mode = FnParseMode { context: FnContext::Free, - req_name: |_| false, + req_name: |_, _| false, req_body: false, }; let param = p.parse_param_general(&mode, false, false); diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs index ad5ab6e6b779..3fe8971f3d6c 100644 --- a/compiler/rustc_parse/src/parser/stmt.rs +++ b/compiler/rustc_parse/src/parser/stmt.rs @@ -154,7 +154,7 @@ impl<'a> Parser<'a> { attrs.clone(), // FIXME: unwanted clone of attrs false, true, - FnParseMode { req_name: |_| true, context: FnContext::Free, req_body: true }, + FnParseMode { req_name: |_, _| true, context: FnContext::Free, req_body: true }, force_collect, )? { self.mk_stmt(lo.to(item.span), StmtKind::Item(Box::new(item))) diff --git a/compiler/rustc_parse/src/parser/token_type.rs b/compiler/rustc_parse/src/parser/token_type.rs index 4c4f09ab3ea8..08c5b06575cd 100644 --- a/compiler/rustc_parse/src/parser/token_type.rs +++ b/compiler/rustc_parse/src/parser/token_type.rs @@ -142,6 +142,7 @@ pub enum TokenType { SymNull, SymOptions, SymOut, + SymPin, SymPreservesFlags, SymPure, SymReadonly, @@ -568,6 +569,7 @@ macro_rules! exp { (Null) => { exp!(@sym, null, SymNull) }; (Options) => { exp!(@sym, options, SymOptions) }; (Out) => { exp!(@sym, out, SymOut) }; + (Pin) => { exp!(@sym, pin, SymPin) }; (PreservesFlags) => { exp!(@sym, preserves_flags, SymPreservesFlags) }; (Pure) => { exp!(@sym, pure, SymPure) }; (Readonly) => { exp!(@sym, readonly, SymReadonly) }; diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index 39d8a1dd9e2d..df69adce142b 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -728,10 +728,7 @@ impl<'a> Parser<'a> { fn parse_borrowed_pointee(&mut self) -> PResult<'a, TyKind> { let and_span = self.prev_token.span; let mut opt_lifetime = self.check_lifetime().then(|| self.expect_lifetime()); - let (pinned, mut mutbl) = match self.parse_pin_and_mut() { - Some(pin_mut) => pin_mut, - None => (Pinnedness::Not, self.parse_mutability()), - }; + let (pinned, mut mutbl) = self.parse_pin_and_mut(); if self.token.is_lifetime() && mutbl == Mutability::Mut && opt_lifetime.is_none() { // A lifetime is invalid here: it would be part of a bare trait bound, which requires // it to be followed by a plus, but we disallow plus in the pointee type. @@ -773,28 +770,17 @@ impl<'a> Parser<'a> { }) } - /// Parses `pin` and `mut` annotations on references. + /// Parses `pin` and `mut` annotations on references, patterns, or borrow modifiers. /// - /// It must be either `pin const` or `pin mut`. - pub(crate) fn parse_pin_and_mut(&mut self) -> Option<(Pinnedness, Mutability)> { - if self.token.is_ident_named(sym::pin) { - let result = self.look_ahead(1, |token| { - if token.is_keyword(kw::Const) { - Some((Pinnedness::Pinned, Mutability::Not)) - } else if token.is_keyword(kw::Mut) { - Some((Pinnedness::Pinned, Mutability::Mut)) - } else { - None - } - }); - if result.is_some() { - self.psess.gated_spans.gate(sym::pin_ergonomics, self.token.span); - self.bump(); - self.bump(); - } - result + /// It must be either `pin const`, `pin mut`, `mut`, or nothing (immutable). + pub(crate) fn parse_pin_and_mut(&mut self) -> (Pinnedness, Mutability) { + if self.token.is_ident_named(sym::pin) && self.look_ahead(1, Token::is_mutability) { + self.psess.gated_spans.gate(sym::pin_ergonomics, self.token.span); + assert!(self.eat_keyword(exp!(Pin))); + let mutbl = self.parse_const_or_mut().unwrap(); + (Pinnedness::Pinned, mutbl) } else { - None + (Pinnedness::Not, self.parse_mutability()) } } @@ -838,7 +824,7 @@ impl<'a> Parser<'a> { self.recover_fn_ptr_with_generics(lo, &mut params, param_insertion_point)?; } let mode = crate::parser::item::FnParseMode { - req_name: |_| false, + req_name: |_, _| false, context: FnContext::Free, req_body: false, }; @@ -1394,7 +1380,8 @@ impl<'a> Parser<'a> { self.bump(); let args_lo = self.token.span; let snapshot = self.create_snapshot_for_diagnostic(); - let mode = FnParseMode { req_name: |_| false, context: FnContext::Free, req_body: false }; + let mode = + FnParseMode { req_name: |_, _| false, context: FnContext::Free, req_body: false }; match self.parse_fn_decl(&mode, AllowPlus::No, RecoverReturnSign::OnlyFatArrow) { Ok(decl) => { self.dcx().emit_err(ExpectedFnPathFoundFnKeyword { fn_token_span }); @@ -1485,7 +1472,8 @@ impl<'a> Parser<'a> { // Parse `(T, U) -> R`. let inputs_lo = self.token.span; - let mode = FnParseMode { req_name: |_| false, context: FnContext::Free, req_body: false }; + let mode = + FnParseMode { req_name: |_, _| false, context: FnContext::Free, req_body: false }; let inputs: ThinVec<_> = self.parse_fn_params(&mode)?.into_iter().map(|input| input.ty).collect(); let inputs_span = inputs_lo.to(self.prev_token.span); diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index c668bf0733d1..b33ccbae0e69 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -219,7 +219,6 @@ passes_doc_test_unknown_passes = unknown `doc` attribute `{$path}` .note = `doc` attribute `{$path}` no longer functions; see issue #44136 .label = no longer functions - .help = you may want to use `doc(document_private_items)` .no_op_note = `doc({$path})` is now a no-op passes_doc_test_unknown_plugins = diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index f5023646b191..ed4cf77d294f 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -347,7 +347,6 @@ pub(crate) struct DocTestUnknownSpotlight { #[derive(LintDiagnostic)] #[diag(passes_doc_test_unknown_passes)] #[note] -#[help] #[note(passes_no_op_note)] pub(crate) struct DocTestUnknownPasses { pub path: String, diff --git a/compiler/rustc_passes/src/input_stats.rs b/compiler/rustc_passes/src/input_stats.rs index c83610da1aad..fe50b730256b 100644 --- a/compiler/rustc_passes/src/input_stats.rs +++ b/compiler/rustc_passes/src/input_stats.rs @@ -3,7 +3,7 @@ // completely accurate (some things might be counted twice, others missed). use rustc_ast::visit::BoundKind; -use rustc_ast::{self as ast, NodeId, visit as ast_visit}; +use rustc_ast::{self as ast, AttrVec, NodeId, visit as ast_visit}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::thousands::usize_with_underscores; use rustc_hir::{self as hir, AmbigArg, HirId, intravisit as hir_visit}; @@ -709,7 +709,7 @@ impl<'v> ast_visit::Visitor<'v> for StatCollector<'v> { ast_visit::walk_where_predicate(self, p) } - fn visit_fn(&mut self, fk: ast_visit::FnKind<'v>, _: Span, _: NodeId) { + fn visit_fn(&mut self, fk: ast_visit::FnKind<'v>, _: &AttrVec, _: Span, _: NodeId) { self.record("FnDecl", None, fk.decl()); ast_visit::walk_fn(self, fk) } diff --git a/compiler/rustc_passes/src/weak_lang_items.rs b/compiler/rustc_passes/src/weak_lang_items.rs index 93d164e7d01f..26cd9e7f44ff 100644 --- a/compiler/rustc_passes/src/weak_lang_items.rs +++ b/compiler/rustc_passes/src/weak_lang_items.rs @@ -8,6 +8,7 @@ use rustc_hir::weak_lang_items::WEAK_LANG_ITEMS; use rustc_middle::middle::lang_items::required; use rustc_middle::ty::TyCtxt; use rustc_session::config::CrateType; +use rustc_target::spec::Os; use crate::errors::{ MissingLangItem, MissingPanicHandler, PanicUnwindWithoutStd, UnknownExternLangItem, @@ -26,7 +27,7 @@ pub(crate) fn check_crate( if items.eh_personality().is_none() { items.missing.push(LangItem::EhPersonality); } - if tcx.sess.target.os == "emscripten" + if tcx.sess.target.os == Os::Emscripten && items.eh_catch_typeinfo().is_none() && !tcx.sess.opts.unstable_opts.emscripten_wasm_eh { diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs index 8df34ee941b2..c3f6eaccfabc 100644 --- a/compiler/rustc_pattern_analysis/src/rustc.rs +++ b/compiler/rustc_pattern_analysis/src/rustc.rs @@ -462,8 +462,12 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { PatKind::Deref { subpattern } => { fields = vec![self.lower_pat(subpattern).at_index(0)]; arity = 1; - ctor = match ty.kind() { - ty::Ref(..) => Ref, + ctor = match ty.pinned_ref() { + None if ty.is_ref() => Ref, + Some((inner_ty, _)) => { + self.internal_state.has_lowered_deref_pat.set(true); + DerefPattern(RevealedTy(inner_ty)) + } _ => span_bug!( pat.span, "pattern has unexpected type: pat: {:?}, ty: {:?}", diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index 886ffcffbb4d..cd12d5ad10cf 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -1358,7 +1358,7 @@ impl<'a, 'ra, 'tcx> Visitor<'a> for BuildReducedGraphVisitor<'a, 'ra, 'tcx> { // Visit attributes after items for backward compatibility. // This way they can use `macro_rules` defined later. self.visit_vis(&item.vis); - item.kind.walk(item.span, item.id, &item.vis, (), self); + item.kind.walk(&item.attrs, item.span, item.id, &item.vis, (), self); visit::walk_list!(self, visit_attribute, &item.attrs); } _ => visit::walk_item(self, item), diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs index 14538df8187d..ea64a1e6c64d 100644 --- a/compiler/rustc_resolve/src/def_collector.rs +++ b/compiler/rustc_resolve/src/def_collector.rs @@ -193,7 +193,7 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> { }); } - fn visit_fn(&mut self, fn_kind: FnKind<'a>, span: Span, _: NodeId) { + fn visit_fn(&mut self, fn_kind: FnKind<'a>, _: &AttrVec, span: Span, _: NodeId) { match fn_kind { FnKind::Fn( _ctxt, diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 16cbfe3b3c74..107803c5c265 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -1034,7 +1034,7 @@ impl<'ast, 'ra, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'ra, 'tc } } } - fn visit_fn(&mut self, fn_kind: FnKind<'ast>, sp: Span, fn_id: NodeId) { + fn visit_fn(&mut self, fn_kind: FnKind<'ast>, _: &AttrVec, sp: Span, fn_id: NodeId) { let previous_value = self.diag_metadata.current_function; match fn_kind { // Bail if the function is foreign, and thus cannot validly have diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index ad3493d93e80..0b4c52d68b6f 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -3592,8 +3592,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { && (lt.kind == MissingLifetimeKind::Ampersand || lt.kind == MissingLifetimeKind::Underscore) { - let pre = if lt.kind == MissingLifetimeKind::Ampersand - && let Some((kind, _span)) = self.diag_metadata.current_function + let pre = if let Some((kind, _span)) = self.diag_metadata.current_function && let FnKind::Fn(_, _, ast::Fn { sig, .. }) = kind && !sig.decl.inputs.is_empty() && let sugg = sig @@ -3623,10 +3622,12 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { } else { ("one of the", "s") }; + let dotdotdot = + if lt.kind == MissingLifetimeKind::Ampersand { "..." } else { "" }; err.multipart_suggestion_verbose( format!( "instead, you are more likely to want to change {the} \ - argument{s} to be borrowed...", + argument{s} to be borrowed{dotdotdot}", ), sugg, Applicability::MaybeIncorrect, diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index 4a5894c9ffa8..323b49e14a57 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -384,6 +384,7 @@ impl<'ra, 'tcx> ResolverExpand for Resolver<'ra, 'tcx> { // is applied, so they have to be produced by the container's expansion rather // than by individual derives. // - Derives in the container need to know whether one of them is a built-in `Copy`. + // (But see the comment mentioning #124794 below.) // Temporarily take the data to avoid borrow checker conflicts. let mut derive_data = mem::take(&mut self.derive_data); let entry = derive_data.entry(expn_id).or_insert_with(|| DeriveData { @@ -440,7 +441,13 @@ impl<'ra, 'tcx> ResolverExpand for Resolver<'ra, 'tcx> { .collect(); self.helper_attrs.insert(expn_id, helper_attrs); // Mark this derive as having `Copy` either if it has `Copy` itself or if its parent derive - // has `Copy`, to support cases like `#[derive(Clone, Copy)] #[derive(Debug)]`. + // has `Copy`, to support `#[derive(Copy, Clone)]`, `#[derive(Clone, Copy)]`, or + // `#[derive(Copy)] #[derive(Clone)]`. We do this because the code generated for + // `derive(Clone)` changes if `derive(Copy)` is also present. + // + // FIXME(#124794): unfortunately this doesn't work with `#[derive(Clone)] #[derive(Copy)]`. + // When the `Clone` impl is generated the `#[derive(Copy)]` hasn't been processed and + // `has_derive_copy` hasn't been set yet. if entry.has_derive_copy || self.has_derive_copy(parent_scope.expansion) { self.containers_deriving_copy.insert(expn_id); } diff --git a/compiler/rustc_session/src/config/cfg.rs b/compiler/rustc_session/src/config/cfg.rs index 26ff87417ab0..cd0556de5c22 100644 --- a/compiler/rustc_session/src/config/cfg.rs +++ b/compiler/rustc_session/src/config/cfg.rs @@ -239,10 +239,10 @@ pub(crate) fn default_configuration(sess: &Session) -> Cfg { ins_none!(sym::sanitizer_cfi_normalize_integers); } - ins_str!(sym::target_abi, &sess.target.abi); + ins_sym!(sym::target_abi, sess.target.abi.desc_symbol()); ins_sym!(sym::target_arch, sess.target.arch.desc_symbol()); ins_str!(sym::target_endian, sess.target.endian.as_str()); - ins_str!(sym::target_env, &sess.target.env); + ins_sym!(sym::target_env, sess.target.env.desc_symbol()); for family in sess.target.families.as_ref() { ins_str!(sym::target_family, family); @@ -291,14 +291,14 @@ pub(crate) fn default_configuration(sess: &Session) -> Cfg { } } - ins_str!(sym::target_os, &sess.target.os); + ins_sym!(sym::target_os, sess.target.os.desc_symbol()); ins_sym!(sym::target_pointer_width, sym::integer(sess.target.pointer_width)); if sess.opts.unstable_opts.has_thread_local.unwrap_or(sess.target.has_thread_local) { ins_none!(sym::target_thread_local); } - ins_str!(sym::target_vendor, &sess.target.vendor); + ins_sym!(sym::target_vendor, sess.target.vendor_symbol()); // If the user wants a test runner, then add the test cfg. if sess.is_test_crate() { @@ -447,16 +447,16 @@ impl CheckCfg { }; for target in Target::builtins().chain(iter::once(current_target.clone())) { - values_target_abi.insert(Symbol::intern(&target.options.abi)); + values_target_abi.insert(target.options.abi.desc_symbol()); values_target_arch.insert(target.arch.desc_symbol()); values_target_endian.insert(Symbol::intern(target.options.endian.as_str())); - values_target_env.insert(Symbol::intern(&target.options.env)); + values_target_env.insert(target.options.env.desc_symbol()); values_target_family.extend( target.options.families.iter().map(|family| Symbol::intern(family)), ); - values_target_os.insert(Symbol::intern(&target.options.os)); + values_target_os.insert(target.options.os.desc_symbol()); values_target_pointer_width.insert(sym::integer(target.pointer_width)); - values_target_vendor.insert(Symbol::intern(&target.options.vendor)); + values_target_vendor.insert(target.vendor_symbol()); } } } diff --git a/compiler/rustc_session/src/filesearch.rs b/compiler/rustc_session/src/filesearch.rs index f64fa86948c8..12b294e124c8 100644 --- a/compiler/rustc_session/src/filesearch.rs +++ b/compiler/rustc_session/src/filesearch.rs @@ -72,7 +72,7 @@ fn current_dll_path() -> Result { #[cfg(not(target_os = "aix"))] unsafe { - let addr = current_dll_path as usize as *mut _; + let addr = current_dll_path as fn() -> Result as *mut _; let mut info = std::mem::zeroed(); if libc::dladdr(addr, &mut info) == 0 { return Err("dladdr failed".into()); @@ -151,7 +151,10 @@ fn current_dll_path() -> Result { unsafe { GetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, - PCWSTR(current_dll_path as *mut u16), + PCWSTR( + current_dll_path as fn() -> Result + as *mut u16, + ), &mut module, ) } diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 9fb3c35d5ef7..f27b32de565d 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -32,7 +32,7 @@ use rustc_span::source_map::{FilePathMapping, SourceMap}; use rustc_span::{FileNameDisplayPreference, RealFileName, Span, Symbol}; use rustc_target::asm::InlineAsmArch; use rustc_target::spec::{ - Arch, CodeModel, DebuginfoKind, PanicStrategy, RelocModel, RelroLevel, SanitizerSet, + Arch, CodeModel, DebuginfoKind, Os, PanicStrategy, RelocModel, RelroLevel, SanitizerSet, SmallDataThresholdSupport, SplitDebuginfo, StackProtector, SymbolVisibility, Target, TargetTuple, TlsModel, apple, }; @@ -382,7 +382,7 @@ impl Session { } pub fn is_wasi_reactor(&self) -> bool { - self.target.options.os == "wasi" + self.target.options.os == Os::Wasi && matches!( self.opts.unstable_opts.wasi_exec_model, Some(config::WasiExecModel::Reactor) diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 0912bad459da..60a5aa2378e2 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -372,6 +372,7 @@ symbols! { ToString, TokenStream, Trait, + TrivialClone, Try, TryCaptureGeneric, TryCapturePrintable, @@ -611,6 +612,7 @@ symbols! { c_str_literals, c_unwind, c_variadic, + c_variadic_naked_functions, c_void, call, call_mut, @@ -898,7 +900,6 @@ symbols! { doc_primitive, doc_spotlight, doctest, - document_private_items, dotdot: "..", dotdot_in_tuple_patterns, dotdoteq_in_patterns, @@ -2269,6 +2270,7 @@ symbols! { transparent_enums, transparent_unions, trivial_bounds, + trivial_clone, truncf16, truncf32, truncf64, diff --git a/compiler/rustc_target/src/asm/aarch64.rs b/compiler/rustc_target/src/asm/aarch64.rs index 43a8d9ca119d..2db8a7ff3020 100644 --- a/compiler/rustc_target/src/asm/aarch64.rs +++ b/compiler/rustc_target/src/asm/aarch64.rs @@ -4,7 +4,7 @@ use rustc_data_structures::fx::FxIndexSet; use rustc_span::{Symbol, sym}; use super::{InlineAsmArch, InlineAsmType, ModifierInfo}; -use crate::spec::{RelocModel, Target}; +use crate::spec::{Env, Os, RelocModel, Target}; def_reg_class! { AArch64 AArch64InlineAsmRegClass { @@ -75,9 +75,9 @@ pub(crate) fn target_reserves_x18(target: &Target, target_features: &FxIndexSet< // See isX18ReservedByDefault in LLVM for targets reserve x18 by default: // https://github.com/llvm/llvm-project/blob/llvmorg-19.1.0/llvm/lib/TargetParser/AArch64TargetParser.cpp#L102-L105 // Note that +reserve-x18 is currently not set for the above targets. - target.os == "android" - || target.os == "fuchsia" - || target.env == "ohos" + target.os == Os::Android + || target.os == Os::Fuchsia + || target.env == Env::Ohos || target.is_like_darwin || target.is_like_windows || target_features.contains(&sym::reserve_x18) diff --git a/compiler/rustc_target/src/asm/mod.rs b/compiler/rustc_target/src/asm/mod.rs index cd7d9125d7b5..57d9cdad454a 100644 --- a/compiler/rustc_target/src/asm/mod.rs +++ b/compiler/rustc_target/src/asm/mod.rs @@ -273,7 +273,7 @@ impl InlineAsmArch { Arch::Msp430 => Some(Self::Msp430), Arch::M68k => Some(Self::M68k), Arch::CSky => Some(Self::CSKY), - Arch::AmdGpu | Arch::Xtensa | Arch::Unknown(_) => None, + Arch::AmdGpu | Arch::Xtensa | Arch::Other(_) => None, } } } diff --git a/compiler/rustc_target/src/asm/powerpc.rs b/compiler/rustc_target/src/asm/powerpc.rs index 09682ee9d4e6..e72984057a82 100644 --- a/compiler/rustc_target/src/asm/powerpc.rs +++ b/compiler/rustc_target/src/asm/powerpc.rs @@ -4,7 +4,7 @@ use rustc_data_structures::fx::FxIndexSet; use rustc_span::Symbol; use super::{InlineAsmArch, InlineAsmType, ModifierInfo}; -use crate::spec::{RelocModel, Target}; +use crate::spec::{Abi, RelocModel, Target}; def_reg_class! { PowerPC PowerPCInlineAsmRegClass { @@ -104,10 +104,10 @@ fn reserved_v20to31( _is_clobber: bool, ) -> Result<(), &'static str> { if target.is_like_aix { - match &*target.options.abi { - "vec-default" => Err("v20-v31 (vs52-vs63) are reserved on vec-default ABI"), - "vec-extabi" => Ok(()), - _ => unreachable!("unrecognized AIX ABI"), + match &target.options.abi { + Abi::VecDefault => Err("v20-v31 (vs52-vs63) are reserved on vec-default ABI"), + Abi::VecExtAbi => Ok(()), + abi => unreachable!("unrecognized AIX ABI: {abi}"), } } else { Ok(()) diff --git a/compiler/rustc_target/src/callconv/aarch64.rs b/compiler/rustc_target/src/callconv/aarch64.rs index b86d0baeb942..cb2b7f4455c6 100644 --- a/compiler/rustc_target/src/callconv/aarch64.rs +++ b/compiler/rustc_target/src/callconv/aarch64.rs @@ -3,7 +3,7 @@ use std::iter; use rustc_abi::{BackendRepr, HasDataLayout, Primitive, TyAbiInterface}; use crate::callconv::{ArgAbi, FnAbi, Reg, RegKind, Uniform}; -use crate::spec::{HasTargetSpec, Target}; +use crate::spec::{Abi, HasTargetSpec, Target}; /// Indicates the variant of the AArch64 ABI we are compiling for. /// Used to accommodate Apple and Microsoft's deviations from the usual AAPCS ABI. @@ -33,7 +33,7 @@ where RegKind::Integer => false, // The softfloat ABI treats floats like integers, so they // do not get homogeneous aggregate treatment. - RegKind::Float => cx.target_spec().abi != "softfloat", + RegKind::Float => cx.target_spec().abi != Abi::SoftFloat, RegKind::Vector => size.bits() == 64 || size.bits() == 128, }; @@ -42,7 +42,7 @@ where } fn softfloat_float_abi(target: &Target, arg: &mut ArgAbi<'_, Ty>) { - if target.abi != "softfloat" { + if target.abi != Abi::SoftFloat { return; } // Do *not* use the float registers for passing arguments, as that would make LLVM pick the ABI diff --git a/compiler/rustc_target/src/callconv/mod.rs b/compiler/rustc_target/src/callconv/mod.rs index 147b17b24bb5..878340143582 100644 --- a/compiler/rustc_target/src/callconv/mod.rs +++ b/compiler/rustc_target/src/callconv/mod.rs @@ -702,7 +702,7 @@ impl<'a, Ty> FnAbi<'a, Ty> { Arch::RiscV32 | Arch::RiscV64 => riscv::compute_abi_info(cx, self), Arch::Wasm32 | Arch::Wasm64 => wasm::compute_abi_info(cx, self), Arch::Bpf => bpf::compute_abi_info(cx, self), - arch @ (Arch::PowerPC64LE | Arch::SpirV | Arch::Unknown(_)) => { + arch @ (Arch::PowerPC64LE | Arch::SpirV | Arch::Other(_)) => { panic!("no lowering implemented for {arch}") } } diff --git a/compiler/rustc_target/src/callconv/powerpc.rs b/compiler/rustc_target/src/callconv/powerpc.rs index 67066672eca3..2b6a104e1221 100644 --- a/compiler/rustc_target/src/callconv/powerpc.rs +++ b/compiler/rustc_target/src/callconv/powerpc.rs @@ -1,7 +1,7 @@ use rustc_abi::TyAbiInterface; use crate::callconv::{ArgAbi, FnAbi}; -use crate::spec::HasTargetSpec; +use crate::spec::{Env, HasTargetSpec, Os}; fn classify_ret(ret: &mut ArgAbi<'_, Ty>) { if ret.layout.is_aggregate() { @@ -17,8 +17,8 @@ where { if arg.is_ignore() { // powerpc-unknown-linux-{gnu,musl,uclibc} doesn't ignore ZSTs. - if cx.target_spec().os == "linux" - && matches!(&*cx.target_spec().env, "gnu" | "musl" | "uclibc") + if cx.target_spec().os == Os::Linux + && matches!(cx.target_spec().env, Env::Gnu | Env::Musl | Env::Uclibc) && arg.layout.is_zst() { arg.make_indirect_from_ignore(); diff --git a/compiler/rustc_target/src/callconv/powerpc64.rs b/compiler/rustc_target/src/callconv/powerpc64.rs index 380b280fbc64..a77724a572dc 100644 --- a/compiler/rustc_target/src/callconv/powerpc64.rs +++ b/compiler/rustc_target/src/callconv/powerpc64.rs @@ -5,7 +5,7 @@ use rustc_abi::{Endian, HasDataLayout, TyAbiInterface}; use crate::callconv::{Align, ArgAbi, FnAbi, Reg, RegKind, Uniform}; -use crate::spec::HasTargetSpec; +use crate::spec::{Env, HasTargetSpec, Os}; #[derive(Debug, Clone, Copy, PartialEq)] enum ABI { @@ -106,9 +106,9 @@ where Ty: TyAbiInterface<'a, C> + Copy, C: HasDataLayout + HasTargetSpec, { - let abi = if cx.target_spec().env == "musl" || cx.target_spec().os == "freebsd" { + let abi = if cx.target_spec().env == Env::Musl || cx.target_spec().os == Os::FreeBsd { ELFv2 - } else if cx.target_spec().os == "aix" { + } else if cx.target_spec().os == Os::Aix { AIX } else { match cx.data_layout().endian { diff --git a/compiler/rustc_target/src/callconv/s390x.rs b/compiler/rustc_target/src/callconv/s390x.rs index c2f2b47690ca..a2ff6f5a3a03 100644 --- a/compiler/rustc_target/src/callconv/s390x.rs +++ b/compiler/rustc_target/src/callconv/s390x.rs @@ -4,7 +4,7 @@ use rustc_abi::{BackendRepr, HasDataLayout, TyAbiInterface}; use crate::callconv::{ArgAbi, FnAbi, Reg, RegKind}; -use crate::spec::HasTargetSpec; +use crate::spec::{Env, HasTargetSpec, Os}; fn classify_ret(ret: &mut ArgAbi<'_, Ty>) { let size = ret.layout.size; @@ -29,8 +29,8 @@ where } if arg.is_ignore() { // s390x-unknown-linux-{gnu,musl,uclibc} doesn't ignore ZSTs. - if cx.target_spec().os == "linux" - && matches!(&*cx.target_spec().env, "gnu" | "musl" | "uclibc") + if cx.target_spec().os == Os::Linux + && matches!(cx.target_spec().env, Env::Gnu | Env::Musl | Env::Uclibc) && arg.layout.is_zst() { arg.make_indirect_from_ignore(); diff --git a/compiler/rustc_target/src/callconv/sparc64.rs b/compiler/rustc_target/src/callconv/sparc64.rs index 911eaaf08f82..73e9a46ed5b2 100644 --- a/compiler/rustc_target/src/callconv/sparc64.rs +++ b/compiler/rustc_target/src/callconv/sparc64.rs @@ -6,7 +6,7 @@ use rustc_abi::{ }; use crate::callconv::{ArgAbi, ArgAttribute, CastTarget, FnAbi, Uniform}; -use crate::spec::HasTargetSpec; +use crate::spec::{Env, HasTargetSpec, Os}; #[derive(Clone, Debug)] struct Sdata { @@ -223,8 +223,8 @@ where for arg in fn_abi.args.iter_mut() { if arg.is_ignore() { // sparc64-unknown-linux-{gnu,musl,uclibc} doesn't ignore ZSTs. - if cx.target_spec().os == "linux" - && matches!(&*cx.target_spec().env, "gnu" | "musl" | "uclibc") + if cx.target_spec().os == Os::Linux + && matches!(cx.target_spec().env, Env::Gnu | Env::Musl | Env::Uclibc) && arg.layout.is_zst() { arg.make_indirect_from_ignore(); diff --git a/compiler/rustc_target/src/lib.rs b/compiler/rustc_target/src/lib.rs index 2d83caa07676..1210169b3a5c 100644 --- a/compiler/rustc_target/src/lib.rs +++ b/compiler/rustc_target/src/lib.rs @@ -9,7 +9,9 @@ // tidy-alphabetical-start #![cfg_attr(bootstrap, feature(debug_closure_helpers))] +#![expect(internal_features)] #![feature(iter_intersperse)] +#![feature(rustc_attrs)] // tidy-alphabetical-end use std::path::{Path, PathBuf}; @@ -135,6 +137,14 @@ macro_rules! target_spec_enum { $( #[$variant_attr:meta] )* $Variant, )* + /// The vast majority of the time, the compiler deals with a fixed + /// set of values, so it is convenient for them to be represented in + /// an enum. However, it is possible to have arbitrary values in a + /// target JSON file (which can be parsed when `--target` is + /// specified). This might occur, for example, for an out-of-tree + /// codegen backend that supports a value (e.g. architecture or OS) + /// that rustc currently doesn't know about. This variant exists as + /// an escape hatch for such cases. $( #[$other_variant_attr] )* $OtherVariant(crate::spec::StaticCow), } diff --git a/compiler/rustc_target/src/spec/base/aix.rs b/compiler/rustc_target/src/spec/base/aix.rs index aa42b4d1c502..76e8fb763e58 100644 --- a/compiler/rustc_target/src/spec/base/aix.rs +++ b/compiler/rustc_target/src/spec/base/aix.rs @@ -1,15 +1,16 @@ use rustc_abi::Endian; use crate::spec::{ - BinaryFormat, Cc, CodeModel, LinkOutputKind, LinkerFlavor, TargetOptions, crt_objects, cvs, + Abi, BinaryFormat, Cc, CodeModel, LinkOutputKind, LinkerFlavor, Os, TargetOptions, crt_objects, + cvs, }; pub(crate) fn opts() -> TargetOptions { TargetOptions { - abi: "vec-extabi".into(), + abi: Abi::VecExtAbi, code_model: Some(CodeModel::Large), cpu: "pwr7".into(), - os: "aix".into(), + os: Os::Aix, vendor: "ibm".into(), dynamic_linking: true, endian: Endian::Big, diff --git a/compiler/rustc_target/src/spec/base/android.rs b/compiler/rustc_target/src/spec/base/android.rs index df2757aaabf6..c7f5d863bf67 100644 --- a/compiler/rustc_target/src/spec/base/android.rs +++ b/compiler/rustc_target/src/spec/base/android.rs @@ -1,8 +1,8 @@ -use crate::spec::{SanitizerSet, TargetOptions, TlsModel, base}; +use crate::spec::{Os, SanitizerSet, TargetOptions, TlsModel, base}; pub(crate) fn opts() -> TargetOptions { let mut base = base::linux::opts(); - base.os = "android".into(); + base.os = Os::Android; base.is_like_android = true; base.default_dwarf_version = 2; base.tls_model = TlsModel::Emulated; diff --git a/compiler/rustc_target/src/spec/base/apple/mod.rs b/compiler/rustc_target/src/spec/base/apple/mod.rs index 047bc9b8518b..542c5e278499 100644 --- a/compiler/rustc_target/src/spec/base/apple/mod.rs +++ b/compiler/rustc_target/src/spec/base/apple/mod.rs @@ -4,8 +4,8 @@ use std::num::ParseIntError; use std::str::FromStr; use crate::spec::{ - BinaryFormat, Cc, DebuginfoKind, FloatAbi, FramePointer, LinkerFlavor, Lld, RustcAbi, - SplitDebuginfo, StackProbeType, StaticCow, Target, TargetOptions, cvs, + Abi, BinaryFormat, Cc, DebuginfoKind, Env, FloatAbi, FramePointer, LinkerFlavor, Lld, Os, + RustcAbi, SplitDebuginfo, StackProbeType, StaticCow, Target, TargetOptions, cvs, }; #[cfg(test)] @@ -94,11 +94,25 @@ pub(crate) enum TargetEnv { } impl TargetEnv { - fn target_env(self) -> &'static str { + fn target_env(self) -> Env { match self { - Self::Normal => "", - Self::MacCatalyst => "macabi", - Self::Simulator => "sim", + Self::Normal => Env::Unspecified, + Self::MacCatalyst => Env::MacAbi, + Self::Simulator => Env::Sim, + } + } + + // NOTE: We originally set `cfg(target_abi = "macabi")` / `cfg(target_abi = "sim")`, + // before it was discovered that those are actually environments: + // https://github.com/rust-lang/rust/issues/133331 + // + // But let's continue setting them for backwards compatibility. + // FIXME(madsmtm): Warn about using these in the future. + fn target_abi(self) -> Abi { + match self { + Self::Normal => Abi::Unspecified, + Self::MacCatalyst => Abi::MacAbi, + Self::Simulator => Abi::Sim, } } } @@ -106,23 +120,19 @@ impl TargetEnv { /// Get the base target options, unversioned LLVM target and `target_arch` from the three /// things that uniquely identify Rust's Apple targets: The OS, the architecture, and the ABI. pub(crate) fn base( - os: &'static str, + os: Os, arch: Arch, env: TargetEnv, ) -> (TargetOptions, StaticCow, crate::spec::Arch) { + let link_env_remove = link_env_remove(&os); + let unversioned_llvm_target = unversioned_llvm_target(&os, arch, env); let mut opts = TargetOptions { llvm_floatabi: Some(FloatAbi::Hard), - os: os.into(), - env: env.target_env().into(), - // NOTE: We originally set `cfg(target_abi = "macabi")` / `cfg(target_abi = "sim")`, - // before it was discovered that those are actually environments: - // https://github.com/rust-lang/rust/issues/133331 - // - // But let's continue setting them for backwards compatibility. - // FIXME(madsmtm): Warn about using these in the future. - abi: env.target_env().into(), + os, + env: env.target_env(), + abi: env.target_abi(), cpu: arch.target_cpu(env).into(), - link_env_remove: link_env_remove(os), + link_env_remove, vendor: "apple".into(), linker_flavor: LinkerFlavor::Darwin(Cc::Yes, Lld::No), // macOS has -dead_strip, which doesn't rely on function_sections @@ -189,23 +199,23 @@ pub(crate) fn base( // All Apple x86-32 targets have SSE2. opts.rustc_abi = Some(RustcAbi::X86Sse2); } - (opts, unversioned_llvm_target(os, arch, env), arch.target_arch()) + (opts, unversioned_llvm_target, arch.target_arch()) } /// Generate part of the LLVM target triple. /// /// See `rustc_codegen_ssa::back::versioned_llvm_target` for the full triple passed to LLVM and /// Clang. -fn unversioned_llvm_target(os: &str, arch: Arch, env: TargetEnv) -> StaticCow { +fn unversioned_llvm_target(os: &Os, arch: Arch, env: TargetEnv) -> StaticCow { let arch = arch.target_name(); // Convert to the "canonical" OS name used by LLVM: // https://github.com/llvm/llvm-project/blob/llvmorg-18.1.8/llvm/lib/TargetParser/Triple.cpp#L236-L282 let os = match os { - "macos" => "macosx", - "ios" => "ios", - "watchos" => "watchos", - "tvos" => "tvos", - "visionos" => "xros", + Os::MacOs => "macosx", + Os::IOs => "ios", + Os::WatchOs => "watchos", + Os::TvOs => "tvos", + Os::VisionOs => "xros", _ => unreachable!("tried to get LLVM target OS for non-Apple platform"), }; let environment = match env { @@ -216,13 +226,13 @@ fn unversioned_llvm_target(os: &str, arch: Arch, env: TargetEnv) -> StaticCow StaticCow<[StaticCow]> { +fn link_env_remove(os: &Os) -> StaticCow<[StaticCow]> { // Apple platforms only officially support macOS as a host for any compilation. // // If building for macOS, we go ahead and remove any erroneous environment state // that's only applicable to cross-OS compilation. Always leave anything for the // host OS alone though. - if os == "macos" { + if *os == Os::MacOs { // `IPHONEOS_DEPLOYMENT_TARGET` must not be set when using the Xcode linker at // "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld", // although this is apparently ignored when using the linker at "/usr/bin/ld". @@ -284,7 +294,7 @@ impl OSVersion { } /// Minimum operating system versions currently supported by `rustc`. - pub fn os_minimum_deployment_target(os: &str) -> Self { + pub fn os_minimum_deployment_target(os: &Os) -> Self { // When bumping a version in here, remember to update the platform-support docs too. // // NOTE: The defaults may change in future `rustc` versions, so if you are looking for the @@ -293,12 +303,14 @@ impl OSVersion { // $ rustc --print deployment-target // ``` let (major, minor, patch) = match os { - "macos" => (10, 12, 0), - "ios" => (10, 0, 0), - "tvos" => (10, 0, 0), - "watchos" => (5, 0, 0), - "visionos" => (1, 0, 0), - _ => unreachable!("tried to get deployment target for non-Apple platform"), + Os::MacOs => (10, 12, 0), + Os::IOs => (10, 0, 0), + Os::TvOs => (10, 0, 0), + Os::WatchOs => (5, 0, 0), + Os::VisionOs => (1, 0, 0), + other => { + unreachable!("tried to get deployment target for non-Apple platform: {:?}", other) + } }; Self { major, minor, patch } } @@ -311,36 +323,36 @@ impl OSVersion { /// This matches what LLVM does, see in part: /// pub fn minimum_deployment_target(target: &Target) -> Self { - let (major, minor, patch) = match (&*target.os, &target.arch, &*target.env) { - ("macos", crate::spec::Arch::AArch64, _) => (11, 0, 0), - ("ios", crate::spec::Arch::AArch64, "macabi") => (14, 0, 0), - ("ios", crate::spec::Arch::AArch64, "sim") => (14, 0, 0), - ("ios", _, _) if target.llvm_target.starts_with("arm64e") => (14, 0, 0), + let (major, minor, patch) = match (&target.os, &target.arch, &target.env) { + (Os::MacOs, crate::spec::Arch::AArch64, _) => (11, 0, 0), + (Os::IOs, crate::spec::Arch::AArch64, Env::MacAbi) => (14, 0, 0), + (Os::IOs, crate::spec::Arch::AArch64, Env::Sim) => (14, 0, 0), + (Os::IOs, _, _) if target.llvm_target.starts_with("arm64e") => (14, 0, 0), // Mac Catalyst defaults to 13.1 in Clang. - ("ios", _, "macabi") => (13, 1, 0), - ("tvos", crate::spec::Arch::AArch64, "sim") => (14, 0, 0), - ("watchos", crate::spec::Arch::AArch64, "sim") => (7, 0, 0), + (Os::IOs, _, Env::MacAbi) => (13, 1, 0), + (Os::TvOs, crate::spec::Arch::AArch64, Env::Sim) => (14, 0, 0), + (Os::WatchOs, crate::spec::Arch::AArch64, Env::Sim) => (7, 0, 0), // True Aarch64 on watchOS (instead of their Aarch64 Ilp32 called `arm64_32`) has been // available since Xcode 14, but it's only actually used more recently in watchOS 26. - ("watchos", crate::spec::Arch::AArch64, "") + (Os::WatchOs, crate::spec::Arch::AArch64, Env::Unspecified) if !target.llvm_target.starts_with("arm64_32") => { (26, 0, 0) } - (os, _, _) => return Self::os_minimum_deployment_target(os), + _ => return Self::os_minimum_deployment_target(&target.os), }; Self { major, minor, patch } } } /// Name of the environment variable used to fetch the deployment target on the given OS. -pub fn deployment_target_env_var(os: &str) -> &'static str { +pub fn deployment_target_env_var(os: &Os) -> &'static str { match os { - "macos" => "MACOSX_DEPLOYMENT_TARGET", - "ios" => "IPHONEOS_DEPLOYMENT_TARGET", - "watchos" => "WATCHOS_DEPLOYMENT_TARGET", - "tvos" => "TVOS_DEPLOYMENT_TARGET", - "visionos" => "XROS_DEPLOYMENT_TARGET", + Os::MacOs => "MACOSX_DEPLOYMENT_TARGET", + Os::IOs => "IPHONEOS_DEPLOYMENT_TARGET", + Os::WatchOs => "WATCHOS_DEPLOYMENT_TARGET", + Os::TvOs => "TVOS_DEPLOYMENT_TARGET", + Os::VisionOs => "XROS_DEPLOYMENT_TARGET", _ => unreachable!("tried to get deployment target env var for non-Apple platform"), } } diff --git a/compiler/rustc_target/src/spec/base/apple/tests.rs b/compiler/rustc_target/src/spec/base/apple/tests.rs index bca86ce33c3d..fd3fd6da9116 100644 --- a/compiler/rustc_target/src/spec/base/apple/tests.rs +++ b/compiler/rustc_target/src/spec/base/apple/tests.rs @@ -4,6 +4,7 @@ use crate::spec::targets::{ aarch64_apple_watchos_sim, i686_apple_darwin, x86_64_apple_darwin, x86_64_apple_ios, x86_64_apple_tvos, x86_64_apple_watchos_sim, }; +use crate::spec::{Abi, Env}; #[test] fn simulator_targets_set_env() { @@ -18,9 +19,9 @@ fn simulator_targets_set_env() { ]; for target in &all_sim_targets { - assert_eq!(target.env, "sim"); + assert_eq!(target.env, Env::Sim); // Ensure backwards compat - assert_eq!(target.abi, "sim"); + assert_eq!(target.abi, Abi::Sim); } } diff --git a/compiler/rustc_target/src/spec/base/cygwin.rs b/compiler/rustc_target/src/spec/base/cygwin.rs index d6ae0a905bf6..fcc2a732c18d 100644 --- a/compiler/rustc_target/src/spec/base/cygwin.rs +++ b/compiler/rustc_target/src/spec/base/cygwin.rs @@ -1,8 +1,8 @@ use std::borrow::Cow; use crate::spec::{ - BinaryFormat, Cc, DebuginfoKind, LinkerFlavor, Lld, SplitDebuginfo, TargetOptions, TlsModel, - cvs, + BinaryFormat, Cc, DebuginfoKind, LinkerFlavor, Lld, Os, SplitDebuginfo, TargetOptions, + TlsModel, cvs, }; pub(crate) fn opts() -> TargetOptions { @@ -24,7 +24,7 @@ pub(crate) fn opts() -> TargetOptions { cygwin_libs, ); TargetOptions { - os: "cygwin".into(), + os: Os::Cygwin, vendor: "pc".into(), // FIXME(#13846) this should be enabled for cygwin function_sections: false, diff --git a/compiler/rustc_target/src/spec/base/dragonfly.rs b/compiler/rustc_target/src/spec/base/dragonfly.rs index 36c9489fb705..af8fd9a03689 100644 --- a/compiler/rustc_target/src/spec/base/dragonfly.rs +++ b/compiler/rustc_target/src/spec/base/dragonfly.rs @@ -1,8 +1,8 @@ -use crate::spec::{RelroLevel, TargetOptions, cvs}; +use crate::spec::{Os, RelroLevel, TargetOptions, cvs}; pub(crate) fn opts() -> TargetOptions { TargetOptions { - os: "dragonfly".into(), + os: Os::Dragonfly, dynamic_linking: true, families: cvs!["unix"], has_rpath: true, diff --git a/compiler/rustc_target/src/spec/base/freebsd.rs b/compiler/rustc_target/src/spec/base/freebsd.rs index 360232933027..6bbb84a653fb 100644 --- a/compiler/rustc_target/src/spec/base/freebsd.rs +++ b/compiler/rustc_target/src/spec/base/freebsd.rs @@ -1,8 +1,8 @@ -use crate::spec::{RelroLevel, TargetOptions, cvs}; +use crate::spec::{Os, RelroLevel, TargetOptions, cvs}; pub(crate) fn opts() -> TargetOptions { TargetOptions { - os: "freebsd".into(), + os: Os::FreeBsd, dynamic_linking: true, families: cvs!["unix"], has_rpath: true, diff --git a/compiler/rustc_target/src/spec/base/fuchsia.rs b/compiler/rustc_target/src/spec/base/fuchsia.rs index 92cb0299ddb2..a43c3e2bab55 100644 --- a/compiler/rustc_target/src/spec/base/fuchsia.rs +++ b/compiler/rustc_target/src/spec/base/fuchsia.rs @@ -1,5 +1,5 @@ use crate::spec::{ - Cc, FramePointer, LinkOutputKind, LinkerFlavor, Lld, TargetOptions, crt_objects, cvs, + Cc, FramePointer, LinkOutputKind, LinkerFlavor, Lld, Os, TargetOptions, crt_objects, cvs, }; pub(crate) fn opts() -> TargetOptions { @@ -30,7 +30,7 @@ pub(crate) fn opts() -> TargetOptions { ); TargetOptions { - os: "fuchsia".into(), + os: Os::Fuchsia, linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), linker: Some("rust-lld".into()), dynamic_linking: true, diff --git a/compiler/rustc_target/src/spec/base/haiku.rs b/compiler/rustc_target/src/spec/base/haiku.rs index 35e4cd2962ee..d4e6545a9f58 100644 --- a/compiler/rustc_target/src/spec/base/haiku.rs +++ b/compiler/rustc_target/src/spec/base/haiku.rs @@ -1,8 +1,8 @@ -use crate::spec::{RelroLevel, TargetOptions, cvs}; +use crate::spec::{Os, RelroLevel, TargetOptions, cvs}; pub(crate) fn opts() -> TargetOptions { TargetOptions { - os: "haiku".into(), + os: Os::Haiku, dynamic_linking: true, families: cvs!["unix"], relro_level: RelroLevel::Full, diff --git a/compiler/rustc_target/src/spec/base/helenos.rs b/compiler/rustc_target/src/spec/base/helenos.rs index 8d6f406e41f7..e26633121b82 100644 --- a/compiler/rustc_target/src/spec/base/helenos.rs +++ b/compiler/rustc_target/src/spec/base/helenos.rs @@ -1,8 +1,8 @@ -use crate::spec::{PanicStrategy, RelroLevel, StackProbeType, TargetOptions}; +use crate::spec::{Os, PanicStrategy, RelroLevel, StackProbeType, TargetOptions}; pub(crate) fn opts() -> TargetOptions { TargetOptions { - os: "helenos".into(), + os: Os::HelenOs, dynamic_linking: true, // we need the linker to keep libgcc and friends diff --git a/compiler/rustc_target/src/spec/base/hermit.rs b/compiler/rustc_target/src/spec/base/hermit.rs index 971abef80d9b..1fa50c25439c 100644 --- a/compiler/rustc_target/src/spec/base/hermit.rs +++ b/compiler/rustc_target/src/spec/base/hermit.rs @@ -1,8 +1,8 @@ -use crate::spec::{Cc, LinkerFlavor, Lld, PanicStrategy, TargetOptions, TlsModel}; +use crate::spec::{Cc, LinkerFlavor, Lld, Os, PanicStrategy, TargetOptions, TlsModel}; pub(crate) fn opts() -> TargetOptions { TargetOptions { - os: "hermit".into(), + os: Os::Hermit, linker: Some("rust-lld".into()), linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), tls_model: TlsModel::InitialExec, diff --git a/compiler/rustc_target/src/spec/base/hurd.rs b/compiler/rustc_target/src/spec/base/hurd.rs index dcb346ddecca..c814fe934291 100644 --- a/compiler/rustc_target/src/spec/base/hurd.rs +++ b/compiler/rustc_target/src/spec/base/hurd.rs @@ -1,8 +1,8 @@ -use crate::spec::{RelroLevel, TargetOptions, cvs}; +use crate::spec::{Os, RelroLevel, TargetOptions, cvs}; pub(crate) fn opts() -> TargetOptions { TargetOptions { - os: "hurd".into(), + os: Os::Hurd, dynamic_linking: true, families: cvs!["unix"], has_rpath: true, diff --git a/compiler/rustc_target/src/spec/base/hurd_gnu.rs b/compiler/rustc_target/src/spec/base/hurd_gnu.rs index d33372b41b90..cc1696b3ab04 100644 --- a/compiler/rustc_target/src/spec/base/hurd_gnu.rs +++ b/compiler/rustc_target/src/spec/base/hurd_gnu.rs @@ -1,5 +1,5 @@ -use crate::spec::{TargetOptions, base}; +use crate::spec::{Env, TargetOptions, base}; pub(crate) fn opts() -> TargetOptions { - TargetOptions { env: "gnu".into(), ..base::hurd::opts() } + TargetOptions { env: Env::Gnu, ..base::hurd::opts() } } diff --git a/compiler/rustc_target/src/spec/base/illumos.rs b/compiler/rustc_target/src/spec/base/illumos.rs index 2391b229e5ba..50ff14bbf0a2 100644 --- a/compiler/rustc_target/src/spec/base/illumos.rs +++ b/compiler/rustc_target/src/spec/base/illumos.rs @@ -1,4 +1,4 @@ -use crate::spec::{Cc, FramePointer, LinkerFlavor, TargetOptions, cvs}; +use crate::spec::{Cc, FramePointer, LinkerFlavor, Os, TargetOptions, cvs}; pub(crate) fn opts() -> TargetOptions { let late_link_args = TargetOptions::link_args( @@ -25,7 +25,7 @@ pub(crate) fn opts() -> TargetOptions { ); TargetOptions { - os: "illumos".into(), + os: Os::Illumos, dynamic_linking: true, has_rpath: true, families: cvs!["unix"], diff --git a/compiler/rustc_target/src/spec/base/l4re.rs b/compiler/rustc_target/src/spec/base/l4re.rs index 072a6a1001bd..8722c8a71e23 100644 --- a/compiler/rustc_target/src/spec/base/l4re.rs +++ b/compiler/rustc_target/src/spec/base/l4re.rs @@ -1,9 +1,9 @@ -use crate::spec::{Cc, LinkerFlavor, PanicStrategy, RelocModel, TargetOptions, cvs}; +use crate::spec::{Cc, Env, LinkerFlavor, Os, PanicStrategy, RelocModel, TargetOptions, cvs}; pub(crate) fn opts() -> TargetOptions { TargetOptions { - os: "l4re".into(), - env: "uclibc".into(), + os: Os::L4Re, + env: Env::Uclibc, linker_flavor: LinkerFlavor::Unix(Cc::No), panic_strategy: PanicStrategy::Abort, linker: Some("l4-bender".into()), diff --git a/compiler/rustc_target/src/spec/base/linux.rs b/compiler/rustc_target/src/spec/base/linux.rs index 26e4590cf5e6..e7757fd4726c 100644 --- a/compiler/rustc_target/src/spec/base/linux.rs +++ b/compiler/rustc_target/src/spec/base/linux.rs @@ -1,10 +1,10 @@ use std::borrow::Cow; -use crate::spec::{RelroLevel, SplitDebuginfo, TargetOptions, cvs}; +use crate::spec::{Os, RelroLevel, SplitDebuginfo, TargetOptions, cvs}; pub(crate) fn opts() -> TargetOptions { TargetOptions { - os: "linux".into(), + os: Os::Linux, dynamic_linking: true, families: cvs!["unix"], has_rpath: true, diff --git a/compiler/rustc_target/src/spec/base/linux_gnu.rs b/compiler/rustc_target/src/spec/base/linux_gnu.rs index 2fcd8c61a9c6..7a907c802df2 100644 --- a/compiler/rustc_target/src/spec/base/linux_gnu.rs +++ b/compiler/rustc_target/src/spec/base/linux_gnu.rs @@ -1,7 +1,7 @@ -use crate::spec::{Cc, LinkerFlavor, Lld, TargetOptions, base}; +use crate::spec::{Cc, Env, LinkerFlavor, Lld, TargetOptions, base}; pub(crate) fn opts() -> TargetOptions { - let mut base = TargetOptions { env: "gnu".into(), ..base::linux::opts() }; + let mut base = TargetOptions { env: Env::Gnu, ..base::linux::opts() }; // When we're asked to use the `rust-lld` linker by default, set the appropriate lld-using // linker flavor, and self-contained linker component. diff --git a/compiler/rustc_target/src/spec/base/linux_musl.rs b/compiler/rustc_target/src/spec/base/linux_musl.rs index 1bef602404e5..6d3124b559b1 100644 --- a/compiler/rustc_target/src/spec/base/linux_musl.rs +++ b/compiler/rustc_target/src/spec/base/linux_musl.rs @@ -1,8 +1,8 @@ -use crate::spec::{LinkSelfContainedDefault, TargetOptions, base, crt_objects}; +use crate::spec::{Env, LinkSelfContainedDefault, TargetOptions, base, crt_objects}; pub(crate) fn opts() -> TargetOptions { TargetOptions { - env: "musl".into(), + env: Env::Musl, pre_link_objects_self_contained: crt_objects::pre_musl_self_contained(), post_link_objects_self_contained: crt_objects::post_musl_self_contained(), link_self_contained: LinkSelfContainedDefault::InferredForMusl, diff --git a/compiler/rustc_target/src/spec/base/linux_ohos.rs b/compiler/rustc_target/src/spec/base/linux_ohos.rs index 1b7f1e196664..dee78fb325c1 100644 --- a/compiler/rustc_target/src/spec/base/linux_ohos.rs +++ b/compiler/rustc_target/src/spec/base/linux_ohos.rs @@ -1,8 +1,8 @@ -use crate::spec::{TargetOptions, TlsModel, base}; +use crate::spec::{Env, TargetOptions, TlsModel, base}; pub(crate) fn opts() -> TargetOptions { TargetOptions { - env: "ohos".into(), + env: Env::Ohos, crt_static_default: false, tls_model: TlsModel::Emulated, has_thread_local: false, diff --git a/compiler/rustc_target/src/spec/base/linux_uclibc.rs b/compiler/rustc_target/src/spec/base/linux_uclibc.rs index 40801b76dca7..c65a3b9139f1 100644 --- a/compiler/rustc_target/src/spec/base/linux_uclibc.rs +++ b/compiler/rustc_target/src/spec/base/linux_uclibc.rs @@ -1,5 +1,5 @@ -use crate::spec::{TargetOptions, base}; +use crate::spec::{Env, TargetOptions, base}; pub(crate) fn opts() -> TargetOptions { - TargetOptions { env: "uclibc".into(), ..base::linux::opts() } + TargetOptions { env: Env::Uclibc, ..base::linux::opts() } } diff --git a/compiler/rustc_target/src/spec/base/linux_wasm.rs b/compiler/rustc_target/src/spec/base/linux_wasm.rs index a8c137c22a97..994299e5c025 100644 --- a/compiler/rustc_target/src/spec/base/linux_wasm.rs +++ b/compiler/rustc_target/src/spec/base/linux_wasm.rs @@ -2,8 +2,8 @@ //! aspects from their respective base targets use crate::spec::{ - Cc, LinkSelfContainedDefault, LinkerFlavor, PanicStrategy, RelocModel, TargetOptions, TlsModel, - add_link_args, crt_objects, cvs, + Cc, Env, LinkSelfContainedDefault, LinkerFlavor, Os, PanicStrategy, RelocModel, TargetOptions, + TlsModel, add_link_args, crt_objects, cvs, }; pub(crate) fn opts() -> TargetOptions { @@ -57,8 +57,8 @@ pub(crate) fn opts() -> TargetOptions { TargetOptions { is_like_wasm: true, families: cvs!["wasm", "unix"], - os: "linux".into(), - env: "musl".into(), + os: Os::Linux, + env: Env::Musl, // we allow dynamic linking, but only cdylibs. Basically we allow a // final library artifact that exports some symbols (a wasm module) but diff --git a/compiler/rustc_target/src/spec/base/lynxos178.rs b/compiler/rustc_target/src/spec/base/lynxos178.rs index b9434ff5faaf..3ce53d59949c 100644 --- a/compiler/rustc_target/src/spec/base/lynxos178.rs +++ b/compiler/rustc_target/src/spec/base/lynxos178.rs @@ -1,12 +1,12 @@ use std::borrow::Cow; use crate::spec::{ - PanicStrategy, RelocModel, RelroLevel, SplitDebuginfo, StackProbeType, TargetOptions, cvs, + Os, PanicStrategy, RelocModel, RelroLevel, SplitDebuginfo, StackProbeType, TargetOptions, cvs, }; pub(crate) fn opts() -> TargetOptions { TargetOptions { - os: "lynxos178".into(), + os: Os::LynxOs178, dynamic_linking: false, families: cvs!["unix"], position_independent_executables: false, diff --git a/compiler/rustc_target/src/spec/base/managarm_mlibc.rs b/compiler/rustc_target/src/spec/base/managarm_mlibc.rs index da3856b212d9..2384fc37d84a 100644 --- a/compiler/rustc_target/src/spec/base/managarm_mlibc.rs +++ b/compiler/rustc_target/src/spec/base/managarm_mlibc.rs @@ -1,9 +1,9 @@ -use crate::spec::{RelroLevel, TargetOptions, cvs}; +use crate::spec::{Env, Os, RelroLevel, TargetOptions, cvs}; pub(crate) fn opts() -> TargetOptions { TargetOptions { - os: "managarm".into(), - env: "mlibc".into(), + os: Os::Managarm, + env: Env::Mlibc, dynamic_linking: true, executables: true, families: cvs!["unix"], diff --git a/compiler/rustc_target/src/spec/base/motor.rs b/compiler/rustc_target/src/spec/base/motor.rs index 18485b2cef2f..7b75c9bf253a 100644 --- a/compiler/rustc_target/src/spec/base/motor.rs +++ b/compiler/rustc_target/src/spec/base/motor.rs @@ -1,5 +1,5 @@ use crate::spec::{ - Cc, FramePointer, LinkerFlavor, Lld, PanicStrategy, StackProbeType, TargetOptions, + Cc, FramePointer, LinkerFlavor, Lld, Os, PanicStrategy, StackProbeType, TargetOptions, }; pub(crate) fn opts() -> TargetOptions { @@ -16,7 +16,7 @@ pub(crate) fn opts() -> TargetOptions { ], ); TargetOptions { - os: "motor".into(), + os: Os::Motor, executables: true, // TLS is false below because if true, the compiler assumes // we handle TLS at the ELF loading level, which we don't. diff --git a/compiler/rustc_target/src/spec/base/netbsd.rs b/compiler/rustc_target/src/spec/base/netbsd.rs index b92d8933a27a..566cebdf744c 100644 --- a/compiler/rustc_target/src/spec/base/netbsd.rs +++ b/compiler/rustc_target/src/spec/base/netbsd.rs @@ -1,8 +1,8 @@ -use crate::spec::{RelroLevel, TargetOptions, cvs}; +use crate::spec::{Os, RelroLevel, TargetOptions, cvs}; pub(crate) fn opts() -> TargetOptions { TargetOptions { - os: "netbsd".into(), + os: Os::NetBsd, dynamic_linking: true, families: cvs!["unix"], no_default_libraries: false, diff --git a/compiler/rustc_target/src/spec/base/nto_qnx.rs b/compiler/rustc_target/src/spec/base/nto_qnx.rs index 119c5ec98f95..417ac0bc0189 100644 --- a/compiler/rustc_target/src/spec/base/nto_qnx.rs +++ b/compiler/rustc_target/src/spec/base/nto_qnx.rs @@ -1,5 +1,5 @@ use crate::spec::{ - Cc, LinkArgs, LinkerFlavor, Lld, RelroLevel, Target, TargetMetadata, TargetOptions, cvs, + Cc, LinkArgs, LinkerFlavor, Lld, Os, RelroLevel, Target, TargetMetadata, TargetOptions, cvs, }; pub(crate) fn opts() -> TargetOptions { @@ -11,7 +11,7 @@ pub(crate) fn opts() -> TargetOptions { has_rpath: true, has_thread_local: false, linker: Some("qcc".into()), - os: "nto".into(), + os: Os::Nto, // We want backtraces to work by default and they rely on unwind tables // (regardless of `-C panic` strategy). default_uwtable: true, diff --git a/compiler/rustc_target/src/spec/base/openbsd.rs b/compiler/rustc_target/src/spec/base/openbsd.rs index 481fbdf0b08e..84395a407895 100644 --- a/compiler/rustc_target/src/spec/base/openbsd.rs +++ b/compiler/rustc_target/src/spec/base/openbsd.rs @@ -1,8 +1,8 @@ -use crate::spec::{FramePointer, RelroLevel, TargetOptions, TlsModel, cvs}; +use crate::spec::{FramePointer, Os, RelroLevel, TargetOptions, TlsModel, cvs}; pub(crate) fn opts() -> TargetOptions { TargetOptions { - os: "openbsd".into(), + os: Os::OpenBsd, dynamic_linking: true, families: cvs!["unix"], has_rpath: true, diff --git a/compiler/rustc_target/src/spec/base/redox.rs b/compiler/rustc_target/src/spec/base/redox.rs index e9b47f3fa3fd..fc12cbb7b2b4 100644 --- a/compiler/rustc_target/src/spec/base/redox.rs +++ b/compiler/rustc_target/src/spec/base/redox.rs @@ -1,9 +1,9 @@ -use crate::spec::{Cc, LinkerFlavor, Lld, RelroLevel, TargetOptions, cvs}; +use crate::spec::{Cc, Env, LinkerFlavor, Lld, Os, RelroLevel, TargetOptions, cvs}; pub(crate) fn opts() -> TargetOptions { TargetOptions { - os: "redox".into(), - env: "relibc".into(), + os: Os::Redox, + env: Env::Relibc, dynamic_linking: true, families: cvs!["unix"], has_rpath: true, diff --git a/compiler/rustc_target/src/spec/base/solaris.rs b/compiler/rustc_target/src/spec/base/solaris.rs index 22288b86e2ec..be43e44557b7 100644 --- a/compiler/rustc_target/src/spec/base/solaris.rs +++ b/compiler/rustc_target/src/spec/base/solaris.rs @@ -1,8 +1,8 @@ -use crate::spec::{Cc, LinkerFlavor, TargetOptions, cvs}; +use crate::spec::{Cc, LinkerFlavor, Os, TargetOptions, cvs}; pub(crate) fn opts() -> TargetOptions { TargetOptions { - os: "solaris".into(), + os: Os::Solaris, dynamic_linking: true, has_rpath: true, families: cvs!["unix"], diff --git a/compiler/rustc_target/src/spec/base/solid.rs b/compiler/rustc_target/src/spec/base/solid.rs index fd55e1d15014..042942a5a196 100644 --- a/compiler/rustc_target/src/spec/base/solid.rs +++ b/compiler/rustc_target/src/spec/base/solid.rs @@ -1,8 +1,8 @@ -use crate::spec::{FramePointer, TargetOptions}; +use crate::spec::{FramePointer, Os, TargetOptions}; -pub(crate) fn opts(kernel: &str) -> TargetOptions { +pub(crate) fn opts() -> TargetOptions { TargetOptions { - os: format!("solid_{kernel}").into(), + os: Os::SolidAsp3, vendor: "kmc".into(), executables: false, frame_pointer: FramePointer::NonLeaf, diff --git a/compiler/rustc_target/src/spec/base/teeos.rs b/compiler/rustc_target/src/spec/base/teeos.rs index ecd9752c213e..f78ea035b221 100644 --- a/compiler/rustc_target/src/spec/base/teeos.rs +++ b/compiler/rustc_target/src/spec/base/teeos.rs @@ -1,4 +1,6 @@ -use crate::spec::{Cc, LinkerFlavor, Lld, PanicStrategy, RelroLevel, TargetOptions, add_link_args}; +use crate::spec::{ + Cc, LinkerFlavor, Lld, Os, PanicStrategy, RelroLevel, TargetOptions, add_link_args, +}; pub(crate) fn opts() -> TargetOptions { let lld_args = &["-zmax-page-size=4096", "-znow", "-ztext", "--execute-only"]; @@ -8,8 +10,7 @@ pub(crate) fn opts() -> TargetOptions { add_link_args(&mut pre_link_args, LinkerFlavor::Gnu(Cc::Yes, Lld::No), cc_args); TargetOptions { - os: "teeos".into(), - vendor: "unknown".into(), + os: Os::TeeOs, dynamic_linking: true, linker_flavor: LinkerFlavor::Gnu(Cc::Yes, Lld::No), // rpath hardcodes -Wl, so it can't be used together with ld.lld. diff --git a/compiler/rustc_target/src/spec/base/uefi_msvc.rs b/compiler/rustc_target/src/spec/base/uefi_msvc.rs index 4766eab7fd7c..99005715018a 100644 --- a/compiler/rustc_target/src/spec/base/uefi_msvc.rs +++ b/compiler/rustc_target/src/spec/base/uefi_msvc.rs @@ -9,7 +9,7 @@ // the timer-interrupt. Device-drivers are required to use polling-based models. Furthermore, all // code runs in the same environment, no process separation is supported. -use crate::spec::{LinkerFlavor, Lld, PanicStrategy, StackProbeType, TargetOptions, base}; +use crate::spec::{LinkerFlavor, Lld, Os, PanicStrategy, StackProbeType, TargetOptions, base}; pub(crate) fn opts() -> TargetOptions { let mut base = base::msvc::opts(); @@ -35,7 +35,7 @@ pub(crate) fn opts() -> TargetOptions { ); TargetOptions { - os: "uefi".into(), + os: Os::Uefi, linker_flavor: LinkerFlavor::Msvc(Lld::Yes), disable_redzone: true, exe_suffix: ".efi".into(), diff --git a/compiler/rustc_target/src/spec/base/unikraft_linux_musl.rs b/compiler/rustc_target/src/spec/base/unikraft_linux_musl.rs index 319a6182303b..4efcc4b03a95 100644 --- a/compiler/rustc_target/src/spec/base/unikraft_linux_musl.rs +++ b/compiler/rustc_target/src/spec/base/unikraft_linux_musl.rs @@ -1,9 +1,9 @@ -use crate::spec::{PanicStrategy, RelocModel, TargetOptions, cvs}; +use crate::spec::{Env, Os, PanicStrategy, RelocModel, TargetOptions, cvs}; pub(crate) fn opts() -> TargetOptions { TargetOptions { - os: "linux".into(), - env: "musl".into(), + os: Os::Linux, + env: Env::Musl, vendor: "unikraft".into(), linker: Some("kraftld".into()), relocation_model: RelocModel::Static, diff --git a/compiler/rustc_target/src/spec/base/vxworks.rs b/compiler/rustc_target/src/spec/base/vxworks.rs index bb0d00f4a4c0..129554b5aae4 100644 --- a/compiler/rustc_target/src/spec/base/vxworks.rs +++ b/compiler/rustc_target/src/spec/base/vxworks.rs @@ -1,9 +1,9 @@ -use crate::spec::{TargetOptions, cvs}; +use crate::spec::{Env, Os, TargetOptions, cvs}; pub(crate) fn opts() -> TargetOptions { TargetOptions { - os: "vxworks".into(), - env: "gnu".into(), + os: Os::VxWorks, + env: Env::Gnu, vendor: "wrs".into(), linker: Some("wr-c++".into()), exe_suffix: ".vxe".into(), diff --git a/compiler/rustc_target/src/spec/base/windows_gnu.rs b/compiler/rustc_target/src/spec/base/windows_gnu.rs index 2867428e42f7..d2fe42b90306 100644 --- a/compiler/rustc_target/src/spec/base/windows_gnu.rs +++ b/compiler/rustc_target/src/spec/base/windows_gnu.rs @@ -1,8 +1,8 @@ use std::borrow::Cow; use crate::spec::{ - BinaryFormat, Cc, DebuginfoKind, LinkSelfContainedDefault, LinkerFlavor, Lld, SplitDebuginfo, - TargetOptions, add_link_args, crt_objects, cvs, + BinaryFormat, Cc, DebuginfoKind, Env, LinkSelfContainedDefault, LinkerFlavor, Lld, Os, + SplitDebuginfo, TargetOptions, add_link_args, crt_objects, cvs, }; pub(crate) fn opts() -> TargetOptions { @@ -77,8 +77,8 @@ pub(crate) fn opts() -> TargetOptions { ); TargetOptions { - os: "windows".into(), - env: "gnu".into(), + os: Os::Windows, + env: Env::Gnu, vendor: "pc".into(), // FIXME(#13846) this should be enabled for windows function_sections: false, diff --git a/compiler/rustc_target/src/spec/base/windows_gnullvm.rs b/compiler/rustc_target/src/spec/base/windows_gnullvm.rs index f24ad781e2b8..58aff198a660 100644 --- a/compiler/rustc_target/src/spec/base/windows_gnullvm.rs +++ b/compiler/rustc_target/src/spec/base/windows_gnullvm.rs @@ -1,7 +1,8 @@ use std::borrow::Cow; use crate::spec::{ - BinaryFormat, Cc, DebuginfoKind, LinkerFlavor, Lld, SplitDebuginfo, TargetOptions, cvs, + Abi, BinaryFormat, Cc, DebuginfoKind, Env, LinkerFlavor, Lld, Os, SplitDebuginfo, + TargetOptions, cvs, }; pub(crate) fn opts() -> TargetOptions { @@ -20,10 +21,10 @@ pub(crate) fn opts() -> TargetOptions { ); TargetOptions { - os: "windows".into(), - env: "gnu".into(), + os: Os::Windows, + env: Env::Gnu, vendor: "pc".into(), - abi: "llvm".into(), + abi: Abi::Llvm, linker: Some("clang".into()), dynamic_linking: true, dll_tls_export: false, diff --git a/compiler/rustc_target/src/spec/base/windows_msvc.rs b/compiler/rustc_target/src/spec/base/windows_msvc.rs index 066785a1ae41..963253c3162b 100644 --- a/compiler/rustc_target/src/spec/base/windows_msvc.rs +++ b/compiler/rustc_target/src/spec/base/windows_msvc.rs @@ -1,11 +1,11 @@ -use crate::spec::{TargetOptions, base, cvs}; +use crate::spec::{Env, Os, TargetOptions, base, cvs}; pub(crate) fn opts() -> TargetOptions { let base = base::msvc::opts(); TargetOptions { - os: "windows".into(), - env: "msvc".into(), + os: Os::Windows, + env: Env::Msvc, vendor: "pc".into(), dynamic_linking: true, dll_prefix: "".into(), diff --git a/compiler/rustc_target/src/spec/base/windows_uwp_gnu.rs b/compiler/rustc_target/src/spec/base/windows_uwp_gnu.rs index 09eb52491f74..0f009fffae8d 100644 --- a/compiler/rustc_target/src/spec/base/windows_uwp_gnu.rs +++ b/compiler/rustc_target/src/spec/base/windows_uwp_gnu.rs @@ -1,4 +1,4 @@ -use crate::spec::{Cc, LinkArgs, LinkerFlavor, Lld, TargetOptions, add_link_args, base}; +use crate::spec::{Abi, Cc, LinkArgs, LinkerFlavor, Lld, TargetOptions, add_link_args, base}; pub(crate) fn opts() -> TargetOptions { let base = base::windows_gnu::opts(); @@ -23,7 +23,7 @@ pub(crate) fn opts() -> TargetOptions { let late_link_args_static = LinkArgs::new(); TargetOptions { - abi: "uwp".into(), + abi: Abi::Uwp, vendor: "uwp".into(), limit_rdylib_exports: false, late_link_args, diff --git a/compiler/rustc_target/src/spec/base/windows_uwp_msvc.rs b/compiler/rustc_target/src/spec/base/windows_uwp_msvc.rs index 374918d38a79..15832989f085 100644 --- a/compiler/rustc_target/src/spec/base/windows_uwp_msvc.rs +++ b/compiler/rustc_target/src/spec/base/windows_uwp_msvc.rs @@ -1,10 +1,9 @@ -use crate::spec::{LinkerFlavor, Lld, TargetOptions, base}; +use crate::spec::{Abi, LinkerFlavor, Lld, TargetOptions, base}; pub(crate) fn opts() -> TargetOptions { - let mut opts = base::windows_msvc::opts(); + let mut opts = + TargetOptions { abi: Abi::Uwp, vendor: "uwp".into(), ..base::windows_msvc::opts() }; - opts.abi = "uwp".into(); - opts.vendor = "uwp".into(); opts.add_pre_link_args(LinkerFlavor::Msvc(Lld::No), &["/APPCONTAINER", "mincore.lib"]); opts diff --git a/compiler/rustc_target/src/spec/base/xtensa.rs b/compiler/rustc_target/src/spec/base/xtensa.rs index a7cc748973c4..d1b803d51a2b 100644 --- a/compiler/rustc_target/src/spec/base/xtensa.rs +++ b/compiler/rustc_target/src/spec/base/xtensa.rs @@ -1,10 +1,10 @@ use rustc_abi::Endian; -use crate::spec::{Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, TargetOptions}; +use crate::spec::{Cc, LinkerFlavor, Lld, Os, PanicStrategy, RelocModel, TargetOptions}; pub(crate) fn opts() -> TargetOptions { TargetOptions { - os: "none".into(), + os: Os::None, endian: Endian::Little, c_int_width: 32, linker_flavor: LinkerFlavor::Gnu(Cc::Yes, Lld::No), diff --git a/compiler/rustc_target/src/spec/json.rs b/compiler/rustc_target/src/spec/json.rs index ab2879f6c6ea..a972299deeac 100644 --- a/compiler/rustc_target/src/spec/json.rs +++ b/compiler/rustc_target/src/spec/json.rs @@ -5,9 +5,9 @@ use rustc_abi::{Align, AlignFromBytesError}; use super::crt_objects::CrtObjects; use super::{ - Arch, BinaryFormat, CodeModel, DebuginfoKind, FloatAbi, FramePointer, LinkArgsCli, + Abi, Arch, BinaryFormat, CodeModel, DebuginfoKind, Env, FloatAbi, FramePointer, LinkArgsCli, LinkSelfContainedComponents, LinkSelfContainedDefault, LinkerFlavorCli, LldFlavor, - MergeFunctions, PanicStrategy, RelocModel, RelroLevel, RustcAbi, SanitizerSet, + MergeFunctions, Os, PanicStrategy, RelocModel, RelroLevel, RustcAbi, SanitizerSet, SmallDataThresholdSupport, SplitDebuginfo, StackProbeType, StaticCow, SymbolVisibility, Target, TargetKind, TargetOptions, TargetWarnings, TlsModel, }; @@ -261,6 +261,7 @@ impl ToJson for Target { ($attr:ident) => {{ target_option_val!($attr, (stringify!($attr)).replace("_", "-")) }}; ($attr:ident, $json_name:expr) => {{ let name = $json_name; + #[allow(rustc::bad_opt_access)] if default.$attr != target.$attr { d.insert(name.into(), target.$attr.to_json()); } @@ -504,9 +505,9 @@ struct TargetSpecJson { #[serde(rename = "target-c-int-width")] c_int_width: Option, c_enum_min_bits: Option, - os: Option>, - env: Option>, - abi: Option>, + os: Option, + env: Option, + abi: Option, vendor: Option>, linker: Option>, #[serde(rename = "linker-flavor")] diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 2dd0fbc4517a..62d3809c2c64 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -1884,14 +1884,7 @@ crate::target_spec_enum! { X86_64 = "x86_64", Xtensa = "xtensa", } - /// The vast majority of the time, the compiler deals with a fixed set of - /// target architectures, so it is convenient for them to be represented in - /// an enum. However, it is possible to have arbitrary values for the "arch" - /// field in a target JSON file (which can be parsed when `--target` is - /// specified). This might occur, for example, for an out-of-tree codegen - /// backend that supports an architecture that rustc currently doesn't know - /// about. This variant exists as an escape hatch for such cases. - other_variant = Unknown; + other_variant = Other; } impl Arch { @@ -1928,11 +1921,135 @@ impl Arch { Self::X86 => sym::x86, Self::X86_64 => sym::x86_64, Self::Xtensa => sym::xtensa, - Self::Unknown(name) => rustc_span::Symbol::intern(name), + Self::Other(name) => rustc_span::Symbol::intern(name), } } } +crate::target_spec_enum! { + pub enum Os { + Aix = "aix", + AmdHsa = "amdhsa", + Android = "android", + Cuda = "cuda", + Cygwin = "cygwin", + Dragonfly = "dragonfly", + Emscripten = "emscripten", + EspIdf = "espidf", + FreeBsd = "freebsd", + Fuchsia = "fuchsia", + Haiku = "haiku", + HelenOs = "helenos", + Hermit = "hermit", + Horizon = "horizon", + Hurd = "hurd", + Illumos = "illumos", + IOs = "ios", + L4Re = "l4re", + Linux = "linux", + LynxOs178 = "lynxos178", + MacOs = "macos", + Managarm = "managarm", + Motor = "motor", + NetBsd = "netbsd", + None = "none", + Nto = "nto", + NuttX = "nuttx", + OpenBsd = "openbsd", + Psp = "psp", + Psx = "psx", + Redox = "redox", + Rtems = "rtems", + Solaris = "solaris", + SolidAsp3 = "solid_asp3", + TeeOs = "teeos", + Trusty = "trusty", + TvOs = "tvos", + Uefi = "uefi", + VexOs = "vexos", + VisionOs = "visionos", + Vita = "vita", + VxWorks = "vxworks", + Wasi = "wasi", + WatchOs = "watchos", + Windows = "windows", + Xous = "xous", + Zkvm = "zkvm", + Unknown = "unknown", + } + other_variant = Other; +} + +impl Os { + pub fn desc_symbol(&self) -> Symbol { + Symbol::intern(self.desc()) + } +} + +crate::target_spec_enum! { + pub enum Env { + Gnu = "gnu", + MacAbi = "macabi", + Mlibc = "mlibc", + Msvc = "msvc", + Musl = "musl", + Newlib = "newlib", + Nto70 = "nto70", + Nto71 = "nto71", + Nto71IoSock = "nto71_iosock", + Nto80 = "nto80", + Ohos = "ohos", + Relibc = "relibc", + Sgx = "sgx", + Sim = "sim", + P1 = "p1", + P2 = "p2", + P3 = "p3", + Uclibc = "uclibc", + V5 = "v5", + Unspecified = "", + } + other_variant = Other; +} + +impl Env { + pub fn desc_symbol(&self) -> Symbol { + Symbol::intern(self.desc()) + } +} + +crate::target_spec_enum! { + pub enum Abi { + Abi64 = "abi64", + AbiV2 = "abiv2", + AbiV2Hf = "abiv2hf", + Eabi = "eabi", + EabiHf = "eabihf", + ElfV1 = "elfv1", + ElfV2 = "elfv2", + Fortanix = "fortanix", + Ilp32 = "ilp32", + Ilp32e = "ilp32e", + Llvm = "llvm", + MacAbi = "macabi", + Sim = "sim", + SoftFloat = "softfloat", + Spe = "spe", + Uwp = "uwp", + VecDefault = "vec-default", + VecExtAbi = "vec-extabi", + X32 = "x32", + Unspecified = "", + } + other_variant = Other; +} + +impl Abi { + pub fn desc_symbol(&self) -> Symbol { + Symbol::intern(self.desc()) + } +} + /// Everything `rustc` knows about how to compile for a specific target. /// /// Every field here must be specified, and has no default value. @@ -2045,25 +2162,29 @@ type StaticCow = Cow<'static, T>; /// construction, all its fields logically belong to `Target` and available from `Target` /// through `Deref` impls. #[derive(PartialEq, Clone, Debug)] +#[rustc_lint_opt_ty] pub struct TargetOptions { /// Used as the `target_endian` `cfg` variable. Defaults to little endian. pub endian: Endian, /// Width of c_int type. Defaults to "32". pub c_int_width: u16, - /// OS name to use for conditional compilation (`target_os`). Defaults to "none". - /// "none" implies a bare metal target without `std` library. - /// A couple of targets having `std` also use "unknown" as an `os` value, + /// OS name to use for conditional compilation (`target_os`). Defaults to [`Os::None`]. + /// [`Os::None`] implies a bare metal target without `std` library. + /// A couple of targets having `std` also use [`Os::Unknown`] as their `os` value, /// but they are exceptions. - pub os: StaticCow, - /// Environment name to use for conditional compilation (`target_env`). Defaults to "". - pub env: StaticCow, + pub os: Os, + /// Environment name to use for conditional compilation (`target_env`). Defaults to [`Env::Unspecified`]. + pub env: Env, /// ABI name to distinguish multiple ABIs on the same OS and architecture. For instance, `"eabi"` - /// or `"eabihf"`. Defaults to "". + /// or `"eabihf"`. Defaults to [`Abi::Unspecified`]. /// This field is *not* forwarded directly to LLVM; its primary purpose is `cfg(target_abi)`. /// However, parts of the backend do check this field for specific values to enable special behavior. - pub abi: StaticCow, + pub abi: Abi, /// Vendor name to use for conditional compilation (`target_vendor`). Defaults to "unknown". - pub vendor: StaticCow, + #[rustc_lint_opt_deny_field_access( + "use `Target::is_like_*` instead of this field; see https://github.com/rust-lang/rust/issues/100343 for rationale" + )] + vendor: StaticCow, /// Linker to invoke pub linker: Option>, @@ -2561,9 +2682,9 @@ impl Default for TargetOptions { TargetOptions { endian: Endian::Little, c_int_width: 32, - os: "none".into(), - env: "".into(), - abi: "".into(), + os: Os::None, + env: Env::Unspecified, + abi: Abi::Unspecified, vendor: "unknown".into(), linker: option_env!("CFG_DEFAULT_LINKER").map(|s| s.into()), linker_flavor: LinkerFlavor::Gnu(Cc::Yes, Lld::No), @@ -2759,7 +2880,7 @@ impl Target { ); check_eq!( self.is_like_solaris, - self.os == "solaris" || self.os == "illumos", + matches!(self.os, Os::Solaris | Os::Illumos), "`is_like_solaris` must be set if and only if `os` is `solaris` or `illumos`" ); check_eq!( @@ -2769,7 +2890,7 @@ impl Target { ); check_eq!( self.is_like_windows, - self.os == "windows" || self.os == "uefi" || self.os == "cygwin", + matches!(self.os, Os::Windows | Os::Uefi | Os::Cygwin), "`is_like_windows` must be set if and only if `os` is `windows`, `uefi` or `cygwin`" ); check_eq!( @@ -2780,7 +2901,7 @@ impl Target { if self.is_like_msvc { check!(self.is_like_windows, "if `is_like_msvc` is set, `is_like_windows` must be set"); } - if self.os == "emscripten" { + if self.os == Os::Emscripten { check!(self.is_like_wasm, "the `emcscripten` os only makes sense on wasm-like targets"); } @@ -2796,12 +2917,12 @@ impl Target { "`linker_flavor` must be `msvc` if and only if `is_like_msvc` is set" ); check_eq!( - self.is_like_wasm && self.os != "emscripten", + self.is_like_wasm && self.os != Os::Emscripten, matches!(self.linker_flavor, LinkerFlavor::WasmLld(..)), "`linker_flavor` must be `wasm-lld` if and only if `is_like_wasm` is set and the `os` is not `emscripten`", ); check_eq!( - self.os == "emscripten", + self.os == Os::Emscripten, matches!(self.linker_flavor, LinkerFlavor::EmCc), "`linker_flavor` must be `em-cc` if and only if `os` is `emscripten`" ); @@ -2928,12 +3049,14 @@ impl Target { // except it and document the reasons. // Keep the default "unknown" vendor instead. check_ne!(self.vendor, "", "`vendor` cannot be empty"); - check_ne!(self.os, "", "`os` cannot be empty"); + if let Os::Other(s) = &self.os { + check!(!s.is_empty(), "`os` cannot be empty"); + } if !self.can_use_os_unknown() { // Keep the default "none" for bare metal targets instead. check_ne!( self.os, - "unknown", + Os::Unknown, "`unknown` os can only be used on particular targets; use `none` for bare-metal targets" ); } @@ -2947,7 +3070,7 @@ impl Target { // BPF: when targeting user space vms (like rbpf), those can load dynamic libraries. // hexagon: when targeting QuRT, that OS can load dynamic libraries. // wasm{32,64}: dynamic linking is inherent in the definition of the VM. - if self.os == "none" + if self.os == Os::None && !matches!(self.arch, Arch::Bpf | Arch::Hexagon | Arch::Wasm32 | Arch::Wasm64) { check!( @@ -2980,7 +3103,7 @@ impl Target { ); } // The UEFI targets do not support dynamic linking but still require PIC (#101377). - if self.relocation_model == RelocModel::Pic && (self.os != "uefi") { + if self.relocation_model == RelocModel::Pic && self.os != Os::Uefi { check!( self.dynamic_linking || self.position_independent_executables, "when the relocation model is `pic`, the target must support dynamic linking or use position-independent executables. \ @@ -3119,7 +3242,7 @@ impl Target { fn can_use_os_unknown(&self) -> bool { self.llvm_target == "wasm32-unknown-unknown" || self.llvm_target == "wasm64-unknown-unknown" - || (self.env == "sgx" && self.vendor == "fortanix") + || (self.env == Env::Sgx && self.vendor == "fortanix") } /// Load a built-in target @@ -3194,15 +3317,7 @@ impl Target { return load_file(&p); } - // Leave in a specialized error message for the removed target. - // FIXME: If you see this and it's been a few months after this has been released, - // you can probably remove it. - if target_tuple == "i586-pc-windows-msvc" { - Err("the `i586-pc-windows-msvc` target has been removed. Use the `i686-pc-windows-msvc` target instead.\n\ - Windows 10 (the minimum required OS version) requires a CPU baseline of at least i686 so you can safely switch".into()) - } else { - Err(format!("could not find specification for target {target_tuple:?}")) - } + Err(format!("could not find specification for target {target_tuple:?}")) } TargetTuple::TargetJson { ref contents, .. } => Target::from_json(contents), } @@ -3301,7 +3416,7 @@ impl Target { | Arch::SpirV | Arch::Wasm32 | Arch::Wasm64 - | Arch::Unknown(_) => return None, + | Arch::Other(_) => return None, }) } @@ -3323,6 +3438,10 @@ impl Target { Align::MAX } } + + pub fn vendor_symbol(&self) -> Symbol { + Symbol::intern(&self.vendor) + } } /// Either a target tuple string or a path to a JSON file. diff --git a/compiler/rustc_target/src/spec/targets/aarch64_apple_darwin.rs b/compiler/rustc_target/src/spec/targets/aarch64_apple_darwin.rs index ecfd6ebba863..da3d7c7d99db 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_apple_darwin.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_apple_darwin.rs @@ -1,8 +1,8 @@ use crate::spec::base::apple::{Arch, TargetEnv, base}; -use crate::spec::{SanitizerSet, Target, TargetMetadata, TargetOptions}; +use crate::spec::{Os, SanitizerSet, Target, TargetMetadata, TargetOptions}; pub(crate) fn target() -> Target { - let (opts, llvm_target, arch) = base("macos", Arch::Arm64, TargetEnv::Normal); + let (opts, llvm_target, arch) = base(Os::MacOs, Arch::Arm64, TargetEnv::Normal); Target { llvm_target, metadata: TargetMetadata { diff --git a/compiler/rustc_target/src/spec/targets/aarch64_apple_ios.rs b/compiler/rustc_target/src/spec/targets/aarch64_apple_ios.rs index 85b4a0614a85..e6c64add9ecb 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_apple_ios.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_apple_ios.rs @@ -1,8 +1,8 @@ use crate::spec::base::apple::{Arch, TargetEnv, base}; -use crate::spec::{SanitizerSet, Target, TargetMetadata, TargetOptions}; +use crate::spec::{Os, SanitizerSet, Target, TargetMetadata, TargetOptions}; pub(crate) fn target() -> Target { - let (opts, llvm_target, arch) = base("ios", Arch::Arm64, TargetEnv::Normal); + let (opts, llvm_target, arch) = base(Os::IOs, Arch::Arm64, TargetEnv::Normal); Target { llvm_target, metadata: TargetMetadata { diff --git a/compiler/rustc_target/src/spec/targets/aarch64_apple_ios_macabi.rs b/compiler/rustc_target/src/spec/targets/aarch64_apple_ios_macabi.rs index 4d6a3103ee30..28d22e022c4e 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_apple_ios_macabi.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_apple_ios_macabi.rs @@ -1,8 +1,8 @@ use crate::spec::base::apple::{Arch, TargetEnv, base}; -use crate::spec::{SanitizerSet, Target, TargetMetadata, TargetOptions}; +use crate::spec::{Os, SanitizerSet, Target, TargetMetadata, TargetOptions}; pub(crate) fn target() -> Target { - let (opts, llvm_target, arch) = base("ios", Arch::Arm64, TargetEnv::MacCatalyst); + let (opts, llvm_target, arch) = base(Os::IOs, Arch::Arm64, TargetEnv::MacCatalyst); Target { llvm_target, metadata: TargetMetadata { diff --git a/compiler/rustc_target/src/spec/targets/aarch64_apple_ios_sim.rs b/compiler/rustc_target/src/spec/targets/aarch64_apple_ios_sim.rs index 2924ba5ebb10..3b6a075588a8 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_apple_ios_sim.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_apple_ios_sim.rs @@ -1,8 +1,8 @@ use crate::spec::base::apple::{Arch, TargetEnv, base}; -use crate::spec::{SanitizerSet, Target, TargetMetadata, TargetOptions}; +use crate::spec::{Os, SanitizerSet, Target, TargetMetadata, TargetOptions}; pub(crate) fn target() -> Target { - let (opts, llvm_target, arch) = base("ios", Arch::Arm64, TargetEnv::Simulator); + let (opts, llvm_target, arch) = base(Os::IOs, Arch::Arm64, TargetEnv::Simulator); Target { llvm_target, metadata: TargetMetadata { diff --git a/compiler/rustc_target/src/spec/targets/aarch64_apple_tvos.rs b/compiler/rustc_target/src/spec/targets/aarch64_apple_tvos.rs index 7aef6f96e1c5..b4e60f769b3b 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_apple_tvos.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_apple_tvos.rs @@ -1,8 +1,8 @@ use crate::spec::base::apple::{Arch, TargetEnv, base}; -use crate::spec::{Target, TargetMetadata, TargetOptions}; +use crate::spec::{Os, Target, TargetMetadata, TargetOptions}; pub(crate) fn target() -> Target { - let (opts, llvm_target, arch) = base("tvos", Arch::Arm64, TargetEnv::Normal); + let (opts, llvm_target, arch) = base(Os::TvOs, Arch::Arm64, TargetEnv::Normal); Target { llvm_target, metadata: TargetMetadata { diff --git a/compiler/rustc_target/src/spec/targets/aarch64_apple_tvos_sim.rs b/compiler/rustc_target/src/spec/targets/aarch64_apple_tvos_sim.rs index f0d17db873bf..0f2f73c50d0b 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_apple_tvos_sim.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_apple_tvos_sim.rs @@ -1,8 +1,8 @@ use crate::spec::base::apple::{Arch, TargetEnv, base}; -use crate::spec::{Target, TargetMetadata, TargetOptions}; +use crate::spec::{Os, Target, TargetMetadata, TargetOptions}; pub(crate) fn target() -> Target { - let (opts, llvm_target, arch) = base("tvos", Arch::Arm64, TargetEnv::Simulator); + let (opts, llvm_target, arch) = base(Os::TvOs, Arch::Arm64, TargetEnv::Simulator); Target { llvm_target, metadata: TargetMetadata { diff --git a/compiler/rustc_target/src/spec/targets/aarch64_apple_visionos.rs b/compiler/rustc_target/src/spec/targets/aarch64_apple_visionos.rs index 22ce52e637f3..b7ddd58fbb32 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_apple_visionos.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_apple_visionos.rs @@ -1,8 +1,8 @@ use crate::spec::base::apple::{Arch, TargetEnv, base}; -use crate::spec::{SanitizerSet, Target, TargetMetadata, TargetOptions}; +use crate::spec::{Os, SanitizerSet, Target, TargetMetadata, TargetOptions}; pub(crate) fn target() -> Target { - let (opts, llvm_target, arch) = base("visionos", Arch::Arm64, TargetEnv::Normal); + let (opts, llvm_target, arch) = base(Os::VisionOs, Arch::Arm64, TargetEnv::Normal); Target { llvm_target, metadata: TargetMetadata { diff --git a/compiler/rustc_target/src/spec/targets/aarch64_apple_visionos_sim.rs b/compiler/rustc_target/src/spec/targets/aarch64_apple_visionos_sim.rs index 21739ba9fdb7..9ad313f14922 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_apple_visionos_sim.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_apple_visionos_sim.rs @@ -1,8 +1,8 @@ use crate::spec::base::apple::{Arch, TargetEnv, base}; -use crate::spec::{SanitizerSet, Target, TargetMetadata, TargetOptions}; +use crate::spec::{Os, SanitizerSet, Target, TargetMetadata, TargetOptions}; pub(crate) fn target() -> Target { - let (opts, llvm_target, arch) = base("visionos", Arch::Arm64, TargetEnv::Simulator); + let (opts, llvm_target, arch) = base(Os::VisionOs, Arch::Arm64, TargetEnv::Simulator); Target { llvm_target, metadata: TargetMetadata { diff --git a/compiler/rustc_target/src/spec/targets/aarch64_apple_watchos.rs b/compiler/rustc_target/src/spec/targets/aarch64_apple_watchos.rs index 2e88f95f1dd8..f0a5a616a6d2 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_apple_watchos.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_apple_watchos.rs @@ -1,8 +1,8 @@ use crate::spec::base::apple::{Arch, TargetEnv, base}; -use crate::spec::{Target, TargetMetadata, TargetOptions}; +use crate::spec::{Os, Target, TargetMetadata, TargetOptions}; pub(crate) fn target() -> Target { - let (opts, llvm_target, arch) = base("watchos", Arch::Arm64, TargetEnv::Normal); + let (opts, llvm_target, arch) = base(Os::WatchOs, Arch::Arm64, TargetEnv::Normal); Target { llvm_target, metadata: TargetMetadata { diff --git a/compiler/rustc_target/src/spec/targets/aarch64_apple_watchos_sim.rs b/compiler/rustc_target/src/spec/targets/aarch64_apple_watchos_sim.rs index 272dc682dc0e..db73687a715f 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_apple_watchos_sim.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_apple_watchos_sim.rs @@ -1,8 +1,8 @@ use crate::spec::base::apple::{Arch, TargetEnv, base}; -use crate::spec::{Target, TargetMetadata, TargetOptions}; +use crate::spec::{Os, Target, TargetMetadata, TargetOptions}; pub(crate) fn target() -> Target { - let (opts, llvm_target, arch) = base("watchos", Arch::Arm64, TargetEnv::Simulator); + let (opts, llvm_target, arch) = base(Os::WatchOs, Arch::Arm64, TargetEnv::Simulator); Target { llvm_target, metadata: TargetMetadata { diff --git a/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_linux_gnu_ilp32.rs b/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_linux_gnu_ilp32.rs index 63a13b8a7d11..4abd5553eb97 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_linux_gnu_ilp32.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_linux_gnu_ilp32.rs @@ -1,7 +1,7 @@ use rustc_abi::Endian; use crate::spec::{ - Arch, FramePointer, StackProbeType, Target, TargetMetadata, TargetOptions, base, + Abi, Arch, FramePointer, StackProbeType, Target, TargetMetadata, TargetOptions, base, }; pub(crate) fn target() -> Target { @@ -20,7 +20,7 @@ pub(crate) fn target() -> Target { data_layout: "E-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(), arch: Arch::AArch64, options: TargetOptions { - abi: "ilp32".into(), + abi: Abi::Ilp32, features: "+v8a,+outline-atomics".into(), // the AAPCS64 expects use of non-leaf frame pointers per // https://github.com/ARM-software/abi-aa/blob/4492d1570eb70c8fd146623e0db65b2d241f12e7/aapcs64/aapcs64.rst#the-frame-pointer diff --git a/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_none_softfloat.rs b/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_none_softfloat.rs index 8ba909a79601..3b899b13d6d0 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_none_softfloat.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_none_softfloat.rs @@ -8,13 +8,13 @@ use rustc_abi::Endian; use crate::spec::{ - Arch, Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, SanitizerSet, StackProbeType, Target, - TargetMetadata, TargetOptions, + Abi, Arch, Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, SanitizerSet, StackProbeType, + Target, TargetMetadata, TargetOptions, }; pub(crate) fn target() -> Target { let opts = TargetOptions { - abi: "softfloat".into(), + abi: Abi::SoftFloat, linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), linker: Some("rust-lld".into()), features: "+v8a,+strict-align,-neon,-fp-armv8".into(), diff --git a/compiler/rustc_target/src/spec/targets/aarch64_kmc_solid_asp3.rs b/compiler/rustc_target/src/spec/targets/aarch64_kmc_solid_asp3.rs index d6b0e0919512..77ed9a6b82c1 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_kmc_solid_asp3.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_kmc_solid_asp3.rs @@ -1,7 +1,7 @@ use crate::spec::{Arch, RelocModel, StackProbeType, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { - let base = base::solid::opts("asp3"); + let base = base::solid::opts(); Target { llvm_target: "aarch64-unknown-none".into(), metadata: TargetMetadata { diff --git a/compiler/rustc_target/src/spec/targets/aarch64_nintendo_switch_freestanding.rs b/compiler/rustc_target/src/spec/targets/aarch64_nintendo_switch_freestanding.rs index eb8144dd44e2..32bdf1d97042 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_nintendo_switch_freestanding.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_nintendo_switch_freestanding.rs @@ -1,6 +1,6 @@ use crate::spec::{ - Arch, Cc, LinkerFlavor, Lld, PanicStrategy, RelroLevel, StackProbeType, Target, TargetMetadata, - TargetOptions, + Arch, Cc, LinkerFlavor, Lld, Os, PanicStrategy, RelroLevel, StackProbeType, Target, + TargetMetadata, TargetOptions, }; const LINKER_SCRIPT: &str = include_str!("./aarch64_nintendo_switch_freestanding_linker_script.ld"); @@ -23,7 +23,7 @@ pub(crate) fn target() -> Target { linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), linker: Some("rust-lld".into()), link_script: Some(LINKER_SCRIPT.into()), - os: "horizon".into(), + os: Os::Horizon, vendor: "nintendo".into(), max_atomic_width: Some(128), stack_probes: StackProbeType::Inline, diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_gnu_ilp32.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_gnu_ilp32.rs index 5020d893c86b..22f2717b56b4 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_gnu_ilp32.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_gnu_ilp32.rs @@ -1,5 +1,5 @@ use crate::spec::{ - Arch, FramePointer, StackProbeType, Target, TargetMetadata, TargetOptions, base, + Abi, Arch, FramePointer, StackProbeType, Target, TargetMetadata, TargetOptions, base, }; pub(crate) fn target() -> Target { @@ -15,7 +15,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(), arch: Arch::AArch64, options: TargetOptions { - abi: "ilp32".into(), + abi: Abi::Ilp32, features: "+v8a,+outline-atomics".into(), // the AAPCS64 expects use of non-leaf frame pointers per // https://github.com/ARM-software/abi-aa/blob/4492d1570eb70c8fd146623e0db65b2d241f12e7/aapcs64/aapcs64.rst#the-frame-pointer diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_none_softfloat.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_none_softfloat.rs index 387fef3074d4..c0fd021497b6 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_none_softfloat.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_none_softfloat.rs @@ -7,13 +7,13 @@ // For example, `-C target-cpu=cortex-a53`. use crate::spec::{ - Arch, Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, SanitizerSet, StackProbeType, Target, - TargetMetadata, TargetOptions, + Abi, Arch, Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, SanitizerSet, StackProbeType, + Target, TargetMetadata, TargetOptions, }; pub(crate) fn target() -> Target { let opts = TargetOptions { - abi: "softfloat".into(), + abi: Abi::SoftFloat, linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), linker: Some("rust-lld".into()), features: "+v8a,+strict-align,-neon,-fp-armv8".into(), diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_nto_qnx700.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_nto_qnx700.rs index b26e6f19e1ab..e1f29f832f0b 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_nto_qnx700.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_nto_qnx700.rs @@ -1,11 +1,11 @@ -use crate::spec::Target; use crate::spec::base::nto_qnx; +use crate::spec::{Env, Target}; pub(crate) fn target() -> Target { let mut target = nto_qnx::aarch64(); target.metadata.description = Some("ARM64 QNX Neutrino 7.0 RTOS".into()); target.options.pre_link_args = nto_qnx::pre_link_args(nto_qnx::ApiVariant::Default, nto_qnx::Arch::Aarch64); - target.options.env = "nto70".into(); + target.options.env = Env::Nto70; target } diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_nto_qnx710.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_nto_qnx710.rs index 3a78952c36c4..1baa56630d3a 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_nto_qnx710.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_nto_qnx710.rs @@ -1,5 +1,5 @@ -use crate::spec::Target; use crate::spec::base::nto_qnx; +use crate::spec::{Env, Target}; pub(crate) fn target() -> Target { let mut target = nto_qnx::aarch64(); @@ -7,6 +7,6 @@ pub(crate) fn target() -> Target { Some("ARM64 QNX Neutrino 7.1 RTOS with io-pkt network stack".into()); target.options.pre_link_args = nto_qnx::pre_link_args(nto_qnx::ApiVariant::Default, nto_qnx::Arch::Aarch64); - target.options.env = "nto71".into(); + target.options.env = Env::Nto71; target } diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_nto_qnx710_iosock.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_nto_qnx710_iosock.rs index 4964f4078f5c..80ae93247a3f 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_nto_qnx710_iosock.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_nto_qnx710_iosock.rs @@ -1,5 +1,5 @@ -use crate::spec::Target; use crate::spec::base::nto_qnx; +use crate::spec::{Env, Target}; pub(crate) fn target() -> Target { let mut target = nto_qnx::aarch64(); @@ -7,6 +7,6 @@ pub(crate) fn target() -> Target { Some("ARM64 QNX Neutrino 7.1 RTOS with io-sock network stack".into()); target.options.pre_link_args = nto_qnx::pre_link_args(nto_qnx::ApiVariant::IoSock, nto_qnx::Arch::Aarch64); - target.options.env = "nto71_iosock".into(); + target.options.env = Env::Nto71IoSock; target } diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_nto_qnx800.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_nto_qnx800.rs index 5b820681efe9..5d265087c4a2 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_nto_qnx800.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_nto_qnx800.rs @@ -1,11 +1,11 @@ -use crate::spec::Target; use crate::spec::base::nto_qnx; +use crate::spec::{Env, Target}; pub(crate) fn target() -> Target { let mut target = nto_qnx::aarch64(); target.metadata.description = Some("ARM64 QNX Neutrino 8.0 RTOS".into()); target.options.pre_link_args = nto_qnx::pre_link_args(nto_qnx::ApiVariant::Default, nto_qnx::Arch::Aarch64); - target.options.env = "nto80".into(); + target.options.env = Env::Nto80; target } diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_nuttx.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_nuttx.rs index 8bcc3e0ae16d..b8618050074d 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_nuttx.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_nuttx.rs @@ -7,8 +7,8 @@ // For example, `-C target-cpu=cortex-a53`. use crate::spec::{ - Arch, Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, SanitizerSet, StackProbeType, Target, - TargetMetadata, TargetOptions, cvs, + Arch, Cc, LinkerFlavor, Lld, Os, PanicStrategy, RelocModel, SanitizerSet, StackProbeType, + Target, TargetMetadata, TargetOptions, cvs, }; pub(crate) fn target() -> Target { @@ -28,7 +28,7 @@ pub(crate) fn target() -> Target { stack_probes: StackProbeType::Inline, panic_strategy: PanicStrategy::Abort, families: cvs!["unix"], - os: "nuttx".into(), + os: Os::NuttX, ..Default::default() }; Target { diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_trusty.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_trusty.rs index 3d0560eb7963..7dfa29787c86 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_trusty.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_trusty.rs @@ -1,7 +1,7 @@ // Trusty OS target for AArch64. use crate::spec::{ - Arch, LinkSelfContainedDefault, PanicStrategy, RelroLevel, Target, TargetMetadata, + Arch, LinkSelfContainedDefault, Os, PanicStrategy, RelroLevel, Target, TargetMetadata, TargetOptions, }; @@ -22,7 +22,7 @@ pub(crate) fn target() -> Target { executables: true, max_atomic_width: Some(128), panic_strategy: PanicStrategy::Abort, - os: "trusty".into(), + os: Os::Trusty, position_independent_executables: true, static_position_independent_executables: true, crt_static_default: true, diff --git a/compiler/rustc_target/src/spec/targets/amdgcn_amd_amdhsa.rs b/compiler/rustc_target/src/spec/targets/amdgcn_amd_amdhsa.rs index d80a3ffd0c7f..828d853ac65e 100644 --- a/compiler/rustc_target/src/spec/targets/amdgcn_amd_amdhsa.rs +++ b/compiler/rustc_target/src/spec/targets/amdgcn_amd_amdhsa.rs @@ -1,5 +1,5 @@ use crate::spec::{ - Arch, Cc, LinkerFlavor, Lld, PanicStrategy, Target, TargetMetadata, TargetOptions, + Arch, Cc, LinkerFlavor, Lld, Os, PanicStrategy, Target, TargetMetadata, TargetOptions, }; pub(crate) fn target() -> Target { @@ -16,7 +16,7 @@ pub(crate) fn target() -> Target { pointer_width: 64, options: TargetOptions { - os: "amdhsa".into(), + os: Os::AmdHsa, vendor: "amd".into(), linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), linker: Some("rust-lld".into()), diff --git a/compiler/rustc_target/src/spec/targets/arm64_32_apple_watchos.rs b/compiler/rustc_target/src/spec/targets/arm64_32_apple_watchos.rs index 564ac2cd7081..dab8cd157d2b 100644 --- a/compiler/rustc_target/src/spec/targets/arm64_32_apple_watchos.rs +++ b/compiler/rustc_target/src/spec/targets/arm64_32_apple_watchos.rs @@ -1,8 +1,8 @@ use crate::spec::base::apple::{Arch, TargetEnv, base}; -use crate::spec::{Target, TargetMetadata, TargetOptions}; +use crate::spec::{Os, Target, TargetMetadata, TargetOptions}; pub(crate) fn target() -> Target { - let (opts, llvm_target, arch) = base("watchos", Arch::Arm64_32, TargetEnv::Normal); + let (opts, llvm_target, arch) = base(Os::WatchOs, Arch::Arm64_32, TargetEnv::Normal); Target { llvm_target, metadata: TargetMetadata { diff --git a/compiler/rustc_target/src/spec/targets/arm64e_apple_darwin.rs b/compiler/rustc_target/src/spec/targets/arm64e_apple_darwin.rs index 86e178a95728..ab8f369f1bee 100644 --- a/compiler/rustc_target/src/spec/targets/arm64e_apple_darwin.rs +++ b/compiler/rustc_target/src/spec/targets/arm64e_apple_darwin.rs @@ -1,8 +1,8 @@ use crate::spec::base::apple::{Arch, TargetEnv, base}; -use crate::spec::{SanitizerSet, Target, TargetMetadata, TargetOptions}; +use crate::spec::{Os, SanitizerSet, Target, TargetMetadata, TargetOptions}; pub(crate) fn target() -> Target { - let (opts, llvm_target, arch) = base("macos", Arch::Arm64e, TargetEnv::Normal); + let (opts, llvm_target, arch) = base(Os::MacOs, Arch::Arm64e, TargetEnv::Normal); Target { llvm_target, metadata: TargetMetadata { diff --git a/compiler/rustc_target/src/spec/targets/arm64e_apple_ios.rs b/compiler/rustc_target/src/spec/targets/arm64e_apple_ios.rs index dae3f77d7ae3..4ee4a16ab747 100644 --- a/compiler/rustc_target/src/spec/targets/arm64e_apple_ios.rs +++ b/compiler/rustc_target/src/spec/targets/arm64e_apple_ios.rs @@ -1,8 +1,8 @@ use crate::spec::base::apple::{Arch, TargetEnv, base}; -use crate::spec::{SanitizerSet, Target, TargetMetadata, TargetOptions}; +use crate::spec::{Os, SanitizerSet, Target, TargetMetadata, TargetOptions}; pub(crate) fn target() -> Target { - let (opts, llvm_target, arch) = base("ios", Arch::Arm64e, TargetEnv::Normal); + let (opts, llvm_target, arch) = base(Os::IOs, Arch::Arm64e, TargetEnv::Normal); Target { llvm_target, metadata: TargetMetadata { diff --git a/compiler/rustc_target/src/spec/targets/arm64e_apple_tvos.rs b/compiler/rustc_target/src/spec/targets/arm64e_apple_tvos.rs index a99fc5dc68c9..c09591be95f9 100644 --- a/compiler/rustc_target/src/spec/targets/arm64e_apple_tvos.rs +++ b/compiler/rustc_target/src/spec/targets/arm64e_apple_tvos.rs @@ -1,8 +1,8 @@ use crate::spec::base::apple::{Arch, TargetEnv, base}; -use crate::spec::{Target, TargetMetadata, TargetOptions}; +use crate::spec::{Os, Target, TargetMetadata, TargetOptions}; pub(crate) fn target() -> Target { - let (opts, llvm_target, arch) = base("tvos", Arch::Arm64e, TargetEnv::Normal); + let (opts, llvm_target, arch) = base(Os::TvOs, Arch::Arm64e, TargetEnv::Normal); Target { llvm_target, metadata: TargetMetadata { diff --git a/compiler/rustc_target/src/spec/targets/arm_linux_androideabi.rs b/compiler/rustc_target/src/spec/targets/arm_linux_androideabi.rs index dad8f5e1c552..7dc6509fc823 100644 --- a/compiler/rustc_target/src/spec/targets/arm_linux_androideabi.rs +++ b/compiler/rustc_target/src/spec/targets/arm_linux_androideabi.rs @@ -1,4 +1,4 @@ -use crate::spec::{Arch, FloatAbi, SanitizerSet, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Abi, Arch, FloatAbi, SanitizerSet, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -13,7 +13,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), arch: Arch::Arm, options: TargetOptions { - abi: "eabi".into(), + abi: Abi::Eabi, llvm_floatabi: Some(FloatAbi::Soft), // https://developer.android.com/ndk/guides/abis.html#armeabi features: "+strict-align,+v5te".into(), diff --git a/compiler/rustc_target/src/spec/targets/arm_unknown_linux_gnueabi.rs b/compiler/rustc_target/src/spec/targets/arm_unknown_linux_gnueabi.rs index 55136255babc..cc63ffa2e2a5 100644 --- a/compiler/rustc_target/src/spec/targets/arm_unknown_linux_gnueabi.rs +++ b/compiler/rustc_target/src/spec/targets/arm_unknown_linux_gnueabi.rs @@ -1,4 +1,4 @@ -use crate::spec::{Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -13,7 +13,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), arch: Arch::Arm, options: TargetOptions { - abi: "eabi".into(), + abi: Abi::Eabi, llvm_floatabi: Some(FloatAbi::Soft), features: "+strict-align,+v6".into(), max_atomic_width: Some(64), diff --git a/compiler/rustc_target/src/spec/targets/arm_unknown_linux_gnueabihf.rs b/compiler/rustc_target/src/spec/targets/arm_unknown_linux_gnueabihf.rs index 087d4cfe800d..e003a65be393 100644 --- a/compiler/rustc_target/src/spec/targets/arm_unknown_linux_gnueabihf.rs +++ b/compiler/rustc_target/src/spec/targets/arm_unknown_linux_gnueabihf.rs @@ -1,4 +1,4 @@ -use crate::spec::{Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -13,7 +13,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), arch: Arch::Arm, options: TargetOptions { - abi: "eabihf".into(), + abi: Abi::EabiHf, llvm_floatabi: Some(FloatAbi::Hard), features: "+strict-align,+v6,+vfp2,-d32".into(), max_atomic_width: Some(64), diff --git a/compiler/rustc_target/src/spec/targets/arm_unknown_linux_musleabi.rs b/compiler/rustc_target/src/spec/targets/arm_unknown_linux_musleabi.rs index e5224e4cce48..25ef767c4b10 100644 --- a/compiler/rustc_target/src/spec/targets/arm_unknown_linux_musleabi.rs +++ b/compiler/rustc_target/src/spec/targets/arm_unknown_linux_musleabi.rs @@ -1,4 +1,4 @@ -use crate::spec::{Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -13,7 +13,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), arch: Arch::Arm, options: TargetOptions { - abi: "eabi".into(), + abi: Abi::Eabi, llvm_floatabi: Some(FloatAbi::Soft), // Most of these settings are copied from the arm_unknown_linux_gnueabi // target. diff --git a/compiler/rustc_target/src/spec/targets/arm_unknown_linux_musleabihf.rs b/compiler/rustc_target/src/spec/targets/arm_unknown_linux_musleabihf.rs index 0e958455994c..76051403a559 100644 --- a/compiler/rustc_target/src/spec/targets/arm_unknown_linux_musleabihf.rs +++ b/compiler/rustc_target/src/spec/targets/arm_unknown_linux_musleabihf.rs @@ -1,4 +1,4 @@ -use crate::spec::{Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -13,7 +13,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), arch: Arch::Arm, options: TargetOptions { - abi: "eabihf".into(), + abi: Abi::EabiHf, llvm_floatabi: Some(FloatAbi::Hard), // Most of these settings are copied from the arm_unknown_linux_gnueabihf // target. diff --git a/compiler/rustc_target/src/spec/targets/armeb_unknown_linux_gnueabi.rs b/compiler/rustc_target/src/spec/targets/armeb_unknown_linux_gnueabi.rs index a9794f80e687..73374bcdf0b1 100644 --- a/compiler/rustc_target/src/spec/targets/armeb_unknown_linux_gnueabi.rs +++ b/compiler/rustc_target/src/spec/targets/armeb_unknown_linux_gnueabi.rs @@ -1,6 +1,6 @@ use rustc_abi::Endian; -use crate::spec::{Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -15,7 +15,7 @@ pub(crate) fn target() -> Target { data_layout: "E-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), arch: Arch::Arm, options: TargetOptions { - abi: "eabi".into(), + abi: Abi::Eabi, llvm_floatabi: Some(FloatAbi::Soft), features: "+strict-align,+v8,+crc".into(), endian: Endian::Big, diff --git a/compiler/rustc_target/src/spec/targets/armebv7r_none_eabi.rs b/compiler/rustc_target/src/spec/targets/armebv7r_none_eabi.rs index bf9519b8a105..849a0f4c9a68 100644 --- a/compiler/rustc_target/src/spec/targets/armebv7r_none_eabi.rs +++ b/compiler/rustc_target/src/spec/targets/armebv7r_none_eabi.rs @@ -3,7 +3,7 @@ use rustc_abi::Endian; use crate::spec::{ - Arch, Cc, FloatAbi, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, + Abi, Arch, Cc, FloatAbi, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, }; @@ -20,7 +20,7 @@ pub(crate) fn target() -> Target { data_layout: "E-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), arch: Arch::Arm, options: TargetOptions { - abi: "eabi".into(), + abi: Abi::Eabi, llvm_floatabi: Some(FloatAbi::Soft), endian: Endian::Big, linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), diff --git a/compiler/rustc_target/src/spec/targets/armebv7r_none_eabihf.rs b/compiler/rustc_target/src/spec/targets/armebv7r_none_eabihf.rs index 75a4ab4d877a..0cf3880cadc9 100644 --- a/compiler/rustc_target/src/spec/targets/armebv7r_none_eabihf.rs +++ b/compiler/rustc_target/src/spec/targets/armebv7r_none_eabihf.rs @@ -3,7 +3,7 @@ use rustc_abi::Endian; use crate::spec::{ - Arch, Cc, FloatAbi, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, + Abi, Arch, Cc, FloatAbi, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, }; @@ -20,7 +20,7 @@ pub(crate) fn target() -> Target { data_layout: "E-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), arch: Arch::Arm, options: TargetOptions { - abi: "eabihf".into(), + abi: Abi::EabiHf, llvm_floatabi: Some(FloatAbi::Hard), endian: Endian::Big, linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), diff --git a/compiler/rustc_target/src/spec/targets/armv4t_none_eabi.rs b/compiler/rustc_target/src/spec/targets/armv4t_none_eabi.rs index 2bb35bd6ea20..129b639c5248 100644 --- a/compiler/rustc_target/src/spec/targets/armv4t_none_eabi.rs +++ b/compiler/rustc_target/src/spec/targets/armv4t_none_eabi.rs @@ -10,7 +10,7 @@ //! `-Clink-arg=-Tmy_script.ld` to override that with a correct linker script. use crate::spec::{ - Arch, Cc, FloatAbi, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, + Abi, Arch, Cc, FloatAbi, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, cvs, }; @@ -36,7 +36,7 @@ pub(crate) fn target() -> Target { */ data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), options: TargetOptions { - abi: "eabi".into(), + abi: Abi::Eabi, llvm_floatabi: Some(FloatAbi::Soft), linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), linker: Some("rust-lld".into()), diff --git a/compiler/rustc_target/src/spec/targets/armv4t_unknown_linux_gnueabi.rs b/compiler/rustc_target/src/spec/targets/armv4t_unknown_linux_gnueabi.rs index 1e13e02045a1..8c386011f89a 100644 --- a/compiler/rustc_target/src/spec/targets/armv4t_unknown_linux_gnueabi.rs +++ b/compiler/rustc_target/src/spec/targets/armv4t_unknown_linux_gnueabi.rs @@ -1,4 +1,4 @@ -use crate::spec::{Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -13,7 +13,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), arch: Arch::Arm, options: TargetOptions { - abi: "eabi".into(), + abi: Abi::Eabi, llvm_floatabi: Some(FloatAbi::Soft), features: "+soft-float,+strict-align".into(), // Atomic operations provided by compiler-builtins diff --git a/compiler/rustc_target/src/spec/targets/armv5te_none_eabi.rs b/compiler/rustc_target/src/spec/targets/armv5te_none_eabi.rs index 28f2533d7a36..7cd571b91479 100644 --- a/compiler/rustc_target/src/spec/targets/armv5te_none_eabi.rs +++ b/compiler/rustc_target/src/spec/targets/armv5te_none_eabi.rs @@ -1,6 +1,8 @@ //! Targets the ARMv5TE, with code as `a32` code by default. -use crate::spec::{Arch, FloatAbi, FramePointer, Target, TargetMetadata, TargetOptions, base, cvs}; +use crate::spec::{ + Abi, Arch, FloatAbi, FramePointer, Target, TargetMetadata, TargetOptions, base, cvs, +}; pub(crate) fn target() -> Target { Target { @@ -25,7 +27,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), options: TargetOptions { - abi: "eabi".into(), + abi: Abi::Eabi, llvm_floatabi: Some(FloatAbi::Soft), // extra args passed to the external assembler (assuming `arm-none-eabi-as`): // * activate t32/a32 interworking diff --git a/compiler/rustc_target/src/spec/targets/armv5te_unknown_linux_gnueabi.rs b/compiler/rustc_target/src/spec/targets/armv5te_unknown_linux_gnueabi.rs index 763d68f0495a..d1fded203671 100644 --- a/compiler/rustc_target/src/spec/targets/armv5te_unknown_linux_gnueabi.rs +++ b/compiler/rustc_target/src/spec/targets/armv5te_unknown_linux_gnueabi.rs @@ -1,4 +1,4 @@ -use crate::spec::{Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -13,7 +13,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), arch: Arch::Arm, options: TargetOptions { - abi: "eabi".into(), + abi: Abi::Eabi, llvm_floatabi: Some(FloatAbi::Soft), features: "+soft-float,+strict-align".into(), // Atomic operations provided by compiler-builtins diff --git a/compiler/rustc_target/src/spec/targets/armv5te_unknown_linux_musleabi.rs b/compiler/rustc_target/src/spec/targets/armv5te_unknown_linux_musleabi.rs index a08d1a1c63ef..2daf2ab4d8fe 100644 --- a/compiler/rustc_target/src/spec/targets/armv5te_unknown_linux_musleabi.rs +++ b/compiler/rustc_target/src/spec/targets/armv5te_unknown_linux_musleabi.rs @@ -1,4 +1,4 @@ -use crate::spec::{Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -13,7 +13,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), arch: Arch::Arm, options: TargetOptions { - abi: "eabi".into(), + abi: Abi::Eabi, llvm_floatabi: Some(FloatAbi::Soft), features: "+soft-float,+strict-align".into(), // Atomic operations provided by compiler-builtins diff --git a/compiler/rustc_target/src/spec/targets/armv5te_unknown_linux_uclibceabi.rs b/compiler/rustc_target/src/spec/targets/armv5te_unknown_linux_uclibceabi.rs index 1719ab7314a4..b05df3a77a43 100644 --- a/compiler/rustc_target/src/spec/targets/armv5te_unknown_linux_uclibceabi.rs +++ b/compiler/rustc_target/src/spec/targets/armv5te_unknown_linux_uclibceabi.rs @@ -1,4 +1,4 @@ -use crate::spec::{Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -13,7 +13,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), arch: Arch::Arm, options: TargetOptions { - abi: "eabi".into(), + abi: Abi::Eabi, llvm_floatabi: Some(FloatAbi::Soft), features: "+soft-float,+strict-align".into(), // Atomic operations provided by compiler-builtins diff --git a/compiler/rustc_target/src/spec/targets/armv6_unknown_freebsd.rs b/compiler/rustc_target/src/spec/targets/armv6_unknown_freebsd.rs index 2da15219d6ce..20d91d6968a6 100644 --- a/compiler/rustc_target/src/spec/targets/armv6_unknown_freebsd.rs +++ b/compiler/rustc_target/src/spec/targets/armv6_unknown_freebsd.rs @@ -1,4 +1,4 @@ -use crate::spec::{Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -13,7 +13,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), arch: Arch::Arm, options: TargetOptions { - abi: "eabihf".into(), + abi: Abi::EabiHf, llvm_floatabi: Some(FloatAbi::Hard), features: "+v6,+vfp2,-d32".into(), max_atomic_width: Some(64), diff --git a/compiler/rustc_target/src/spec/targets/armv6_unknown_netbsd_eabihf.rs b/compiler/rustc_target/src/spec/targets/armv6_unknown_netbsd_eabihf.rs index fbd55a371487..0316bd92999b 100644 --- a/compiler/rustc_target/src/spec/targets/armv6_unknown_netbsd_eabihf.rs +++ b/compiler/rustc_target/src/spec/targets/armv6_unknown_netbsd_eabihf.rs @@ -1,4 +1,4 @@ -use crate::spec::{Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -13,7 +13,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), arch: Arch::Arm, options: TargetOptions { - abi: "eabihf".into(), + abi: Abi::EabiHf, llvm_floatabi: Some(FloatAbi::Hard), features: "+v6,+vfp2,-d32".into(), max_atomic_width: Some(64), diff --git a/compiler/rustc_target/src/spec/targets/armv6k_nintendo_3ds.rs b/compiler/rustc_target/src/spec/targets/armv6k_nintendo_3ds.rs index a79c64287012..ed2ab47c0e24 100644 --- a/compiler/rustc_target/src/spec/targets/armv6k_nintendo_3ds.rs +++ b/compiler/rustc_target/src/spec/targets/armv6k_nintendo_3ds.rs @@ -1,11 +1,11 @@ use crate::spec::{ - Arch, Cc, FloatAbi, LinkerFlavor, Lld, RelocModel, Target, TargetMetadata, TargetOptions, cvs, + Abi, Arch, Cc, Env, FloatAbi, LinkerFlavor, Lld, Os, RelocModel, Target, TargetMetadata, + TargetOptions, cvs, }; /// A base target for Nintendo 3DS devices using the devkitARM toolchain. /// /// Requires the devkitARM toolchain for 3DS targets on the host system. - pub(crate) fn target() -> Target { let pre_link_args = TargetOptions::link_args( LinkerFlavor::Gnu(Cc::Yes, Lld::No), @@ -25,11 +25,11 @@ pub(crate) fn target() -> Target { arch: Arch::Arm, options: TargetOptions { - os: "horizon".into(), - env: "newlib".into(), + os: Os::Horizon, + env: Env::Newlib, vendor: "nintendo".into(), cpu: "mpcore".into(), - abi: "eabihf".into(), + abi: Abi::EabiHf, llvm_floatabi: Some(FloatAbi::Hard), families: cvs!["unix"], linker: Some("arm-none-eabi-gcc".into()), diff --git a/compiler/rustc_target/src/spec/targets/armv7_linux_androideabi.rs b/compiler/rustc_target/src/spec/targets/armv7_linux_androideabi.rs index ce6c3c8a6c14..ad8a14fdad53 100644 --- a/compiler/rustc_target/src/spec/targets/armv7_linux_androideabi.rs +++ b/compiler/rustc_target/src/spec/targets/armv7_linux_androideabi.rs @@ -1,6 +1,6 @@ use crate::spec::{ - Arch, Cc, FloatAbi, LinkerFlavor, Lld, SanitizerSet, Target, TargetMetadata, TargetOptions, - base, + Abi, Arch, Cc, FloatAbi, LinkerFlavor, Lld, SanitizerSet, Target, TargetMetadata, + TargetOptions, base, }; // This target if is for the baseline of the Android v7a ABI @@ -26,7 +26,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), arch: Arch::Arm, options: TargetOptions { - abi: "eabi".into(), + abi: Abi::Eabi, llvm_floatabi: Some(FloatAbi::Soft), features: "+v7,+thumb-mode,+thumb2,+vfp3,-d32,-neon".into(), supported_sanitizers: SanitizerSet::ADDRESS, diff --git a/compiler/rustc_target/src/spec/targets/armv7_rtems_eabihf.rs b/compiler/rustc_target/src/spec/targets/armv7_rtems_eabihf.rs index 0958f617663f..382658a87b54 100644 --- a/compiler/rustc_target/src/spec/targets/armv7_rtems_eabihf.rs +++ b/compiler/rustc_target/src/spec/targets/armv7_rtems_eabihf.rs @@ -1,6 +1,6 @@ use crate::spec::{ - Arch, Cc, FloatAbi, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, - TargetOptions, cvs, + Abi, Arch, Cc, Env, FloatAbi, LinkerFlavor, Lld, Os, PanicStrategy, RelocModel, Target, + TargetMetadata, TargetOptions, cvs, }; pub(crate) fn target() -> Target { @@ -17,9 +17,9 @@ pub(crate) fn target() -> Target { arch: Arch::Arm, options: TargetOptions { - os: "rtems".into(), + os: Os::Rtems, families: cvs!["unix"], - abi: "eabihf".into(), + abi: Abi::EabiHf, llvm_floatabi: Some(FloatAbi::Hard), linker_flavor: LinkerFlavor::Gnu(Cc::Yes, Lld::No), linker: None, @@ -32,7 +32,7 @@ pub(crate) fn target() -> Target { c_enum_min_bits: Some(8), eh_frame_header: false, no_default_libraries: false, - env: "newlib".into(), + env: Env::Newlib, ..Default::default() }, } diff --git a/compiler/rustc_target/src/spec/targets/armv7_sony_vita_newlibeabihf.rs b/compiler/rustc_target/src/spec/targets/armv7_sony_vita_newlibeabihf.rs index 6c02ec26fea4..20e5c0acca96 100644 --- a/compiler/rustc_target/src/spec/targets/armv7_sony_vita_newlibeabihf.rs +++ b/compiler/rustc_target/src/spec/targets/armv7_sony_vita_newlibeabihf.rs @@ -1,13 +1,13 @@ use rustc_abi::Endian; use crate::spec::{ - Arch, Cc, FloatAbi, LinkerFlavor, Lld, RelocModel, Target, TargetMetadata, TargetOptions, cvs, + Abi, Arch, Cc, Env, FloatAbi, LinkerFlavor, Lld, Os, RelocModel, Target, TargetMetadata, + TargetOptions, cvs, }; /// A base target for PlayStation Vita devices using the VITASDK toolchain (using newlib). /// /// Requires the VITASDK toolchain on the host system. - pub(crate) fn target() -> Target { let pre_link_args = TargetOptions::link_args( LinkerFlavor::Gnu(Cc::Yes, Lld::No), @@ -29,12 +29,12 @@ pub(crate) fn target() -> Target { arch: Arch::Arm, options: TargetOptions { - os: "vita".into(), + os: Os::Vita, endian: Endian::Little, c_int_width: 32, - env: "newlib".into(), + env: Env::Newlib, vendor: "sony".into(), - abi: "eabihf".into(), + abi: Abi::EabiHf, llvm_floatabi: Some(FloatAbi::Hard), linker_flavor: LinkerFlavor::Gnu(Cc::Yes, Lld::No), no_default_libraries: false, diff --git a/compiler/rustc_target/src/spec/targets/armv7_unknown_freebsd.rs b/compiler/rustc_target/src/spec/targets/armv7_unknown_freebsd.rs index 63aee180299e..0a8432ea8fe9 100644 --- a/compiler/rustc_target/src/spec/targets/armv7_unknown_freebsd.rs +++ b/compiler/rustc_target/src/spec/targets/armv7_unknown_freebsd.rs @@ -1,4 +1,4 @@ -use crate::spec::{Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -13,7 +13,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), arch: Arch::Arm, options: TargetOptions { - abi: "eabihf".into(), + abi: Abi::EabiHf, llvm_floatabi: Some(FloatAbi::Hard), features: "+v7,+vfp3,-d32,+thumb2,-neon".into(), max_atomic_width: Some(64), diff --git a/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_gnueabi.rs b/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_gnueabi.rs index 6288095fcf4c..8fad2ce19632 100644 --- a/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_gnueabi.rs +++ b/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_gnueabi.rs @@ -1,4 +1,4 @@ -use crate::spec::{Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; // This target is for glibc Linux on ARMv7 without thumb-mode, NEON or // hardfloat. @@ -16,7 +16,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), arch: Arch::Arm, options: TargetOptions { - abi: "eabi".into(), + abi: Abi::Eabi, llvm_floatabi: Some(FloatAbi::Soft), features: "+v7,+thumb2,+soft-float,-neon".into(), max_atomic_width: Some(64), diff --git a/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_gnueabihf.rs b/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_gnueabihf.rs index 57374b8af9d7..cbf6d5d08dd0 100644 --- a/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_gnueabihf.rs +++ b/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_gnueabihf.rs @@ -1,4 +1,4 @@ -use crate::spec::{Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; // This target is for glibc Linux on ARMv7 without NEON or // thumb-mode. See the thumbv7neon variant for enabling both. @@ -16,7 +16,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), arch: Arch::Arm, options: TargetOptions { - abi: "eabihf".into(), + abi: Abi::EabiHf, llvm_floatabi: Some(FloatAbi::Hard), // Info about features at https://wiki.debian.org/ArmHardFloatPort features: "+v7,+vfp3,-d32,+thumb2,-neon".into(), diff --git a/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_musleabi.rs b/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_musleabi.rs index 20545aba821f..9bf0b4fd7e4c 100644 --- a/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_musleabi.rs +++ b/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_musleabi.rs @@ -1,4 +1,4 @@ -use crate::spec::{Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; // This target is for musl Linux on ARMv7 without thumb-mode, NEON or // hardfloat. @@ -19,7 +19,7 @@ pub(crate) fn target() -> Target { arch: Arch::Arm, options: TargetOptions { - abi: "eabi".into(), + abi: Abi::Eabi, llvm_floatabi: Some(FloatAbi::Soft), features: "+v7,+thumb2,+soft-float,-neon".into(), max_atomic_width: Some(64), diff --git a/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_musleabihf.rs b/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_musleabihf.rs index 7028f430ff8f..9b5fcd87b120 100644 --- a/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_musleabihf.rs +++ b/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_musleabihf.rs @@ -1,4 +1,4 @@ -use crate::spec::{Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; // This target is for musl Linux on ARMv7 without thumb-mode or NEON. @@ -18,7 +18,7 @@ pub(crate) fn target() -> Target { // Most of these settings are copied from the armv7_unknown_linux_gnueabihf // target. options: TargetOptions { - abi: "eabihf".into(), + abi: Abi::EabiHf, llvm_floatabi: Some(FloatAbi::Hard), features: "+v7,+vfp3,-d32,+thumb2,-neon".into(), max_atomic_width: Some(64), diff --git a/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_ohos.rs b/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_ohos.rs index f0946183fcad..318170fe0f8d 100644 --- a/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_ohos.rs +++ b/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_ohos.rs @@ -1,4 +1,4 @@ -use crate::spec::{Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; // This target is for OpenHarmony on ARMv7 Linux with thumb-mode, but no NEON or // hardfloat. @@ -19,7 +19,7 @@ pub(crate) fn target() -> Target { arch: Arch::Arm, options: TargetOptions { - abi: "eabi".into(), + abi: Abi::Eabi, llvm_floatabi: Some(FloatAbi::Soft), features: "+v7,+thumb2,+soft-float,-neon".into(), max_atomic_width: Some(64), diff --git a/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_uclibceabi.rs b/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_uclibceabi.rs index c2cc2526ec3f..37a70da09c51 100644 --- a/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_uclibceabi.rs +++ b/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_uclibceabi.rs @@ -1,4 +1,4 @@ -use crate::spec::{Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; // This target is for uclibc Linux on ARMv7 without NEON, // thumb-mode or hardfloat. @@ -18,7 +18,7 @@ pub(crate) fn target() -> Target { arch: Arch::Arm, options: TargetOptions { - abi: "eabi".into(), + abi: Abi::Eabi, llvm_floatabi: Some(FloatAbi::Soft), features: "+v7,+thumb2,+soft-float,-neon".into(), cpu: "generic".into(), diff --git a/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_uclibceabihf.rs b/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_uclibceabihf.rs index 0649ba3c5ed5..927c910da596 100644 --- a/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_uclibceabihf.rs +++ b/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_uclibceabihf.rs @@ -1,4 +1,4 @@ -use crate::spec::{Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; // This target is for uclibc Linux on ARMv7 without NEON or // thumb-mode. See the thumbv7neon variant for enabling both. @@ -23,7 +23,7 @@ pub(crate) fn target() -> Target { cpu: "generic".into(), max_atomic_width: Some(64), mcount: "_mcount".into(), - abi: "eabihf".into(), + abi: Abi::EabiHf, llvm_floatabi: Some(FloatAbi::Hard), ..base }, diff --git a/compiler/rustc_target/src/spec/targets/armv7_unknown_netbsd_eabihf.rs b/compiler/rustc_target/src/spec/targets/armv7_unknown_netbsd_eabihf.rs index d6cb517759d9..788944e64c84 100644 --- a/compiler/rustc_target/src/spec/targets/armv7_unknown_netbsd_eabihf.rs +++ b/compiler/rustc_target/src/spec/targets/armv7_unknown_netbsd_eabihf.rs @@ -1,4 +1,4 @@ -use crate::spec::{Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -13,7 +13,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), arch: Arch::Arm, options: TargetOptions { - abi: "eabihf".into(), + abi: Abi::EabiHf, llvm_floatabi: Some(FloatAbi::Hard), features: "+v7,+vfp3,-d32,+thumb2,-neon".into(), max_atomic_width: Some(64), diff --git a/compiler/rustc_target/src/spec/targets/armv7_unknown_trusty.rs b/compiler/rustc_target/src/spec/targets/armv7_unknown_trusty.rs index 765d1982a679..fb3954abb286 100644 --- a/compiler/rustc_target/src/spec/targets/armv7_unknown_trusty.rs +++ b/compiler/rustc_target/src/spec/targets/armv7_unknown_trusty.rs @@ -1,6 +1,6 @@ use crate::spec::{ - Arch, FloatAbi, LinkSelfContainedDefault, PanicStrategy, RelroLevel, Target, TargetMetadata, - TargetOptions, + Abi, Arch, FloatAbi, LinkSelfContainedDefault, Os, PanicStrategy, RelroLevel, Target, + TargetMetadata, TargetOptions, }; pub(crate) fn target() -> Target { @@ -19,12 +19,12 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), arch: Arch::Arm, options: TargetOptions { - abi: "eabi".into(), + abi: Abi::Eabi, llvm_floatabi: Some(FloatAbi::Soft), features: "+v7,+thumb2,+soft-float,-neon".into(), max_atomic_width: Some(64), mcount: "\u{1}mcount".into(), - os: "trusty".into(), + os: Os::Trusty, link_self_contained: LinkSelfContainedDefault::InferredForMusl, dynamic_linking: false, executables: true, diff --git a/compiler/rustc_target/src/spec/targets/armv7_wrs_vxworks_eabihf.rs b/compiler/rustc_target/src/spec/targets/armv7_wrs_vxworks_eabihf.rs index ef261150f220..e43e4fe85cad 100644 --- a/compiler/rustc_target/src/spec/targets/armv7_wrs_vxworks_eabihf.rs +++ b/compiler/rustc_target/src/spec/targets/armv7_wrs_vxworks_eabihf.rs @@ -1,4 +1,4 @@ -use crate::spec::{Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -13,7 +13,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), arch: Arch::Arm, options: TargetOptions { - abi: "eabihf".into(), + abi: Abi::EabiHf, llvm_floatabi: Some(FloatAbi::Hard), // Info about features at https://wiki.debian.org/ArmHardFloatPort features: "+v7,+vfp3,-d32,+thumb2,-neon".into(), diff --git a/compiler/rustc_target/src/spec/targets/armv7a_kmc_solid_asp3_eabi.rs b/compiler/rustc_target/src/spec/targets/armv7a_kmc_solid_asp3_eabi.rs index 3ceeef4e0696..bd18d6d8ae90 100644 --- a/compiler/rustc_target/src/spec/targets/armv7a_kmc_solid_asp3_eabi.rs +++ b/compiler/rustc_target/src/spec/targets/armv7a_kmc_solid_asp3_eabi.rs @@ -1,7 +1,7 @@ -use crate::spec::{Arch, FloatAbi, RelocModel, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Abi, Arch, FloatAbi, RelocModel, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { - let base = base::solid::opts("asp3"); + let base = base::solid::opts(); Target { llvm_target: "armv7a-none-eabi".into(), metadata: TargetMetadata { @@ -14,7 +14,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), arch: Arch::Arm, options: TargetOptions { - abi: "eabi".into(), + abi: Abi::Eabi, llvm_floatabi: Some(FloatAbi::Soft), linker: Some("arm-kmc-eabi-gcc".into()), features: "+v7,+soft-float,+thumb2,-neon".into(), diff --git a/compiler/rustc_target/src/spec/targets/armv7a_kmc_solid_asp3_eabihf.rs b/compiler/rustc_target/src/spec/targets/armv7a_kmc_solid_asp3_eabihf.rs index 65af0bda5dfe..9433cbd46627 100644 --- a/compiler/rustc_target/src/spec/targets/armv7a_kmc_solid_asp3_eabihf.rs +++ b/compiler/rustc_target/src/spec/targets/armv7a_kmc_solid_asp3_eabihf.rs @@ -1,7 +1,7 @@ -use crate::spec::{Arch, FloatAbi, RelocModel, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Abi, Arch, FloatAbi, RelocModel, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { - let base = base::solid::opts("asp3"); + let base = base::solid::opts(); Target { llvm_target: "armv7a-none-eabihf".into(), metadata: TargetMetadata { @@ -14,7 +14,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), arch: Arch::Arm, options: TargetOptions { - abi: "eabihf".into(), + abi: Abi::EabiHf, llvm_floatabi: Some(FloatAbi::Hard), linker: Some("arm-kmc-eabi-gcc".into()), features: "+v7,+vfp3,-d32,+thumb2,-neon".into(), diff --git a/compiler/rustc_target/src/spec/targets/armv7a_none_eabi.rs b/compiler/rustc_target/src/spec/targets/armv7a_none_eabi.rs index 3d4328abe9b4..13a95a113b13 100644 --- a/compiler/rustc_target/src/spec/targets/armv7a_none_eabi.rs +++ b/compiler/rustc_target/src/spec/targets/armv7a_none_eabi.rs @@ -15,13 +15,13 @@ // linking. rationale: matches `thumb` targets use crate::spec::{ - Arch, Cc, FloatAbi, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, + Abi, Arch, Cc, FloatAbi, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, }; pub(crate) fn target() -> Target { let opts = TargetOptions { - abi: "eabi".into(), + abi: Abi::Eabi, llvm_floatabi: Some(FloatAbi::Soft), linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), linker: Some("rust-lld".into()), diff --git a/compiler/rustc_target/src/spec/targets/armv7a_none_eabihf.rs b/compiler/rustc_target/src/spec/targets/armv7a_none_eabihf.rs index e3c5dce88fc1..e03fe3e78b9d 100644 --- a/compiler/rustc_target/src/spec/targets/armv7a_none_eabihf.rs +++ b/compiler/rustc_target/src/spec/targets/armv7a_none_eabihf.rs @@ -6,13 +6,13 @@ // `thumb` & `aarch64` targets. use crate::spec::{ - Arch, Cc, FloatAbi, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, + Abi, Arch, Cc, FloatAbi, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, }; pub(crate) fn target() -> Target { let opts = TargetOptions { - abi: "eabihf".into(), + abi: Abi::EabiHf, llvm_floatabi: Some(FloatAbi::Hard), linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), linker: Some("rust-lld".into()), diff --git a/compiler/rustc_target/src/spec/targets/armv7a_nuttx_eabi.rs b/compiler/rustc_target/src/spec/targets/armv7a_nuttx_eabi.rs index 93302540795d..5ab74e0533ba 100644 --- a/compiler/rustc_target/src/spec/targets/armv7a_nuttx_eabi.rs +++ b/compiler/rustc_target/src/spec/targets/armv7a_nuttx_eabi.rs @@ -5,13 +5,13 @@ // configuration without hardware floating point support. use crate::spec::{ - Arch, Cc, FloatAbi, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, - TargetOptions, cvs, + Abi, Arch, Cc, FloatAbi, LinkerFlavor, Lld, Os, PanicStrategy, RelocModel, Target, + TargetMetadata, TargetOptions, cvs, }; pub(crate) fn target() -> Target { let opts = TargetOptions { - abi: "eabi".into(), + abi: Abi::Eabi, llvm_floatabi: Some(FloatAbi::Soft), linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), linker: Some("rust-lld".into()), @@ -23,7 +23,7 @@ pub(crate) fn target() -> Target { emit_debug_gdb_scripts: false, c_enum_min_bits: Some(8), families: cvs!["unix"], - os: "nuttx".into(), + os: Os::NuttX, ..Default::default() }; Target { diff --git a/compiler/rustc_target/src/spec/targets/armv7a_nuttx_eabihf.rs b/compiler/rustc_target/src/spec/targets/armv7a_nuttx_eabihf.rs index 864517557c30..4ac07e24a48b 100644 --- a/compiler/rustc_target/src/spec/targets/armv7a_nuttx_eabihf.rs +++ b/compiler/rustc_target/src/spec/targets/armv7a_nuttx_eabihf.rs @@ -5,13 +5,13 @@ // configuration with hardware floating point support. use crate::spec::{ - Arch, Cc, FloatAbi, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, - TargetOptions, cvs, + Abi, Arch, Cc, FloatAbi, LinkerFlavor, Lld, Os, PanicStrategy, RelocModel, Target, + TargetMetadata, TargetOptions, cvs, }; pub(crate) fn target() -> Target { let opts = TargetOptions { - abi: "eabihf".into(), + abi: Abi::EabiHf, llvm_floatabi: Some(FloatAbi::Hard), linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), linker: Some("rust-lld".into()), @@ -23,7 +23,7 @@ pub(crate) fn target() -> Target { emit_debug_gdb_scripts: false, c_enum_min_bits: Some(8), families: cvs!["unix"], - os: "nuttx".into(), + os: Os::NuttX, ..Default::default() }; Target { diff --git a/compiler/rustc_target/src/spec/targets/armv7a_vex_v5.rs b/compiler/rustc_target/src/spec/targets/armv7a_vex_v5.rs index 6da1a35474ac..b83d7b090689 100644 --- a/compiler/rustc_target/src/spec/targets/armv7a_vex_v5.rs +++ b/compiler/rustc_target/src/spec/targets/armv7a_vex_v5.rs @@ -1,6 +1,6 @@ use crate::spec::{ - Arch, Cc, FloatAbi, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, - TargetOptions, + Abi, Arch, Cc, Env, FloatAbi, LinkerFlavor, Lld, Os, PanicStrategy, RelocModel, Target, + TargetMetadata, TargetOptions, }; const LINKER_SCRIPT: &str = include_str!("./armv7a_vex_v5_linker_script.ld"); @@ -8,10 +8,10 @@ const LINKER_SCRIPT: &str = include_str!("./armv7a_vex_v5_linker_script.ld"); pub(crate) fn target() -> Target { let opts = TargetOptions { vendor: "vex".into(), - env: "v5".into(), - os: "vexos".into(), + env: Env::V5, + os: Os::VexOs, cpu: "cortex-a9".into(), - abi: "eabihf".into(), + abi: Abi::EabiHf, is_like_vexos: true, llvm_floatabi: Some(FloatAbi::Hard), linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), diff --git a/compiler/rustc_target/src/spec/targets/armv7k_apple_watchos.rs b/compiler/rustc_target/src/spec/targets/armv7k_apple_watchos.rs index df58559848a0..2547cf19004b 100644 --- a/compiler/rustc_target/src/spec/targets/armv7k_apple_watchos.rs +++ b/compiler/rustc_target/src/spec/targets/armv7k_apple_watchos.rs @@ -1,8 +1,8 @@ use crate::spec::base::apple::{Arch, TargetEnv, base}; -use crate::spec::{Target, TargetMetadata, TargetOptions}; +use crate::spec::{Os, Target, TargetMetadata, TargetOptions}; pub(crate) fn target() -> Target { - let (opts, llvm_target, arch) = base("watchos", Arch::Armv7k, TargetEnv::Normal); + let (opts, llvm_target, arch) = base(Os::WatchOs, Arch::Armv7k, TargetEnv::Normal); Target { llvm_target, metadata: TargetMetadata { diff --git a/compiler/rustc_target/src/spec/targets/armv7r_none_eabi.rs b/compiler/rustc_target/src/spec/targets/armv7r_none_eabi.rs index bd07e724901c..b490b716f4b0 100644 --- a/compiler/rustc_target/src/spec/targets/armv7r_none_eabi.rs +++ b/compiler/rustc_target/src/spec/targets/armv7r_none_eabi.rs @@ -1,7 +1,7 @@ // Targets the Little-endian Cortex-R4/R5 processor (ARMv7-R) use crate::spec::{ - Arch, Cc, FloatAbi, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, + Abi, Arch, Cc, FloatAbi, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, }; @@ -19,7 +19,7 @@ pub(crate) fn target() -> Target { arch: Arch::Arm, options: TargetOptions { - abi: "eabi".into(), + abi: Abi::Eabi, llvm_floatabi: Some(FloatAbi::Soft), linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), linker: Some("rust-lld".into()), diff --git a/compiler/rustc_target/src/spec/targets/armv7r_none_eabihf.rs b/compiler/rustc_target/src/spec/targets/armv7r_none_eabihf.rs index 2f89f8042c4a..7a3eb3b811a6 100644 --- a/compiler/rustc_target/src/spec/targets/armv7r_none_eabihf.rs +++ b/compiler/rustc_target/src/spec/targets/armv7r_none_eabihf.rs @@ -1,7 +1,7 @@ // Targets the Little-endian Cortex-R4F/R5F processor (ARMv7-R) use crate::spec::{ - Arch, Cc, FloatAbi, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, + Abi, Arch, Cc, FloatAbi, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, }; @@ -19,7 +19,7 @@ pub(crate) fn target() -> Target { arch: Arch::Arm, options: TargetOptions { - abi: "eabihf".into(), + abi: Abi::EabiHf, llvm_floatabi: Some(FloatAbi::Hard), linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), linker: Some("rust-lld".into()), diff --git a/compiler/rustc_target/src/spec/targets/armv7s_apple_ios.rs b/compiler/rustc_target/src/spec/targets/armv7s_apple_ios.rs index 63259043b73d..cd9da114acfb 100644 --- a/compiler/rustc_target/src/spec/targets/armv7s_apple_ios.rs +++ b/compiler/rustc_target/src/spec/targets/armv7s_apple_ios.rs @@ -1,8 +1,8 @@ use crate::spec::base::apple::{Arch, TargetEnv, base}; -use crate::spec::{Target, TargetMetadata, TargetOptions}; +use crate::spec::{Os, Target, TargetMetadata, TargetOptions}; pub(crate) fn target() -> Target { - let (opts, llvm_target, arch) = base("ios", Arch::Armv7s, TargetEnv::Normal); + let (opts, llvm_target, arch) = base(Os::IOs, Arch::Armv7s, TargetEnv::Normal); Target { llvm_target, metadata: TargetMetadata { diff --git a/compiler/rustc_target/src/spec/targets/armv8r_none_eabihf.rs b/compiler/rustc_target/src/spec/targets/armv8r_none_eabihf.rs index 58bd9fafde96..423bf260d89c 100644 --- a/compiler/rustc_target/src/spec/targets/armv8r_none_eabihf.rs +++ b/compiler/rustc_target/src/spec/targets/armv8r_none_eabihf.rs @@ -1,7 +1,7 @@ // Targets the Little-endian Cortex-R52 processor (ARMv8-R) use crate::spec::{ - Arch, Cc, FloatAbi, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, + Abi, Arch, Cc, FloatAbi, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, }; @@ -19,7 +19,7 @@ pub(crate) fn target() -> Target { arch: Arch::Arm, options: TargetOptions { - abi: "eabihf".into(), + abi: Abi::EabiHf, llvm_floatabi: Some(FloatAbi::Hard), linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), linker: Some("rust-lld".into()), diff --git a/compiler/rustc_target/src/spec/targets/csky_unknown_linux_gnuabiv2.rs b/compiler/rustc_target/src/spec/targets/csky_unknown_linux_gnuabiv2.rs index 1f7f7899f3a6..176b853493ef 100644 --- a/compiler/rustc_target/src/spec/targets/csky_unknown_linux_gnuabiv2.rs +++ b/compiler/rustc_target/src/spec/targets/csky_unknown_linux_gnuabiv2.rs @@ -1,4 +1,4 @@ -use crate::spec::{Arch, Cc, LinkerFlavor, Lld, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Abi, Arch, Cc, LinkerFlavor, Lld, Target, TargetMetadata, TargetOptions, base}; // This target is for glibc Linux on Csky @@ -16,7 +16,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-S32-p:32:32-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:32:32-v128:32:32-a:0:32-Fi32-n32".into(), arch: Arch::CSky, options: TargetOptions { - abi: "abiv2".into(), + abi: Abi::AbiV2, features: "+2e3,+3e7,+7e10,+cache,+dsp1e2,+dspe60,+e1,+e2,+edsp,+elrw,+hard-tp,+high-registers,+hwdiv,+mp,+mp1e2,+nvic,+trust".into(), late_link_args: TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-l:libatomic.a"]), max_atomic_width: Some(32), diff --git a/compiler/rustc_target/src/spec/targets/csky_unknown_linux_gnuabiv2hf.rs b/compiler/rustc_target/src/spec/targets/csky_unknown_linux_gnuabiv2hf.rs index 68fdb69fe9d8..5af54493063d 100644 --- a/compiler/rustc_target/src/spec/targets/csky_unknown_linux_gnuabiv2hf.rs +++ b/compiler/rustc_target/src/spec/targets/csky_unknown_linux_gnuabiv2hf.rs @@ -1,4 +1,4 @@ -use crate::spec::{Arch, Cc, LinkerFlavor, Lld, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Abi, Arch, Cc, LinkerFlavor, Lld, Target, TargetMetadata, TargetOptions, base}; // This target is for glibc Linux on Csky @@ -16,7 +16,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-S32-p:32:32-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:32:32-v128:32:32-a:0:32-Fi32-n32".into(), arch: Arch::CSky, options: TargetOptions { - abi: "abiv2hf".into(), + abi: Abi::AbiV2Hf, cpu: "ck860fv".into(), features: "+hard-float,+hard-float-abi,+2e3,+3e7,+7e10,+cache,+dsp1e2,+dspe60,+e1,+e2,+edsp,+elrw,+hard-tp,+high-registers,+hwdiv,+mp,+mp1e2,+nvic,+trust".into(), late_link_args: TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-l:libatomic.a", "-mhard-float"]), diff --git a/compiler/rustc_target/src/spec/targets/i386_apple_ios.rs b/compiler/rustc_target/src/spec/targets/i386_apple_ios.rs index a919be765a27..3992e7aa9dbc 100644 --- a/compiler/rustc_target/src/spec/targets/i386_apple_ios.rs +++ b/compiler/rustc_target/src/spec/targets/i386_apple_ios.rs @@ -1,10 +1,10 @@ use crate::spec::base::apple::{Arch, TargetEnv, base}; -use crate::spec::{Target, TargetMetadata, TargetOptions}; +use crate::spec::{Os, Target, TargetMetadata, TargetOptions}; pub(crate) fn target() -> Target { // i386-apple-ios is a simulator target, even though it isn't declared // that way in the target name like the other ones... - let (opts, llvm_target, arch) = base("ios", Arch::I386, TargetEnv::Simulator); + let (opts, llvm_target, arch) = base(Os::IOs, Arch::I386, TargetEnv::Simulator); Target { llvm_target, metadata: TargetMetadata { diff --git a/compiler/rustc_target/src/spec/targets/i686_apple_darwin.rs b/compiler/rustc_target/src/spec/targets/i686_apple_darwin.rs index 96c477d52367..1c3481928a85 100644 --- a/compiler/rustc_target/src/spec/targets/i686_apple_darwin.rs +++ b/compiler/rustc_target/src/spec/targets/i686_apple_darwin.rs @@ -1,8 +1,8 @@ use crate::spec::base::apple::{Arch, TargetEnv, base}; -use crate::spec::{Target, TargetMetadata, TargetOptions}; +use crate::spec::{Os, Target, TargetMetadata, TargetOptions}; pub(crate) fn target() -> Target { - let (opts, llvm_target, arch) = base("macos", Arch::I686, TargetEnv::Normal); + let (opts, llvm_target, arch) = base(Os::MacOs, Arch::I686, TargetEnv::Normal); Target { llvm_target, metadata: TargetMetadata { diff --git a/compiler/rustc_target/src/spec/targets/i686_pc_nto_qnx700.rs b/compiler/rustc_target/src/spec/targets/i686_pc_nto_qnx700.rs index af7f3b6b8563..7184a54961e2 100644 --- a/compiler/rustc_target/src/spec/targets/i686_pc_nto_qnx700.rs +++ b/compiler/rustc_target/src/spec/targets/i686_pc_nto_qnx700.rs @@ -1,5 +1,5 @@ use crate::spec::base::nto_qnx; -use crate::spec::{Arch, RustcAbi, StackProbeType, Target, TargetOptions, base}; +use crate::spec::{Arch, Env, RustcAbi, StackProbeType, Target, TargetOptions, base}; pub(crate) fn target() -> Target { let mut meta = nto_qnx::meta(); @@ -21,7 +21,7 @@ pub(crate) fn target() -> Target { nto_qnx::ApiVariant::Default, nto_qnx::Arch::I586, ), - env: "nto70".into(), + env: Env::Nto70, vendor: "pc".into(), stack_probes: StackProbeType::Inline, ..base::nto_qnx::opts() diff --git a/compiler/rustc_target/src/spec/targets/i686_win7_windows_gnu.rs b/compiler/rustc_target/src/spec/targets/i686_win7_windows_gnu.rs index c026f915906c..43ebc54c2b40 100644 --- a/compiler/rustc_target/src/spec/targets/i686_win7_windows_gnu.rs +++ b/compiler/rustc_target/src/spec/targets/i686_win7_windows_gnu.rs @@ -1,15 +1,18 @@ use crate::spec::{ - Arch, Cc, FramePointer, LinkerFlavor, Lld, RustcAbi, Target, TargetMetadata, base, + Arch, Cc, FramePointer, LinkerFlavor, Lld, RustcAbi, Target, TargetMetadata, TargetOptions, + base, }; pub(crate) fn target() -> Target { - let mut base = base::windows_gnu::opts(); - base.vendor = "win7".into(); - base.rustc_abi = Some(RustcAbi::X86Sse2); - base.cpu = "pentium4".into(); - base.max_atomic_width = Some(64); - base.frame_pointer = FramePointer::Always; // Required for backtraces - base.linker = Some("i686-w64-mingw32-gcc".into()); + let mut base = TargetOptions { + vendor: "win7".into(), + rustc_abi: Some(RustcAbi::X86Sse2), + cpu: "pentium4".into(), + max_atomic_width: Some(64), + frame_pointer: FramePointer::Always, // Required for backtraces + linker: Some("i686-w64-mingw32-gcc".into()), + ..base::windows_gnu::opts() + }; // Mark all dynamic libraries and executables as compatible with the larger 4GiB address // space available to x86 Windows binaries on x86_64. diff --git a/compiler/rustc_target/src/spec/targets/i686_win7_windows_msvc.rs b/compiler/rustc_target/src/spec/targets/i686_win7_windows_msvc.rs index 68131bf65426..8994c245d7b9 100644 --- a/compiler/rustc_target/src/spec/targets/i686_win7_windows_msvc.rs +++ b/compiler/rustc_target/src/spec/targets/i686_win7_windows_msvc.rs @@ -1,18 +1,22 @@ -use crate::spec::{Arch, LinkerFlavor, Lld, RustcAbi, SanitizerSet, Target, TargetMetadata, base}; +use crate::spec::{ + Arch, LinkerFlavor, Lld, RustcAbi, SanitizerSet, Target, TargetMetadata, TargetOptions, base, +}; pub(crate) fn target() -> Target { - let mut base = base::windows_msvc::opts(); - base.vendor = "win7".into(); - base.rustc_abi = Some(RustcAbi::X86Sse2); - base.cpu = "pentium4".into(); - base.max_atomic_width = Some(64); - base.supported_sanitizers = SanitizerSet::ADDRESS; - // On Windows 7 32-bit, the alignment characteristic of the TLS Directory - // don't appear to be respected by the PE Loader, leading to crashes. As - // a result, let's disable has_thread_local to make sure TLS goes through - // the emulation layer. - // See https://github.com/rust-lang/rust/issues/138903 - base.has_thread_local = false; + let mut base = TargetOptions { + vendor: "win7".into(), + rustc_abi: Some(RustcAbi::X86Sse2), + cpu: "pentium4".into(), + max_atomic_width: Some(64), + supported_sanitizers: SanitizerSet::ADDRESS, + // On Windows 7 32-bit, the alignment characteristic of the TLS Directory + // don't appear to be respected by the PE Loader, leading to crashes. As + // a result, let's disable has_thread_local to make sure TLS goes through + // the emulation layer. + // See https://github.com/rust-lang/rust/issues/138903 + has_thread_local: false, + ..base::windows_msvc::opts() + }; base.add_pre_link_args( LinkerFlavor::Msvc(Lld::No), diff --git a/compiler/rustc_target/src/spec/targets/loongarch32_unknown_none_softfloat.rs b/compiler/rustc_target/src/spec/targets/loongarch32_unknown_none_softfloat.rs index 4ac9241fb8c6..896cf0f59d58 100644 --- a/compiler/rustc_target/src/spec/targets/loongarch32_unknown_none_softfloat.rs +++ b/compiler/rustc_target/src/spec/targets/loongarch32_unknown_none_softfloat.rs @@ -1,5 +1,6 @@ use crate::spec::{ - Arch, Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, + Abi, Arch, Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, + TargetOptions, }; pub(crate) fn target() -> Target { @@ -17,7 +18,7 @@ pub(crate) fn target() -> Target { options: TargetOptions { cpu: "generic".into(), features: "-f,-d".into(), - abi: "softfloat".into(), + abi: Abi::SoftFloat, linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), linker: Some("rust-lld".into()), llvm_abiname: "ilp32s".into(), diff --git a/compiler/rustc_target/src/spec/targets/loongarch64_unknown_none_softfloat.rs b/compiler/rustc_target/src/spec/targets/loongarch64_unknown_none_softfloat.rs index e33d8c954fd0..efeb864de1a7 100644 --- a/compiler/rustc_target/src/spec/targets/loongarch64_unknown_none_softfloat.rs +++ b/compiler/rustc_target/src/spec/targets/loongarch64_unknown_none_softfloat.rs @@ -1,5 +1,5 @@ use crate::spec::{ - Arch, Cc, CodeModel, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, + Abi, Arch, Cc, CodeModel, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, }; @@ -18,7 +18,7 @@ pub(crate) fn target() -> Target { options: TargetOptions { cpu: "generic".into(), features: "-f,-d".into(), - abi: "softfloat".into(), + abi: Abi::SoftFloat, linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), linker: Some("rust-lld".into()), llvm_abiname: "lp64s".into(), diff --git a/compiler/rustc_target/src/spec/targets/mips64_openwrt_linux_musl.rs b/compiler/rustc_target/src/spec/targets/mips64_openwrt_linux_musl.rs index 0cd93429f6e2..f90e689912e1 100644 --- a/compiler/rustc_target/src/spec/targets/mips64_openwrt_linux_musl.rs +++ b/compiler/rustc_target/src/spec/targets/mips64_openwrt_linux_musl.rs @@ -2,7 +2,7 @@ use rustc_abi::Endian; -use crate::spec::{Arch, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Abi, Arch, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { let mut base = base::linux_musl::opts(); @@ -24,7 +24,7 @@ pub(crate) fn target() -> Target { arch: Arch::Mips64, options: TargetOptions { vendor: "openwrt".into(), - abi: "abi64".into(), + abi: Abi::Abi64, endian: Endian::Big, mcount: "_mcount".into(), llvm_abiname: "n64".into(), diff --git a/compiler/rustc_target/src/spec/targets/mips64_unknown_linux_gnuabi64.rs b/compiler/rustc_target/src/spec/targets/mips64_unknown_linux_gnuabi64.rs index 4d06466e6553..ecb66b43712c 100644 --- a/compiler/rustc_target/src/spec/targets/mips64_unknown_linux_gnuabi64.rs +++ b/compiler/rustc_target/src/spec/targets/mips64_unknown_linux_gnuabi64.rs @@ -1,6 +1,6 @@ use rustc_abi::Endian; -use crate::spec::{Arch, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Abi, Arch, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -15,7 +15,7 @@ pub(crate) fn target() -> Target { data_layout: "E-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".into(), arch: Arch::Mips64, options: TargetOptions { - abi: "abi64".into(), + abi: Abi::Abi64, endian: Endian::Big, // NOTE(mips64r2) matches C toolchain cpu: "mips64r2".into(), diff --git a/compiler/rustc_target/src/spec/targets/mips64_unknown_linux_muslabi64.rs b/compiler/rustc_target/src/spec/targets/mips64_unknown_linux_muslabi64.rs index a37508c34dbd..ccb13fee37a1 100644 --- a/compiler/rustc_target/src/spec/targets/mips64_unknown_linux_muslabi64.rs +++ b/compiler/rustc_target/src/spec/targets/mips64_unknown_linux_muslabi64.rs @@ -1,6 +1,6 @@ use rustc_abi::Endian; -use crate::spec::{Arch, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Abi, Arch, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { let mut base = base::linux_musl::opts(); @@ -20,7 +20,7 @@ pub(crate) fn target() -> Target { data_layout: "E-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".into(), arch: Arch::Mips64, options: TargetOptions { - abi: "abi64".into(), + abi: Abi::Abi64, endian: Endian::Big, mcount: "_mcount".into(), llvm_abiname: "n64".into(), diff --git a/compiler/rustc_target/src/spec/targets/mips64el_unknown_linux_gnuabi64.rs b/compiler/rustc_target/src/spec/targets/mips64el_unknown_linux_gnuabi64.rs index 9ece84ed5442..2457bd838c57 100644 --- a/compiler/rustc_target/src/spec/targets/mips64el_unknown_linux_gnuabi64.rs +++ b/compiler/rustc_target/src/spec/targets/mips64el_unknown_linux_gnuabi64.rs @@ -1,4 +1,4 @@ -use crate::spec::{Arch, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Abi, Arch, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -13,7 +13,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".into(), arch: Arch::Mips64, options: TargetOptions { - abi: "abi64".into(), + abi: Abi::Abi64, // NOTE(mips64r2) matches C toolchain cpu: "mips64r2".into(), features: "+mips64r2,+xgot".into(), diff --git a/compiler/rustc_target/src/spec/targets/mips64el_unknown_linux_muslabi64.rs b/compiler/rustc_target/src/spec/targets/mips64el_unknown_linux_muslabi64.rs index 759a04d24b7c..41353729df8f 100644 --- a/compiler/rustc_target/src/spec/targets/mips64el_unknown_linux_muslabi64.rs +++ b/compiler/rustc_target/src/spec/targets/mips64el_unknown_linux_muslabi64.rs @@ -1,4 +1,4 @@ -use crate::spec::{Arch, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Abi, Arch, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { let mut base = base::linux_musl::opts(); @@ -18,7 +18,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".into(), arch: Arch::Mips64, options: TargetOptions { - abi: "abi64".into(), + abi: Abi::Abi64, mcount: "_mcount".into(), llvm_abiname: "n64".into(), ..base diff --git a/compiler/rustc_target/src/spec/targets/mipsel_sony_psp.rs b/compiler/rustc_target/src/spec/targets/mipsel_sony_psp.rs index 200735f4e0fb..370e585f65ad 100644 --- a/compiler/rustc_target/src/spec/targets/mipsel_sony_psp.rs +++ b/compiler/rustc_target/src/spec/targets/mipsel_sony_psp.rs @@ -1,5 +1,5 @@ use crate::spec::{ - Arch, Cc, LinkerFlavor, Lld, RelocModel, Target, TargetMetadata, TargetOptions, cvs, + Arch, Cc, LinkerFlavor, Lld, Os, RelocModel, Target, TargetMetadata, TargetOptions, cvs, }; // The PSP has custom linker requirements. @@ -24,7 +24,7 @@ pub(crate) fn target() -> Target { arch: Arch::Mips, options: TargetOptions { - os: "psp".into(), + os: Os::Psp, vendor: "sony".into(), linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), cpu: "mips2".into(), diff --git a/compiler/rustc_target/src/spec/targets/mipsel_sony_psx.rs b/compiler/rustc_target/src/spec/targets/mipsel_sony_psx.rs index b6d30be589ea..06631fdefb4a 100644 --- a/compiler/rustc_target/src/spec/targets/mipsel_sony_psx.rs +++ b/compiler/rustc_target/src/spec/targets/mipsel_sony_psx.rs @@ -1,6 +1,6 @@ use crate::spec::{ - Arch, Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, - cvs, + Arch, Cc, LinkerFlavor, Lld, Os, PanicStrategy, RelocModel, Target, TargetMetadata, + TargetOptions, cvs, }; pub(crate) fn target() -> Target { @@ -21,7 +21,7 @@ pub(crate) fn target() -> Target { // of functionality post load, so we still declare it as `cfg!(target_os = "psx")`. // // See for details. - os: "psx".into(), + os: Os::Psx, vendor: "sony".into(), linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), cpu: "mips1".into(), diff --git a/compiler/rustc_target/src/spec/targets/mipsisa64r6_unknown_linux_gnuabi64.rs b/compiler/rustc_target/src/spec/targets/mipsisa64r6_unknown_linux_gnuabi64.rs index 3a95f78482bb..fb97a2e65eab 100644 --- a/compiler/rustc_target/src/spec/targets/mipsisa64r6_unknown_linux_gnuabi64.rs +++ b/compiler/rustc_target/src/spec/targets/mipsisa64r6_unknown_linux_gnuabi64.rs @@ -1,6 +1,6 @@ use rustc_abi::Endian; -use crate::spec::{Arch, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Abi, Arch, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -15,7 +15,7 @@ pub(crate) fn target() -> Target { data_layout: "E-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".into(), arch: Arch::Mips64r6, options: TargetOptions { - abi: "abi64".into(), + abi: Abi::Abi64, endian: Endian::Big, // NOTE(mips64r6) matches C toolchain cpu: "mips64r6".into(), diff --git a/compiler/rustc_target/src/spec/targets/mipsisa64r6el_unknown_linux_gnuabi64.rs b/compiler/rustc_target/src/spec/targets/mipsisa64r6el_unknown_linux_gnuabi64.rs index 8e5bf3d36559..556962458fa5 100644 --- a/compiler/rustc_target/src/spec/targets/mipsisa64r6el_unknown_linux_gnuabi64.rs +++ b/compiler/rustc_target/src/spec/targets/mipsisa64r6el_unknown_linux_gnuabi64.rs @@ -1,4 +1,4 @@ -use crate::spec::{Arch, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Abi, Arch, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -13,7 +13,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".into(), arch: Arch::Mips64r6, options: TargetOptions { - abi: "abi64".into(), + abi: Abi::Abi64, // NOTE(mips64r6) matches C toolchain cpu: "mips64r6".into(), features: "+mips64r6".into(), diff --git a/compiler/rustc_target/src/spec/targets/nvptx64_nvidia_cuda.rs b/compiler/rustc_target/src/spec/targets/nvptx64_nvidia_cuda.rs index 5bbf40b5fadd..35003c4d4dd6 100644 --- a/compiler/rustc_target/src/spec/targets/nvptx64_nvidia_cuda.rs +++ b/compiler/rustc_target/src/spec/targets/nvptx64_nvidia_cuda.rs @@ -1,5 +1,5 @@ use crate::spec::{ - Arch, LinkSelfContainedDefault, LinkerFlavor, MergeFunctions, PanicStrategy, Target, + Arch, LinkSelfContainedDefault, LinkerFlavor, MergeFunctions, Os, PanicStrategy, Target, TargetMetadata, TargetOptions, }; @@ -17,7 +17,7 @@ pub(crate) fn target() -> Target { pointer_width: 64, options: TargetOptions { - os: "cuda".into(), + os: Os::Cuda, vendor: "nvidia".into(), linker_flavor: LinkerFlavor::Ptx, // The linker can be installed from `crates.io`. diff --git a/compiler/rustc_target/src/spec/targets/powerpc64_unknown_freebsd.rs b/compiler/rustc_target/src/spec/targets/powerpc64_unknown_freebsd.rs index de94d2023452..f5d5698713c2 100644 --- a/compiler/rustc_target/src/spec/targets/powerpc64_unknown_freebsd.rs +++ b/compiler/rustc_target/src/spec/targets/powerpc64_unknown_freebsd.rs @@ -1,7 +1,7 @@ use rustc_abi::Endian; use crate::spec::{ - Arch, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, TargetOptions, base, + Abi, Arch, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, TargetOptions, base, }; pub(crate) fn target() -> Target { @@ -10,7 +10,7 @@ pub(crate) fn target() -> Target { base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]); base.max_atomic_width = Some(64); base.stack_probes = StackProbeType::Inline; - base.abi = "elfv2".into(); + base.abi = Abi::ElfV2; base.llvm_abiname = "elfv2".into(); Target { diff --git a/compiler/rustc_target/src/spec/targets/powerpc64_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/powerpc64_unknown_linux_gnu.rs index 18a3f059039d..e2dada235271 100644 --- a/compiler/rustc_target/src/spec/targets/powerpc64_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/targets/powerpc64_unknown_linux_gnu.rs @@ -1,7 +1,7 @@ use rustc_abi::Endian; use crate::spec::{ - Arch, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, TargetOptions, base, + Abi, Arch, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, TargetOptions, base, }; pub(crate) fn target() -> Target { @@ -10,7 +10,7 @@ pub(crate) fn target() -> Target { base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]); base.max_atomic_width = Some(64); base.stack_probes = StackProbeType::Inline; - base.abi = "elfv1".into(); + base.abi = Abi::ElfV1; base.llvm_abiname = "elfv1".into(); Target { diff --git a/compiler/rustc_target/src/spec/targets/powerpc64_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/powerpc64_unknown_linux_musl.rs index 64d4f58a4664..b663ddf962ea 100644 --- a/compiler/rustc_target/src/spec/targets/powerpc64_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/targets/powerpc64_unknown_linux_musl.rs @@ -1,7 +1,7 @@ use rustc_abi::Endian; use crate::spec::{ - Arch, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, TargetOptions, base, + Abi, Arch, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, TargetOptions, base, }; pub(crate) fn target() -> Target { @@ -10,7 +10,7 @@ pub(crate) fn target() -> Target { base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]); base.max_atomic_width = Some(64); base.stack_probes = StackProbeType::Inline; - base.abi = "elfv2".into(); + base.abi = Abi::ElfV2; base.llvm_abiname = "elfv2".into(); Target { diff --git a/compiler/rustc_target/src/spec/targets/powerpc64_unknown_openbsd.rs b/compiler/rustc_target/src/spec/targets/powerpc64_unknown_openbsd.rs index 1034a1603026..082358e82be1 100644 --- a/compiler/rustc_target/src/spec/targets/powerpc64_unknown_openbsd.rs +++ b/compiler/rustc_target/src/spec/targets/powerpc64_unknown_openbsd.rs @@ -1,7 +1,7 @@ use rustc_abi::Endian; use crate::spec::{ - Arch, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, TargetOptions, base, + Abi, Arch, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, TargetOptions, base, }; pub(crate) fn target() -> Target { @@ -10,7 +10,7 @@ pub(crate) fn target() -> Target { base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]); base.max_atomic_width = Some(64); base.stack_probes = StackProbeType::Inline; - base.abi = "elfv2".into(); + base.abi = Abi::ElfV2; base.llvm_abiname = "elfv2".into(); Target { diff --git a/compiler/rustc_target/src/spec/targets/powerpc64_wrs_vxworks.rs b/compiler/rustc_target/src/spec/targets/powerpc64_wrs_vxworks.rs index fb40316d75dc..f576d2372bfa 100644 --- a/compiler/rustc_target/src/spec/targets/powerpc64_wrs_vxworks.rs +++ b/compiler/rustc_target/src/spec/targets/powerpc64_wrs_vxworks.rs @@ -1,7 +1,7 @@ use rustc_abi::Endian; use crate::spec::{ - Arch, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, TargetOptions, base, + Abi, Arch, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, TargetOptions, base, }; pub(crate) fn target() -> Target { @@ -10,7 +10,7 @@ pub(crate) fn target() -> Target { base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]); base.max_atomic_width = Some(64); base.stack_probes = StackProbeType::Inline; - base.abi = "elfv1".into(); + base.abi = Abi::ElfV1; base.llvm_abiname = "elfv1".into(); Target { diff --git a/compiler/rustc_target/src/spec/targets/powerpc64le_unknown_freebsd.rs b/compiler/rustc_target/src/spec/targets/powerpc64le_unknown_freebsd.rs index 7ae74dc882fd..b2713af3bd56 100644 --- a/compiler/rustc_target/src/spec/targets/powerpc64le_unknown_freebsd.rs +++ b/compiler/rustc_target/src/spec/targets/powerpc64le_unknown_freebsd.rs @@ -1,5 +1,5 @@ use crate::spec::{ - Arch, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, TargetOptions, base, + Abi, Arch, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, TargetOptions, base, }; pub(crate) fn target() -> Target { @@ -8,7 +8,7 @@ pub(crate) fn target() -> Target { base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]); base.max_atomic_width = Some(64); base.stack_probes = StackProbeType::Inline; - base.abi = "elfv2".into(); + base.abi = Abi::ElfV2; base.llvm_abiname = "elfv2".into(); Target { diff --git a/compiler/rustc_target/src/spec/targets/powerpc64le_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/powerpc64le_unknown_linux_gnu.rs index 4d1e3dfae456..550ad563e6f2 100644 --- a/compiler/rustc_target/src/spec/targets/powerpc64le_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/targets/powerpc64le_unknown_linux_gnu.rs @@ -1,5 +1,5 @@ use crate::spec::{ - Arch, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, TargetOptions, base, + Abi, Arch, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, TargetOptions, base, }; pub(crate) fn target() -> Target { @@ -8,7 +8,7 @@ pub(crate) fn target() -> Target { base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]); base.max_atomic_width = Some(64); base.stack_probes = StackProbeType::Inline; - base.abi = "elfv2".into(); + base.abi = Abi::ElfV2; base.llvm_abiname = "elfv2".into(); Target { diff --git a/compiler/rustc_target/src/spec/targets/powerpc64le_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/powerpc64le_unknown_linux_musl.rs index 3813e29229d9..38e3d09c2c35 100644 --- a/compiler/rustc_target/src/spec/targets/powerpc64le_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/targets/powerpc64le_unknown_linux_musl.rs @@ -1,5 +1,5 @@ use crate::spec::{ - Arch, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, TargetOptions, base, + Abi, Arch, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, TargetOptions, base, }; pub(crate) fn target() -> Target { @@ -10,7 +10,7 @@ pub(crate) fn target() -> Target { base.stack_probes = StackProbeType::Inline; // FIXME(compiler-team#422): musl targets should be dynamically linked by default. base.crt_static_default = true; - base.abi = "elfv2".into(); + base.abi = Abi::ElfV2; base.llvm_abiname = "elfv2".into(); Target { diff --git a/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_gnuspe.rs b/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_gnuspe.rs index 8bbed94f2f7a..49620305e0e8 100644 --- a/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_gnuspe.rs +++ b/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_gnuspe.rs @@ -1,7 +1,7 @@ use rustc_abi::Endian; use crate::spec::{ - Arch, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, TargetOptions, base, + Abi, Arch, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, TargetOptions, base, }; pub(crate) fn target() -> Target { @@ -22,7 +22,7 @@ pub(crate) fn target() -> Target { data_layout: "E-m:e-p:32:32-Fn32-i64:64-n32".into(), arch: Arch::PowerPC, options: TargetOptions { - abi: "spe".into(), + abi: Abi::Spe, endian: Endian::Big, features: "+secure-plt,+msync".into(), mcount: "_mcount".into(), diff --git a/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_muslspe.rs b/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_muslspe.rs index 0b6535e5debe..210a80fe422e 100644 --- a/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_muslspe.rs +++ b/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_muslspe.rs @@ -1,7 +1,7 @@ use rustc_abi::Endian; use crate::spec::{ - Arch, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, TargetOptions, base, + Abi, Arch, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, TargetOptions, base, }; pub(crate) fn target() -> Target { @@ -22,7 +22,7 @@ pub(crate) fn target() -> Target { data_layout: "E-m:e-p:32:32-Fn32-i64:64-n32".into(), arch: Arch::PowerPC, options: TargetOptions { - abi: "spe".into(), + abi: Abi::Spe, endian: Endian::Big, features: "+msync".into(), mcount: "_mcount".into(), diff --git a/compiler/rustc_target/src/spec/targets/powerpc_wrs_vxworks_spe.rs b/compiler/rustc_target/src/spec/targets/powerpc_wrs_vxworks_spe.rs index 85de246605d7..041580f2bdaf 100644 --- a/compiler/rustc_target/src/spec/targets/powerpc_wrs_vxworks_spe.rs +++ b/compiler/rustc_target/src/spec/targets/powerpc_wrs_vxworks_spe.rs @@ -1,7 +1,7 @@ use rustc_abi::Endian; use crate::spec::{ - Arch, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, TargetOptions, base, + Abi, Arch, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, TargetOptions, base, }; pub(crate) fn target() -> Target { @@ -22,7 +22,7 @@ pub(crate) fn target() -> Target { data_layout: "E-m:e-p:32:32-Fn32-i64:64-n32".into(), arch: Arch::PowerPC, options: TargetOptions { - abi: "spe".into(), + abi: Abi::Spe, endian: Endian::Big, // feature msync would disable instruction 'fsync' which is not supported by fsl_p1p2 features: "+secure-plt,+msync".into(), diff --git a/compiler/rustc_target/src/spec/targets/riscv32e_unknown_none_elf.rs b/compiler/rustc_target/src/spec/targets/riscv32e_unknown_none_elf.rs index 1f8b2cacd9b5..65dbd391db74 100644 --- a/compiler/rustc_target/src/spec/targets/riscv32e_unknown_none_elf.rs +++ b/compiler/rustc_target/src/spec/targets/riscv32e_unknown_none_elf.rs @@ -1,9 +1,9 @@ use crate::spec::{ - Arch, Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, + Abi, Arch, Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, + TargetOptions, }; pub(crate) fn target() -> Target { - let abi = "ilp32e"; Target { // The below `data_layout` is explicitly specified by the ilp32e ABI in LLVM. See also // `options.llvm_abiname`. @@ -19,12 +19,12 @@ pub(crate) fn target() -> Target { arch: Arch::RiscV32, options: TargetOptions { - abi: abi.into(), + abi: Abi::Ilp32e, linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), linker: Some("rust-lld".into()), cpu: "generic-rv32".into(), // The ilp32e ABI specifies the `data_layout` - llvm_abiname: abi.into(), + llvm_abiname: "ilp32e".into(), max_atomic_width: Some(32), atomic_cas: false, features: "+e,+forced-atomics".into(), diff --git a/compiler/rustc_target/src/spec/targets/riscv32em_unknown_none_elf.rs b/compiler/rustc_target/src/spec/targets/riscv32em_unknown_none_elf.rs index 1ae868e9b135..0826326a2b4b 100644 --- a/compiler/rustc_target/src/spec/targets/riscv32em_unknown_none_elf.rs +++ b/compiler/rustc_target/src/spec/targets/riscv32em_unknown_none_elf.rs @@ -1,9 +1,9 @@ use crate::spec::{ - Arch, Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, + Abi, Arch, Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, + TargetOptions, }; pub(crate) fn target() -> Target { - let abi = "ilp32e"; Target { // The below `data_layout` is explicitly specified by the ilp32e ABI in LLVM. See also // `options.llvm_abiname`. @@ -19,12 +19,12 @@ pub(crate) fn target() -> Target { arch: Arch::RiscV32, options: TargetOptions { - abi: abi.into(), + abi: Abi::Ilp32e, linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), linker: Some("rust-lld".into()), cpu: "generic-rv32".into(), // The ilp32e ABI specifies the `data_layout` - llvm_abiname: abi.into(), + llvm_abiname: "ilp32e".into(), max_atomic_width: Some(32), atomic_cas: false, features: "+e,+m,+forced-atomics".into(), diff --git a/compiler/rustc_target/src/spec/targets/riscv32emc_unknown_none_elf.rs b/compiler/rustc_target/src/spec/targets/riscv32emc_unknown_none_elf.rs index e0958e0f9c5e..e37a44e1edc4 100644 --- a/compiler/rustc_target/src/spec/targets/riscv32emc_unknown_none_elf.rs +++ b/compiler/rustc_target/src/spec/targets/riscv32emc_unknown_none_elf.rs @@ -1,9 +1,9 @@ use crate::spec::{ - Arch, Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, + Abi, Arch, Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, + TargetOptions, }; pub(crate) fn target() -> Target { - let abi = "ilp32e"; Target { // The below `data_layout` is explicitly specified by the ilp32e ABI in LLVM. See also // `options.llvm_abiname`. @@ -19,12 +19,12 @@ pub(crate) fn target() -> Target { arch: Arch::RiscV32, options: TargetOptions { - abi: abi.into(), + abi: Abi::Ilp32e, linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), linker: Some("rust-lld".into()), cpu: "generic-rv32".into(), // The ilp32e ABI specifies the `data_layout` - llvm_abiname: abi.into(), + llvm_abiname: "ilp32e".into(), max_atomic_width: Some(32), atomic_cas: false, features: "+e,+m,+c,+forced-atomics".into(), diff --git a/compiler/rustc_target/src/spec/targets/riscv32im_risc0_zkvm_elf.rs b/compiler/rustc_target/src/spec/targets/riscv32im_risc0_zkvm_elf.rs index c0372035cd7e..af25334a2e53 100644 --- a/compiler/rustc_target/src/spec/targets/riscv32im_risc0_zkvm_elf.rs +++ b/compiler/rustc_target/src/spec/targets/riscv32im_risc0_zkvm_elf.rs @@ -1,5 +1,6 @@ use crate::spec::{ - Arch, Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, + Arch, Cc, LinkerFlavor, Lld, Os, PanicStrategy, RelocModel, Target, TargetMetadata, + TargetOptions, }; pub(crate) fn target() -> Target { @@ -16,7 +17,7 @@ pub(crate) fn target() -> Target { arch: Arch::RiscV32, options: TargetOptions { - os: "zkvm".into(), + os: Os::Zkvm, vendor: "risc0".into(), linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), linker: Some("rust-lld".into()), diff --git a/compiler/rustc_target/src/spec/targets/riscv32imac_esp_espidf.rs b/compiler/rustc_target/src/spec/targets/riscv32imac_esp_espidf.rs index 6b3e5a47ad87..11a5626c5641 100644 --- a/compiler/rustc_target/src/spec/targets/riscv32imac_esp_espidf.rs +++ b/compiler/rustc_target/src/spec/targets/riscv32imac_esp_espidf.rs @@ -1,4 +1,6 @@ -use crate::spec::{Arch, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, cvs}; +use crate::spec::{ + Arch, Env, Os, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, cvs, +}; pub(crate) fn target() -> Target { Target { @@ -15,8 +17,8 @@ pub(crate) fn target() -> Target { options: TargetOptions { families: cvs!["unix"], - os: "espidf".into(), - env: "newlib".into(), + os: Os::EspIdf, + env: Env::Newlib, vendor: "espressif".into(), linker: Some("riscv32-esp-elf-gcc".into()), cpu: "generic-rv32".into(), diff --git a/compiler/rustc_target/src/spec/targets/riscv32imac_unknown_nuttx_elf.rs b/compiler/rustc_target/src/spec/targets/riscv32imac_unknown_nuttx_elf.rs index 70eb7cb78d65..7205fb61de74 100644 --- a/compiler/rustc_target/src/spec/targets/riscv32imac_unknown_nuttx_elf.rs +++ b/compiler/rustc_target/src/spec/targets/riscv32imac_unknown_nuttx_elf.rs @@ -1,6 +1,6 @@ use crate::spec::{ - Arch, Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, - cvs, + Arch, Cc, LinkerFlavor, Lld, Os, PanicStrategy, RelocModel, Target, TargetMetadata, + TargetOptions, cvs, }; pub(crate) fn target() -> Target { @@ -18,7 +18,7 @@ pub(crate) fn target() -> Target { options: TargetOptions { families: cvs!["unix"], - os: "nuttx".into(), + os: Os::NuttX, linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), linker: Some("rust-lld".into()), cpu: "generic-rv32".into(), diff --git a/compiler/rustc_target/src/spec/targets/riscv32imac_unknown_xous_elf.rs b/compiler/rustc_target/src/spec/targets/riscv32imac_unknown_xous_elf.rs index e50de1cc9371..363e465e2ef4 100644 --- a/compiler/rustc_target/src/spec/targets/riscv32imac_unknown_xous_elf.rs +++ b/compiler/rustc_target/src/spec/targets/riscv32imac_unknown_xous_elf.rs @@ -1,5 +1,6 @@ use crate::spec::{ - Arch, Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, + Arch, Cc, LinkerFlavor, Lld, Os, PanicStrategy, RelocModel, Target, TargetMetadata, + TargetOptions, }; pub(crate) fn target() -> Target { @@ -16,7 +17,7 @@ pub(crate) fn target() -> Target { arch: Arch::RiscV32, options: TargetOptions { - os: "xous".into(), + os: Os::Xous, linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), linker: Some("rust-lld".into()), cpu: "generic-rv32".into(), diff --git a/compiler/rustc_target/src/spec/targets/riscv32imafc_esp_espidf.rs b/compiler/rustc_target/src/spec/targets/riscv32imafc_esp_espidf.rs index 196a3de95cfb..b3a3ab9b7543 100644 --- a/compiler/rustc_target/src/spec/targets/riscv32imafc_esp_espidf.rs +++ b/compiler/rustc_target/src/spec/targets/riscv32imafc_esp_espidf.rs @@ -1,4 +1,6 @@ -use crate::spec::{Arch, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, cvs}; +use crate::spec::{ + Arch, Env, Os, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, cvs, +}; pub(crate) fn target() -> Target { Target { @@ -15,8 +17,8 @@ pub(crate) fn target() -> Target { options: TargetOptions { families: cvs!["unix"], - os: "espidf".into(), - env: "newlib".into(), + os: Os::EspIdf, + env: Env::Newlib, vendor: "espressif".into(), linker: Some("riscv32-esp-elf-gcc".into()), cpu: "generic-rv32".into(), diff --git a/compiler/rustc_target/src/spec/targets/riscv32imafc_unknown_nuttx_elf.rs b/compiler/rustc_target/src/spec/targets/riscv32imafc_unknown_nuttx_elf.rs index f7b8bd49e527..0bba2e47dc85 100644 --- a/compiler/rustc_target/src/spec/targets/riscv32imafc_unknown_nuttx_elf.rs +++ b/compiler/rustc_target/src/spec/targets/riscv32imafc_unknown_nuttx_elf.rs @@ -1,6 +1,6 @@ use crate::spec::{ - Arch, Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, - cvs, + Arch, Cc, LinkerFlavor, Lld, Os, PanicStrategy, RelocModel, Target, TargetMetadata, + TargetOptions, cvs, }; pub(crate) fn target() -> Target { @@ -18,7 +18,7 @@ pub(crate) fn target() -> Target { options: TargetOptions { families: cvs!["unix"], - os: "nuttx".into(), + os: Os::NuttX, linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), linker: Some("rust-lld".into()), cpu: "generic-rv32".into(), diff --git a/compiler/rustc_target/src/spec/targets/riscv32imc_esp_espidf.rs b/compiler/rustc_target/src/spec/targets/riscv32imc_esp_espidf.rs index 66c64667d0dc..f903bbdb04bf 100644 --- a/compiler/rustc_target/src/spec/targets/riscv32imc_esp_espidf.rs +++ b/compiler/rustc_target/src/spec/targets/riscv32imc_esp_espidf.rs @@ -1,4 +1,6 @@ -use crate::spec::{Arch, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, cvs}; +use crate::spec::{ + Arch, Env, Os, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, cvs, +}; pub(crate) fn target() -> Target { Target { @@ -15,8 +17,8 @@ pub(crate) fn target() -> Target { options: TargetOptions { families: cvs!["unix"], - os: "espidf".into(), - env: "newlib".into(), + os: Os::EspIdf, + env: Env::Newlib, vendor: "espressif".into(), linker: Some("riscv32-esp-elf-gcc".into()), cpu: "generic-rv32".into(), diff --git a/compiler/rustc_target/src/spec/targets/riscv32imc_unknown_nuttx_elf.rs b/compiler/rustc_target/src/spec/targets/riscv32imc_unknown_nuttx_elf.rs index a10ddb2d0569..d1d73842703e 100644 --- a/compiler/rustc_target/src/spec/targets/riscv32imc_unknown_nuttx_elf.rs +++ b/compiler/rustc_target/src/spec/targets/riscv32imc_unknown_nuttx_elf.rs @@ -1,6 +1,6 @@ use crate::spec::{ - Arch, Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, - cvs, + Arch, Cc, LinkerFlavor, Lld, Os, PanicStrategy, RelocModel, Target, TargetMetadata, + TargetOptions, cvs, }; pub(crate) fn target() -> Target { @@ -18,7 +18,7 @@ pub(crate) fn target() -> Target { options: TargetOptions { families: cvs!["unix"], - os: "nuttx".into(), + os: Os::NuttX, linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), linker: Some("rust-lld".into()), cpu: "generic-rv32".into(), diff --git a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_nuttx_elf.rs b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_nuttx_elf.rs index 93dd6dc7ed1c..7850cc8105d9 100644 --- a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_nuttx_elf.rs +++ b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_nuttx_elf.rs @@ -1,5 +1,5 @@ use crate::spec::{ - Arch, Cc, CodeModel, LinkerFlavor, Lld, PanicStrategy, RelocModel, SanitizerSet, Target, + Arch, Cc, CodeModel, LinkerFlavor, Lld, Os, PanicStrategy, RelocModel, SanitizerSet, Target, TargetMetadata, TargetOptions, cvs, }; @@ -18,7 +18,7 @@ pub(crate) fn target() -> Target { options: TargetOptions { families: cvs!["unix"], - os: "nuttx".into(), + os: Os::NuttX, linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), linker: Some("rust-lld".into()), llvm_abiname: "lp64d".into(), diff --git a/compiler/rustc_target/src/spec/targets/riscv64imac_unknown_nuttx_elf.rs b/compiler/rustc_target/src/spec/targets/riscv64imac_unknown_nuttx_elf.rs index 25e3e72f9de9..b1a1817bbe1f 100644 --- a/compiler/rustc_target/src/spec/targets/riscv64imac_unknown_nuttx_elf.rs +++ b/compiler/rustc_target/src/spec/targets/riscv64imac_unknown_nuttx_elf.rs @@ -1,5 +1,5 @@ use crate::spec::{ - Arch, Cc, CodeModel, LinkerFlavor, Lld, PanicStrategy, RelocModel, SanitizerSet, Target, + Arch, Cc, CodeModel, LinkerFlavor, Lld, Os, PanicStrategy, RelocModel, SanitizerSet, Target, TargetMetadata, TargetOptions, cvs, }; @@ -18,7 +18,7 @@ pub(crate) fn target() -> Target { options: TargetOptions { families: cvs!["unix"], - os: "nuttx".into(), + os: Os::NuttX, linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), linker: Some("rust-lld".into()), cpu: "generic-rv64".into(), diff --git a/compiler/rustc_target/src/spec/targets/sparcv9_sun_solaris.rs b/compiler/rustc_target/src/spec/targets/sparcv9_sun_solaris.rs index 79035c791156..498d8182ad58 100644 --- a/compiler/rustc_target/src/spec/targets/sparcv9_sun_solaris.rs +++ b/compiler/rustc_target/src/spec/targets/sparcv9_sun_solaris.rs @@ -1,15 +1,17 @@ use rustc_abi::Endian; -use crate::spec::{Arch, Cc, LinkerFlavor, Target, TargetMetadata, base}; +use crate::spec::{Arch, Cc, LinkerFlavor, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { - let mut base = base::solaris::opts(); - base.endian = Endian::Big; + let mut base = TargetOptions { + endian: Endian::Big, + // llvm calls this "v9" + cpu: "v9".into(), + vendor: "sun".into(), + max_atomic_width: Some(64), + ..base::solaris::opts() + }; base.add_pre_link_args(LinkerFlavor::Unix(Cc::Yes), &["-m64"]); - // llvm calls this "v9" - base.cpu = "v9".into(); - base.vendor = "sun".into(); - base.max_atomic_width = Some(64); Target { llvm_target: "sparcv9-sun-solaris".into(), diff --git a/compiler/rustc_target/src/spec/targets/thumbv4t_none_eabi.rs b/compiler/rustc_target/src/spec/targets/thumbv4t_none_eabi.rs index 7a183bf5414e..0498c55e9827 100644 --- a/compiler/rustc_target/src/spec/targets/thumbv4t_none_eabi.rs +++ b/compiler/rustc_target/src/spec/targets/thumbv4t_none_eabi.rs @@ -10,8 +10,8 @@ //! `-Clink-arg=-Tmy_script.ld` to override that with a correct linker script. use crate::spec::{ - Arch, FloatAbi, FramePointer, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, - base, cvs, + Abi, Arch, FloatAbi, FramePointer, PanicStrategy, RelocModel, Target, TargetMetadata, + TargetOptions, base, cvs, }; pub(crate) fn target() -> Target { @@ -36,7 +36,7 @@ pub(crate) fn target() -> Target { */ data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), options: TargetOptions { - abi: "eabi".into(), + abi: Abi::Eabi, llvm_floatabi: Some(FloatAbi::Soft), // extra args passed to the external assembler (assuming `arm-none-eabi-as`): diff --git a/compiler/rustc_target/src/spec/targets/thumbv5te_none_eabi.rs b/compiler/rustc_target/src/spec/targets/thumbv5te_none_eabi.rs index b20be27665e0..a07e9127a36e 100644 --- a/compiler/rustc_target/src/spec/targets/thumbv5te_none_eabi.rs +++ b/compiler/rustc_target/src/spec/targets/thumbv5te_none_eabi.rs @@ -1,6 +1,8 @@ //! Targets the ARMv5TE, with code as `t32` code by default. -use crate::spec::{Arch, FloatAbi, FramePointer, Target, TargetMetadata, TargetOptions, base, cvs}; +use crate::spec::{ + Abi, Arch, FloatAbi, FramePointer, Target, TargetMetadata, TargetOptions, base, cvs, +}; pub(crate) fn target() -> Target { Target { @@ -25,7 +27,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), options: TargetOptions { - abi: "eabi".into(), + abi: Abi::Eabi, llvm_floatabi: Some(FloatAbi::Soft), // extra args passed to the external assembler (assuming `arm-none-eabi-as`): // * activate t32/a32 interworking diff --git a/compiler/rustc_target/src/spec/targets/thumbv6m_none_eabi.rs b/compiler/rustc_target/src/spec/targets/thumbv6m_none_eabi.rs index 684e465af4a6..836b2ff63a16 100644 --- a/compiler/rustc_target/src/spec/targets/thumbv6m_none_eabi.rs +++ b/compiler/rustc_target/src/spec/targets/thumbv6m_none_eabi.rs @@ -1,6 +1,6 @@ // Targets the Cortex-M0, Cortex-M0+ and Cortex-M1 processors (ARMv6-M architecture) -use crate::spec::{Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -16,7 +16,7 @@ pub(crate) fn target() -> Target { arch: Arch::Arm, options: TargetOptions { - abi: "eabi".into(), + abi: Abi::Eabi, llvm_floatabi: Some(FloatAbi::Soft), // The ARMv6-M architecture doesn't support unaligned loads/stores so we disable them // with +strict-align. diff --git a/compiler/rustc_target/src/spec/targets/thumbv6m_nuttx_eabi.rs b/compiler/rustc_target/src/spec/targets/thumbv6m_nuttx_eabi.rs index c0dd931e66a4..fa0154d65d68 100644 --- a/compiler/rustc_target/src/spec/targets/thumbv6m_nuttx_eabi.rs +++ b/compiler/rustc_target/src/spec/targets/thumbv6m_nuttx_eabi.rs @@ -1,6 +1,6 @@ // Targets the Cortex-M0, Cortex-M0+ and Cortex-M1 processors (ARMv6-M architecture) -use crate::spec::{Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base, cvs}; +use crate::spec::{Abi, Arch, FloatAbi, Os, Target, TargetMetadata, TargetOptions, base, cvs}; pub(crate) fn target() -> Target { Target { @@ -17,8 +17,8 @@ pub(crate) fn target() -> Target { options: TargetOptions { families: cvs!["unix"], - os: "nuttx".into(), - abi: "eabi".into(), + os: Os::NuttX, + abi: Abi::Eabi, llvm_floatabi: Some(FloatAbi::Soft), // The ARMv6-M architecture doesn't support unaligned loads/stores so we disable them // with +strict-align. diff --git a/compiler/rustc_target/src/spec/targets/thumbv7a_nuttx_eabi.rs b/compiler/rustc_target/src/spec/targets/thumbv7a_nuttx_eabi.rs index 335c4c1af510..7c1adc932626 100644 --- a/compiler/rustc_target/src/spec/targets/thumbv7a_nuttx_eabi.rs +++ b/compiler/rustc_target/src/spec/targets/thumbv7a_nuttx_eabi.rs @@ -4,7 +4,7 @@ // and will use software floating point operations. This matches the NuttX EABI // configuration without hardware floating point support. -use crate::spec::{Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base, cvs}; +use crate::spec::{Abi, Arch, FloatAbi, Os, Target, TargetMetadata, TargetOptions, base, cvs}; pub(crate) fn target() -> Target { Target { @@ -21,8 +21,8 @@ pub(crate) fn target() -> Target { options: TargetOptions { families: cvs!["unix"], - os: "nuttx".into(), - abi: "eabi".into(), + os: Os::NuttX, + abi: Abi::Eabi, llvm_floatabi: Some(FloatAbi::Soft), // Cortex-A7/A8/A9 with software floating point features: "+soft-float,-neon".into(), diff --git a/compiler/rustc_target/src/spec/targets/thumbv7a_nuttx_eabihf.rs b/compiler/rustc_target/src/spec/targets/thumbv7a_nuttx_eabihf.rs index 0a0dbaf12554..0e6d5b1f2ea9 100644 --- a/compiler/rustc_target/src/spec/targets/thumbv7a_nuttx_eabihf.rs +++ b/compiler/rustc_target/src/spec/targets/thumbv7a_nuttx_eabihf.rs @@ -7,7 +7,7 @@ // This target uses the "hard" floating convention (ABI) where floating point values // are passed to/from subroutines via FPU registers (S0, S1, D0, D1, etc.). -use crate::spec::{Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base, cvs}; +use crate::spec::{Abi, Arch, FloatAbi, Os, Target, TargetMetadata, TargetOptions, base, cvs}; pub(crate) fn target() -> Target { Target { @@ -24,8 +24,8 @@ pub(crate) fn target() -> Target { options: TargetOptions { families: cvs!["unix"], - os: "nuttx".into(), - abi: "eabihf".into(), + os: Os::NuttX, + abi: Abi::EabiHf, llvm_floatabi: Some(FloatAbi::Hard), // Cortex-A7/A8/A9 support VFPv3-D32/VFPv4-D32 with optional double-precision // and NEON SIMD instructions diff --git a/compiler/rustc_target/src/spec/targets/thumbv7em_none_eabi.rs b/compiler/rustc_target/src/spec/targets/thumbv7em_none_eabi.rs index c67e955d0856..9e0f09b45191 100644 --- a/compiler/rustc_target/src/spec/targets/thumbv7em_none_eabi.rs +++ b/compiler/rustc_target/src/spec/targets/thumbv7em_none_eabi.rs @@ -9,7 +9,7 @@ // To opt-in to hardware accelerated floating point operations, you can use, for example, // `-C target-feature=+vfp4` or `-C target-cpu=cortex-m4`. -use crate::spec::{Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -25,7 +25,7 @@ pub(crate) fn target() -> Target { arch: Arch::Arm, options: TargetOptions { - abi: "eabi".into(), + abi: Abi::Eabi, llvm_floatabi: Some(FloatAbi::Soft), max_atomic_width: Some(32), ..base::thumb::opts() diff --git a/compiler/rustc_target/src/spec/targets/thumbv7em_none_eabihf.rs b/compiler/rustc_target/src/spec/targets/thumbv7em_none_eabihf.rs index 9a05209b0eb6..acc31cc42d4a 100644 --- a/compiler/rustc_target/src/spec/targets/thumbv7em_none_eabihf.rs +++ b/compiler/rustc_target/src/spec/targets/thumbv7em_none_eabihf.rs @@ -8,7 +8,7 @@ // // To opt into double precision hardware support, use the `-C target-feature=+fp64` flag. -use crate::spec::{Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -24,7 +24,7 @@ pub(crate) fn target() -> Target { arch: Arch::Arm, options: TargetOptions { - abi: "eabihf".into(), + abi: Abi::EabiHf, llvm_floatabi: Some(FloatAbi::Hard), // vfp4 is the lowest common denominator between the Cortex-M4F (vfp4) and the // Cortex-M7 (vfp5). diff --git a/compiler/rustc_target/src/spec/targets/thumbv7em_nuttx_eabi.rs b/compiler/rustc_target/src/spec/targets/thumbv7em_nuttx_eabi.rs index 7888587ce9e3..796206d4ffee 100644 --- a/compiler/rustc_target/src/spec/targets/thumbv7em_nuttx_eabi.rs +++ b/compiler/rustc_target/src/spec/targets/thumbv7em_nuttx_eabi.rs @@ -9,7 +9,7 @@ // To opt-in to hardware accelerated floating point operations, you can use, for example, // `-C target-feature=+vfp4` or `-C target-cpu=cortex-m4`. -use crate::spec::{Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base, cvs}; +use crate::spec::{Abi, Arch, FloatAbi, Os, Target, TargetMetadata, TargetOptions, base, cvs}; pub(crate) fn target() -> Target { Target { @@ -26,8 +26,8 @@ pub(crate) fn target() -> Target { options: TargetOptions { families: cvs!["unix"], - os: "nuttx".into(), - abi: "eabi".into(), + os: Os::NuttX, + abi: Abi::Eabi, llvm_floatabi: Some(FloatAbi::Soft), max_atomic_width: Some(32), ..base::thumb::opts() diff --git a/compiler/rustc_target/src/spec/targets/thumbv7em_nuttx_eabihf.rs b/compiler/rustc_target/src/spec/targets/thumbv7em_nuttx_eabihf.rs index 51e57f77963a..f85aef1ab5a6 100644 --- a/compiler/rustc_target/src/spec/targets/thumbv7em_nuttx_eabihf.rs +++ b/compiler/rustc_target/src/spec/targets/thumbv7em_nuttx_eabihf.rs @@ -8,7 +8,7 @@ // // To opt into double precision hardware support, use the `-C target-feature=+fp64` flag. -use crate::spec::{Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base, cvs}; +use crate::spec::{Abi, Arch, FloatAbi, Os, Target, TargetMetadata, TargetOptions, base, cvs}; pub(crate) fn target() -> Target { Target { @@ -25,8 +25,8 @@ pub(crate) fn target() -> Target { options: TargetOptions { families: cvs!["unix"], - os: "nuttx".into(), - abi: "eabihf".into(), + os: Os::NuttX, + abi: Abi::EabiHf, llvm_floatabi: Some(FloatAbi::Hard), // vfp4 is the lowest common denominator between the Cortex-M4F (vfp4) and the // Cortex-M7 (vfp5). diff --git a/compiler/rustc_target/src/spec/targets/thumbv7m_none_eabi.rs b/compiler/rustc_target/src/spec/targets/thumbv7m_none_eabi.rs index fea5f15fe0a6..8c5807b1a907 100644 --- a/compiler/rustc_target/src/spec/targets/thumbv7m_none_eabi.rs +++ b/compiler/rustc_target/src/spec/targets/thumbv7m_none_eabi.rs @@ -1,6 +1,6 @@ // Targets the Cortex-M3 processor (ARMv7-M) -use crate::spec::{Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -16,7 +16,7 @@ pub(crate) fn target() -> Target { arch: Arch::Arm, options: TargetOptions { - abi: "eabi".into(), + abi: Abi::Eabi, llvm_floatabi: Some(FloatAbi::Soft), max_atomic_width: Some(32), ..base::thumb::opts() diff --git a/compiler/rustc_target/src/spec/targets/thumbv7m_nuttx_eabi.rs b/compiler/rustc_target/src/spec/targets/thumbv7m_nuttx_eabi.rs index 50ab8c5a4ee0..3d3d48748a9c 100644 --- a/compiler/rustc_target/src/spec/targets/thumbv7m_nuttx_eabi.rs +++ b/compiler/rustc_target/src/spec/targets/thumbv7m_nuttx_eabi.rs @@ -1,6 +1,6 @@ // Targets the Cortex-M3 processor (ARMv7-M) -use crate::spec::{Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base, cvs}; +use crate::spec::{Abi, Arch, FloatAbi, Os, Target, TargetMetadata, TargetOptions, base, cvs}; pub(crate) fn target() -> Target { Target { @@ -17,8 +17,8 @@ pub(crate) fn target() -> Target { options: TargetOptions { families: cvs!["unix"], - os: "nuttx".into(), - abi: "eabi".into(), + os: Os::NuttX, + abi: Abi::Eabi, llvm_floatabi: Some(FloatAbi::Soft), max_atomic_width: Some(32), ..base::thumb::opts() diff --git a/compiler/rustc_target/src/spec/targets/thumbv7neon_linux_androideabi.rs b/compiler/rustc_target/src/spec/targets/thumbv7neon_linux_androideabi.rs index cc6f26d38dea..3ffa30129298 100644 --- a/compiler/rustc_target/src/spec/targets/thumbv7neon_linux_androideabi.rs +++ b/compiler/rustc_target/src/spec/targets/thumbv7neon_linux_androideabi.rs @@ -1,5 +1,5 @@ use crate::spec::{ - Arch, Cc, FloatAbi, LinkerFlavor, Lld, Target, TargetMetadata, TargetOptions, base, + Abi, Arch, Cc, FloatAbi, LinkerFlavor, Lld, Target, TargetMetadata, TargetOptions, base, }; // This target if is for the Android v7a ABI in thumb mode with @@ -25,7 +25,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), arch: Arch::Arm, options: TargetOptions { - abi: "eabi".into(), + abi: Abi::Eabi, llvm_floatabi: Some(FloatAbi::Soft), features: "+v7,+thumb-mode,+thumb2,+vfp3,+neon".into(), max_atomic_width: Some(64), diff --git a/compiler/rustc_target/src/spec/targets/thumbv7neon_unknown_linux_gnueabihf.rs b/compiler/rustc_target/src/spec/targets/thumbv7neon_unknown_linux_gnueabihf.rs index 9abbec824b0f..36b99516d377 100644 --- a/compiler/rustc_target/src/spec/targets/thumbv7neon_unknown_linux_gnueabihf.rs +++ b/compiler/rustc_target/src/spec/targets/thumbv7neon_unknown_linux_gnueabihf.rs @@ -1,4 +1,4 @@ -use crate::spec::{Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; // This target is for glibc Linux on ARMv7 with thumb mode enabled // (for consistency with Android and Debian-based distributions) @@ -21,7 +21,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), arch: Arch::Arm, options: TargetOptions { - abi: "eabihf".into(), + abi: Abi::EabiHf, llvm_floatabi: Some(FloatAbi::Hard), // Info about features at https://wiki.debian.org/ArmHardFloatPort features: "+v7,+thumb-mode,+thumb2,+vfp3,+neon".into(), diff --git a/compiler/rustc_target/src/spec/targets/thumbv7neon_unknown_linux_musleabihf.rs b/compiler/rustc_target/src/spec/targets/thumbv7neon_unknown_linux_musleabihf.rs index e8239172409b..41c4bc91f701 100644 --- a/compiler/rustc_target/src/spec/targets/thumbv7neon_unknown_linux_musleabihf.rs +++ b/compiler/rustc_target/src/spec/targets/thumbv7neon_unknown_linux_musleabihf.rs @@ -1,4 +1,4 @@ -use crate::spec::{Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; // This target is for musl Linux on ARMv7 with thumb mode enabled // (for consistency with Android and Debian-based distributions) @@ -22,7 +22,7 @@ pub(crate) fn target() -> Target { // Most of these settings are copied from the thumbv7neon_unknown_linux_gnueabihf // target. options: TargetOptions { - abi: "eabihf".into(), + abi: Abi::EabiHf, llvm_floatabi: Some(FloatAbi::Hard), features: "+v7,+thumb-mode,+thumb2,+vfp3,+neon".into(), max_atomic_width: Some(64), diff --git a/compiler/rustc_target/src/spec/targets/thumbv8m_base_none_eabi.rs b/compiler/rustc_target/src/spec/targets/thumbv8m_base_none_eabi.rs index aca7441d34ab..298bad565e48 100644 --- a/compiler/rustc_target/src/spec/targets/thumbv8m_base_none_eabi.rs +++ b/compiler/rustc_target/src/spec/targets/thumbv8m_base_none_eabi.rs @@ -1,6 +1,6 @@ // Targets the Cortex-M23 processor (Baseline ARMv8-M) -use crate::spec::{Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -16,7 +16,7 @@ pub(crate) fn target() -> Target { arch: Arch::Arm, options: TargetOptions { - abi: "eabi".into(), + abi: Abi::Eabi, llvm_floatabi: Some(FloatAbi::Soft), // ARMv8-M baseline doesn't support unaligned loads/stores so we disable them // with +strict-align. diff --git a/compiler/rustc_target/src/spec/targets/thumbv8m_base_nuttx_eabi.rs b/compiler/rustc_target/src/spec/targets/thumbv8m_base_nuttx_eabi.rs index 26bf14d176ba..18bafc72553d 100644 --- a/compiler/rustc_target/src/spec/targets/thumbv8m_base_nuttx_eabi.rs +++ b/compiler/rustc_target/src/spec/targets/thumbv8m_base_nuttx_eabi.rs @@ -1,6 +1,6 @@ // Targets the Cortex-M23 processor (Baseline ARMv8-M) -use crate::spec::{Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base, cvs}; +use crate::spec::{Abi, Arch, FloatAbi, Os, Target, TargetMetadata, TargetOptions, base, cvs}; pub(crate) fn target() -> Target { Target { @@ -17,8 +17,8 @@ pub(crate) fn target() -> Target { options: TargetOptions { families: cvs!["unix"], - os: "nuttx".into(), - abi: "eabi".into(), + os: Os::NuttX, + abi: Abi::Eabi, llvm_floatabi: Some(FloatAbi::Soft), // ARMv8-M baseline doesn't support unaligned loads/stores so we disable them // with +strict-align. diff --git a/compiler/rustc_target/src/spec/targets/thumbv8m_main_none_eabi.rs b/compiler/rustc_target/src/spec/targets/thumbv8m_main_none_eabi.rs index e1cc16aeb5c6..90d7df75d44b 100644 --- a/compiler/rustc_target/src/spec/targets/thumbv8m_main_none_eabi.rs +++ b/compiler/rustc_target/src/spec/targets/thumbv8m_main_none_eabi.rs @@ -1,7 +1,7 @@ // Targets the Cortex-M33 processor (Armv8-M Mainline architecture profile), // without the Floating Point extension. -use crate::spec::{Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -17,7 +17,7 @@ pub(crate) fn target() -> Target { arch: Arch::Arm, options: TargetOptions { - abi: "eabi".into(), + abi: Abi::Eabi, llvm_floatabi: Some(FloatAbi::Soft), max_atomic_width: Some(32), ..base::thumb::opts() diff --git a/compiler/rustc_target/src/spec/targets/thumbv8m_main_none_eabihf.rs b/compiler/rustc_target/src/spec/targets/thumbv8m_main_none_eabihf.rs index cd3d3327a5c4..debdb47d507b 100644 --- a/compiler/rustc_target/src/spec/targets/thumbv8m_main_none_eabihf.rs +++ b/compiler/rustc_target/src/spec/targets/thumbv8m_main_none_eabihf.rs @@ -1,7 +1,7 @@ // Targets the Cortex-M33 processor (Armv8-M Mainline architecture profile), // with the Floating Point extension. -use crate::spec::{Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; +use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -17,7 +17,7 @@ pub(crate) fn target() -> Target { arch: Arch::Arm, options: TargetOptions { - abi: "eabihf".into(), + abi: Abi::EabiHf, llvm_floatabi: Some(FloatAbi::Hard), // If the Floating Point extension is implemented in the Cortex-M33 // processor, the Cortex-M33 Technical Reference Manual states that diff --git a/compiler/rustc_target/src/spec/targets/thumbv8m_main_nuttx_eabi.rs b/compiler/rustc_target/src/spec/targets/thumbv8m_main_nuttx_eabi.rs index 1fae7a92d923..f5039f13bc09 100644 --- a/compiler/rustc_target/src/spec/targets/thumbv8m_main_nuttx_eabi.rs +++ b/compiler/rustc_target/src/spec/targets/thumbv8m_main_nuttx_eabi.rs @@ -1,7 +1,7 @@ // Targets the Cortex-M33 processor (Armv8-M Mainline architecture profile), // without the Floating Point extension. -use crate::spec::{Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base, cvs}; +use crate::spec::{Abi, Arch, FloatAbi, Os, Target, TargetMetadata, TargetOptions, base, cvs}; pub(crate) fn target() -> Target { Target { @@ -18,8 +18,8 @@ pub(crate) fn target() -> Target { options: TargetOptions { families: cvs!["unix"], - os: "nuttx".into(), - abi: "eabi".into(), + os: Os::NuttX, + abi: Abi::Eabi, llvm_floatabi: Some(FloatAbi::Soft), max_atomic_width: Some(32), ..base::thumb::opts() diff --git a/compiler/rustc_target/src/spec/targets/thumbv8m_main_nuttx_eabihf.rs b/compiler/rustc_target/src/spec/targets/thumbv8m_main_nuttx_eabihf.rs index b8de91edfb23..77d23a255278 100644 --- a/compiler/rustc_target/src/spec/targets/thumbv8m_main_nuttx_eabihf.rs +++ b/compiler/rustc_target/src/spec/targets/thumbv8m_main_nuttx_eabihf.rs @@ -1,7 +1,7 @@ // Targets the Cortex-M33 processor (Armv8-M Mainline architecture profile), // with the Floating Point extension. -use crate::spec::{Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base, cvs}; +use crate::spec::{Abi, Arch, FloatAbi, Os, Target, TargetMetadata, TargetOptions, base, cvs}; pub(crate) fn target() -> Target { Target { @@ -18,8 +18,8 @@ pub(crate) fn target() -> Target { options: TargetOptions { families: cvs!["unix"], - os: "nuttx".into(), - abi: "eabihf".into(), + os: Os::NuttX, + abi: Abi::EabiHf, llvm_floatabi: Some(FloatAbi::Hard), // If the Floating Point extension is implemented in the Cortex-M33 // processor, the Cortex-M33 Technical Reference Manual states that diff --git a/compiler/rustc_target/src/spec/targets/wasm32_unknown_emscripten.rs b/compiler/rustc_target/src/spec/targets/wasm32_unknown_emscripten.rs index aa4a1be99291..47623c34dce3 100644 --- a/compiler/rustc_target/src/spec/targets/wasm32_unknown_emscripten.rs +++ b/compiler/rustc_target/src/spec/targets/wasm32_unknown_emscripten.rs @@ -1,6 +1,6 @@ use crate::spec::{ - Arch, LinkArgs, LinkerFlavor, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, - base, cvs, + Arch, LinkArgs, LinkerFlavor, Os, PanicStrategy, RelocModel, Target, TargetMetadata, + TargetOptions, base, cvs, }; pub(crate) fn target() -> Target { @@ -10,7 +10,7 @@ pub(crate) fn target() -> Target { TargetOptions::link_args(LinkerFlavor::EmCc, &["-sABORTING_MALLOC=0", "-sWASM_BIGINT"]); let opts = TargetOptions { - os: "emscripten".into(), + os: Os::Emscripten, linker_flavor: LinkerFlavor::EmCc, // emcc emits two files - a .js file to instantiate the wasm and supply platform // functionality, and a .wasm file. diff --git a/compiler/rustc_target/src/spec/targets/wasm32_unknown_unknown.rs b/compiler/rustc_target/src/spec/targets/wasm32_unknown_unknown.rs index 3050f17d5efb..cff336c04190 100644 --- a/compiler/rustc_target/src/spec/targets/wasm32_unknown_unknown.rs +++ b/compiler/rustc_target/src/spec/targets/wasm32_unknown_unknown.rs @@ -10,11 +10,11 @@ //! This target is more or less managed by the Rust and WebAssembly Working //! Group nowadays at . -use crate::spec::{Arch, Cc, LinkerFlavor, Target, TargetMetadata, base}; +use crate::spec::{Arch, Cc, LinkerFlavor, Os, Target, TargetMetadata, base}; pub(crate) fn target() -> Target { let mut options = base::wasm::options(); - options.os = "unknown".into(); + options.os = Os::Unknown; options.add_pre_link_args( LinkerFlavor::WasmLld(Cc::No), diff --git a/compiler/rustc_target/src/spec/targets/wasm32_wasip1.rs b/compiler/rustc_target/src/spec/targets/wasm32_wasip1.rs index a7c196c4530f..2d3dd0862d64 100644 --- a/compiler/rustc_target/src/spec/targets/wasm32_wasip1.rs +++ b/compiler/rustc_target/src/spec/targets/wasm32_wasip1.rs @@ -11,14 +11,15 @@ //! introduced. use crate::spec::{ - Arch, Cc, LinkSelfContainedDefault, LinkerFlavor, Target, TargetMetadata, base, crt_objects, + Arch, Cc, Env, LinkSelfContainedDefault, LinkerFlavor, Os, Target, TargetMetadata, base, + crt_objects, }; pub(crate) fn target() -> Target { let mut options = base::wasm::options(); - options.os = "wasi".into(); - options.env = "p1".into(); + options.os = Os::Wasi; + options.env = Env::P1; options.add_pre_link_args(LinkerFlavor::WasmLld(Cc::Yes), &["--target=wasm32-wasip1"]); options.pre_link_objects_self_contained = crt_objects::pre_wasi_self_contained(); diff --git a/compiler/rustc_target/src/spec/targets/wasm32_wasip1_threads.rs b/compiler/rustc_target/src/spec/targets/wasm32_wasip1_threads.rs index d4953cc9d498..645f7ad40bb6 100644 --- a/compiler/rustc_target/src/spec/targets/wasm32_wasip1_threads.rs +++ b/compiler/rustc_target/src/spec/targets/wasm32_wasip1_threads.rs @@ -8,14 +8,15 @@ //! Historically this target was known as `wasm32-wasi-preview1-threads`. use crate::spec::{ - Arch, Cc, LinkSelfContainedDefault, LinkerFlavor, Target, TargetMetadata, base, crt_objects, + Arch, Cc, Env, LinkSelfContainedDefault, LinkerFlavor, Os, Target, TargetMetadata, base, + crt_objects, }; pub(crate) fn target() -> Target { let mut options = base::wasm::options(); - options.os = "wasi".into(); - options.env = "p1".into(); + options.os = Os::Wasi; + options.env = Env::P1; options.add_pre_link_args( LinkerFlavor::WasmLld(Cc::No), diff --git a/compiler/rustc_target/src/spec/targets/wasm32_wasip2.rs b/compiler/rustc_target/src/spec/targets/wasm32_wasip2.rs index 717d49004a17..e594d187e42b 100644 --- a/compiler/rustc_target/src/spec/targets/wasm32_wasip2.rs +++ b/compiler/rustc_target/src/spec/targets/wasm32_wasip2.rs @@ -17,14 +17,14 @@ //! . use crate::spec::{ - Arch, LinkSelfContainedDefault, RelocModel, Target, TargetMetadata, base, crt_objects, + Arch, Env, LinkSelfContainedDefault, Os, RelocModel, Target, TargetMetadata, base, crt_objects, }; pub(crate) fn target() -> Target { let mut options = base::wasm::options(); - options.os = "wasi".into(); - options.env = "p2".into(); + options.os = Os::Wasi; + options.env = Env::P2; options.linker = Some("wasm-component-ld".into()); options.pre_link_objects_self_contained = crt_objects::pre_wasi_self_contained(); diff --git a/compiler/rustc_target/src/spec/targets/wasm32_wasip3.rs b/compiler/rustc_target/src/spec/targets/wasm32_wasip3.rs index e3d5e6542c26..d417f3d48a4b 100644 --- a/compiler/rustc_target/src/spec/targets/wasm32_wasip3.rs +++ b/compiler/rustc_target/src/spec/targets/wasm32_wasip3.rs @@ -8,13 +8,13 @@ //! all component-model-level imports anyway. Over time the imports of the //! standard library will change to WASIp3. -use crate::spec::Target; +use crate::spec::{Env, Target}; pub(crate) fn target() -> Target { // As of now WASIp3 is a lightly edited wasip2 target, so start with that // and this may grow over time as more features are supported. let mut target = super::wasm32_wasip2::target(); target.llvm_target = "wasm32-wasip3".into(); - target.options.env = "p3".into(); + target.options.env = Env::P3; target } diff --git a/compiler/rustc_target/src/spec/targets/wasm32v1_none.rs b/compiler/rustc_target/src/spec/targets/wasm32v1_none.rs index 41267f0e5708..8c5a253b0e2f 100644 --- a/compiler/rustc_target/src/spec/targets/wasm32v1_none.rs +++ b/compiler/rustc_target/src/spec/targets/wasm32v1_none.rs @@ -12,11 +12,11 @@ //! nightly Rust feature `-Zbuild-std`. This target is for people who want to //! use stable Rust, and target a stable set pf WebAssembly features. -use crate::spec::{Arch, Cc, LinkerFlavor, Target, TargetMetadata, base}; +use crate::spec::{Arch, Cc, LinkerFlavor, Os, Target, TargetMetadata, base}; pub(crate) fn target() -> Target { let mut options = base::wasm::options(); - options.os = "none".into(); + options.os = Os::None; // WebAssembly 1.0 shipped in 2019 and included exactly one proposal // after the initial "MVP" feature set: "mutable-globals". diff --git a/compiler/rustc_target/src/spec/targets/wasm64_unknown_unknown.rs b/compiler/rustc_target/src/spec/targets/wasm64_unknown_unknown.rs index 850e85591661..7f9341b3ef91 100644 --- a/compiler/rustc_target/src/spec/targets/wasm64_unknown_unknown.rs +++ b/compiler/rustc_target/src/spec/targets/wasm64_unknown_unknown.rs @@ -7,11 +7,11 @@ //! the standard library is available, most of it returns an error immediately //! (e.g. trying to create a TCP stream or something like that). -use crate::spec::{Arch, Cc, LinkerFlavor, Target, TargetMetadata, base}; +use crate::spec::{Arch, Cc, LinkerFlavor, Os, Target, TargetMetadata, base}; pub(crate) fn target() -> Target { let mut options = base::wasm::options(); - options.os = "unknown".into(); + options.os = Os::Unknown; options.add_pre_link_args( LinkerFlavor::WasmLld(Cc::No), diff --git a/compiler/rustc_target/src/spec/targets/x86_64_apple_darwin.rs b/compiler/rustc_target/src/spec/targets/x86_64_apple_darwin.rs index cb517b2a357a..8d0febc362d4 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_apple_darwin.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_apple_darwin.rs @@ -1,8 +1,8 @@ use crate::spec::base::apple::{Arch, TargetEnv, base}; -use crate::spec::{SanitizerSet, Target, TargetMetadata, TargetOptions}; +use crate::spec::{Os, SanitizerSet, Target, TargetMetadata, TargetOptions}; pub(crate) fn target() -> Target { - let (opts, llvm_target, arch) = base("macos", Arch::X86_64, TargetEnv::Normal); + let (opts, llvm_target, arch) = base(Os::MacOs, Arch::X86_64, TargetEnv::Normal); Target { llvm_target, metadata: TargetMetadata { diff --git a/compiler/rustc_target/src/spec/targets/x86_64_apple_ios.rs b/compiler/rustc_target/src/spec/targets/x86_64_apple_ios.rs index d74a688fa0f7..349460331e56 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_apple_ios.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_apple_ios.rs @@ -1,10 +1,10 @@ use crate::spec::base::apple::{Arch, TargetEnv, base}; -use crate::spec::{SanitizerSet, Target, TargetMetadata, TargetOptions}; +use crate::spec::{Os, SanitizerSet, Target, TargetMetadata, TargetOptions}; pub(crate) fn target() -> Target { // x86_64-apple-ios is a simulator target, even though it isn't declared // that way in the target name like the other ones... - let (opts, llvm_target, arch) = base("ios", Arch::X86_64, TargetEnv::Simulator); + let (opts, llvm_target, arch) = base(Os::IOs, Arch::X86_64, TargetEnv::Simulator); Target { llvm_target, metadata: TargetMetadata { diff --git a/compiler/rustc_target/src/spec/targets/x86_64_apple_ios_macabi.rs b/compiler/rustc_target/src/spec/targets/x86_64_apple_ios_macabi.rs index 193e26f94c98..2b8d552bf854 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_apple_ios_macabi.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_apple_ios_macabi.rs @@ -1,8 +1,8 @@ use crate::spec::base::apple::{Arch, TargetEnv, base}; -use crate::spec::{SanitizerSet, Target, TargetMetadata, TargetOptions}; +use crate::spec::{Os, SanitizerSet, Target, TargetMetadata, TargetOptions}; pub(crate) fn target() -> Target { - let (opts, llvm_target, arch) = base("ios", Arch::X86_64, TargetEnv::MacCatalyst); + let (opts, llvm_target, arch) = base(Os::IOs, Arch::X86_64, TargetEnv::MacCatalyst); Target { llvm_target, metadata: TargetMetadata { diff --git a/compiler/rustc_target/src/spec/targets/x86_64_apple_tvos.rs b/compiler/rustc_target/src/spec/targets/x86_64_apple_tvos.rs index e69bd17a0496..273cf31b7631 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_apple_tvos.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_apple_tvos.rs @@ -1,10 +1,10 @@ use crate::spec::base::apple::{Arch, TargetEnv, base}; -use crate::spec::{Target, TargetMetadata, TargetOptions}; +use crate::spec::{Os, Target, TargetMetadata, TargetOptions}; pub(crate) fn target() -> Target { // x86_64-apple-tvos is a simulator target, even though it isn't declared // that way in the target name like the other ones... - let (opts, llvm_target, arch) = base("tvos", Arch::X86_64, TargetEnv::Simulator); + let (opts, llvm_target, arch) = base(Os::TvOs, Arch::X86_64, TargetEnv::Simulator); Target { llvm_target, metadata: TargetMetadata { diff --git a/compiler/rustc_target/src/spec/targets/x86_64_apple_watchos_sim.rs b/compiler/rustc_target/src/spec/targets/x86_64_apple_watchos_sim.rs index 9490ca6aa36c..395f4fe5db4a 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_apple_watchos_sim.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_apple_watchos_sim.rs @@ -1,8 +1,8 @@ use crate::spec::base::apple::{Arch, TargetEnv, base}; -use crate::spec::{Target, TargetMetadata, TargetOptions}; +use crate::spec::{Os, Target, TargetMetadata, TargetOptions}; pub(crate) fn target() -> Target { - let (opts, llvm_target, arch) = base("watchos", Arch::X86_64, TargetEnv::Simulator); + let (opts, llvm_target, arch) = base(Os::WatchOs, Arch::X86_64, TargetEnv::Simulator); Target { llvm_target, metadata: TargetMetadata { diff --git a/compiler/rustc_target/src/spec/targets/x86_64_fortanix_unknown_sgx.rs b/compiler/rustc_target/src/spec/targets/x86_64_fortanix_unknown_sgx.rs index 6232de48da70..290087d8cef6 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_fortanix_unknown_sgx.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_fortanix_unknown_sgx.rs @@ -1,6 +1,8 @@ use std::borrow::Cow; -use crate::spec::{Arch, Cc, LinkerFlavor, Lld, Target, TargetMetadata, TargetOptions, cvs}; +use crate::spec::{ + Abi, Arch, Cc, Env, LinkerFlavor, Lld, Os, Target, TargetMetadata, TargetOptions, cvs, +}; pub(crate) fn target() -> Target { let pre_link_args = TargetOptions::link_args( @@ -55,10 +57,10 @@ pub(crate) fn target() -> Target { "TEXT_SIZE", ]; let opts = TargetOptions { - os: "unknown".into(), - env: "sgx".into(), + os: Os::Unknown, + env: Env::Sgx, vendor: "fortanix".into(), - abi: "fortanix".into(), + abi: Abi::Fortanix, linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), linker: Some("rust-lld".into()), max_atomic_width: Some(64), diff --git a/compiler/rustc_target/src/spec/targets/x86_64_pc_nto_qnx710.rs b/compiler/rustc_target/src/spec/targets/x86_64_pc_nto_qnx710.rs index 248aa91862c9..916001548509 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_pc_nto_qnx710.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_pc_nto_qnx710.rs @@ -1,5 +1,5 @@ -use crate::spec::Target; use crate::spec::base::nto_qnx; +use crate::spec::{Env, Target}; pub(crate) fn target() -> Target { let mut target = nto_qnx::x86_64(); @@ -7,6 +7,6 @@ pub(crate) fn target() -> Target { Some("x86 64-bit QNX Neutrino 7.1 RTOS with io-pkt network stack".into()); target.options.pre_link_args = nto_qnx::pre_link_args(nto_qnx::ApiVariant::Default, nto_qnx::Arch::X86_64); - target.options.env = "nto71".into(); + target.options.env = Env::Nto71; target } diff --git a/compiler/rustc_target/src/spec/targets/x86_64_pc_nto_qnx710_iosock.rs b/compiler/rustc_target/src/spec/targets/x86_64_pc_nto_qnx710_iosock.rs index 8f4c4924a295..1e97ae6b7a08 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_pc_nto_qnx710_iosock.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_pc_nto_qnx710_iosock.rs @@ -1,5 +1,5 @@ -use crate::spec::Target; use crate::spec::base::nto_qnx; +use crate::spec::{Env, Target}; pub(crate) fn target() -> Target { let mut target = nto_qnx::x86_64(); @@ -7,6 +7,6 @@ pub(crate) fn target() -> Target { Some("x86 64-bit QNX Neutrino 7.1 RTOS with io-sock network stack".into()); target.options.pre_link_args = nto_qnx::pre_link_args(nto_qnx::ApiVariant::IoSock, nto_qnx::Arch::X86_64); - target.options.env = "nto71_iosock".into(); + target.options.env = Env::Nto71IoSock; target } diff --git a/compiler/rustc_target/src/spec/targets/x86_64_pc_nto_qnx800.rs b/compiler/rustc_target/src/spec/targets/x86_64_pc_nto_qnx800.rs index d91a94a2ba55..bd98df621db1 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_pc_nto_qnx800.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_pc_nto_qnx800.rs @@ -1,11 +1,11 @@ -use crate::spec::Target; use crate::spec::base::nto_qnx; +use crate::spec::{Env, Target}; pub(crate) fn target() -> Target { let mut target = nto_qnx::x86_64(); target.metadata.description = Some("x86 64-bit QNX Neutrino 8.0 RTOS".into()); target.options.pre_link_args = nto_qnx::pre_link_args(nto_qnx::ApiVariant::Default, nto_qnx::Arch::X86_64); - target.options.env = "nto80".into(); + target.options.env = Env::Nto80; target } diff --git a/compiler/rustc_target/src/spec/targets/x86_64_pc_solaris.rs b/compiler/rustc_target/src/spec/targets/x86_64_pc_solaris.rs index 7b8d5def3a70..39ebe6243047 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_pc_solaris.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_pc_solaris.rs @@ -1,16 +1,19 @@ use crate::spec::{ - Arch, Cc, LinkerFlavor, SanitizerSet, StackProbeType, Target, TargetMetadata, base, + Arch, Cc, LinkerFlavor, SanitizerSet, StackProbeType, Target, TargetMetadata, TargetOptions, + base, }; pub(crate) fn target() -> Target { - let mut base = base::solaris::opts(); + let mut base = TargetOptions { + cpu: "x86-64".into(), + plt_by_default: false, + vendor: "pc".into(), + max_atomic_width: Some(64), + stack_probes: StackProbeType::Inline, + supported_sanitizers: SanitizerSet::ADDRESS | SanitizerSet::CFI | SanitizerSet::THREAD, + ..base::solaris::opts() + }; base.add_pre_link_args(LinkerFlavor::Unix(Cc::Yes), &["-m64"]); - base.cpu = "x86-64".into(); - base.plt_by_default = false; - base.vendor = "pc".into(); - base.max_atomic_width = Some(64); - base.stack_probes = StackProbeType::Inline; - base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::CFI | SanitizerSet::THREAD; Target { llvm_target: "x86_64-pc-solaris".into(), diff --git a/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_gnux32.rs b/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_gnux32.rs index 0b3e25bebf36..7e06a718e480 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_gnux32.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_gnux32.rs @@ -1,9 +1,9 @@ -use crate::spec::{Arch, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, base}; +use crate::spec::{Abi, Arch, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetMetadata, base}; pub(crate) fn target() -> Target { let mut base = base::linux_gnu::opts(); base.cpu = "x86-64".into(); - base.abi = "x32".into(); + base.abi = Abi::X32; base.max_atomic_width = Some(64); base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-mx32"]); base.stack_probes = StackProbeType::Inline; diff --git a/compiler/rustc_target/src/spec/targets/x86_64_unknown_trusty.rs b/compiler/rustc_target/src/spec/targets/x86_64_unknown_trusty.rs index 88c66ff6db9f..af9d653dbd2d 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_unknown_trusty.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_unknown_trusty.rs @@ -1,7 +1,7 @@ // Trusty OS target for X86_64. use crate::spec::{ - Arch, LinkSelfContainedDefault, PanicStrategy, RelroLevel, StackProbeType, Target, + Arch, LinkSelfContainedDefault, Os, PanicStrategy, RelroLevel, StackProbeType, Target, TargetMetadata, TargetOptions, }; @@ -22,7 +22,7 @@ pub(crate) fn target() -> Target { executables: true, max_atomic_width: Some(64), panic_strategy: PanicStrategy::Abort, - os: "trusty".into(), + os: Os::Trusty, link_self_contained: LinkSelfContainedDefault::InferredForMusl, position_independent_executables: true, static_position_independent_executables: true, diff --git a/compiler/rustc_target/src/spec/targets/x86_64_win7_windows_gnu.rs b/compiler/rustc_target/src/spec/targets/x86_64_win7_windows_gnu.rs index 22a1a126b891..0bd421585526 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_win7_windows_gnu.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_win7_windows_gnu.rs @@ -1,18 +1,20 @@ -use crate::spec::{Arch, Cc, LinkerFlavor, Lld, Target, TargetMetadata, base}; +use crate::spec::{Arch, Cc, LinkerFlavor, Lld, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { - let mut base = base::windows_gnu::opts(); - base.vendor = "win7".into(); - base.cpu = "x86-64".into(); - base.plt_by_default = false; + let mut base = TargetOptions { + vendor: "win7".into(), + cpu: "x86-64".into(), + plt_by_default: false, + max_atomic_width: Some(64), + linker: Some("x86_64-w64-mingw32-gcc".into()), + ..base::windows_gnu::opts() + }; // Use high-entropy 64 bit address space for ASLR base.add_pre_link_args( LinkerFlavor::Gnu(Cc::No, Lld::No), &["-m", "i386pep", "--high-entropy-va"], ); base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64", "-Wl,--high-entropy-va"]); - base.max_atomic_width = Some(64); - base.linker = Some("x86_64-w64-mingw32-gcc".into()); Target { llvm_target: "x86_64-pc-windows-gnu".into(), diff --git a/compiler/rustc_target/src/spec/targets/x86_64_win7_windows_msvc.rs b/compiler/rustc_target/src/spec/targets/x86_64_win7_windows_msvc.rs index 99b59154811f..1cc2efaae5f5 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_win7_windows_msvc.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_win7_windows_msvc.rs @@ -1,12 +1,14 @@ -use crate::spec::{Arch, SanitizerSet, Target, TargetMetadata, base}; +use crate::spec::{Arch, SanitizerSet, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { - let mut base = base::windows_msvc::opts(); - base.vendor = "win7".into(); - base.cpu = "x86-64".into(); - base.plt_by_default = false; - base.max_atomic_width = Some(64); - base.supported_sanitizers = SanitizerSet::ADDRESS; + let base = TargetOptions { + vendor: "win7".into(), + cpu: "x86-64".into(), + plt_by_default: false, + max_atomic_width: Some(64), + supported_sanitizers: SanitizerSet::ADDRESS, + ..base::windows_msvc::opts() + }; Target { llvm_target: "x86_64-pc-windows-msvc".into(), diff --git a/compiler/rustc_target/src/spec/targets/x86_64h_apple_darwin.rs b/compiler/rustc_target/src/spec/targets/x86_64h_apple_darwin.rs index 67b5a160a89a..adc87378fc7e 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64h_apple_darwin.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64h_apple_darwin.rs @@ -1,8 +1,8 @@ use crate::spec::base::apple::{Arch, TargetEnv, base}; -use crate::spec::{SanitizerSet, Target, TargetMetadata, TargetOptions}; +use crate::spec::{Os, SanitizerSet, Target, TargetMetadata, TargetOptions}; pub(crate) fn target() -> Target { - let (mut opts, llvm_target, arch) = base("macos", Arch::X86_64h, TargetEnv::Normal); + let (mut opts, llvm_target, arch) = base(Os::MacOs, Arch::X86_64h, TargetEnv::Normal); opts.max_atomic_width = Some(128); opts.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::CFI | SanitizerSet::LEAK | SanitizerSet::THREAD; diff --git a/compiler/rustc_target/src/spec/targets/xtensa_esp32_espidf.rs b/compiler/rustc_target/src/spec/targets/xtensa_esp32_espidf.rs index d909271e218e..83835705f3da 100644 --- a/compiler/rustc_target/src/spec/targets/xtensa_esp32_espidf.rs +++ b/compiler/rustc_target/src/spec/targets/xtensa_esp32_espidf.rs @@ -1,7 +1,7 @@ use rustc_abi::Endian; use crate::spec::base::xtensa; -use crate::spec::{Arch, Target, TargetMetadata, TargetOptions, cvs}; +use crate::spec::{Arch, Env, Os, Target, TargetMetadata, TargetOptions, cvs}; pub(crate) fn target() -> Target { Target { @@ -15,8 +15,8 @@ pub(crate) fn target() -> Target { endian: Endian::Little, c_int_width: 32, families: cvs!["unix"], - os: "espidf".into(), - env: "newlib".into(), + os: Os::EspIdf, + env: Env::Newlib, vendor: "espressif".into(), executables: true, diff --git a/compiler/rustc_target/src/spec/targets/xtensa_esp32s2_espidf.rs b/compiler/rustc_target/src/spec/targets/xtensa_esp32s2_espidf.rs index b1ed0ffe264e..42e4c7bf8bec 100644 --- a/compiler/rustc_target/src/spec/targets/xtensa_esp32s2_espidf.rs +++ b/compiler/rustc_target/src/spec/targets/xtensa_esp32s2_espidf.rs @@ -1,7 +1,7 @@ use rustc_abi::Endian; use crate::spec::base::xtensa; -use crate::spec::{Arch, Target, TargetMetadata, TargetOptions, cvs}; +use crate::spec::{Arch, Env, Os, Target, TargetMetadata, TargetOptions, cvs}; pub(crate) fn target() -> Target { Target { @@ -15,8 +15,8 @@ pub(crate) fn target() -> Target { endian: Endian::Little, c_int_width: 32, families: cvs!["unix"], - os: "espidf".into(), - env: "newlib".into(), + os: Os::EspIdf, + env: Env::Newlib, vendor: "espressif".into(), executables: true, diff --git a/compiler/rustc_target/src/spec/targets/xtensa_esp32s3_espidf.rs b/compiler/rustc_target/src/spec/targets/xtensa_esp32s3_espidf.rs index 8e1fee4ad657..498daf4e6063 100644 --- a/compiler/rustc_target/src/spec/targets/xtensa_esp32s3_espidf.rs +++ b/compiler/rustc_target/src/spec/targets/xtensa_esp32s3_espidf.rs @@ -1,7 +1,7 @@ use rustc_abi::Endian; use crate::spec::base::xtensa; -use crate::spec::{Arch, Target, TargetMetadata, TargetOptions, cvs}; +use crate::spec::{Arch, Env, Os, Target, TargetMetadata, TargetOptions, cvs}; pub(crate) fn target() -> Target { Target { @@ -15,8 +15,8 @@ pub(crate) fn target() -> Target { endian: Endian::Little, c_int_width: 32, families: cvs!["unix"], - os: "espidf".into(), - env: "newlib".into(), + os: Os::EspIdf, + env: Env::Newlib, vendor: "espressif".into(), executables: true, diff --git a/compiler/rustc_target/src/target_features.rs b/compiler/rustc_target/src/target_features.rs index 1789e52ed26f..990928774731 100644 --- a/compiler/rustc_target/src/target_features.rs +++ b/compiler/rustc_target/src/target_features.rs @@ -5,7 +5,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_span::{Symbol, sym}; -use crate::spec::{Arch, FloatAbi, RustcAbi, Target}; +use crate::spec::{Abi, Arch, FloatAbi, RustcAbi, Target}; /// Features that control behaviour of rustc, rather than the codegen. /// These exist globally and are not in the target-specific lists below. @@ -977,7 +977,7 @@ impl Target { | Arch::PowerPC64LE | Arch::SpirV | Arch::Xtensa - | Arch::Unknown(_) => &[], + | Arch::Other(_) => &[], } } @@ -1006,7 +1006,7 @@ impl Target { | Arch::PowerPC64LE | Arch::SpirV | Arch::Xtensa - | Arch::Unknown(_) => &[], + | Arch::Other(_) => &[], } } @@ -1119,20 +1119,17 @@ impl Target { Arch::AArch64 | Arch::Arm64EC => { // Aarch64 has no sane ABI specifier, and LLVM doesn't even have a way to force // the use of soft-float, so all we can do here is some crude hacks. - match &*self.abi { - "softfloat" => { - // LLVM will use float registers when `fp-armv8` is available, e.g. for - // calls to built-ins. The only way to ensure a consistent softfloat ABI - // on aarch64 is to never enable `fp-armv8`, so we enforce that. - // In Rust we tie `neon` and `fp-armv8` together, therefore `neon` is the - // feature we have to mark as incompatible. - FeatureConstraints { required: &[], incompatible: &["neon"] } - } - _ => { - // Everything else is assumed to use a hardfloat ABI. neon and fp-armv8 must be enabled. - // `FeatureConstraints` uses Rust feature names, hence only "neon" shows up. - FeatureConstraints { required: &["neon"], incompatible: &[] } - } + if matches!(self.abi, Abi::SoftFloat) { + // LLVM will use float registers when `fp-armv8` is available, e.g. for + // calls to built-ins. The only way to ensure a consistent softfloat ABI + // on aarch64 is to never enable `fp-armv8`, so we enforce that. + // In Rust we tie `neon` and `fp-armv8` together, therefore `neon` is the + // feature we have to mark as incompatible. + FeatureConstraints { required: &[], incompatible: &["neon"] } + } else { + // Everything else is assumed to use a hardfloat ABI. neon and fp-armv8 must be enabled. + // `FeatureConstraints` uses Rust feature names, hence only "neon" shows up. + FeatureConstraints { required: &["neon"], incompatible: &[] } } } Arch::RiscV32 | Arch::RiscV64 => { diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs index e18e294635b5..b280a6ec55af 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs @@ -51,11 +51,8 @@ use std::path::PathBuf; use std::{cmp, fmt, iter}; use rustc_abi::ExternAbi; -use rustc_ast::join_path_syms; use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; -use rustc_errors::{ - Applicability, Diag, DiagStyledString, IntoDiagArg, MultiSpan, StringPart, pluralize, -}; +use rustc_errors::{Applicability, Diag, DiagStyledString, IntoDiagArg, StringPart, pluralize}; use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; use rustc_hir::intravisit::Visitor; @@ -66,15 +63,12 @@ use rustc_middle::bug; use rustc_middle::dep_graph::DepContext; use rustc_middle::traits::PatternOriginExpr; use rustc_middle::ty::error::{ExpectedFound, TypeError, TypeErrorToStringExt}; -use rustc_middle::ty::print::{ - PrintError, PrintTraitRefExt as _, WrapBinderMode, with_forced_trimmed_paths, -}; +use rustc_middle::ty::print::{PrintTraitRefExt as _, WrapBinderMode, with_forced_trimmed_paths}; use rustc_middle::ty::{ self, List, ParamEnv, Region, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, }; -use rustc_span::def_id::LOCAL_CRATE; -use rustc_span::{BytePos, DUMMY_SP, DesugaringKind, Pos, Span, Symbol, sym}; +use rustc_span::{BytePos, DUMMY_SP, DesugaringKind, Pos, Span, sym}; use tracing::{debug, instrument}; use crate::error_reporting::TypeErrCtxt; @@ -216,201 +210,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { /// Adds a note if the types come from similarly named crates fn check_and_note_conflicting_crates(&self, err: &mut Diag<'_>, terr: TypeError<'tcx>) -> bool { - // FIXME(estebank): unify with `report_similar_impl_candidates`. The message is similar, - // even if the logic needed to detect the case is very different. - use hir::def_id::CrateNum; - use rustc_hir::definitions::DisambiguatedDefPathData; - use ty::GenericArg; - use ty::print::Printer; - - struct ConflictingPathPrinter<'tcx> { - tcx: TyCtxt<'tcx>, - segments: Vec, - } - - impl<'tcx> Printer<'tcx> for ConflictingPathPrinter<'tcx> { - fn tcx<'a>(&'a self) -> TyCtxt<'tcx> { - self.tcx - } - - fn print_region(&mut self, _region: ty::Region<'_>) -> Result<(), PrintError> { - unreachable!(); // because `print_path_with_generic_args` ignores the `GenericArgs` - } - - fn print_type(&mut self, _ty: Ty<'tcx>) -> Result<(), PrintError> { - unreachable!(); // because `print_path_with_generic_args` ignores the `GenericArgs` - } - - fn print_dyn_existential( - &mut self, - _predicates: &'tcx ty::List>, - ) -> Result<(), PrintError> { - unreachable!(); // because `print_path_with_generic_args` ignores the `GenericArgs` - } - - fn print_const(&mut self, _ct: ty::Const<'tcx>) -> Result<(), PrintError> { - unreachable!(); // because `print_path_with_generic_args` ignores the `GenericArgs` - } - - fn print_crate_name(&mut self, cnum: CrateNum) -> Result<(), PrintError> { - self.segments = vec![self.tcx.crate_name(cnum)]; - Ok(()) - } - - fn print_path_with_qualified( - &mut self, - _self_ty: Ty<'tcx>, - _trait_ref: Option>, - ) -> Result<(), PrintError> { - Err(fmt::Error) - } - - fn print_path_with_impl( - &mut self, - _print_prefix: impl FnOnce(&mut Self) -> Result<(), PrintError>, - _self_ty: Ty<'tcx>, - _trait_ref: Option>, - ) -> Result<(), PrintError> { - Err(fmt::Error) - } - - fn print_path_with_simple( - &mut self, - print_prefix: impl FnOnce(&mut Self) -> Result<(), PrintError>, - disambiguated_data: &DisambiguatedDefPathData, - ) -> Result<(), PrintError> { - print_prefix(self)?; - self.segments.push(disambiguated_data.as_sym(true)); - Ok(()) - } - - fn print_path_with_generic_args( - &mut self, - print_prefix: impl FnOnce(&mut Self) -> Result<(), PrintError>, - _args: &[GenericArg<'tcx>], - ) -> Result<(), PrintError> { - print_prefix(self) - } - } - - let report_path_match = |err: &mut Diag<'_>, did1: DefId, did2: DefId, ty: &str| -> bool { - // Only report definitions from different crates. If both definitions - // are from a local module we could have false positives, e.g. - // let _ = [{struct Foo; Foo}, {struct Foo; Foo}]; - if did1.krate != did2.krate { - let abs_path = |def_id| { - let mut p = ConflictingPathPrinter { tcx: self.tcx, segments: vec![] }; - p.print_def_path(def_id, &[]).map(|_| p.segments) - }; - - // We compare strings because DefPath can be different for imported and - // non-imported crates. - let expected_str = self.tcx.def_path_str(did1); - let found_str = self.tcx.def_path_str(did2); - let Ok(expected_abs) = abs_path(did1) else { return false }; - let Ok(found_abs) = abs_path(did2) else { return false }; - let same_path = expected_str == found_str || expected_abs == found_abs; - if same_path { - // We want to use as unique a type path as possible. If both types are "locally - // known" by the same name, we use the "absolute path" which uses the original - // crate name instead. - let (expected, found) = if expected_str == found_str { - (join_path_syms(&expected_abs), join_path_syms(&found_abs)) - } else { - (expected_str, found_str) - }; - - // We've displayed "expected `a::b`, found `a::b`". We add context to - // differentiate the different cases where that might happen. - let expected_crate_name = self.tcx.crate_name(did1.krate); - let found_crate_name = self.tcx.crate_name(did2.krate); - let same_crate = expected_crate_name == found_crate_name; - let expected_sp = self.tcx.def_span(did1); - let found_sp = self.tcx.def_span(did2); - - let both_direct_dependencies = if !did1.is_local() - && !did2.is_local() - && let Some(data1) = self.tcx.extern_crate(did1.krate) - && let Some(data2) = self.tcx.extern_crate(did2.krate) - && data1.dependency_of == LOCAL_CRATE - && data2.dependency_of == LOCAL_CRATE - { - // If both crates are directly depended on, we don't want to mention that - // in the final message, as it is redundant wording. - // We skip the case of semver trick, where one version of the local crate - // depends on another version of itself by checking that both crates at play - // are not the current one. - true - } else { - false - }; - - let mut span: MultiSpan = vec![expected_sp, found_sp].into(); - span.push_span_label( - self.tcx.def_span(did1), - format!("this is the expected {ty} `{expected}`"), - ); - span.push_span_label( - self.tcx.def_span(did2), - format!("this is the found {ty} `{found}`"), - ); - for def_id in [did1, did2] { - let crate_name = self.tcx.crate_name(def_id.krate); - if !def_id.is_local() - && let Some(data) = self.tcx.extern_crate(def_id.krate) - { - let descr = if same_crate { - "one version of".to_string() - } else { - format!("one {ty} comes from") - }; - let dependency = if both_direct_dependencies { - if let rustc_session::cstore::ExternCrateSource::Extern(def_id) = - data.src - && let Some(name) = self.tcx.opt_item_name(def_id) - { - format!(", which is renamed locally to `{name}`") - } else { - String::new() - } - } else if data.dependency_of == LOCAL_CRATE { - ", as a direct dependency of the current crate".to_string() - } else { - let dep = self.tcx.crate_name(data.dependency_of); - format!(", as a dependency of crate `{dep}`") - }; - span.push_span_label( - data.span, - format!("{descr} crate `{crate_name}` used here{dependency}"), - ); - } - } - let msg = if (did1.is_local() || did2.is_local()) && same_crate { - format!( - "the crate `{expected_crate_name}` is compiled multiple times, \ - possibly with different configurations", - ) - } else if same_crate { - format!( - "two different versions of crate `{expected_crate_name}` are being \ - used; two types coming from two different versions of the same crate \ - are different types even if they look the same", - ) - } else { - format!( - "two types coming from two different crates are different types even \ - if they look the same", - ) - }; - err.span_note(span, msg); - if same_crate { - err.help("you can use `cargo tree` to explore your dependency tree"); - } - return true; - } - } - false - }; match terr { TypeError::Sorts(ref exp_found) => { // if they are both "path types", there's a chance of ambiguity @@ -418,11 +217,23 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { if let (&ty::Adt(exp_adt, _), &ty::Adt(found_adt, _)) = (exp_found.expected.kind(), exp_found.found.kind()) { - return report_path_match(err, exp_adt.did(), found_adt.did(), "type"); + return self.check_same_definition_different_crate( + err, + exp_adt.did(), + [found_adt.did()].into_iter(), + |did| vec![self.tcx.def_span(did)], + "type", + ); } } TypeError::Traits(ref exp_found) => { - return report_path_match(err, exp_found.expected, exp_found.found, "trait"); + return self.check_same_definition_different_crate( + err, + exp_found.expected, + [exp_found.found].into_iter(), + |did| vec![self.tcx.def_span(did)], + "trait", + ); } _ => (), // FIXME(#22750) handle traits and stuff } diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs index e225656af852..da888acc4755 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs @@ -864,6 +864,42 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { } } + if sub.kind() == ty::ReStatic + && let Some(node) = self.tcx.hir_get_if_local(generic_param_scope.into()) + && let hir::Node::Item(hir::Item { + kind: hir::ItemKind::Fn { sig, body, has_body: true, .. }, + .. + }) + | hir::Node::TraitItem(hir::TraitItem { + kind: hir::TraitItemKind::Fn(sig, hir::TraitFn::Provided(body)), + .. + }) + | hir::Node::ImplItem(hir::ImplItem { + kind: hir::ImplItemKind::Fn(sig, body), .. + }) = node + && let hir::Node::Expr(expr) = self.tcx.hir_node(body.hir_id) + && let hir::ExprKind::Block(block, _) = expr.kind + && let Some(tail) = block.expr + && tail.span == span + && let hir::FnRetTy::Return(ty) = sig.decl.output + && let hir::TyKind::Path(path) = ty.kind + && let hir::QPath::Resolved(None, path) = path + && let hir::def::Res::Def(_, def_id) = path.res + && Some(def_id) == self.tcx.lang_items().owned_box() + && let [segment] = path.segments + && let Some(args) = segment.args + && let [hir::GenericArg::Type(ty)] = args.args + && let hir::TyKind::TraitObject(_, tagged_ref) = ty.kind + && let hir::LifetimeKind::ImplicitObjectLifetimeDefault = tagged_ref.pointer().kind + { + // Explicitly look for `-> Box` to point at it as the *likely* source of + // the `'static` lifetime requirement. + err.span_label( + ty.span, + format!("this `dyn Trait` has an implicit `'static` lifetime bound"), + ); + } + err } diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index c282f4204260..27eb614bae13 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs @@ -468,7 +468,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { span, leaf_trait_predicate, ); - self.note_trait_version_mismatch(&mut err, leaf_trait_predicate); + self.note_different_trait_with_same_name(&mut err, &obligation, leaf_trait_predicate); self.note_adt_version_mismatch(&mut err, leaf_trait_predicate); self.suggest_remove_await(&obligation, &mut err); self.suggest_derive(&obligation, &mut err, leaf_trait_predicate); @@ -1974,115 +1974,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { impl_candidates }; - // We'll check for the case where the reason for the mismatch is that the trait comes from - // one crate version and the type comes from another crate version, even though they both - // are from the same crate. - let trait_def_id = trait_pred.def_id(); - let trait_name = self.tcx.item_name(trait_def_id); - let crate_name = self.tcx.crate_name(trait_def_id.krate); - if let Some(other_trait_def_id) = self.tcx.all_traits_including_private().find(|def_id| { - trait_name == self.tcx.item_name(trait_def_id) - && trait_def_id.krate != def_id.krate - && crate_name == self.tcx.crate_name(def_id.krate) - }) { - // We've found two different traits with the same name, same crate name, but - // different crate `DefId`. We highlight the traits. - - let found_type = - if let ty::Adt(def, _) = trait_pred.self_ty().skip_binder().peel_refs().kind() { - Some(def.did()) - } else { - None - }; - let candidates = if impl_candidates.is_empty() { - alternative_candidates(trait_def_id) - } else { - impl_candidates.into_iter().map(|cand| (cand.trait_ref, cand.impl_def_id)).collect() - }; - let mut span: MultiSpan = self.tcx.def_span(trait_def_id).into(); - span.push_span_label(self.tcx.def_span(trait_def_id), "this is the required trait"); - for (sp, label) in [trait_def_id, other_trait_def_id] - .iter() - // The current crate-version might depend on another version of the same crate - // (Think "semver-trick"). Do not call `extern_crate` in that case for the local - // crate as that doesn't make sense and ICEs (#133563). - .filter(|def_id| !def_id.is_local()) - .filter_map(|def_id| self.tcx.extern_crate(def_id.krate)) - .map(|data| { - let dependency = if data.dependency_of == LOCAL_CRATE { - "direct dependency of the current crate".to_string() - } else { - let dep = self.tcx.crate_name(data.dependency_of); - format!("dependency of crate `{dep}`") - }; - ( - data.span, - format!("one version of crate `{crate_name}` used here, as a {dependency}"), - ) - }) - { - span.push_span_label(sp, label); - } - let mut points_at_type = false; - if let Some(found_type) = found_type { - span.push_span_label( - self.tcx.def_span(found_type), - "this type doesn't implement the required trait", - ); - for (trait_ref, _) in candidates { - if let ty::Adt(def, _) = trait_ref.self_ty().peel_refs().kind() - && let candidate_def_id = def.did() - && let Some(name) = self.tcx.opt_item_name(candidate_def_id) - && let Some(found) = self.tcx.opt_item_name(found_type) - && name == found - && candidate_def_id.krate != found_type.krate - && self.tcx.crate_name(candidate_def_id.krate) - == self.tcx.crate_name(found_type.krate) - { - // A candidate was found of an item with the same name, from two separate - // versions of the same crate, let's clarify. - let candidate_span = self.tcx.def_span(candidate_def_id); - span.push_span_label( - candidate_span, - "this type implements the required trait", - ); - points_at_type = true; - } - } - } - span.push_span_label(self.tcx.def_span(other_trait_def_id), "this is the found trait"); - err.highlighted_span_note( - span, - vec![ - StringPart::normal("there are ".to_string()), - StringPart::highlighted("multiple different versions".to_string()), - StringPart::normal(" of crate `".to_string()), - StringPart::highlighted(format!("{crate_name}")), - StringPart::normal("` in the dependency graph".to_string()), - ], - ); - if points_at_type { - // We only clarify that the same type from different crate versions are not the - // same when we *find* the same type coming from different crate versions, otherwise - // it could be that it was a type provided by a different crate than the one that - // provides the trait, and mentioning this adds verbosity without clarification. - err.highlighted_note(vec![ - StringPart::normal( - "two types coming from two different versions of the same crate are \ - different types " - .to_string(), - ), - StringPart::highlighted("even if they look the same".to_string()), - ]); - } - err.highlighted_help(vec![ - StringPart::normal("you can use `".to_string()), - StringPart::highlighted("cargo tree".to_string()), - StringPart::normal("` to explore your dependency tree".to_string()), - ]); - return true; - } - if let [single] = &impl_candidates { // If we have a single implementation, try to unify it with the trait ref // that failed. This should uncover a better hint for what *is* implemented. @@ -2478,10 +2369,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { } } - /// If the `Self` type of the unsatisfied trait `trait_ref` implements a trait - /// with the same path as `trait_ref`, a help message about - /// a probable version mismatch is added to `err` - fn note_trait_version_mismatch( + fn check_same_trait_different_version( &self, err: &mut Diag<'_>, trait_pred: ty::PolyTraitPredicate<'tcx>, @@ -2492,46 +2380,33 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { trait_def_id, trait_pred.skip_binder().self_ty(), |impl_def_id| { - trait_impls.push(impl_def_id); + let impl_trait_header = self.tcx.impl_trait_header(impl_def_id); + trait_impls + .push(self.tcx.def_span(impl_trait_header.trait_ref.skip_binder().def_id)); }, ); trait_impls }; - - let required_trait_path = self.tcx.def_path_str(trait_pred.def_id()); - let traits_with_same_path: UnordSet<_> = self - .tcx - .visible_traits() - .filter(|trait_def_id| *trait_def_id != trait_pred.def_id()) - .map(|trait_def_id| (self.tcx.def_path_str(trait_def_id), trait_def_id)) - .filter(|(p, _)| *p == required_trait_path) - .collect(); - - let traits_with_same_path = - traits_with_same_path.into_items().into_sorted_stable_ord_by_key(|(p, _)| p); - let mut suggested = false; - for (_, trait_with_same_path) in traits_with_same_path { - let trait_impls = get_trait_impls(trait_with_same_path); - if trait_impls.is_empty() { - continue; - } - let impl_spans: Vec<_> = - trait_impls.iter().map(|impl_def_id| self.tcx.def_span(*impl_def_id)).collect(); - err.span_help( - impl_spans, - format!("trait impl{} with same name found", pluralize!(trait_impls.len())), - ); - self.note_two_crate_versions(trait_with_same_path, err); - suggested = true; - } - suggested + self.check_same_definition_different_crate( + err, + trait_pred.def_id(), + self.tcx.visible_traits(), + get_trait_impls, + "trait", + ) } - fn note_two_crate_versions(&self, did: DefId, err: &mut Diag<'_>) { + pub fn note_two_crate_versions( + &self, + did: DefId, + sp: impl Into, + err: &mut Diag<'_>, + ) { let crate_name = self.tcx.crate_name(did.krate); - let crate_msg = - format!("perhaps two different versions of crate `{crate_name}` are being used?"); - err.note(crate_msg); + let crate_msg = format!( + "there are multiple different versions of crate `{crate_name}` in the dependency graph" + ); + err.span_note(sp, crate_msg); } fn note_adt_version_mismatch( @@ -2592,10 +2467,82 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { for (similar_item, _) in similar_items { err.span_help(self.tcx.def_span(similar_item), "item with same name found"); - self.note_two_crate_versions(similar_item, err); + self.note_two_crate_versions(similar_item, MultiSpan::new(), err); } } + fn check_same_name_different_path( + &self, + err: &mut Diag<'_>, + obligation: &PredicateObligation<'tcx>, + trait_pred: ty::PolyTraitPredicate<'tcx>, + ) -> bool { + let mut suggested = false; + let trait_def_id = trait_pred.def_id(); + let trait_has_same_params = |other_trait_def_id: DefId| -> bool { + let trait_generics = self.tcx.generics_of(trait_def_id); + let other_trait_generics = self.tcx.generics_of(other_trait_def_id); + + if trait_generics.count() != other_trait_generics.count() { + return false; + } + trait_generics.own_params.iter().zip(other_trait_generics.own_params.iter()).all( + |(a, b)| match (&a.kind, &b.kind) { + (ty::GenericParamDefKind::Lifetime, ty::GenericParamDefKind::Lifetime) + | ( + ty::GenericParamDefKind::Type { .. }, + ty::GenericParamDefKind::Type { .. }, + ) + | ( + ty::GenericParamDefKind::Const { .. }, + ty::GenericParamDefKind::Const { .. }, + ) => true, + _ => false, + }, + ) + }; + let trait_name = self.tcx.item_name(trait_def_id); + if let Some(other_trait_def_id) = self.tcx.all_traits_including_private().find(|def_id| { + trait_def_id != *def_id + && trait_name == self.tcx.item_name(def_id) + && trait_has_same_params(*def_id) + && self.predicate_must_hold_modulo_regions(&Obligation::new( + self.tcx, + obligation.cause.clone(), + obligation.param_env, + trait_pred.map_bound(|tr| ty::TraitPredicate { + trait_ref: ty::TraitRef::new(self.tcx, *def_id, tr.trait_ref.args), + ..tr + }), + )) + }) { + err.note(format!( + "`{}` implements similarly named trait `{}`, but not `{}`", + trait_pred.self_ty(), + self.tcx.def_path_str(other_trait_def_id), + trait_pred.print_modifiers_and_trait_path() + )); + suggested = true; + } + suggested + } + + /// If the `Self` type of the unsatisfied trait `trait_ref` implements a trait + /// with the same path as `trait_ref`, a help message about a multiple different + /// versions of the same crate is added to `err`. Otherwise if it implements another + /// trait with the same name, a note message about a similarly named trait is added to `err`. + pub fn note_different_trait_with_same_name( + &self, + err: &mut Diag<'_>, + obligation: &PredicateObligation<'tcx>, + trait_pred: ty::PolyTraitPredicate<'tcx>, + ) -> bool { + if self.check_same_trait_different_version(err, trait_pred) { + return true; + } + self.check_same_name_different_path(err, obligation, trait_pred) + } + /// Add a `::` prefix when comparing paths so that paths with just one item /// like "Foo" does not equal the end of "OtherFoo". fn comparable_path(&self, did: DefId) -> String { diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs index 1825719a3077..befc83a592c0 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs @@ -1,6 +1,6 @@ pub mod ambiguity; pub mod call_kind; -mod fulfillment_errors; +pub mod fulfillment_errors; pub mod on_unimplemented; pub mod on_unimplemented_condition; pub mod on_unimplemented_format; @@ -10,6 +10,7 @@ pub mod suggestions; use std::{fmt, iter}; use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; +use rustc_data_structures::unord::UnordSet; use rustc_errors::{Applicability, Diag, E0038, E0276, MultiSpan, struct_span_code_err}; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::intravisit::Visitor; @@ -21,7 +22,7 @@ use rustc_infer::traits::{ }; use rustc_middle::ty::print::{PrintTraitRefExt as _, with_no_trimmed_paths}; use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt as _}; -use rustc_span::{DesugaringKind, ErrorGuaranteed, ExpnKind, Span}; +use rustc_span::{DesugaringKind, ErrorGuaranteed, ExpnKind, Span, Symbol}; use tracing::{info, instrument}; pub use self::overflow::*; @@ -351,6 +352,80 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { FulfillmentErrorCode::Cycle(ref cycle) => self.report_overflow_obligation_cycle(cycle), } } + + fn get_extern_crate_renamed_symbol(&self, trait_def_id: DefId) -> Option { + if !trait_def_id.is_local() + && let Some(data) = self.tcx.extern_crate(trait_def_id.krate) + && let rustc_session::cstore::ExternCrateSource::Extern(def_id) = data.src + { + self.tcx.opt_item_name(def_id) + } else { + None + } + } + + pub fn check_same_definition_different_crate( + &self, + err: &mut Diag<'_>, + expected_did: DefId, + found_dids: impl Iterator, + get_impls: F, + ty: &str, + ) -> bool + where + F: Fn(DefId) -> Vec, + { + let krate = self.tcx.crate_name(expected_did.krate); + let name = self.tcx.item_name(expected_did); + let locally_renamed_krate = self + .get_extern_crate_renamed_symbol(expected_did) + .map_or(None, |s| if s != krate { Some(s) } else { None }); + let definitions_with_same_path: UnordSet<_> = found_dids + .filter(|def_id| { + def_id.krate != expected_did.krate + && (locally_renamed_krate == self.get_extern_crate_renamed_symbol(*def_id) + || self.tcx.crate_name(def_id.krate) == krate) + && self.tcx.item_name(def_id) == name + }) + .map(|def_id| (self.tcx.def_path_str(def_id), def_id)) + .collect(); + + let definitions_with_same_path = + definitions_with_same_path.into_items().into_sorted_stable_ord_by_key(|(p, _)| p); + let mut suggested = false; + let mut trait_is_impl = false; + + if !definitions_with_same_path.is_empty() { + let mut span: MultiSpan = self.tcx.def_span(expected_did).into(); + span.push_span_label( + self.tcx.def_span(expected_did), + format!("this is the expected {ty}"), + ); + suggested = true; + for (_, definition_with_same_path) in &definitions_with_same_path { + let definitions_impls = get_impls(*definition_with_same_path); + if definitions_impls.is_empty() { + continue; + } + + for candidate_span in definitions_impls { + span.push_span_label(candidate_span, format!("this is the found {ty}")); + trait_is_impl = true; + } + } + if !trait_is_impl { + for (_, def_id) in definitions_with_same_path { + span.push_span_label( + self.tcx.def_span(def_id), + format!("this is the {ty} that was imported"), + ); + } + } + self.note_two_crate_versions(expected_did, span, err); + err.help("you can use `cargo tree` to explore your dependency tree"); + } + suggested + } } /// Recovers the "impl X for Y" signature from `impl_def_id` and returns it as a diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 0906284e7019..e5c2adaa261d 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -2055,6 +2055,9 @@ fn confirm_impl_candidate<'cx, 'tcx>( // Get obligations corresponding to the predicates from the where-clause of the // associated type itself. +// +// This is necessary for soundness until we properly handle implied bounds on binders. +// see tests/ui/generic-associated-types/must-prove-where-clauses-on-norm.rs. // FIXME(mgca): While this supports constants, it is only used for types by default right now fn assoc_term_own_obligations<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index cecb43e537a8..d0833f030835 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -67,7 +67,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let lang_item = tcx.as_lang_item(def_id); match lang_item { - Some(LangItem::Copy | LangItem::Clone) => { + Some(LangItem::Copy | LangItem::Clone | LangItem::TrivialClone) => { debug!(obligation_self_ty = ?obligation.predicate.skip_binder().self_ty()); // User-defined copy impls are permitted, but only for diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 88f512708ff0..20a8842f2e8e 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -249,7 +249,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { Some(LangItem::PointeeSized) => { bug!("`PointeeSized` is removing during lowering"); } - Some(LangItem::Copy | LangItem::Clone) => self.copy_clone_conditions(self_ty), + Some(LangItem::Copy | LangItem::Clone | LangItem::TrivialClone) => { + self.copy_clone_conditions(self_ty) + } Some(LangItem::FusedIterator) => { if self.coroutine_is_gen(self_ty) { ty::Binder::dummy(vec![]) diff --git a/compiler/rustc_type_ir/src/lang_items.rs b/compiler/rustc_type_ir/src/lang_items.rs index 5f503d8b912e..39b575ebab63 100644 --- a/compiler/rustc_type_ir/src/lang_items.rs +++ b/compiler/rustc_type_ir/src/lang_items.rs @@ -48,6 +48,7 @@ pub enum SolverTraitLangItem { PointeeTrait, Sized, TransmuteTrait, + TrivialClone, Tuple, Unpin, Unsize, diff --git a/library/alloc/src/boxed/convert.rs b/library/alloc/src/boxed/convert.rs index 45c46fb52636..73940db5d2f5 100644 --- a/library/alloc/src/boxed/convert.rs +++ b/library/alloc/src/boxed/convert.rs @@ -1,4 +1,6 @@ use core::any::Any; +#[cfg(not(no_global_oom_handling))] +use core::clone::TrivialClone; use core::error::Error; use core::mem; use core::pin::Pin; @@ -75,11 +77,13 @@ impl BoxFromSlice for Box<[T]> { } #[cfg(not(no_global_oom_handling))] -impl BoxFromSlice for Box<[T]> { +impl BoxFromSlice for Box<[T]> { #[inline] fn from_slice(slice: &[T]) -> Self { let len = slice.len(); let buf = RawVec::with_capacity(len); + // SAFETY: since `T` implements `TrivialClone`, this is sound and + // equivalent to the above. unsafe { ptr::copy_nonoverlapping(slice.as_ptr(), buf.ptr(), len); buf.into_box(slice.len()).assume_init() diff --git a/library/alloc/src/collections/vec_deque/mod.rs b/library/alloc/src/collections/vec_deque/mod.rs index 1d4b3b558c01..78930364a926 100644 --- a/library/alloc/src/collections/vec_deque/mod.rs +++ b/library/alloc/src/collections/vec_deque/mod.rs @@ -7,6 +7,8 @@ #![stable(feature = "rust1", since = "1.0.0")] +#[cfg(not(no_global_oom_handling))] +use core::clone::TrivialClone; use core::cmp::{self, Ordering}; use core::hash::{Hash, Hasher}; use core::iter::{ByRefSized, repeat_n, repeat_with}; @@ -3419,7 +3421,7 @@ impl SpecExtendFromWithin for VecDeque { } #[cfg(not(no_global_oom_handling))] -impl SpecExtendFromWithin for VecDeque { +impl SpecExtendFromWithin for VecDeque { unsafe fn spec_extend_from_within(&mut self, src: Range) { let dst = self.len(); let count = src.end - src.start; diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index 73197d021f1a..666ae27fb863 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -146,6 +146,7 @@ #![feature(std_internals)] #![feature(str_internals)] #![feature(temporary_niche_types)] +#![feature(trivial_clone)] #![feature(trusted_fused)] #![feature(trusted_len)] #![feature(trusted_random_access)] diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index 89520e68920e..0ab019a68ea0 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -243,9 +243,9 @@ use core::any::Any; use core::cell::{Cell, CloneFromCell}; -#[cfg(not(no_global_oom_handling))] -use core::clone::CloneToUninit; use core::clone::UseCloned; +#[cfg(not(no_global_oom_handling))] +use core::clone::{CloneToUninit, TrivialClone}; use core::cmp::Ordering; use core::hash::{Hash, Hasher}; use core::intrinsics::abort; @@ -2224,7 +2224,8 @@ impl Rc<[T]> { /// Copy elements from slice into newly allocated `Rc<[T]>` /// - /// Unsafe because the caller must either take ownership or bind `T: Copy` + /// Unsafe because the caller must either take ownership, bind `T: Copy` or + /// bind `T: TrivialClone`. #[cfg(not(no_global_oom_handling))] unsafe fn copy_from_slice(v: &[T]) -> Rc<[T]> { unsafe { @@ -2314,9 +2315,11 @@ impl RcFromSlice for Rc<[T]> { } #[cfg(not(no_global_oom_handling))] -impl RcFromSlice for Rc<[T]> { +impl RcFromSlice for Rc<[T]> { #[inline] fn from_slice(v: &[T]) -> Self { + // SAFETY: `T` implements `TrivialClone`, so this is sound and equivalent + // to the above. unsafe { Rc::copy_from_slice(v) } } } diff --git a/library/alloc/src/slice.rs b/library/alloc/src/slice.rs index ce9f967cc387..a83b51ccb60c 100644 --- a/library/alloc/src/slice.rs +++ b/library/alloc/src/slice.rs @@ -11,6 +11,8 @@ use core::borrow::{Borrow, BorrowMut}; #[cfg(not(no_global_oom_handling))] +use core::clone::TrivialClone; +#[cfg(not(no_global_oom_handling))] use core::cmp::Ordering::{self, Less}; #[cfg(not(no_global_oom_handling))] use core::mem::MaybeUninit; @@ -439,7 +441,7 @@ impl [T] { } } - impl ConvertVec for T { + impl ConvertVec for T { #[inline] fn to_vec(s: &[Self], alloc: A) -> Vec { let mut v = Vec::with_capacity_in(s.len(), alloc); @@ -822,7 +824,7 @@ impl SpecCloneIntoVec for [T] { } #[cfg(not(no_global_oom_handling))] -impl SpecCloneIntoVec for [T] { +impl SpecCloneIntoVec for [T] { fn clone_into(&self, target: &mut Vec) { target.clear(); target.extend_from_slice(self); diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index ccf26ba4c2ac..c302f35e5ed6 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -12,6 +12,8 @@ use core::any::Any; use core::cell::CloneFromCell; #[cfg(not(no_global_oom_handling))] use core::clone::CloneToUninit; +#[cfg(not(no_global_oom_handling))] +use core::clone::TrivialClone; use core::clone::UseCloned; use core::cmp::Ordering; use core::hash::{Hash, Hasher}; @@ -2156,7 +2158,8 @@ impl Arc<[T]> { /// Copy elements from slice into newly allocated `Arc<[T]>` /// - /// Unsafe because the caller must either take ownership or bind `T: Copy`. + /// Unsafe because the caller must either take ownership, bind `T: Copy` or + /// bind `T: TrivialClone`. #[cfg(not(no_global_oom_handling))] unsafe fn copy_from_slice(v: &[T]) -> Arc<[T]> { unsafe { @@ -2248,9 +2251,11 @@ impl ArcFromSlice for Arc<[T]> { } #[cfg(not(no_global_oom_handling))] -impl ArcFromSlice for Arc<[T]> { +impl ArcFromSlice for Arc<[T]> { #[inline] fn from_slice(v: &[T]) -> Self { + // SAFETY: `T` implements `TrivialClone`, so this is sound and equivalent + // to the above. unsafe { Arc::copy_from_slice(v) } } } diff --git a/library/alloc/src/vec/is_zero.rs b/library/alloc/src/vec/is_zero.rs index a3ddd6f6e230..04b50e576298 100644 --- a/library/alloc/src/vec/is_zero.rs +++ b/library/alloc/src/vec/is_zero.rs @@ -1,3 +1,4 @@ +use core::mem::SizedTypeProperties; use core::num::{NonZero, Saturating, Wrapping}; use crate::boxed::Box; @@ -20,6 +21,8 @@ macro_rules! impl_is_zero { }; } +impl_is_zero!((), |_: ()| true); // It is needed to impl for arrays and tuples of (). + impl_is_zero!(i8, |x| x == 0); // It is needed to impl for arrays and tuples of i8. impl_is_zero!(i16, |x| x == 0); impl_is_zero!(i32, |x| x == 0); @@ -43,17 +46,38 @@ impl_is_zero!(f64, |x: f64| x.to_bits() == 0); // `IsZero` cannot be soundly implemented for pointers because of provenance // (see #135338). +unsafe impl IsZero for [T; N] { + #[inline] + default fn is_zero(&self) -> bool { + // If the array is of length zero, + // then it doesn't actually contain any `T`s, + // so `T::clone` doesn't need to be called, + // and we can "zero-initialize" all zero bytes of the array. + N == 0 + } +} + unsafe impl IsZero for [T; N] { #[inline] fn is_zero(&self) -> bool { - // Because this is generated as a runtime check, it's not obvious that - // it's worth doing if the array is really long. The threshold here - // is largely arbitrary, but was picked because as of 2022-07-01 LLVM - // fails to const-fold the check in `vec![[1; 32]; n]` - // See https://github.com/rust-lang/rust/pull/97581#issuecomment-1166628022 - // Feel free to tweak if you have better evidence. + if T::IS_ZST { + // If T is a ZST, then there is at most one possible value of `T`, + // so we only need to check one element for zeroness. + // We can't unconditionally return `true` here, since, e.g. + // `T = [NonTrivialCloneZst; 5]` is a ZST that implements `IsZero` + // due to the generic array impl, but `T::is_zero` returns `false` + // since the length is not 0. + self.get(0).is_none_or(IsZero::is_zero) + } else { + // Because this is generated as a runtime check, it's not obvious that + // it's worth doing if the array is really long. The threshold here + // is largely arbitrary, but was picked because as of 2022-07-01 LLVM + // fails to const-fold the check in `vec![[1; 32]; n]` + // See https://github.com/rust-lang/rust/pull/97581#issuecomment-1166628022 + // Feel free to tweak if you have better evidence. - N <= 16 && self.iter().all(IsZero::is_zero) + N <= 16 && self.iter().all(IsZero::is_zero) + } } } @@ -61,7 +85,7 @@ unsafe impl IsZero for [T; N] { macro_rules! impl_is_zero_tuples { // Stopper () => { - // No use for implementing for empty tuple because it is ZST. + // We already have an impl for () above. }; ($first_arg:ident $(,$rest:ident)*) => { unsafe impl <$first_arg: IsZero, $($rest: IsZero,)*> IsZero for ($first_arg, $($rest,)*){ diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index dc610d7b4674..43a68ff20373 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -73,6 +73,8 @@ #![stable(feature = "rust1", since = "1.0.0")] +#[cfg(not(no_global_oom_handling))] +use core::clone::TrivialClone; #[cfg(not(no_global_oom_handling))] use core::cmp; use core::cmp::Ordering; @@ -3494,7 +3496,7 @@ impl ExtendFromWithinSpec for Vec { } #[cfg(not(no_global_oom_handling))] -impl ExtendFromWithinSpec for Vec { +impl ExtendFromWithinSpec for Vec { unsafe fn spec_extend_from_within(&mut self, src: Range) { let count = src.len(); { @@ -3507,8 +3509,8 @@ impl ExtendFromWithinSpec for Vec { // SAFETY: // - Both pointers are created from unique slice references (`&mut [_]`) // so they are valid and do not overlap. - // - Elements are :Copy so it's OK to copy them, without doing - // anything with the original values + // - Elements implement `TrivialClone` so this is equivalent to calling + // `clone` on every one of them. // - `count` is equal to the len of `source`, so source is valid for // `count` reads // - `.reserve(count)` guarantees that `spare.len() >= count` so spare diff --git a/library/alloc/src/vec/spec_extend.rs b/library/alloc/src/vec/spec_extend.rs index 7085bceef5ba..f5bcd3ec9d82 100644 --- a/library/alloc/src/vec/spec_extend.rs +++ b/library/alloc/src/vec/spec_extend.rs @@ -1,3 +1,4 @@ +use core::clone::TrivialClone; use core::iter::TrustedLen; use core::slice::{self}; @@ -48,7 +49,7 @@ where impl<'a, T: 'a, A: Allocator> SpecExtend<&'a T, slice::Iter<'a, T>> for Vec where - T: Copy, + T: TrivialClone, { fn spec_extend(&mut self, iterator: slice::Iter<'a, T>) { let slice = iterator.as_slice(); diff --git a/library/alloctests/lib.rs b/library/alloctests/lib.rs index efdcb893bfee..665bc2704794 100644 --- a/library/alloctests/lib.rs +++ b/library/alloctests/lib.rs @@ -40,6 +40,7 @@ #![feature(slice_range)] #![feature(std_internals)] #![feature(temporary_niche_types)] +#![feature(trivial_clone)] #![feature(trusted_fused)] #![feature(trusted_len)] #![feature(trusted_random_access)] diff --git a/library/alloctests/tests/vec.rs b/library/alloctests/tests/vec.rs index ea334ab0f143..03b82fa82440 100644 --- a/library/alloctests/tests/vec.rs +++ b/library/alloctests/tests/vec.rs @@ -2299,20 +2299,6 @@ fn test_vec_swap() { assert_eq!(n, 0); } -#[test] -fn test_extend_from_within_spec() { - #[derive(Copy)] - struct CopyOnly; - - impl Clone for CopyOnly { - fn clone(&self) -> Self { - panic!("extend_from_within must use specialization on copy"); - } - } - - vec![CopyOnly, CopyOnly].extend_from_within(..); -} - #[test] fn test_extend_from_within_clone() { let mut v = vec![String::from("sssss"), String::from("12334567890"), String::from("c")]; diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs index 0dc10758a856..2dd639d68f0e 100644 --- a/library/core/src/array/mod.rs +++ b/library/core/src/array/mod.rs @@ -5,10 +5,10 @@ #![stable(feature = "core_array", since = "1.35.0")] use crate::borrow::{Borrow, BorrowMut}; +use crate::clone::TrivialClone; use crate::cmp::Ordering; use crate::convert::Infallible; use crate::error::Error; -use crate::fmt; use crate::hash::{self, Hash}; use crate::intrinsics::transmute_unchecked; use crate::iter::{UncheckedIterator, repeat_n}; @@ -18,6 +18,7 @@ use crate::ops::{ }; use crate::ptr::{null, null_mut}; use crate::slice::{Iter, IterMut}; +use crate::{fmt, ptr}; mod ascii; mod drain; @@ -451,6 +452,10 @@ impl Clone for [T; N] { } } +#[doc(hidden)] +#[unstable(feature = "trivial_clone", issue = "none")] +unsafe impl TrivialClone for [T; N] {} + trait SpecArrayClone: Clone { fn clone(array: &[Self; N]) -> [Self; N]; } @@ -462,10 +467,12 @@ impl SpecArrayClone for T { } } -impl SpecArrayClone for T { +impl SpecArrayClone for T { #[inline] fn clone(array: &[T; N]) -> [T; N] { - *array + // SAFETY: `TrivialClone` implies that this is equivalent to calling + // `Clone` on every element. + unsafe { ptr::read(array) } } } diff --git a/library/core/src/clone.rs b/library/core/src/clone.rs index 06d2c93cc698..bf8875098edf 100644 --- a/library/core/src/clone.rs +++ b/library/core/src/clone.rs @@ -250,10 +250,42 @@ pub const trait Clone: Sized { } } +/// Indicates that the `Clone` implementation is identical to copying the value. +/// +/// This is used for some optimizations in the standard library, which specializes +/// on this trait to select faster implementations of functions such as +/// [`clone_from_slice`](slice::clone_from_slice). It is automatically implemented +/// when using `#[derive(Clone, Copy)]`. +/// +/// Note that this trait does not imply that the type is `Copy`, because e.g. +/// `core::ops::Range` could soundly implement this trait. +/// +/// # Safety +/// `Clone::clone` must be equivalent to copying the value, otherwise calling functions +/// such as `slice::clone_from_slice` can have undefined behaviour. +#[unstable( + feature = "trivial_clone", + reason = "this isn't part of any API guarantee", + issue = "none" +)] +#[rustc_const_unstable(feature = "const_clone", issue = "142757")] +#[lang = "trivial_clone"] +// SAFETY: +// It is sound to specialize on this because the `clone` implementation cannot be +// lifetime-dependent. Therefore, if `TrivialClone` is implemented for any lifetime, +// its invariant holds whenever `Clone` is implemented, even if the actual +// `TrivialClone` bound would not be satisfied because of lifetime bounds. +#[rustc_unsafe_specialization_marker] +// If `#[derive(Clone, Clone, Copy)]` is written, there will be multiple +// implementations of `TrivialClone`. To keep it from appearing in error +// messages, make it a `#[marker]` trait. +#[marker] +pub const unsafe trait TrivialClone: [const] Clone {} + /// Derive macro generating an impl of the trait `Clone`. #[rustc_builtin_macro] #[stable(feature = "builtin_macro_prelude", since = "1.38.0")] -#[allow_internal_unstable(core_intrinsics, derive_clone_copy)] +#[allow_internal_unstable(core_intrinsics, derive_clone_copy, trivial_clone)] pub macro Clone($item:item) { /* compiler built-in */ } @@ -569,6 +601,7 @@ unsafe impl CloneToUninit for crate::bstr::ByteStr { /// are implemented in `traits::SelectionContext::copy_clone_conditions()` /// in `rustc_trait_selection`. mod impls { + use super::TrivialClone; use crate::marker::PointeeSized; macro_rules! impl_clone { @@ -582,6 +615,11 @@ mod impls { *self } } + + #[doc(hidden)] + #[unstable(feature = "trivial_clone", issue = "none")] + #[rustc_const_unstable(feature = "const_clone", issue = "142757")] + unsafe impl const TrivialClone for $t {} )* } } @@ -602,6 +640,11 @@ mod impls { } } + #[doc(hidden)] + #[unstable(feature = "trivial_clone", issue = "none")] + #[rustc_const_unstable(feature = "const_clone", issue = "142757")] + unsafe impl const TrivialClone for ! {} + #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_unstable(feature = "const_clone", issue = "142757")] impl const Clone for *const T { @@ -611,6 +654,11 @@ mod impls { } } + #[doc(hidden)] + #[unstable(feature = "trivial_clone", issue = "none")] + #[rustc_const_unstable(feature = "const_clone", issue = "142757")] + unsafe impl const TrivialClone for *const T {} + #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_unstable(feature = "const_clone", issue = "142757")] impl const Clone for *mut T { @@ -620,6 +668,11 @@ mod impls { } } + #[doc(hidden)] + #[unstable(feature = "trivial_clone", issue = "none")] + #[rustc_const_unstable(feature = "const_clone", issue = "142757")] + unsafe impl const TrivialClone for *mut T {} + /// Shared references can be cloned, but mutable references *cannot*! #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_unstable(feature = "const_clone", issue = "142757")] @@ -631,6 +684,11 @@ mod impls { } } + #[doc(hidden)] + #[unstable(feature = "trivial_clone", issue = "none")] + #[rustc_const_unstable(feature = "const_clone", issue = "142757")] + unsafe impl const TrivialClone for &T {} + /// Shared references can be cloned, but mutable references *cannot*! #[stable(feature = "rust1", since = "1.0.0")] impl !Clone for &mut T {} diff --git a/library/core/src/clone/uninit.rs b/library/core/src/clone/uninit.rs index 8b738bec796d..8d1185067eb8 100644 --- a/library/core/src/clone/uninit.rs +++ b/library/core/src/clone/uninit.rs @@ -1,3 +1,4 @@ +use super::TrivialClone; use crate::mem::{self, MaybeUninit}; use crate::ptr; @@ -49,9 +50,9 @@ unsafe impl CopySpec for T { } } -// Specialized implementation for types that are [`Copy`], not just [`Clone`], +// Specialized implementation for types that are [`TrivialClone`], not just [`Clone`], // and can therefore be copied bitwise. -unsafe impl CopySpec for T { +unsafe impl CopySpec for T { #[inline] unsafe fn clone_one(src: &Self, dst: *mut Self) { // SAFETY: The safety conditions of clone_to_uninit() are a superset of those of diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs index 4f6a425a0983..6b13b4c4f56c 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -622,7 +622,7 @@ pub const fn forget(_: T); /// // Crucially, we `as`-cast to a raw pointer before `transmute`ing to a function pointer. /// // This avoids an integer-to-pointer `transmute`, which can be problematic. /// // Transmuting between raw pointers and function pointers (i.e., two pointer types) is fine. -/// let pointer = foo as *const (); +/// let pointer = foo as fn() -> i32 as *const (); /// let function = unsafe { /// std::mem::transmute::<*const (), fn() -> i32>(pointer) /// }; diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index 5fd0611a1843..e945cd77a75f 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -14,6 +14,7 @@ pub use self::variance::{ PhantomInvariant, PhantomInvariantLifetime, Variance, variance, }; use crate::cell::UnsafeCell; +use crate::clone::TrivialClone; use crate::cmp; use crate::fmt::Debug; use crate::hash::{Hash, Hasher}; @@ -454,12 +455,8 @@ marker_impls! { /// [impls]: #implementors #[stable(feature = "rust1", since = "1.0.0")] #[lang = "copy"] -// FIXME(matthewjasper) This allows copying a type that doesn't implement -// `Copy` because of unsatisfied lifetime bounds (copying `A<'_>` when only -// `A<'static>: Copy` and `A<'_>: Clone`). -// We have this attribute here for now only because there are quite a few -// existing specializations on `Copy` that already exist in the standard -// library, and there's no way to safely have this behavior right now. +// This is unsound, but required by `hashbrown` +// FIXME(joboet): change `hashbrown` to use `TrivialClone` #[rustc_unsafe_specialization_marker] #[rustc_diagnostic_item = "Copy"] pub trait Copy: Clone { @@ -861,6 +858,10 @@ impl Clone for PhantomData { } } +#[doc(hidden)] +#[unstable(feature = "trivial_clone", issue = "none")] +unsafe impl TrivialClone for PhantomData {} + #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_unstable(feature = "const_default", issue = "143894")] impl const Default for PhantomData { diff --git a/library/core/src/marker/variance.rs b/library/core/src/marker/variance.rs index 55fdacb014e6..5fc62a5ad7ac 100644 --- a/library/core/src/marker/variance.rs +++ b/library/core/src/marker/variance.rs @@ -2,6 +2,7 @@ use super::PhantomData; use crate::any::type_name; +use crate::clone::TrivialClone; use crate::cmp::Ordering; use crate::fmt; use crate::hash::{Hash, Hasher}; @@ -60,6 +61,9 @@ macro_rules! phantom_type { impl Copy for $name where T: ?Sized {} + #[doc(hidden)] + unsafe impl TrivialClone for $name where T: ?Sized {} + impl PartialEq for $name where T: ?Sized { diff --git a/library/core/src/mem/maybe_uninit.rs b/library/core/src/mem/maybe_uninit.rs index 4ed914386eb8..3507d1a0a9a8 100644 --- a/library/core/src/mem/maybe_uninit.rs +++ b/library/core/src/mem/maybe_uninit.rs @@ -1,4 +1,5 @@ use crate::any::type_name; +use crate::clone::TrivialClone; use crate::marker::Destruct; use crate::mem::ManuallyDrop; use crate::{fmt, intrinsics, ptr, slice}; @@ -356,6 +357,11 @@ impl Clone for MaybeUninit { } } +// SAFETY: the clone implementation is a copy, see above. +#[doc(hidden)] +#[unstable(feature = "trivial_clone", issue = "none")] +unsafe impl TrivialClone for MaybeUninit where MaybeUninit: Clone {} + #[stable(feature = "maybe_uninit_debug", since = "1.41.0")] impl fmt::Debug for MaybeUninit { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -1599,8 +1605,12 @@ impl SpecFill for [MaybeUninit] { } } -impl SpecFill for [MaybeUninit] { +impl SpecFill for [MaybeUninit] { fn spec_fill(&mut self, value: T) { - self.fill(MaybeUninit::new(value)); + // SAFETY: because `T` is `TrivialClone`, this is equivalent to calling + // `T::clone` for every element. Notably, `TrivialClone` also implies + // that the `clone` implementation will not panic, so we can avoid + // initialization guards and such. + self.fill_with(|| MaybeUninit::new(unsafe { ptr::read(&value) })); } } diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs index 619e8a263db4..b180e88fd49b 100644 --- a/library/core/src/mem/mod.rs +++ b/library/core/src/mem/mod.rs @@ -6,6 +6,7 @@ #![stable(feature = "rust1", since = "1.0.0")] use crate::alloc::Layout; +use crate::clone::TrivialClone; use crate::marker::{Destruct, DiscriminantKind}; use crate::panic::const_assert; use crate::{clone, cmp, fmt, hash, intrinsics, ptr}; @@ -1070,6 +1071,10 @@ impl clone::Clone for Discriminant { } } +#[doc(hidden)] +#[unstable(feature = "trivial_clone", issue = "none")] +unsafe impl TrivialClone for Discriminant {} + #[stable(feature = "discriminant_value", since = "1.21.0")] impl cmp::PartialEq for Discriminant { fn eq(&self, rhs: &Self) -> bool { diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs index 7d395eb78034..70e764de9069 100644 --- a/library/core/src/num/int_macros.rs +++ b/library/core/src/num/int_macros.rs @@ -992,10 +992,10 @@ macro_rules! int_impl { /// /// ``` /// #![feature(exact_div)] - #[doc = concat!("assert_eq!((", stringify!($SelfT), "::MIN + 1).checked_exact_div(-1), Some(", stringify!($Max), "));")] - #[doc = concat!("assert_eq!((-5", stringify!($SelfT), ").checked_exact_div(2), None);")] - #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MIN.checked_exact_div(-1), None);")] - #[doc = concat!("assert_eq!((1", stringify!($SelfT), ").checked_exact_div(0), None);")] + #[doc = concat!("assert_eq!((", stringify!($SelfT), "::MIN + 1).checked_div_exact(-1), Some(", stringify!($Max), "));")] + #[doc = concat!("assert_eq!((-5", stringify!($SelfT), ").checked_div_exact(2), None);")] + #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MIN.checked_div_exact(-1), None);")] + #[doc = concat!("assert_eq!((1", stringify!($SelfT), ").checked_div_exact(0), None);")] /// ``` #[unstable( feature = "exact_div", @@ -1004,7 +1004,7 @@ macro_rules! int_impl { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub const fn checked_exact_div(self, rhs: Self) -> Option { + pub const fn checked_div_exact(self, rhs: Self) -> Option { if intrinsics::unlikely(rhs == 0 || ((self == Self::MIN) && (rhs == -1))) { None } else { @@ -1034,18 +1034,18 @@ macro_rules! int_impl { /// /// ``` /// #![feature(exact_div)] - #[doc = concat!("assert_eq!(64", stringify!($SelfT), ".exact_div(2), Some(32));")] - #[doc = concat!("assert_eq!(64", stringify!($SelfT), ".exact_div(32), Some(2));")] - #[doc = concat!("assert_eq!((", stringify!($SelfT), "::MIN + 1).exact_div(-1), Some(", stringify!($Max), "));")] - #[doc = concat!("assert_eq!(65", stringify!($SelfT), ".exact_div(2), None);")] + #[doc = concat!("assert_eq!(64", stringify!($SelfT), ".div_exact(2), Some(32));")] + #[doc = concat!("assert_eq!(64", stringify!($SelfT), ".div_exact(32), Some(2));")] + #[doc = concat!("assert_eq!((", stringify!($SelfT), "::MIN + 1).div_exact(-1), Some(", stringify!($Max), "));")] + #[doc = concat!("assert_eq!(65", stringify!($SelfT), ".div_exact(2), None);")] /// ``` /// ```should_panic /// #![feature(exact_div)] - #[doc = concat!("let _ = 64", stringify!($SelfT),".exact_div(0);")] + #[doc = concat!("let _ = 64", stringify!($SelfT),".div_exact(0);")] /// ``` /// ```should_panic /// #![feature(exact_div)] - #[doc = concat!("let _ = ", stringify!($SelfT), "::MIN.exact_div(-1);")] + #[doc = concat!("let _ = ", stringify!($SelfT), "::MIN.div_exact(-1);")] /// ``` #[unstable( feature = "exact_div", @@ -1055,7 +1055,7 @@ macro_rules! int_impl { without modifying the original"] #[inline] #[rustc_inherit_overflow_checks] - pub const fn exact_div(self, rhs: Self) -> Option { + pub const fn div_exact(self, rhs: Self) -> Option { if self % rhs != 0 { None } else { @@ -1069,7 +1069,7 @@ macro_rules! int_impl { /// /// This results in undefined behavior when `rhs == 0`, `self % rhs != 0`, or #[doc = concat!("`self == ", stringify!($SelfT), "::MIN && rhs == -1`,")] - /// i.e. when [`checked_exact_div`](Self::checked_exact_div) would return `None`. + /// i.e. when [`checked_div_exact`](Self::checked_div_exact) would return `None`. #[unstable( feature = "exact_div", issue = "139911", @@ -1077,10 +1077,10 @@ macro_rules! int_impl { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub const unsafe fn unchecked_exact_div(self, rhs: Self) -> Self { + pub const unsafe fn unchecked_div_exact(self, rhs: Self) -> Self { assert_unsafe_precondition!( check_language_ub, - concat!(stringify!($SelfT), "::unchecked_exact_div cannot overflow, divide by zero, or leave a remainder"), + concat!(stringify!($SelfT), "::unchecked_div_exact cannot overflow, divide by zero, or leave a remainder"), ( lhs: $SelfT = self, rhs: $SelfT = rhs, @@ -1431,17 +1431,17 @@ macro_rules! int_impl { /// ``` /// #![feature(exact_bitshifts)] /// - #[doc = concat!("assert_eq!(0x1", stringify!($SelfT), ".exact_shl(4), Some(0x10));")] - #[doc = concat!("assert_eq!(0x1", stringify!($SelfT), ".exact_shl(", stringify!($SelfT), "::BITS - 2), Some(1 << ", stringify!($SelfT), "::BITS - 2));")] - #[doc = concat!("assert_eq!(0x1", stringify!($SelfT), ".exact_shl(", stringify!($SelfT), "::BITS - 1), None);")] - #[doc = concat!("assert_eq!((-0x2", stringify!($SelfT), ").exact_shl(", stringify!($SelfT), "::BITS - 2), Some(-0x2 << ", stringify!($SelfT), "::BITS - 2));")] - #[doc = concat!("assert_eq!((-0x2", stringify!($SelfT), ").exact_shl(", stringify!($SelfT), "::BITS - 1), None);")] + #[doc = concat!("assert_eq!(0x1", stringify!($SelfT), ".shl_exact(4), Some(0x10));")] + #[doc = concat!("assert_eq!(0x1", stringify!($SelfT), ".shl_exact(", stringify!($SelfT), "::BITS - 2), Some(1 << ", stringify!($SelfT), "::BITS - 2));")] + #[doc = concat!("assert_eq!(0x1", stringify!($SelfT), ".shl_exact(", stringify!($SelfT), "::BITS - 1), None);")] + #[doc = concat!("assert_eq!((-0x2", stringify!($SelfT), ").shl_exact(", stringify!($SelfT), "::BITS - 2), Some(-0x2 << ", stringify!($SelfT), "::BITS - 2));")] + #[doc = concat!("assert_eq!((-0x2", stringify!($SelfT), ").shl_exact(", stringify!($SelfT), "::BITS - 1), None);")] /// ``` #[unstable(feature = "exact_bitshifts", issue = "144336")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub const fn exact_shl(self, rhs: u32) -> Option<$SelfT> { + pub const fn shl_exact(self, rhs: u32) -> Option<$SelfT> { if rhs < self.leading_zeros() || rhs < self.leading_ones() { // SAFETY: rhs is checked above Some(unsafe { self.unchecked_shl(rhs) }) @@ -1458,16 +1458,16 @@ macro_rules! int_impl { /// /// This results in undefined behavior when `rhs >= self.leading_zeros() && rhs >= /// self.leading_ones()` i.e. when - #[doc = concat!("[`", stringify!($SelfT), "::exact_shl`]")] + #[doc = concat!("[`", stringify!($SelfT), "::shl_exact`]")] /// would return `None`. #[unstable(feature = "exact_bitshifts", issue = "144336")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub const unsafe fn unchecked_exact_shl(self, rhs: u32) -> $SelfT { + pub const unsafe fn unchecked_shl_exact(self, rhs: u32) -> $SelfT { assert_unsafe_precondition!( check_library_ub, - concat!(stringify!($SelfT), "::unchecked_exact_shl cannot shift out bits that would change the value of the first bit"), + concat!(stringify!($SelfT), "::unchecked_shl_exact cannot shift out bits that would change the value of the first bit"), ( zeros: u32 = self.leading_zeros(), ones: u32 = self.leading_ones(), @@ -1503,7 +1503,7 @@ macro_rules! int_impl { } } - /// Strict shift right. Computes `self >> rhs`, panicking `rhs` is + /// Strict shift right. Computes `self >> rhs`, panicking if `rhs` is /// larger than or equal to the number of bits in `self`. /// /// # Panics @@ -1611,14 +1611,14 @@ macro_rules! int_impl { /// ``` /// #![feature(exact_bitshifts)] /// - #[doc = concat!("assert_eq!(0x10", stringify!($SelfT), ".exact_shr(4), Some(0x1));")] - #[doc = concat!("assert_eq!(0x10", stringify!($SelfT), ".exact_shr(5), None);")] + #[doc = concat!("assert_eq!(0x10", stringify!($SelfT), ".shr_exact(4), Some(0x1));")] + #[doc = concat!("assert_eq!(0x10", stringify!($SelfT), ".shr_exact(5), None);")] /// ``` #[unstable(feature = "exact_bitshifts", issue = "144336")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub const fn exact_shr(self, rhs: u32) -> Option<$SelfT> { + pub const fn shr_exact(self, rhs: u32) -> Option<$SelfT> { if rhs <= self.trailing_zeros() && rhs < <$SelfT>::BITS { // SAFETY: rhs is checked above Some(unsafe { self.unchecked_shr(rhs) }) @@ -1636,16 +1636,16 @@ macro_rules! int_impl { /// This results in undefined behavior when `rhs > self.trailing_zeros() || rhs >= #[doc = concat!(stringify!($SelfT), "::BITS`")] /// i.e. when - #[doc = concat!("[`", stringify!($SelfT), "::exact_shr`]")] + #[doc = concat!("[`", stringify!($SelfT), "::shr_exact`]")] /// would return `None`. #[unstable(feature = "exact_bitshifts", issue = "144336")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub const unsafe fn unchecked_exact_shr(self, rhs: u32) -> $SelfT { + pub const unsafe fn unchecked_shr_exact(self, rhs: u32) -> $SelfT { assert_unsafe_precondition!( check_library_ub, - concat!(stringify!($SelfT), "::unchecked_exact_shr cannot shift out non-zero bits"), + concat!(stringify!($SelfT), "::unchecked_shr_exact cannot shift out non-zero bits"), ( zeros: u32 = self.trailing_zeros(), bits: u32 = <$SelfT>::BITS, diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs index 8cd8b0850e94..983e00e46a5f 100644 --- a/library/core/src/num/nonzero.rs +++ b/library/core/src/num/nonzero.rs @@ -1,7 +1,7 @@ //! Definitions of integer that is known not to equal zero. use super::{IntErrorKind, ParseIntError}; -use crate::clone::UseCloned; +use crate::clone::{TrivialClone, UseCloned}; use crate::cmp::Ordering; use crate::hash::{Hash, Hasher}; use crate::marker::{Destruct, Freeze, StructuralPartialEq}; @@ -199,6 +199,10 @@ impl UseCloned for NonZero where T: ZeroablePrimitive {} #[stable(feature = "nonzero", since = "1.28.0")] impl Copy for NonZero where T: ZeroablePrimitive {} +#[doc(hidden)] +#[unstable(feature = "trivial_clone", issue = "none")] +unsafe impl TrivialClone for NonZero where T: ZeroablePrimitive {} + #[stable(feature = "nonzero", since = "1.28.0")] #[rustc_const_unstable(feature = "const_cmp", issue = "143800")] impl const PartialEq for NonZero diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index 2996e7b00da4..d38d3a1a5ad4 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -1222,10 +1222,10 @@ macro_rules! uint_impl { /// /// ``` /// #![feature(exact_div)] - #[doc = concat!("assert_eq!(64", stringify!($SelfT), ".checked_exact_div(2), Some(32));")] - #[doc = concat!("assert_eq!(64", stringify!($SelfT), ".checked_exact_div(32), Some(2));")] - #[doc = concat!("assert_eq!(64", stringify!($SelfT), ".checked_exact_div(0), None);")] - #[doc = concat!("assert_eq!(65", stringify!($SelfT), ".checked_exact_div(2), None);")] + #[doc = concat!("assert_eq!(64", stringify!($SelfT), ".checked_div_exact(2), Some(32));")] + #[doc = concat!("assert_eq!(64", stringify!($SelfT), ".checked_div_exact(32), Some(2));")] + #[doc = concat!("assert_eq!(64", stringify!($SelfT), ".checked_div_exact(0), None);")] + #[doc = concat!("assert_eq!(65", stringify!($SelfT), ".checked_div_exact(2), None);")] /// ``` #[unstable( feature = "exact_div", @@ -1234,7 +1234,7 @@ macro_rules! uint_impl { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub const fn checked_exact_div(self, rhs: Self) -> Option { + pub const fn checked_div_exact(self, rhs: Self) -> Option { if intrinsics::unlikely(rhs == 0) { None } else { @@ -1259,9 +1259,9 @@ macro_rules! uint_impl { /// /// ``` /// #![feature(exact_div)] - #[doc = concat!("assert_eq!(64", stringify!($SelfT), ".exact_div(2), Some(32));")] - #[doc = concat!("assert_eq!(64", stringify!($SelfT), ".exact_div(32), Some(2));")] - #[doc = concat!("assert_eq!(65", stringify!($SelfT), ".exact_div(2), None);")] + #[doc = concat!("assert_eq!(64", stringify!($SelfT), ".div_exact(2), Some(32));")] + #[doc = concat!("assert_eq!(64", stringify!($SelfT), ".div_exact(32), Some(2));")] + #[doc = concat!("assert_eq!(65", stringify!($SelfT), ".div_exact(2), None);")] /// ``` #[unstable( feature = "exact_div", @@ -1271,7 +1271,7 @@ macro_rules! uint_impl { without modifying the original"] #[inline] #[rustc_inherit_overflow_checks] - pub const fn exact_div(self, rhs: Self) -> Option { + pub const fn div_exact(self, rhs: Self) -> Option { if self % rhs != 0 { None } else { @@ -1284,7 +1284,7 @@ macro_rules! uint_impl { /// # Safety /// /// This results in undefined behavior when `rhs == 0` or `self % rhs != 0`, - /// i.e. when [`checked_exact_div`](Self::checked_exact_div) would return `None`. + /// i.e. when [`checked_div_exact`](Self::checked_div_exact) would return `None`. #[unstable( feature = "exact_div", issue = "139911", @@ -1292,10 +1292,10 @@ macro_rules! uint_impl { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub const unsafe fn unchecked_exact_div(self, rhs: Self) -> Self { + pub const unsafe fn unchecked_div_exact(self, rhs: Self) -> Self { assert_unsafe_precondition!( check_language_ub, - concat!(stringify!($SelfT), "::unchecked_exact_div divide by zero or leave a remainder"), + concat!(stringify!($SelfT), "::unchecked_div_exact divide by zero or leave a remainder"), ( lhs: $SelfT = self, rhs: $SelfT = rhs, @@ -1830,14 +1830,14 @@ macro_rules! uint_impl { /// ``` /// #![feature(exact_bitshifts)] /// - #[doc = concat!("assert_eq!(0x1", stringify!($SelfT), ".exact_shl(4), Some(0x10));")] - #[doc = concat!("assert_eq!(0x1", stringify!($SelfT), ".exact_shl(129), None);")] + #[doc = concat!("assert_eq!(0x1", stringify!($SelfT), ".shl_exact(4), Some(0x10));")] + #[doc = concat!("assert_eq!(0x1", stringify!($SelfT), ".shl_exact(129), None);")] /// ``` #[unstable(feature = "exact_bitshifts", issue = "144336")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub const fn exact_shl(self, rhs: u32) -> Option<$SelfT> { + pub const fn shl_exact(self, rhs: u32) -> Option<$SelfT> { if rhs <= self.leading_zeros() && rhs < <$SelfT>::BITS { // SAFETY: rhs is checked above Some(unsafe { self.unchecked_shl(rhs) }) @@ -1855,16 +1855,16 @@ macro_rules! uint_impl { /// This results in undefined behavior when `rhs > self.leading_zeros() || rhs >= #[doc = concat!(stringify!($SelfT), "::BITS`")] /// i.e. when - #[doc = concat!("[`", stringify!($SelfT), "::exact_shl`]")] + #[doc = concat!("[`", stringify!($SelfT), "::shl_exact`]")] /// would return `None`. #[unstable(feature = "exact_bitshifts", issue = "144336")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub const unsafe fn unchecked_exact_shl(self, rhs: u32) -> $SelfT { + pub const unsafe fn unchecked_shl_exact(self, rhs: u32) -> $SelfT { assert_unsafe_precondition!( check_library_ub, - concat!(stringify!($SelfT), "::exact_shl_unchecked cannot shift out non-zero bits"), + concat!(stringify!($SelfT), "::unchecked_shl_exact cannot shift out non-zero bits"), ( zeros: u32 = self.leading_zeros(), bits: u32 = <$SelfT>::BITS, @@ -1900,7 +1900,7 @@ macro_rules! uint_impl { } } - /// Strict shift right. Computes `self >> rhs`, panicking `rhs` is + /// Strict shift right. Computes `self >> rhs`, panicking if `rhs` is /// larger than or equal to the number of bits in `self`. /// /// # Panics @@ -2002,14 +2002,14 @@ macro_rules! uint_impl { /// ``` /// #![feature(exact_bitshifts)] /// - #[doc = concat!("assert_eq!(0x10", stringify!($SelfT), ".exact_shr(4), Some(0x1));")] - #[doc = concat!("assert_eq!(0x10", stringify!($SelfT), ".exact_shr(5), None);")] + #[doc = concat!("assert_eq!(0x10", stringify!($SelfT), ".shr_exact(4), Some(0x1));")] + #[doc = concat!("assert_eq!(0x10", stringify!($SelfT), ".shr_exact(5), None);")] /// ``` #[unstable(feature = "exact_bitshifts", issue = "144336")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub const fn exact_shr(self, rhs: u32) -> Option<$SelfT> { + pub const fn shr_exact(self, rhs: u32) -> Option<$SelfT> { if rhs <= self.trailing_zeros() && rhs < <$SelfT>::BITS { // SAFETY: rhs is checked above Some(unsafe { self.unchecked_shr(rhs) }) @@ -2027,16 +2027,16 @@ macro_rules! uint_impl { /// This results in undefined behavior when `rhs > self.trailing_zeros() || rhs >= #[doc = concat!(stringify!($SelfT), "::BITS`")] /// i.e. when - #[doc = concat!("[`", stringify!($SelfT), "::exact_shr`]")] + #[doc = concat!("[`", stringify!($SelfT), "::shr_exact`]")] /// would return `None`. #[unstable(feature = "exact_bitshifts", issue = "144336")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub const unsafe fn unchecked_exact_shr(self, rhs: u32) -> $SelfT { + pub const unsafe fn unchecked_shr_exact(self, rhs: u32) -> $SelfT { assert_unsafe_precondition!( check_library_ub, - concat!(stringify!($SelfT), "::exact_shr_unchecked cannot shift out non-zero bits"), + concat!(stringify!($SelfT), "::unchecked_shr_exact cannot shift out non-zero bits"), ( zeros: u32 = self.trailing_zeros(), bits: u32 = <$SelfT>::BITS, diff --git a/library/core/src/option.rs b/library/core/src/option.rs index e3c4758bc6af..57098b95f641 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -581,6 +581,7 @@ #![stable(feature = "rust1", since = "1.0.0")] +use crate::clone::TrivialClone; use crate::iter::{self, FusedIterator, TrustedLen}; use crate::marker::Destruct; use crate::ops::{self, ControlFlow, Deref, DerefMut}; @@ -2215,6 +2216,11 @@ where #[unstable(feature = "ergonomic_clones", issue = "132290")] impl crate::clone::UseCloned for Option where T: crate::clone::UseCloned {} +#[doc(hidden)] +#[unstable(feature = "trivial_clone", issue = "none")] +#[rustc_const_unstable(feature = "const_clone", issue = "142757")] +unsafe impl const TrivialClone for Option where T: [const] TrivialClone + [const] Destruct {} + #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_unstable(feature = "const_default", issue = "143894")] impl const Default for Option { diff --git a/library/core/src/ptr/metadata.rs b/library/core/src/ptr/metadata.rs index dc3ec3fd1994..998a5b031c28 100644 --- a/library/core/src/ptr/metadata.rs +++ b/library/core/src/ptr/metadata.rs @@ -1,5 +1,6 @@ #![unstable(feature = "ptr_metadata", issue = "81513")] +use crate::clone::TrivialClone; use crate::fmt; use crate::hash::{Hash, Hasher}; use crate::intrinsics::{aggregate_raw_ptr, ptr_metadata}; @@ -231,6 +232,9 @@ impl Clone for DynMetadata { } } +#[doc(hidden)] +unsafe impl TrivialClone for DynMetadata {} + impl Eq for DynMetadata {} impl PartialEq for DynMetadata { diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs index a762e969b52d..aa3af2f18528 100644 --- a/library/core/src/ptr/non_null.rs +++ b/library/core/src/ptr/non_null.rs @@ -1,3 +1,4 @@ +use crate::clone::TrivialClone; use crate::cmp::Ordering; use crate::marker::{Destruct, PointeeSized, Unsize}; use crate::mem::{MaybeUninit, SizedTypeProperties}; @@ -1653,6 +1654,10 @@ impl Clone for NonNull { #[stable(feature = "nonnull", since = "1.25.0")] impl Copy for NonNull {} +#[doc(hidden)] +#[unstable(feature = "trivial_clone", issue = "none")] +unsafe impl TrivialClone for NonNull {} + #[unstable(feature = "coerce_unsized", issue = "18598")] impl CoerceUnsized> for NonNull where T: Unsize {} diff --git a/library/core/src/ptr/unique.rs b/library/core/src/ptr/unique.rs index cdc8b6cc936d..5e7b1f703802 100644 --- a/library/core/src/ptr/unique.rs +++ b/library/core/src/ptr/unique.rs @@ -1,3 +1,4 @@ +use crate::clone::TrivialClone; use crate::fmt; use crate::marker::{PhantomData, PointeeSized, Unsize}; use crate::ops::{CoerceUnsized, DispatchFromDyn}; @@ -165,6 +166,10 @@ impl Clone for Unique { #[unstable(feature = "ptr_internals", issue = "none")] impl Copy for Unique {} +#[doc(hidden)] +#[unstable(feature = "trivial_clone", issue = "none")] +unsafe impl TrivialClone for Unique {} + #[unstable(feature = "ptr_internals", issue = "none")] impl CoerceUnsized> for Unique where T: Unsize {} diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index 1d88eb33dce1..f03f2045444d 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -6,6 +6,7 @@ #![stable(feature = "rust1", since = "1.0.0")] +use crate::clone::TrivialClone; use crate::cmp::Ordering::{self, Equal, Greater, Less}; use crate::intrinsics::{exact_div, unchecked_sub}; use crate::mem::{self, MaybeUninit, SizedTypeProperties}; @@ -3890,30 +3891,8 @@ impl [T] { where T: Copy, { - // The panic code path was put into a cold function to not bloat the - // call site. - #[cfg_attr(not(panic = "immediate-abort"), inline(never), cold)] - #[cfg_attr(panic = "immediate-abort", inline)] - #[track_caller] - const fn len_mismatch_fail(dst_len: usize, src_len: usize) -> ! { - const_panic!( - "copy_from_slice: source slice length does not match destination slice length", - "copy_from_slice: source slice length ({src_len}) does not match destination slice length ({dst_len})", - src_len: usize, - dst_len: usize, - ) - } - - if self.len() != src.len() { - len_mismatch_fail(self.len(), src.len()); - } - - // SAFETY: `self` is valid for `self.len()` elements by definition, and `src` was - // checked to have the same length. The slices cannot overlap because - // mutable references are exclusive. - unsafe { - ptr::copy_nonoverlapping(src.as_ptr(), self.as_mut_ptr(), self.len()); - } + // SAFETY: `T` implements `Copy`. + unsafe { copy_from_slice_impl(self, src) } } /// Copies elements from one part of the slice to another part of itself, @@ -5123,6 +5102,38 @@ impl [f64] { } } +/// Copies `src` to `dest`. +/// +/// # Safety +/// `T` must implement one of `Copy` or `TrivialClone`. +#[track_caller] +const unsafe fn copy_from_slice_impl(dest: &mut [T], src: &[T]) { + // The panic code path was put into a cold function to not bloat the + // call site. + #[cfg_attr(not(panic = "immediate-abort"), inline(never), cold)] + #[cfg_attr(panic = "immediate-abort", inline)] + #[track_caller] + const fn len_mismatch_fail(dst_len: usize, src_len: usize) -> ! { + const_panic!( + "copy_from_slice: source slice length does not match destination slice length", + "copy_from_slice: source slice length ({src_len}) does not match destination slice length ({dst_len})", + src_len: usize, + dst_len: usize, + ) + } + + if dest.len() != src.len() { + len_mismatch_fail(dest.len(), src.len()); + } + + // SAFETY: `self` is valid for `self.len()` elements by definition, and `src` was + // checked to have the same length. The slices cannot overlap because + // mutable references are exclusive. + unsafe { + ptr::copy_nonoverlapping(src.as_ptr(), dest.as_mut_ptr(), dest.len()); + } +} + trait CloneFromSpec { fn spec_clone_from(&mut self, src: &[T]); } @@ -5147,11 +5158,14 @@ where impl CloneFromSpec for [T] where - T: Copy, + T: TrivialClone, { #[track_caller] fn spec_clone_from(&mut self, src: &[T]) { - self.copy_from_slice(src); + // SAFETY: `T` implements `TrivialClone`. + unsafe { + copy_from_slice_impl(self, src); + } } } diff --git a/library/core/src/slice/specialize.rs b/library/core/src/slice/specialize.rs index 17436395fee6..c44225b75364 100644 --- a/library/core/src/slice/specialize.rs +++ b/library/core/src/slice/specialize.rs @@ -1,3 +1,6 @@ +use crate::clone::TrivialClone; +use crate::ptr; + pub(super) trait SpecFill { fn spec_fill(&mut self, value: T); } @@ -14,10 +17,12 @@ impl SpecFill for [T] { } } -impl SpecFill for [T] { +impl SpecFill for [T] { default fn spec_fill(&mut self, value: T) { for item in self.iter_mut() { - *item = value; + // SAFETY: `TrivialClone` indicates that this is equivalent to + // calling `Clone::clone` + *item = unsafe { ptr::read(&value) }; } } } diff --git a/library/core/src/sync/exclusive.rs b/library/core/src/sync/exclusive.rs index f181c5514f25..35b812099518 100644 --- a/library/core/src/sync/exclusive.rs +++ b/library/core/src/sync/exclusive.rs @@ -1,5 +1,6 @@ //! Defines [`Exclusive`]. +use core::clone::TrivialClone; use core::cmp::Ordering; use core::fmt; use core::future::Future; @@ -261,6 +262,10 @@ where } } +#[doc(hidden)] +#[unstable(feature = "trivial_clone", issue = "none")] +unsafe impl TrivialClone for Exclusive where T: Sync + TrivialClone {} + #[unstable(feature = "exclusive_wrapper", issue = "98407")] impl Copy for Exclusive where T: Sync + Copy {} diff --git a/library/coretests/tests/num/int_macros.rs b/library/coretests/tests/num/int_macros.rs index e640b7853bd9..37336f49ef1b 100644 --- a/library/coretests/tests/num/int_macros.rs +++ b/library/coretests/tests/num/int_macros.rs @@ -724,42 +724,42 @@ macro_rules! int_module { } } - const EXACT_DIV_SUCCESS_DIVIDEND1: $T = 42; - const EXACT_DIV_SUCCESS_DIVISOR1: $T = 6; - const EXACT_DIV_SUCCESS_QUOTIENT1: $T = 7; - const EXACT_DIV_SUCCESS_DIVIDEND2: $T = 18; - const EXACT_DIV_SUCCESS_DIVISOR2: $T = 3; - const EXACT_DIV_SUCCESS_QUOTIENT2: $T = 6; - const EXACT_DIV_SUCCESS_DIVIDEND3: $T = -91; - const EXACT_DIV_SUCCESS_DIVISOR3: $T = 13; - const EXACT_DIV_SUCCESS_QUOTIENT3: $T = -7; - const EXACT_DIV_SUCCESS_DIVIDEND4: $T = -57; - const EXACT_DIV_SUCCESS_DIVISOR4: $T = -3; - const EXACT_DIV_SUCCESS_QUOTIENT4: $T = 19; + const DIV_EXACT_SUCCESS_DIVIDEND1: $T = 42; + const DIV_EXACT_SUCCESS_DIVISOR1: $T = 6; + const DIV_EXACT_SUCCESS_QUOTIENT1: $T = 7; + const DIV_EXACT_SUCCESS_DIVIDEND2: $T = 18; + const DIV_EXACT_SUCCESS_DIVISOR2: $T = 3; + const DIV_EXACT_SUCCESS_QUOTIENT2: $T = 6; + const DIV_EXACT_SUCCESS_DIVIDEND3: $T = -91; + const DIV_EXACT_SUCCESS_DIVISOR3: $T = 13; + const DIV_EXACT_SUCCESS_QUOTIENT3: $T = -7; + const DIV_EXACT_SUCCESS_DIVIDEND4: $T = -57; + const DIV_EXACT_SUCCESS_DIVISOR4: $T = -3; + const DIV_EXACT_SUCCESS_QUOTIENT4: $T = 19; test_runtime_and_compiletime! { - fn test_exact_div() { + fn test_div_exact() { // 42 / 6 - assert_eq_const_safe!(Option<$T>: <$T>::checked_exact_div(EXACT_DIV_SUCCESS_DIVIDEND1, EXACT_DIV_SUCCESS_DIVISOR1), Some(EXACT_DIV_SUCCESS_QUOTIENT1)); - assert_eq_const_safe!(Option<$T>: <$T>::exact_div(EXACT_DIV_SUCCESS_DIVIDEND1, EXACT_DIV_SUCCESS_DIVISOR1), Some(EXACT_DIV_SUCCESS_QUOTIENT1)); + assert_eq_const_safe!(Option<$T>: <$T>::checked_div_exact(DIV_EXACT_SUCCESS_DIVIDEND1, DIV_EXACT_SUCCESS_DIVISOR1), Some(DIV_EXACT_SUCCESS_QUOTIENT1)); + assert_eq_const_safe!(Option<$T>: <$T>::div_exact(DIV_EXACT_SUCCESS_DIVIDEND1, DIV_EXACT_SUCCESS_DIVISOR1), Some(DIV_EXACT_SUCCESS_QUOTIENT1)); // 18 / 3 - assert_eq_const_safe!(Option<$T>: <$T>::checked_exact_div(EXACT_DIV_SUCCESS_DIVIDEND2, EXACT_DIV_SUCCESS_DIVISOR2), Some(EXACT_DIV_SUCCESS_QUOTIENT2)); - assert_eq_const_safe!(Option<$T>: <$T>::exact_div(EXACT_DIV_SUCCESS_DIVIDEND2, EXACT_DIV_SUCCESS_DIVISOR2), Some(EXACT_DIV_SUCCESS_QUOTIENT2)); + assert_eq_const_safe!(Option<$T>: <$T>::checked_div_exact(DIV_EXACT_SUCCESS_DIVIDEND2, DIV_EXACT_SUCCESS_DIVISOR2), Some(DIV_EXACT_SUCCESS_QUOTIENT2)); + assert_eq_const_safe!(Option<$T>: <$T>::div_exact(DIV_EXACT_SUCCESS_DIVIDEND2, DIV_EXACT_SUCCESS_DIVISOR2), Some(DIV_EXACT_SUCCESS_QUOTIENT2)); // -91 / 13 - assert_eq_const_safe!(Option<$T>: <$T>::checked_exact_div(EXACT_DIV_SUCCESS_DIVIDEND3, EXACT_DIV_SUCCESS_DIVISOR3), Some(EXACT_DIV_SUCCESS_QUOTIENT3)); - assert_eq_const_safe!(Option<$T>: <$T>::exact_div(EXACT_DIV_SUCCESS_DIVIDEND3, EXACT_DIV_SUCCESS_DIVISOR3), Some(EXACT_DIV_SUCCESS_QUOTIENT3)); + assert_eq_const_safe!(Option<$T>: <$T>::checked_div_exact(DIV_EXACT_SUCCESS_DIVIDEND3, DIV_EXACT_SUCCESS_DIVISOR3), Some(DIV_EXACT_SUCCESS_QUOTIENT3)); + assert_eq_const_safe!(Option<$T>: <$T>::div_exact(DIV_EXACT_SUCCESS_DIVIDEND3, DIV_EXACT_SUCCESS_DIVISOR3), Some(DIV_EXACT_SUCCESS_QUOTIENT3)); // -57 / -3 - assert_eq_const_safe!(Option<$T>: <$T>::checked_exact_div(EXACT_DIV_SUCCESS_DIVIDEND4, EXACT_DIV_SUCCESS_DIVISOR4), Some(EXACT_DIV_SUCCESS_QUOTIENT4)); - assert_eq_const_safe!(Option<$T>: <$T>::exact_div(EXACT_DIV_SUCCESS_DIVIDEND4, EXACT_DIV_SUCCESS_DIVISOR4), Some(EXACT_DIV_SUCCESS_QUOTIENT4)); + assert_eq_const_safe!(Option<$T>: <$T>::checked_div_exact(DIV_EXACT_SUCCESS_DIVIDEND4, DIV_EXACT_SUCCESS_DIVISOR4), Some(DIV_EXACT_SUCCESS_QUOTIENT4)); + assert_eq_const_safe!(Option<$T>: <$T>::div_exact(DIV_EXACT_SUCCESS_DIVIDEND4, DIV_EXACT_SUCCESS_DIVISOR4), Some(DIV_EXACT_SUCCESS_QUOTIENT4)); // failures - assert_eq_const_safe!(Option<$T>: <$T>::checked_exact_div(1, 2), None); - assert_eq_const_safe!(Option<$T>: <$T>::exact_div(1, 2), None); - assert_eq_const_safe!(Option<$T>: <$T>::checked_exact_div(<$T>::MIN, -1), None); - assert_eq_const_safe!(Option<$T>: <$T>::checked_exact_div(0, 0), None); + assert_eq_const_safe!(Option<$T>: <$T>::checked_div_exact(1, 2), None); + assert_eq_const_safe!(Option<$T>: <$T>::div_exact(1, 2), None); + assert_eq_const_safe!(Option<$T>: <$T>::checked_div_exact(<$T>::MIN, -1), None); + assert_eq_const_safe!(Option<$T>: <$T>::checked_div_exact(0, 0), None); } } }; diff --git a/library/coretests/tests/num/uint_macros.rs b/library/coretests/tests/num/uint_macros.rs index c1cfc448f14f..b89a371efcc2 100644 --- a/library/coretests/tests/num/uint_macros.rs +++ b/library/coretests/tests/num/uint_macros.rs @@ -595,27 +595,27 @@ macro_rules! uint_module { } } - const EXACT_DIV_SUCCESS_DIVIDEND1: $T = 42; - const EXACT_DIV_SUCCESS_DIVISOR1: $T = 6; - const EXACT_DIV_SUCCESS_QUOTIENT1: $T = 7; - const EXACT_DIV_SUCCESS_DIVIDEND2: $T = 18; - const EXACT_DIV_SUCCESS_DIVISOR2: $T = 3; - const EXACT_DIV_SUCCESS_QUOTIENT2: $T = 6; + const DIV_EXACT_SUCCESS_DIVIDEND1: $T = 42; + const DIV_EXACT_SUCCESS_DIVISOR1: $T = 6; + const DIV_EXACT_SUCCESS_QUOTIENT1: $T = 7; + const DIV_EXACT_SUCCESS_DIVIDEND2: $T = 18; + const DIV_EXACT_SUCCESS_DIVISOR2: $T = 3; + const DIV_EXACT_SUCCESS_QUOTIENT2: $T = 6; test_runtime_and_compiletime! { - fn test_exact_div() { + fn test_div_exact() { // 42 / 6 - assert_eq_const_safe!(Option<$T>: <$T>::checked_exact_div(EXACT_DIV_SUCCESS_DIVIDEND1, EXACT_DIV_SUCCESS_DIVISOR1), Some(EXACT_DIV_SUCCESS_QUOTIENT1)); - assert_eq_const_safe!(Option<$T>: <$T>::exact_div(EXACT_DIV_SUCCESS_DIVIDEND1, EXACT_DIV_SUCCESS_DIVISOR1), Some(EXACT_DIV_SUCCESS_QUOTIENT1)); + assert_eq_const_safe!(Option<$T>: <$T>::checked_div_exact(DIV_EXACT_SUCCESS_DIVIDEND1, DIV_EXACT_SUCCESS_DIVISOR1), Some(DIV_EXACT_SUCCESS_QUOTIENT1)); + assert_eq_const_safe!(Option<$T>: <$T>::div_exact(DIV_EXACT_SUCCESS_DIVIDEND1, DIV_EXACT_SUCCESS_DIVISOR1), Some(DIV_EXACT_SUCCESS_QUOTIENT1)); // 18 / 3 - assert_eq_const_safe!(Option<$T>: <$T>::checked_exact_div(EXACT_DIV_SUCCESS_DIVIDEND2, EXACT_DIV_SUCCESS_DIVISOR2), Some(EXACT_DIV_SUCCESS_QUOTIENT2)); - assert_eq_const_safe!(Option<$T>: <$T>::exact_div(EXACT_DIV_SUCCESS_DIVIDEND2, EXACT_DIV_SUCCESS_DIVISOR2), Some(EXACT_DIV_SUCCESS_QUOTIENT2)); + assert_eq_const_safe!(Option<$T>: <$T>::checked_div_exact(DIV_EXACT_SUCCESS_DIVIDEND2, DIV_EXACT_SUCCESS_DIVISOR2), Some(DIV_EXACT_SUCCESS_QUOTIENT2)); + assert_eq_const_safe!(Option<$T>: <$T>::div_exact(DIV_EXACT_SUCCESS_DIVIDEND2, DIV_EXACT_SUCCESS_DIVISOR2), Some(DIV_EXACT_SUCCESS_QUOTIENT2)); // failures - assert_eq_const_safe!(Option<$T>: <$T>::checked_exact_div(1, 2), None); - assert_eq_const_safe!(Option<$T>: <$T>::exact_div(1, 2), None); - assert_eq_const_safe!(Option<$T>: <$T>::checked_exact_div(0, 0), None); + assert_eq_const_safe!(Option<$T>: <$T>::checked_div_exact(1, 2), None); + assert_eq_const_safe!(Option<$T>: <$T>::div_exact(1, 2), None); + assert_eq_const_safe!(Option<$T>: <$T>::checked_div_exact(0, 0), None); } } }; diff --git a/library/coretests/tests/ptr.rs b/library/coretests/tests/ptr.rs index 4d5138d539b9..555a3b01f1fc 100644 --- a/library/coretests/tests/ptr.rs +++ b/library/coretests/tests/ptr.rs @@ -565,6 +565,7 @@ fn ptr_metadata() { #[test] fn ptr_metadata_bounds() { + #[allow(unknown_lints, function_casts_as_integer)] fn metadata_eq_method_address() -> usize { // The `Metadata` associated type has an `Ord` bound, so this is valid: <::Metadata as PartialEq>::eq as usize diff --git a/library/panic_unwind/src/seh.rs b/library/panic_unwind/src/seh.rs index a5d67dbb6a9f..257916c4d5cd 100644 --- a/library/panic_unwind/src/seh.rs +++ b/library/panic_unwind/src/seh.rs @@ -336,6 +336,7 @@ unsafe fn throw_exception(data: Option>) -> ! { // In any case, we basically need to do something like this until we can // express more operations in statics (and we may never be able to). unsafe { + #[allow(function_casts_as_integer)] atomic_store::<_, { AtomicOrdering::SeqCst }>( (&raw mut THROW_INFO.pmfnUnwind).cast(), ptr_t::new(exception_cleanup as *mut u8).raw(), @@ -352,6 +353,7 @@ unsafe fn throw_exception(data: Option>) -> ! { (&raw mut CATCHABLE_TYPE.pType).cast(), ptr_t::new((&raw mut TYPE_DESCRIPTOR).cast()).raw(), ); + #[allow(function_casts_as_integer)] atomic_store::<_, { AtomicOrdering::SeqCst }>( (&raw mut CATCHABLE_TYPE.copyFunction).cast(), ptr_t::new(exception_copy as *mut u8).raw(), diff --git a/library/portable-simd/crates/core_simd/src/masks/bitmask.rs b/library/portable-simd/crates/core_simd/src/masks/bitmask.rs index 8221d8f17e90..32d37b553392 100644 --- a/library/portable-simd/crates/core_simd/src/masks/bitmask.rs +++ b/library/portable-simd/crates/core_simd/src/masks/bitmask.rs @@ -170,7 +170,6 @@ where { type Output = Self; #[inline] - #[must_use = "method returns a new mask and does not mutate the original value"] fn bitand(mut self, rhs: Self) -> Self { for (l, r) in self.0.as_mut().iter_mut().zip(rhs.0.as_ref().iter()) { *l &= r; @@ -187,7 +186,6 @@ where { type Output = Self; #[inline] - #[must_use = "method returns a new mask and does not mutate the original value"] fn bitor(mut self, rhs: Self) -> Self { for (l, r) in self.0.as_mut().iter_mut().zip(rhs.0.as_ref().iter()) { *l |= r; @@ -203,7 +201,6 @@ where { type Output = Self; #[inline] - #[must_use = "method returns a new mask and does not mutate the original value"] fn bitxor(mut self, rhs: Self) -> Self::Output { for (l, r) in self.0.as_mut().iter_mut().zip(rhs.0.as_ref().iter()) { *l ^= r; @@ -219,7 +216,6 @@ where { type Output = Self; #[inline] - #[must_use = "method returns a new mask and does not mutate the original value"] fn not(mut self) -> Self::Output { for x in self.0.as_mut() { *x = !*x; diff --git a/library/std/src/backtrace.rs b/library/std/src/backtrace.rs index c3fcb0e2e42b..99724e29e02b 100644 --- a/library/std/src/backtrace.rs +++ b/library/std/src/backtrace.rs @@ -293,7 +293,7 @@ impl Backtrace { if !Backtrace::enabled() { return Backtrace { inner: Inner::Disabled }; } - Backtrace::create(Backtrace::capture as usize) + Backtrace::create(Backtrace::capture as fn() -> Backtrace as usize) } /// Forcibly captures a full backtrace, regardless of environment variable @@ -309,7 +309,7 @@ impl Backtrace { #[stable(feature = "backtrace", since = "1.65.0")] #[inline(never)] // want to make sure there's a frame here to remove pub fn force_capture() -> Backtrace { - Backtrace::create(Backtrace::force_capture as usize) + Backtrace::create(Backtrace::force_capture as fn() -> Backtrace as usize) } /// Forcibly captures a disabled backtrace, regardless of environment diff --git a/library/std/src/sys/pal/unix/stack_overflow.rs b/library/std/src/sys/pal/unix/stack_overflow.rs index 062f031189fc..226b6bce01b5 100644 --- a/library/std/src/sys/pal/unix/stack_overflow.rs +++ b/library/std/src/sys/pal/unix/stack_overflow.rs @@ -174,7 +174,9 @@ mod imp { } action.sa_flags = SA_SIGINFO | SA_ONSTACK; - action.sa_sigaction = signal_handler as sighandler_t; + action.sa_sigaction = signal_handler + as unsafe extern "C" fn(i32, *mut libc::siginfo_t, *mut libc::c_void) + as sighandler_t; // SAFETY: only overriding signals if the default is set unsafe { sigaction(signal, &action, ptr::null_mut()) }; } diff --git a/library/std/src/sys/pal/windows/compat.rs b/library/std/src/sys/pal/windows/compat.rs index 14f2c8d881cf..c465ceb2301c 100644 --- a/library/std/src/sys/pal/windows/compat.rs +++ b/library/std/src/sys/pal/windows/compat.rs @@ -155,7 +155,7 @@ macro_rules! compat_fn_with_fallback { /// When that is called it attempts to load the requested symbol. /// If it succeeds, `PTR` is set to the address of that symbol. /// If it fails, then `PTR` is set to `fallback`. - static PTR: Atomic<*mut c_void> = AtomicPtr::new(load as *mut _); + static PTR: Atomic<*mut c_void> = AtomicPtr::new(load as unsafe extern "system" fn($($argname: $argtype),*) -> $rettype as *mut _); unsafe extern "system" fn load($($argname: $argtype),*) -> $rettype { unsafe { @@ -171,7 +171,7 @@ macro_rules! compat_fn_with_fallback { PTR.store(f.as_ptr(), Ordering::Relaxed); mem::transmute(f) } else { - PTR.store(fallback as *mut _, Ordering::Relaxed); + PTR.store(fallback as unsafe extern "system" fn($($argname: $argtype),*) -> $rettype as *mut _, Ordering::Relaxed); fallback } } diff --git a/library/std/src/sys/sync/rwlock/mod.rs b/library/std/src/sys/sync/rwlock/mod.rs index ab5715bf2de3..8603fca2da5b 100644 --- a/library/std/src/sys/sync/rwlock/mod.rs +++ b/library/std/src/sys/sync/rwlock/mod.rs @@ -19,6 +19,7 @@ cfg_select! { all(target_os = "windows", target_vendor = "win7"), all(target_vendor = "fortanix", target_env = "sgx"), target_os = "xous", + target_os = "teeos", ) => { mod queue; pub use queue::RwLock; @@ -27,10 +28,6 @@ cfg_select! { mod solid; pub use solid::RwLock; } - target_os = "teeos" => { - mod teeos; - pub use teeos::RwLock; - } _ => { mod no_threads; pub use no_threads::RwLock; diff --git a/library/std/src/sys/sync/rwlock/teeos.rs b/library/std/src/sys/sync/rwlock/teeos.rs deleted file mode 100644 index 4a71a3abc272..000000000000 --- a/library/std/src/sys/sync/rwlock/teeos.rs +++ /dev/null @@ -1,50 +0,0 @@ -use crate::sys::sync::mutex::Mutex; - -/// we do not supported rwlock, so use mutex to simulate rwlock. -/// it's useful because so many code in std will use rwlock. -pub struct RwLock { - inner: Mutex, -} - -impl RwLock { - #[inline] - pub const fn new() -> RwLock { - RwLock { inner: Mutex::new() } - } - - #[inline] - pub fn read(&self) { - self.inner.lock() - } - - #[inline] - pub fn try_read(&self) -> bool { - self.inner.try_lock() - } - - #[inline] - pub fn write(&self) { - self.inner.lock() - } - - #[inline] - pub unsafe fn try_write(&self) -> bool { - self.inner.try_lock() - } - - #[inline] - pub unsafe fn read_unlock(&self) { - unsafe { self.inner.unlock() }; - } - - #[inline] - pub unsafe fn write_unlock(&self) { - unsafe { self.inner.unlock() }; - } - - #[inline] - pub unsafe fn downgrade(&self) { - // Since there is no difference between read-locked and write-locked on this platform, this - // function is simply a no-op as only 1 reader can read: the original writer. - } -} diff --git a/library/std/src/sys/sync/thread_parking/mod.rs b/library/std/src/sys/sync/thread_parking/mod.rs index e8a9dc884f81..74b5b72b19a7 100644 --- a/library/std/src/sys/sync/thread_parking/mod.rs +++ b/library/std/src/sys/sync/thread_parking/mod.rs @@ -35,7 +35,10 @@ cfg_select! { mod xous; pub use xous::Parker; } - target_family = "unix" => { + any( + target_family = "unix", + target_os = "teeos", + ) => { mod pthread; pub use pthread::Parker; } diff --git a/src/bootstrap/README.md b/src/bootstrap/README.md index 12e09cb07dbb..dcf2221b8bfc 100644 --- a/src/bootstrap/README.md +++ b/src/bootstrap/README.md @@ -28,14 +28,14 @@ compiler. What actually happens when you invoke bootstrap is: `x.py` cross-platform) is run. This script is responsible for downloading the stage0 compiler/Cargo binaries, and it then compiles the build system itself (this folder). Finally, it then invokes the actual `bootstrap` binary build system. -2. In Rust, `bootstrap` will slurp up all configuration, perform a number of - sanity checks (whether compilers exist, for example), and then start building the - stage0 artifacts. -3. The stage0 `cargo`, downloaded earlier, is used to build the standard library - and the compiler, and then these binaries are then copied to the `stage1` - directory. That compiler is then used to generate the stage1 artifacts which - are then copied to the stage2 directory, and then finally, the stage2 - artifacts are generated using that compiler. +2. In Rust, the bootstrap binary reads all configuration, performs a number of sanity + checks (for example, verifying toolchains and paths), and then prepares to build the + stage 1 compiler and libraries using the prebuilt stage 0 compiler. +3. The stage 0 compiler and standard library, downloaded earlier, are used to build the + stage 1 compiler, which links against the stage 0 standard library. The newly built stage 1 + compiler is then used to build the stage 1 standard library. After that, the stage 1 + compiler is used once more to produce the stage 2 compiler, which links against the + stage 1 standard library. The goal of each stage is to (a) leverage Cargo as much as possible and failing that (b) leverage Rust as much as possible! @@ -167,7 +167,6 @@ build/ # no extra build output in these directories. stage1/ stage2/ - stage3/ ``` ## Extending bootstrap @@ -177,8 +176,9 @@ When you use bootstrap, you'll call it through the entry point script `bootstrap` has a difficult problem: it is written in Rust, but yet it is run before the Rust compiler is built! To work around this, there are two components of bootstrap: the main one written in rust, and `bootstrap.py`. `bootstrap.py` -is what gets run by entry point script. It takes care of downloading the `stage0` -compiler, which will then build the bootstrap binary written in Rust. +is what gets run by entry point script. It takes care of downloading the prebuilt +stage 0 compiler, std and Cargo binaries, which are then used to build the +bootstrap binary. Because there are two separate codebases behind `x.py`, they need to be kept in sync. In particular, both `bootstrap.py` and the bootstrap binary diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index b66f965cd555..be05b92a0973 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -2075,7 +2075,9 @@ Please disable assertions with `rust.debug-assertions = false`. cmd.arg("--target-rustcflags").arg(flag); } - cmd.arg("--python").arg(builder.python()); + cmd.arg("--python").arg( + builder.config.python.as_ref().expect("python is required for running rustdoc tests"), + ); // FIXME(#148099): Currently we set these Android-related flags in all // modes, even though they should only be needed in "debuginfo" mode, @@ -2094,11 +2096,11 @@ Please disable assertions with `rust.debug-assertions = false`. cmd.arg("--gdb").arg(gdb); } - if let Some(debuggers::Lldb { lldb_version, lldb_python_dir }) = + if let Some(debuggers::Lldb { lldb_exe, lldb_version }) = debuggers::discover_lldb(builder) { + cmd.arg("--lldb").arg(lldb_exe); cmd.arg("--lldb-version").arg(lldb_version); - cmd.arg("--lldb-python-dir").arg(lldb_python_dir); } } @@ -3359,7 +3361,9 @@ impl Step for BootstrapPy { } fn run(self, builder: &Builder<'_>) -> Self::Output { - let mut check_bootstrap = command(builder.python()); + let mut check_bootstrap = command( + builder.config.python.as_ref().expect("python is required for running bootstrap tests"), + ); check_bootstrap .args(["-m", "unittest", "bootstrap_test.py"]) // Forward command-line args after `--` to unittest, for filtering etc. diff --git a/src/bootstrap/src/core/debuggers/lldb.rs b/src/bootstrap/src/core/debuggers/lldb.rs index 66ab45573d6b..55c9818eb315 100644 --- a/src/bootstrap/src/core/debuggers/lldb.rs +++ b/src/bootstrap/src/core/debuggers/lldb.rs @@ -4,8 +4,8 @@ use crate::core::builder::Builder; use crate::utils::exec::command; pub(crate) struct Lldb { + pub(crate) lldb_exe: PathBuf, pub(crate) lldb_version: String, - pub(crate) lldb_python_dir: String, } pub(crate) fn discover_lldb(builder: &Builder<'_>) -> Option { @@ -21,12 +21,5 @@ pub(crate) fn discover_lldb(builder: &Builder<'_>) -> Option { .stdout_if_ok() .and_then(|v| if v.trim().is_empty() { None } else { Some(v) })?; - let lldb_python_dir = command(&lldb_exe) - .allow_failure() - .arg("-P") - .run_capture_stdout(builder) - .stdout_if_ok() - .map(|p| p.lines().next().expect("lldb Python dir not found").to_string())?; - - Some(Lldb { lldb_version, lldb_python_dir }) + Some(Lldb { lldb_exe, lldb_version }) } diff --git a/src/bootstrap/src/core/sanity.rs b/src/bootstrap/src/core/sanity.rs index ed63b2aae452..e5afb31213ce 100644 --- a/src/bootstrap/src/core/sanity.rs +++ b/src/bootstrap/src/core/sanity.rs @@ -1,9 +1,10 @@ -//! Sanity checking performed by bootstrap before actually executing anything. +//! Sanity checking and tool selection performed by bootstrap. //! -//! This module contains the implementation of ensuring that the build -//! environment looks reasonable before progressing. This will verify that -//! various programs like git and python exist, along with ensuring that all C -//! compilers for cross-compiling are found. +//! This module ensures that the build environment is correctly set up before +//! executing any build tasks. It verifies required programs exist (like git and +//! cmake when needed), selects some tools based on the environment (like the +//! Python interpreter), and validates that C compilers for cross-compiling are +//! available. //! //! In theory if we get past this phase it's a bug if a build fails, but in //! practice that's likely not true! diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index d646e3badb41..093db739e6cb 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -1522,21 +1522,6 @@ impl Build { self.config.target_config.get(&target).and_then(|t| t.qemu_rootfs.as_ref()).map(|p| &**p) } - /// Path to the python interpreter to use - fn python(&self) -> &Path { - if self.config.host_target.ends_with("apple-darwin") { - // Force /usr/bin/python3 on macOS for LLDB tests because we're loading the - // LLDB plugin's compiled module which only works with the system python - // (namely not Homebrew-installed python) - Path::new("/usr/bin/python3") - } else { - self.config - .python - .as_ref() - .expect("python is required for running LLDB or rustdoc tests") - } - } - /// Temporary directory that extended error information is emitted to. fn extended_error_dir(&self) -> PathBuf { self.out.join("tmp/extended-error-metadata") diff --git a/src/bootstrap/src/utils/change_tracker.rs b/src/bootstrap/src/utils/change_tracker.rs index 921f57eb66d6..59140b9ce84c 100644 --- a/src/bootstrap/src/utils/change_tracker.rs +++ b/src/bootstrap/src/utils/change_tracker.rs @@ -576,4 +576,9 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[ severity: ChangeSeverity::Info, summary: "`llvm.enzyme` now works with `download-ci-llvm=true`.", }, + ChangeInfo { + change_id: 148636, + severity: ChangeSeverity::Info, + summary: "The `build.python` option is now respected on macOS (previously ignored and forced to be /usr/bin/python3).", + }, ]; diff --git a/src/build_helper/src/git.rs b/src/build_helper/src/git.rs index cbefb836c004..42d9b00f004a 100644 --- a/src/build_helper/src/git.rs +++ b/src/build_helper/src/git.rs @@ -143,14 +143,13 @@ pub fn check_path_modifications( /// Returns true if any of the passed `paths` have changed since the `base` commit. pub fn has_changed_since(git_dir: &Path, base: &str, paths: &[&str]) -> bool { - let mut git = Command::new("git"); - git.current_dir(git_dir); + run_git_diff_index(Some(git_dir), |cmd| { + cmd.args(["--quiet", base, "--"]).args(paths); - git.args(["diff-index", "--quiet", base, "--"]).args(paths); - - // Exit code 0 => no changes - // Exit code 1 => some changes were detected - !git.status().expect("cannot run git diff-index").success() + // Exit code 0 => no changes + // Exit code 1 => some changes were detected + !cmd.status().expect("cannot run git diff-index").success() + }) } /// Returns the latest upstream commit that modified `target_paths`, or `None` if no such commit @@ -267,31 +266,49 @@ pub fn get_git_modified_files( return Err("No upstream commit was found".to_string()); }; - let mut git = Command::new("git"); - if let Some(git_dir) = git_dir { - git.current_dir(git_dir); - } - let files = output_result(git.args(["diff-index", "--name-status", merge_base.trim()]))? - .lines() - .filter_map(|f| { - let (status, name) = f.trim().split_once(char::is_whitespace).unwrap(); - if status == "D" { - None - } else if Path::new(name).extension().map_or(extensions.is_empty(), |ext| { - // If there is no extension, we allow the path if `extensions` is empty - // If there is an extension, we allow it if `extension` is empty or it contains the - // extension. - extensions.is_empty() || extensions.contains(&ext.to_str().unwrap()) - }) { - Some(name.to_owned()) - } else { - None - } - }) - .collect(); + let files = run_git_diff_index(git_dir, |cmd| { + output_result(cmd.args(["--name-status", merge_base.trim()])) + })? + .lines() + .filter_map(|f| { + let (status, name) = f.trim().split_once(char::is_whitespace).unwrap(); + if status == "D" { + None + } else if Path::new(name).extension().map_or(extensions.is_empty(), |ext| { + // If there is no extension, we allow the path if `extensions` is empty + // If there is an extension, we allow it if `extension` is empty or it contains the + // extension. + extensions.is_empty() || extensions.contains(&ext.to_str().unwrap()) + }) { + Some(name.to_owned()) + } else { + None + } + }) + .collect(); Ok(files) } +/// diff-index can return outdated information, because it does not update the git index. +/// This function uses `update-index` to update the index first, and then provides `func` with a +/// command prepared to run `git diff-index`. +fn run_git_diff_index(git_dir: Option<&Path>, func: F) -> T +where + F: FnOnce(&mut Command) -> T, +{ + let git = || { + let mut git = Command::new("git"); + if let Some(git_dir) = git_dir { + git.current_dir(git_dir); + } + git + }; + + // We ignore the exit code, as it errors out when some files are modified. + let _ = output_result(git().args(["update-index", "--refresh", "-q"])); + func(git().arg("diff-index")) +} + /// Returns the files that haven't been added to git yet. pub fn get_git_untracked_files(git_dir: Option<&Path>) -> Result>, String> { let mut git = Command::new("git"); diff --git a/src/ci/citool/src/jobs.rs b/src/ci/citool/src/jobs.rs index 47516cbc1f4c..245ab31fa644 100644 --- a/src/ci/citool/src/jobs.rs +++ b/src/ci/citool/src/jobs.rs @@ -123,7 +123,7 @@ pub fn load_job_db(db: &str) -> anyhow::Result { /// modulo certain carve-outs" in [`validate_job_database`]. /// /// This invariant is important to make sure that it's not easily possible (without modifying -/// `citool`) to have PRs with red PR-only CI jobs merged into `master`, causing all subsequent PR +/// `citool`) to have PRs with red PR-only CI jobs merged into `main`, causing all subsequent PR /// CI runs to be red until the cause is fixed. fn register_pr_jobs_as_auto_jobs(db: &mut JobDatabase) -> anyhow::Result<()> { for pr_job in &db.pr_jobs { @@ -273,7 +273,7 @@ pub enum RunType { /// Merge attempt workflow AutoJob, /// Fake job only used for sharing Github Actions cache. - MasterJob, + MainJob, } /// Maximum number of custom try jobs that can be requested in a single @@ -323,7 +323,7 @@ fn calculate_jobs( (jobs, "try", &db.envs.try_env) } RunType::AutoJob => (db.auto_jobs.clone(), "auto", &db.envs.auto_env), - RunType::MasterJob => return Ok(vec![]), + RunType::MainJob => return Ok(vec![]), }; let jobs = substitute_github_vars(jobs.clone()) .context("Failed to substitute GitHub context variables in jobs")?; @@ -376,7 +376,7 @@ pub fn calculate_job_matrix( eprintln!("Run type: {run_type:?}"); let jobs = calculate_jobs(&run_type, &db, channel)?; - if jobs.is_empty() && !matches!(run_type, RunType::MasterJob) { + if jobs.is_empty() && !matches!(run_type, RunType::MainJob) { return Err(anyhow::anyhow!("Computed job list is empty")); } @@ -384,7 +384,7 @@ pub fn calculate_job_matrix( RunType::PullRequest => "pr", RunType::TryJob { .. } => "try", RunType::AutoJob => "auto", - RunType::MasterJob => "master", + RunType::MainJob => "main", }; eprintln!("Output"); diff --git a/src/ci/citool/src/main.rs b/src/ci/citool/src/main.rs index 255d39846da1..4fe9cee900ca 100644 --- a/src/ci/citool/src/main.rs +++ b/src/ci/citool/src/main.rs @@ -47,7 +47,7 @@ impl GitHubContext { Some(RunType::TryJob { job_patterns: patterns }) } ("push", "refs/heads/auto") => Some(RunType::AutoJob), - ("push", "refs/heads/master") => Some(RunType::MasterJob), + ("push", "refs/heads/main") => Some(RunType::MainJob), _ => None, } } diff --git a/src/ci/citool/tests/jobs.rs b/src/ci/citool/tests/jobs.rs index 24e0b85cab22..5231d4616e04 100644 --- a/src/ci/citool/tests/jobs.rs +++ b/src/ci/citool/tests/jobs.rs @@ -46,11 +46,11 @@ fn pr_jobs() { } #[test] -fn master_jobs() { - let stdout = get_matrix("push", "commit", "refs/heads/master"); +fn main_jobs() { + let stdout = get_matrix("push", "commit", "refs/heads/main"); insta::assert_snapshot!(stdout, @r#" jobs=[] - run_type=master + run_type=main "#); } diff --git a/src/ci/scripts/verify-channel.sh b/src/ci/scripts/verify-channel.sh index edeea20144be..9a9e713243d7 100755 --- a/src/ci/scripts/verify-channel.sh +++ b/src/ci/scripts/verify-channel.sh @@ -1,7 +1,7 @@ #!/bin/bash # We want to make sure all PRs are targeting the right branch when they're # opened, otherwise we risk (for example) to land a beta-specific change to the -# master branch. This script ensures the branch of the PR matches the channel. +# default branch. This script ensures the branch of the PR matches the channel. set -euo pipefail IFS=$'\n\t' @@ -16,7 +16,7 @@ fi channel=$(cat "$(ciCheckoutPath)/src/ci/channel") case "${channel}" in nightly) - channel_branch="master" + channel_branch="main" ;; beta) channel_branch="beta" diff --git a/src/doc/rustc-dev-guide/ci/sembr/src/main.rs b/src/doc/rustc-dev-guide/ci/sembr/src/main.rs index c056f68c31d7..b50190c78b7b 100644 --- a/src/doc/rustc-dev-guide/ci/sembr/src/main.rs +++ b/src/doc/rustc-dev-guide/ci/sembr/src/main.rs @@ -27,7 +27,8 @@ static REGEX_IGNORE: LazyLock = static REGEX_IGNORE_END: LazyLock = LazyLock::new(|| Regex::new(r"(\.|\?|;|!)$").unwrap()); static REGEX_IGNORE_LINK_TARGETS: LazyLock = LazyLock::new(|| Regex::new(r"^\[.+\]: ").unwrap()); -static REGEX_SPLIT: LazyLock = LazyLock::new(|| Regex::new(r"(\.|[^r]\?|;|!)\s+").unwrap()); +static REGEX_SPLIT: LazyLock = + LazyLock::new(|| Regex::new(r"([^\.]\.|[^r]\?|;|!)\s+").unwrap()); fn main() -> Result<()> { let cli = Cli::parse(); @@ -136,6 +137,7 @@ fn lengthen_lines(content: &str, limit: usize) -> String { let mut new_content = content.clone(); let mut new_n = 0; let mut in_code_block = false; + let mut in_html_div = false; let mut skip_next = false; for (n, line) in content.iter().enumerate() { if skip_next { @@ -149,6 +151,17 @@ fn lengthen_lines(content: &str, limit: usize) -> String { in_code_block = !in_code_block; continue; } + if line.trim_start().starts_with(" String { .. }; let s = c().await; // ^^^ If we can't project `<{c} as AsyncFn>::call()` to a coroutine, then the `IntoFuture::into_future` call inside of the `.await` stalls, and the type of `s` is left unconstrained as an infer var. diff --git a/src/doc/rustc-dev-guide/src/getting-started.md b/src/doc/rustc-dev-guide/src/getting-started.md index 857e8ff51b03..64abd94c69e2 100644 --- a/src/doc/rustc-dev-guide/src/getting-started.md +++ b/src/doc/rustc-dev-guide/src/getting-started.md @@ -1,14 +1,15 @@ # Getting Started -Thank you for your interest in contributing to Rust! There are many ways to -contribute, and we appreciate all of them. +Thank you for your interest in contributing to Rust! +There are many ways to contribute, and we appreciate all of them. If this is your first time contributing, the [walkthrough] chapter can give you a good example of how a typical contribution would go. -This documentation is _not_ intended to be comprehensive; it is meant to be a -quick guide for the most useful things. For more information, [see this -chapter on how to build and run the compiler](./building/how-to-build-and-run.md). +This documentation is _not_ intended to be comprehensive; +it is meant to be a quick guide for the most useful things. +For more information, +see [How to build and run the compiler](building/how-to-build-and-run.md). [internals]: https://internals.rust-lang.org [rust-zulip]: https://rust-lang.zulipchat.com @@ -36,26 +37,30 @@ questions about how the compiler works can go in [#t-compiler/help][z-help]. [z-help]: https://rust-lang.zulipchat.com/#narrow/channel/182449-t-compiler.2Fhelp **Please ask questions!** A lot of people report feeling that they are "wasting -expert's time", but nobody on `t-compiler` feels this way. Contributors are -important to us. +expert's time", but nobody on `t-compiler` feels this way. +Contributors are important to us. Also, if you feel comfortable, prefer public topics, as this means others can -see the questions and answers, and perhaps even integrate them back into this -guide :) +see the questions and answers, and perhaps even integrate them back into this guide :) -**Tip**: If you're not a native English speaker and feel unsure about writing, try using a translator to help. But avoid using LLM tools that generate long, complex words. In daily teamwork, **simple and clear words** are best for easy understanding. Even small typos or grammar mistakes can make you seem more human, and people connect better with humans. +**Tip**: If you're not a native English speaker and feel unsure about writing, try using a translator to help. +But avoid using LLM tools that generate long, complex words. +In daily teamwork, **simple and clear words** are best for easy understanding. +Even small typos or grammar mistakes can make you seem more human, and people connect better with humans. ### Experts -Not all `t-compiler` members are experts on all parts of `rustc`; it's a -pretty large project. To find out who could have some expertise on +Not all `t-compiler` members are experts on all parts of `rustc`; +it's a pretty large project. +To find out who could have some expertise on different parts of the compiler, [consult triagebot assign groups][map]. -The sections that start with `[assign*` in `triagebot.toml` file. +The sections that start with `[assign*` in `triagebot.toml` file. But also, feel free to ask questions even if you can't figure out who to ping. Another way to find experts for a given part of the compiler is to see who has made recent commits. For example, to find people who have recently worked on name resolution since the 1.68.2 release, -you could run `git shortlog -n 1.68.2.. compiler/rustc_resolve/`. Ignore any commits starting with +you could run `git shortlog -n 1.68.2.. compiler/rustc_resolve/`. +Ignore any commits starting with "Rollup merge" or commits by `@bors` (see [CI contribution procedures](./contributing.md#ci) for more information about these commits). @@ -64,8 +69,7 @@ more information about these commits). ### Etiquette We do ask that you be mindful to include as much useful information as you can -in your question, but we recognize this can be hard if you are unfamiliar with -contributing to Rust. +in your question, but we recognize this can be hard if you are unfamiliar with contributing to Rust. Just pinging someone without providing any context can be a bit annoying and just create noise, so we ask that you be mindful of the fact that the @@ -74,13 +78,16 @@ just create noise, so we ask that you be mindful of the fact that the ## What should I work on? The Rust project is quite large and it can be difficult to know which parts of the project need -help, or are a good starting place for beginners. Here are some suggested starting places. +help, or are a good starting place for beginners. +Here are some suggested starting places. ### Easy or mentored issues If you're looking for somewhere to start, check out the following [issue -search][help-wanted-search]. See the [Triage] for an explanation of these labels. You can also try -filtering the search to areas you're interested in. For example: +search][help-wanted-search]. +See the [Triage] for an explanation of these labels. +You can also try filtering the search to areas you're interested in. +For example: - `repo:rust-lang/rust-clippy` will only show clippy issues - `label:T-compiler` will only show issues related to the compiler @@ -94,8 +101,9 @@ See below for how to find work that isn't labelled. ### Recurring work -Some work is too large to be done by a single person. In this case, it's common to have "Tracking -issues" to co-ordinate the work between contributors. Here are some example tracking issues where +Some work is too large to be done by a single person. +In this case, it's common to have "Tracking issues" to co-ordinate the work between contributors. +Here are some example tracking issues where it's easy to pick up work without a large time commitment: - *Add recurring work items here.* @@ -105,8 +113,8 @@ If you find more recurring work, please feel free to add it here! ### Clippy issues The [Clippy] project has spent a long time making its contribution process as friendly to newcomers -as possible. Consider working on it first to get familiar with the process and the compiler -internals. +as possible. +Consider working on it first to get familiar with the process and the compiler internals. See [the Clippy contribution guide][clippy-contributing] for instructions on getting started. @@ -116,19 +124,22 @@ See [the Clippy contribution guide][clippy-contributing] for instructions on get ### Diagnostic issues Many diagnostic issues are self-contained and don't need detailed background knowledge of the -compiler. You can see a list of diagnostic issues [here][diagnostic-issues]. +compiler. +You can see a list of diagnostic issues [here][diagnostic-issues]. [diagnostic-issues]: https://github.com/rust-lang/rust/issues?q=is%3Aissue+is%3Aopen+label%3AA-diagnostics+no%3Aassignee ### Picking up abandoned pull requests Sometimes, contributors send a pull request, but later find out that they don't have enough -time to work on it, or they simply are not interested in it anymore. Such PRs are often -eventually closed and they receive the `S-inactive` label. You could try to examine some of -these PRs and pick up the work. You can find the list of such PRs [here][abandoned-prs]. +time to work on it, or they simply are not interested in it anymore. +Such PRs are often eventually closed and they receive the `S-inactive` label. +You could try to examine some of these PRs and pick up the work. +You can find the list of such PRs [here][abandoned-prs]. If the PR has been implemented in some other way in the meantime, the `S-inactive` label -should be removed from it. If not, and it seems that there is still interest in the change, +should be removed from it. +If not, and it seems that there is still interest in the change, you can try to rebase the pull request on top of the latest `master` branch and send a new pull request, continuing the work on the feature. @@ -136,7 +147,10 @@ pull request, continuing the work on the feature. ### Writing tests -Issues that have been resolved but do not have a regression test are marked with the `E-needs-test` label. Writing unit tests is a low-risk, lower-priority task that offers new contributors a great opportunity to familiarize themselves with the testing infrastructure and contribution workflow. +Issues that have been resolved but do not have a regression test are marked with the `E-needs-test` label. +Writing unit tests is a low-risk, +lower-priority task that offers new contributors a great opportunity to familiarize themselves +with the testing infrastructure and contribution workflow. ### Contributing to std (standard library) @@ -147,28 +161,28 @@ See [std-dev-guide](https://std-dev-guide.rust-lang.org/). There are a bunch of other projects that you can contribute to outside of the `rust-lang/rust` repo, including `cargo`, `miri`, `rustup`, and many others. -These repos might have their own contributing guidelines and procedures. Many -of them are owned by working groups. For more info, see the documentation in those repos' READMEs. +These repos might have their own contributing guidelines and procedures. +Many of them are owned by working groups. +For more info, see the documentation in those repos' READMEs. ### Other ways to contribute There are a bunch of other ways you can contribute, especially if you don't feel comfortable jumping straight into the large `rust-lang/rust` codebase. -The following tasks are doable without much background knowledge but are -incredibly helpful: +The following tasks are doable without much background knowledge but are incredibly helpful: - [Writing documentation][wd]: if you are feeling a bit more intrepid, you could try - to read a part of the code and write doc comments for it. This will help you - to learn some part of the compiler while also producing a useful artifact! + to read a part of the code and write doc comments for it. + This will help you to learn some part of the compiler while also producing a useful artifact! - [Triaging issues][triage]: categorizing, replicating, and minimizing issues is very helpful to the Rust maintainers. - [Working groups][wg]: there are a bunch of working groups on a wide variety of rust-related things. - Answer questions on [users.rust-lang.org][users], or on [Stack Overflow][so]. - Participate in the [RFC process](https://github.com/rust-lang/rfcs). - Find a [requested community library][community-library], build it, and publish - it to [Crates.io](http://crates.io). Easier said than done, but very, very - valuable! + it to [Crates.io](http://crates.io). + Easier said than done, but very, very valuable! [users]: https://users.rust-lang.org/ [so]: http://stackoverflow.com/questions/tagged/rust diff --git a/src/doc/rustc-dev-guide/src/offload/usage.md b/src/doc/rustc-dev-guide/src/offload/usage.md index 7d1a5c9e2e0e..9d5839334b1a 100644 --- a/src/doc/rustc-dev-guide/src/offload/usage.md +++ b/src/doc/rustc-dev-guide/src/offload/usage.md @@ -79,7 +79,7 @@ Now we generate the device code. Replace the target-cpu with the right code for RUSTFLAGS="-Ctarget-cpu=gfx90a --emit=llvm-bc,llvm-ir" cargo +offload build -Zunstable-options -r -v --target amdgcn-amd-amdhsa -Zbuild-std=core ``` -Now find the .ll under target/amdgcn-amd-amdhsa folder and copy it to a device.ll file (or adjust the file names below). +Now find the `.ll` under target/amdgcn-amd-amdhsa folder and copy it to a device.ll file (or adjust the file names below). If you work on an NVIDIA or Intel gpu, please adjust the names acordingly and open an issue to share your results (either if you succeed or fail). First we compile our .ll files (good for manual inspections) to .bc files and clean up leftover artifacts. The cleanup is important, otherwise caching might interfere on following runs. ``` diff --git a/src/doc/rustc-dev-guide/src/rustdoc-internals.md b/src/doc/rustc-dev-guide/src/rustdoc-internals.md index 55b08e8893c0..989a77290b6b 100644 --- a/src/doc/rustc-dev-guide/src/rustdoc-internals.md +++ b/src/doc/rustc-dev-guide/src/rustdoc-internals.md @@ -1,22 +1,23 @@ -# Rustdoc Internals +# Rustdoc internals -This page describes [`rustdoc`]'s passes and modes. For an overview of `rustdoc`, -see the ["Rustdoc overview" chapter](./rustdoc.md). +This page describes [`rustdoc`]'s passes and modes. +For an overview of `rustdoc`, see the ["Rustdoc overview" chapter](./rustdoc.md). [`rustdoc`]: https://github.com/rust-lang/rust/tree/HEAD/src/tools/rustdoc -## From Crate to Clean +## From crate to clean In [`core.rs`] are two central items: the [`rustdoc::core::DocContext`] -`struct`, and the [`rustdoc::core::run_global_ctxt`] function. The latter is -where `rustdoc` calls out to `rustc` to compile a crate to the point where -`rustdoc` can take over. The former is a state container used when crawling -through a crate to gather its documentation. +`struct`, and the [`rustdoc::core::run_global_ctxt`] function. +The latter is where `rustdoc` calls out to `rustc` to compile a crate to the point where +`rustdoc` can take over. +The former is a state container used when crawling through a crate to gather its documentation. The main process of crate crawling is done in [`clean/mod.rs`] through several -functions with names that start with `clean_`. Each function accepts an `hir` -or `ty` data structure, and outputs a `clean` structure used by `rustdoc`. For -example, [this function for converting lifetimes]: +functions with names that start with `clean_`. +Each function accepts an `hir` +or `ty` data structure, and outputs a `clean` structure used by `rustdoc`. +For example, [this function for converting lifetimes]: ```rust,ignore fn clean_lifetime<'tcx>(lifetime: &hir::Lifetime, cx: &mut DocContext<'tcx>) -> Lifetime { @@ -34,17 +35,19 @@ fn clean_lifetime<'tcx>(lifetime: &hir::Lifetime, cx: &mut DocContext<'tcx>) -> ``` Also, `clean/mod.rs` defines the types for the "cleaned" [Abstract Syntax Tree -(`AST`)][ast] used later to render documentation pages. Each usually accompanies a +(`AST`)][ast] used later to render documentation pages. +Each usually accompanies a `clean_*` function that takes some [`AST`][ast] or [High-Level Intermediate -Representation (`HIR`)][hir] type from `rustc` and converts it into the -appropriate "cleaned" type. "Big" items like modules or associated items may +Representation (`HIR`)][hir] type from `rustc` and converts it into the appropriate "cleaned" type. +"Big" items like modules or associated items may have some extra processing in its `clean` function, but for the most part these -`impl`s are straightforward conversions. The "entry point" to this module is +`impl`s are straightforward conversions. +The "entry point" to this module is [`clean::utils::krate`][ck0], which is called by [`run_global_ctxt`]. The first step in [`clean::utils::krate`][ck1] is to invoke -[`visit_ast::RustdocVisitor`] to process the module tree into an intermediate -[`visit_ast::Module`]. This is the step that actually crawls the +[`visit_ast::RustdocVisitor`] to process the module tree into an intermediate [`visit_ast::Module`]. +This is the step that actually crawls the [`rustc_hir::Crate`], normalizing various aspects of name resolution, such as: * handling `#[doc(inline)]` and `#[doc(no_inline)]` @@ -57,14 +60,14 @@ The first step in [`clean::utils::krate`][ck1] is to invoke they're defined as a reexport or not After this step, `clean::krate` invokes [`clean_doc_module`], which actually -converts the `HIR` items to the cleaned [`AST`][ast]. This is also the step where cross- -crate inlining is performed, which requires converting `rustc_middle` data -structures into the cleaned [`AST`][ast]. +converts the `HIR` items to the cleaned [`AST`][ast]. +This is also the step where cross-crate inlining is performed, +which requires converting `rustc_middle` data structures into the cleaned [`AST`][ast]. The other major thing that happens in `clean/mod.rs` is the collection of doc comments and `#[doc=""]` attributes into a separate field of the [`Attributes`] -`struct`, present on anything that gets hand-written documentation. This makes it -easier to collect this documentation later in the process. +`struct`, present on anything that gets hand-written documentation. +This makes it easier to collect this documentation later in the process. The primary output of this process is a [`clean::types::Crate`] with a tree of [`Item`]s which describe the publicly-documentable items in the target crate. @@ -90,13 +93,14 @@ which describe the publicly-documentable items in the target crate. ### Passes Anything But a Gas Station (or: [Hot Potato](https://www.youtube.com/watch?v=WNFBIt5HxdY)) Before moving on to the next major step, a few important "passes" occur over -the cleaned [`AST`][ast]. Several of these passes are `lint`s and reports, but some of -them mutate or generate new items. +the cleaned [`AST`][ast]. +Several of these passes are `lint`s and reports, but some of them mutate or generate new items. These are all implemented in the [`librustdoc/passes`] directory, one file per pass. By default, all of these passes are run on a crate, but the ones regarding dropping private/hidden items can be bypassed by passing -`--document-private-items` to `rustdoc`. Note that unlike the previous set of [`AST`][ast] +`--document-private-items` to `rustdoc`. +Note that, unlike the previous set of [`AST`][ast] transformations, the passes are run on the _cleaned_ crate. Here is the list of passes as of March 2023: @@ -105,8 +109,7 @@ Here is the list of passes as of March 2023: flag. - `check-doc-test-visibility` runs `doctest` visibility–related `lint`s. This pass - runs before `strip-private`, which is why it needs to be separate from - `run-lints`. + runs before `strip-private`, which is why it needs to be separate from `run-lints`. - `collect-intra-doc-links` resolves [intra-doc links](https://doc.rust-lang.org/nightly/rustdoc/write-documentation/linking-to-items-by-name.html). @@ -121,8 +124,8 @@ Here is the list of passes as of March 2023: - `bare_urls` detects links that are not linkified, e.g., in Markdown such as `Go to https://example.com/.` It suggests wrapping the link with angle brackets: - `Go to .` to linkify it. This is the code behind the `rustdoc::bare_urls` `lint`. + `Go to .` to linkify it. + This is the code behind the `rustdoc::bare_urls` `lint`. - `check_code_block_syntax` validates syntax inside Rust code blocks (```rust) @@ -131,33 +134,37 @@ Here is the list of passes as of March 2023: in doc comments. - `strip-hidden` and `strip-private` strip all `doc(hidden)` and private items - from the output. `strip-private` implies `strip-priv-imports`. Basically, the - goal is to remove items that are not relevant for public documentation. This - pass is skipped when `--document-hidden-items` is passed. + from the output. + `strip-private` implies `strip-priv-imports`. + Basically, the goal is to remove items that are not relevant for public documentation. + This pass is skipped when `--document-hidden-items` is passed. - `strip-priv-imports` strips all private import statements (`use`, `extern - crate`) from a crate. This is necessary because `rustdoc` will handle *public* + crate`) from a crate. + This is necessary because `rustdoc` will handle *public* imports by either inlining the item's documentation to the module or creating - a "Reexports" section with the import in it. The pass ensures that all of - these imports are actually relevant to documentation. It is technically - only run when `--document-private-items` is passed, but `strip-private` + a "Reexports" section with the import in it. + The pass ensures that all of these imports are actually relevant to documentation. + It is technically only run when `--document-private-items` is passed, but `strip-private` accomplishes the same thing. - `strip-private` strips all private items from a crate which cannot be seen - externally. This pass is skipped when `--document-private-items` is passed. + externally. + This pass is skipped when `--document-private-items` is passed. There is also a [`stripper`] module in `librustdoc/passes`, but it is a -collection of utility functions for the `strip-*` passes and is not a pass -itself. +collection of utility functions for the `strip-*` passes and is not a pass itself. [`librustdoc/passes`]: https://github.com/rust-lang/rust/tree/HEAD/src/librustdoc/passes [`stripper`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustdoc/passes/stripper/index.html -## From Clean To HTML +## From clean to HTML -This is where the "second phase" in `rustdoc` begins. This phase primarily lives +This is where the "second phase" in `rustdoc` begins. +This phase primarily lives in the [`librustdoc/formats`] and [`librustdoc/html`] folders, and it all starts with -[`formats::renderer::run_format`]. This code is responsible for setting up a type that +[`formats::renderer::run_format`]. +This code is responsible for setting up a type that `impl FormatRenderer`, which for `HTML` is [`Context`]. This structure contains methods that get called by `run_format` to drive the @@ -168,8 +175,8 @@ doc rendering, which includes: * `after_krate` generates other global resources like `all.html` In `item`, the "page rendering" occurs, via a mixture of [Askama] templates -and manual `write!()` calls, starting in [`html/layout.rs`]. The parts that have -not been converted to templates occur within a series of `std::fmt::Display` +and manual `write!()` calls, starting in [`html/layout.rs`]. +The parts that have not been converted to templates occur within a series of `std::fmt::Display` implementations and functions that pass around a `&mut std::fmt::Formatter`. The parts that actually generate `HTML` from the items and documentation start @@ -183,11 +190,13 @@ pieces like "how should I print a where clause as part of some other item". Whenever `rustdoc` comes across an item that should print hand-written documentation alongside, it calls out to [`html/markdown.rs`] which interfaces -with the Markdown parser. This is exposed as a series of types that wrap a -string of Markdown, and implement `fmt::Display` to emit `HTML` text. It takes -special care to enable certain features like footnotes and tables and add +with the Markdown parser. +This is exposed as a series of types that wrap a +string of Markdown, and implement `fmt::Display` to emit `HTML` text. +It takes special care to enable certain features like footnotes and tables and add syntax highlighting to Rust code blocks (via `html/highlight.rs`) before -running the Markdown parser. There's also a function [`find_codes`] which is +running the Markdown parser. +There's also a function [`find_codes`] which is called by `find_testable_codes` that specifically scans for Rust code blocks so the test-runner code can find all the `doctest`s in the crate. @@ -208,11 +217,11 @@ the test-runner code can find all the `doctest`s in the crate. [video]: https://www.youtube.com/watch?v=hOLAGYmUQV0 It's important to note that `rustdoc` can ask the compiler for type information -directly, even during `HTML` generation. This [didn't used to be the case], and +directly, even during `HTML` generation. +This [didn't used to be the case], and a lot of `rustdoc`'s architecture was designed around not doing that, but a `TyCtxt` is now passed to `formats::renderer::run_format`, which is used to -run generation for both `HTML` and the -(unstable as of March 2023) JSON format. +run generation for both `HTML` and the (unstable as of Nov 2025) JSON format. This change has allowed other changes to remove data from the "clean" [`AST`][ast] that can be easily derived from `TyCtxt` queries, and we'll usually accept @@ -222,18 +231,17 @@ is complicated from two other constraints that `rustdoc` runs under: * Docs can be generated for crates that don't actually pass type checking. This is used for generating docs that cover mutually-exclusive platform configurations, such as `libstd` having a single package of docs that - cover all supported operating systems. This means `rustdoc` has to be able - to generate docs from `HIR`. + cover all supported operating systems. + This means `rustdoc` has to be able to generate docs from `HIR`. * Docs can inline across crates. Since crate metadata doesn't contain `HIR`, it must be possible to generate inlined docs from the `rustc_middle` data. -The "clean" [`AST`][ast] acts as a common output format for both input formats. There -is also some data in clean that doesn't correspond directly to `HIR`, such as -synthetic `impl`s for auto traits and blanket `impl`s generated by the -`collect-trait-impls` pass. +The "clean" [`AST`][ast] acts as a common output format for both input formats. +There is also some data in clean that doesn't correspond directly to `HIR`, such as +synthetic `impl`s for auto traits and blanket `impl`s generated by the `collect-trait-impls` pass. -Some additional data is stored in -`html::render::context::{Context, SharedContext}`. These two types serve as +Some additional data is stored in `html::render::context::{Context, SharedContext}`. +These two types serve as ways to segregate `rustdoc`'s data for an eventual future with multithreaded doc generation, as well as just keeping things organized: @@ -247,44 +255,44 @@ generation, as well as just keeping things organized: [didn't used to be the case]: https://github.com/rust-lang/rust/pull/80090 [`SharedContext`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustdoc/html/render/context/struct.SharedContext.html -## Other Tricks Up Its Sleeve +## Other tricks up its sleeve All this describes the process for generating `HTML` documentation from a Rust -crate, but there are couple other major modes that `rustdoc` runs in. It can also -be run on a standalone Markdown file, or it can run `doctest`s on Rust code or -standalone Markdown files. For the former, it shortcuts straight to +crate, but there are couple other major modes that `rustdoc` runs in. +It can also be run on a standalone Markdown file, or it can run `doctest`s on Rust code or +standalone Markdown files. +For the former, it shortcuts straight to `html/markdown.rs`, optionally including a mode which inserts a Table of Contents to the output `HTML`. For the latter, `rustdoc` runs a similar partial-compilation to get relevant documentation in `test.rs`, but instead of going through the full clean and -render process, it runs a much simpler crate walk to grab *just* the -hand-written documentation. Combined with the aforementioned +render process, it runs a much simpler crate walk to grab *just* the hand-written documentation. +Combined with the aforementioned "`find_testable_code`" in `html/markdown.rs`, it builds up a collection of -tests to run before handing them off to the test runner. One notable location -in `test.rs` is the function `make_test`, which is where hand-written +tests to run before handing them off to the test runner. +One notable location in `test.rs` is the function `make_test`, which is where hand-written `doctest`s get transformed into something that can be executed. Some extra reading about `make_test` can be found [here](https://quietmisdreavus.net/code/2018/02/23/how-the-doctests-get-made/). -## Testing Locally +## Testing locally Some features of the generated `HTML` documentation might require local -storage to be used across pages, which doesn't work well without an `HTTP` -server. To test these features locally, you can run a local `HTTP` server, like -this: +storage to be used across pages, which doesn't work well without an `HTTP` server. +To test these features locally, you can run a local `HTTP` server, like this: -```bash +```console $ ./x doc library # The documentation has been generated into `build/[YOUR ARCH]/doc`. $ python3 -m http.server -d build/[YOUR ARCH]/doc ``` -Now you can browse your documentation just like you would if it was hosted -on the internet. For example, the url for `std` will be `rust/std/`. +Now you can browse your documentation just like you would if it was hosted on the internet. +For example, the url for `std` will be `rust/std/`. -## See Also +## See also - The [`rustdoc` api docs] - [An overview of `rustdoc`](./rustdoc.md) diff --git a/src/doc/rustc-dev-guide/src/rustdoc.md b/src/doc/rustc-dev-guide/src/rustdoc.md index 7901e951112c..47b18f4e7e52 100644 --- a/src/doc/rustc-dev-guide/src/rustdoc.md +++ b/src/doc/rustc-dev-guide/src/rustdoc.md @@ -1,28 +1,26 @@ # Rustdoc overview -`rustdoc` lives in-tree with the -compiler and standard library. This chapter is about how it works. +`rustdoc` lives in-tree with the compiler and standard library. +This chapter is about how it works. For information about Rustdoc's features and how to use them, see the [Rustdoc book](https://doc.rust-lang.org/nightly/rustdoc/). -For more details about how rustdoc works, see the -["Rustdoc internals" chapter][Rustdoc internals]. +For more details about how rustdoc works, see the ["Rustdoc internals" chapter][Rustdoc internals]. [Rustdoc internals]: ./rustdoc-internals.md `rustdoc` uses `rustc` internals (and, of course, the standard library), so you will have to build the compiler and `std` once before you can build `rustdoc`. -Rustdoc is implemented entirely within the crate [`librustdoc`][rd]. It runs -the compiler up to the point where we have an internal representation of a -crate (HIR) and the ability to run some queries about the types of items. [HIR] -and [queries] are discussed in the linked chapters. +Rustdoc is implemented entirely within the crate [`librustdoc`][rd]. +It runs the compiler up to the point where we have an internal representation of a +crate (HIR) and the ability to run some queries about the types of items. +[HIR] and [queries] are discussed in the linked chapters. [HIR]: ./hir.md [queries]: ./query.md [rd]: https://github.com/rust-lang/rust/tree/HEAD/src/librustdoc -`librustdoc` performs two major steps after that to render a set of -documentation: +`librustdoc` performs two major steps after that to render a set of documentation: * "Clean" the AST into a form that's more suited to creating documentation (and slightly more resistant to churn in the compiler). @@ -31,9 +29,9 @@ documentation: Naturally, there's more than just this, and those descriptions simplify out lots of details, but that's the high-level overview. -(Side note: `librustdoc` is a library crate! The `rustdoc` binary is created -using the project in [`src/tools/rustdoc`][bin]. Note that literally all that -does is call the `main()` that's in this crate's `lib.rs`, though.) +(Side note: `librustdoc` is a library crate! +The `rustdoc` binary is created using the project in [`src/tools/rustdoc`][bin]. +Note that literally all that does is call the `main()` that's in this crate's `lib.rs`, though.) [bin]: https://github.com/rust-lang/rust/tree/HEAD/src/tools/rustdoc @@ -47,15 +45,14 @@ does is call the `main()` that's in this crate's `lib.rs`, though.) rustdoc you can run on other projects. * Add `library/test` to be able to use `rustdoc --test`. * Run `rustup toolchain link stage2 build/host/stage2` to add a - custom toolchain called `stage2` to your rustup environment. After - running that, `cargo +stage2 doc` in any directory will build with + custom toolchain called `stage2` to your rustup environment. + After running that, `cargo +stage2 doc` in any directory will build with your locally-compiled rustdoc. * Use `./x doc library` to use this rustdoc to generate the standard library docs. * The completed docs will be available in `build/host/doc` (under `core`, `alloc`, and `std`). * If you want to copy those docs to a webserver, copy all of - `build/host/doc`, since that's where the CSS, JS, fonts, and landing - page are. + `build/host/doc`, since that's where the CSS, JS, fonts, and landing page are. * For frontend debugging, disable the `rust.docs-minification` option in [`bootstrap.toml`]. * Use `./x test tests/rustdoc*` to run the tests using a stage1 rustdoc. @@ -65,9 +62,10 @@ does is call the `main()` that's in this crate's `lib.rs`, though.) ### JavaScript CI checks -Rustdoc’s JavaScript and TypeScript are checked during CI by `eslint`, `es-check`, and `tsc` (not by compiletest). These run as part of the `tidy` job. +Rustdoc’s JavaScript and TypeScript are checked during CI by `eslint`, `es-check`, and `tsc` (not by compiletest). +These run as part of the `tidy` job. -```bash +```console ./x.py test tidy --extra-checks=js ``` @@ -103,23 +101,24 @@ See [Rustdoc tests suites](tests/compiletest.md#rustdoc-test-suites) for more de ## Constraints -We try to make rustdoc work reasonably well with JavaScript disabled, and when -browsing local files. We support -[these browsers](https://rust-lang.github.io/rfcs/1985-tiered-browser-support.html#supported-browsers). +We try to make rustdoc work reasonably well with JavaScript disabled, and when browsing local files. +We have [a list of supported browsers]. Supporting local files (`file:///` URLs) brings some surprising restrictions. Certain browser features that require secure origins, like `localStorage` and -Service Workers, don't work reliably. We can still use such features but we -should make sure pages are still usable without them. +Service Workers, don't work reliably. +We can still use such features, but we should make sure pages are still usable without them. Rustdoc [does not type-check function bodies][platform-specific docs]. This works by [overriding the built-in queries for typeck][override queries], by [silencing name resolution errors], and by [not resolving opaque types]. This comes with several caveats: in particular, rustdoc *cannot* run any parts of the compiler that -require type-checking bodies; for example it cannot generate `.rlib` files or run most lints. +require type-checking bodies; +for example, it cannot generate `.rlib` files or run most lints. We want to move away from this model eventually, but we need some alternative for -[the people using it][async-std]; see [various][zulip stop accepting broken code] -[previous][rustdoc meeting 2024-07-08] [Zulip][compiler meeting 2023-01-26] [discussion][notriddle rfc]. +[the people using it][async-std]; +see [various][zulip stop accepting broken code] +[previous][rustdoc meeting 2024-07-08] [Zulip][compiler meeting 2023-01-26] [discussions][notriddle rfc]. For examples of code that breaks if this hack is removed, see [`tests/rustdoc-ui/error-in-impl-trait`]. @@ -133,12 +132,13 @@ For examples of code that breaks if this hack is removed, see [zulip stop accepting broken code]: https://rust-lang.zulipchat.com/#narrow/stream/266220-rustdoc/topic/stop.20accepting.20broken.20code [notriddle rfc]: https://rust-lang.zulipchat.com/#narrow/channel/266220-t-rustdoc/topic/Pre-RFC.3A.20stop.20accepting.20broken.20code [`tests/rustdoc-ui/error-in-impl-trait`]: https://github.com/rust-lang/rust/tree/163cb4ea3f0ae3bc7921cc259a08a7bf92e73ee6/tests/rustdoc-ui/error-in-impl-trait +[a list of supported browsers]: https://rust-lang.github.io/rfcs/1985-tiered-browser-support.html#supported-browsers ## Multiple runs, same output directory -Rustdoc can be run multiple times for varying inputs, with its output set to the -same directory. That's how cargo produces documentation for dependencies of the -current crate. It can also be done manually if a user wants a big +Rustdoc can be run multiple times for varying inputs, with its output set to the same directory. +That's how cargo produces documentation for dependencies of the current crate. +It can also be done manually if a user wants a big documentation bundle with all of the docs they care about. HTML is generated independently for each crate, but there is some cross-crate @@ -147,68 +147,67 @@ information that we update as we add crates to the output directory: - `crates.js` holds a list of all crates in the output directory. - `search-index.js` holds a list of all searchable items. - For each trait, there is a file under `implementors/.../trait.TraitName.js` - containing a list of implementors of that trait. The implementors may be in - different crates than the trait, and the JS file is updated as we discover - new ones. + containing a list of implementors of that trait. + The implementors may be in + different crates than the trait, and the JS file is updated as we discover new ones. ## Use cases -There are a few major use cases for rustdoc that you should keep in mind when -working on it: +There are a few major use cases for rustdoc that you should keep in mind when working on it: ### Standard library docs -These are published at as part of the Rust release -process. Stable releases are also uploaded to specific versioned URLs like -. Beta and nightly docs are published to +These are published at as part of the Rust release process. +Stable releases are also uploaded to specific versioned URLs like +. +Beta and nightly docs are published to and . The docs are uploaded with the [promote-release -tool](https://github.com/rust-lang/promote-release) and served from S3 with -CloudFront. +tool](https://github.com/rust-lang/promote-release) and served from S3 with CloudFront. -The standard library docs contain five crates: alloc, core, proc_macro, std, and -test. +The standard library docs contain five crates: alloc, core, proc_macro, std, and test. ### docs.rs When crates are published to crates.io, docs.rs automatically builds -and publishes their documentation, for instance at -. It always builds with the current nightly +and publishes their documentation, for instance at . +It always builds with the current nightly rustdoc, so any changes you land in rustdoc are "insta-stable" in that they will -have an immediate public effect on docs.rs. Old documentation is not rebuilt, so -you will see some variation in UI when browsing old releases in docs.rs. Crate -authors can request rebuilds, which will be run with the latest rustdoc. +have an immediate public effect on docs.rs. +Old documentation is only sometimes rebuilt, so +you will see some variation in UI when browsing old releases in docs.rs. +Crate authors can request rebuilds, which will be run with the latest rustdoc. Docs.rs performs some transformations on rustdoc's output in order to save -storage and display a navigation bar at the top. In particular, certain static +storage and display a navigation bar at the top. +In particular, certain static files, like main.js and rustdoc.css, may be shared across multiple invocations -of the same version of rustdoc. Others, like crates.js and sidebar-items.js, are -different for different invocations. Still others, like fonts, will never -change. These categories are distinguished using the `SharedResource` enum in +of the same version of rustdoc. +Others, like crates.js and sidebar-items.js, are different for different invocations. +Still others, like fonts, will never change. +These categories are distinguished using the `SharedResource` enum in `src/librustdoc/html/render/write_shared.rs` Documentation on docs.rs is always generated for a single crate at a time, so -the search and sidebar functionality don't include dependencies of the current -crate. +the search and sidebar functionality don't include dependencies of the current crate. ### Locally generated docs -Crate authors can run `cargo doc --open` in crates they have checked -out locally to see the docs. This is useful to check that the docs they -are writing are useful and display correctly. It can also be useful for -people to view documentation on crates they aren't authors of, but want to -use. In both cases, people may use `--document-private-items` Cargo flag to +Crate authors can run `cargo doc --open` in crates they have checked out locally to see the docs. +This is useful to check that the docs they are writing are useful and display correctly. +It can also be useful for people to view documentation on crates they aren't authors of, but want to +use. +In both cases, people may use `--document-private-items` Cargo flag to see private methods, fields, and so on, which are normally not displayed. -By default `cargo doc` will generate documentation for a crate and all of its -dependencies. That can result in a very large documentation bundle, with a large -(and slow) search corpus. The Cargo flag `--no-deps` inhibits that behavior and -generates docs for just the crate. +By default, `cargo doc` will generate documentation for a crate and all of its dependencies. +That can result in a very large documentation bundle, with a large (and slow) search corpus. +The Cargo flag `--no-deps` inhibits that behavior and generates docs for just the crate. ### Self-hosted project docs -Some projects like to host their own documentation. For example: -. This is easy to do by locally generating docs, and -simply copying them to a web server. Rustdoc's HTML output can be extensively -customized by flags. Users can add a theme, set the default theme, and inject -arbitrary HTML. See `rustdoc --help` for details. +Some projects host their own documentation. +This is easy to do by locally generating docs, and simply copying them to a web server. +Rustdoc's HTML output can be extensively customized by flags. +Users can add a theme, set the default theme, and inject arbitrary HTML. +See `rustdoc --help` for details. diff --git a/src/doc/rustc-dev-guide/src/sanitizers.md b/src/doc/rustc-dev-guide/src/sanitizers.md index 53df27412f05..7b84335e3b90 100644 --- a/src/doc/rustc-dev-guide/src/sanitizers.md +++ b/src/doc/rustc-dev-guide/src/sanitizers.md @@ -10,8 +10,7 @@ The rustc compiler contains support for following sanitizers: * [Hardware-assisted AddressSanitizer][clang-hwasan] a tool similar to AddressSanitizer but based on partial hardware assistance. * [KernelControlFlowIntegrity][clang-kcfi] LLVM Kernel Control Flow Integrity - (KCFI) provides forward-edge control flow protection for operating systems - kernels. + (KCFI) provides forward-edge control flow protection for operating systems kernels. * [LeakSanitizer][clang-lsan] a run-time memory leak detector. * [MemorySanitizer][clang-msan] a detector of uninitialized reads. * [ThreadSanitizer][clang-tsan] a fast data race detector. @@ -19,16 +18,18 @@ The rustc compiler contains support for following sanitizers: ## How to use the sanitizers? To enable a sanitizer compile with `-Z sanitizer=...` option, where value is one -of `address`, `cfi`, `hwaddress`, `kcfi`, `leak`, `memory` or `thread`. For more -details on how to use sanitizers please refer to the sanitizer flag in [the -unstable book](https://doc.rust-lang.org/unstable-book/). +of `address`, `cfi`, `hwaddress`, `kcfi`, `leak`, `memory` or `thread`. +For more details on how to use sanitizers, +please refer to the sanitizer flag in [The Unstable Book]. + +[The Unstable Book]: https://doc.rust-lang.org/unstable-book ## How are sanitizers implemented in rustc? The implementation of sanitizers (except CFI) relies almost entirely on LLVM. The rustc is an integration point for LLVM compile time instrumentation passes -and runtime libraries. Highlight of the most important aspects of the -implementation: +and runtime libraries. +Highlight of the most important aspects of the implementation: * The sanitizer runtime libraries are part of the [compiler-rt] project, and [will be built][sanitizer-build] on [supported targets][sanitizer-targets] @@ -43,23 +44,26 @@ implementation: * During LLVM code generation, the functions intended for instrumentation are [marked][sanitizer-attribute] with appropriate LLVM attribute: - `SanitizeAddress`, `SanitizeHWAddress`, `SanitizeMemory`, or - `SanitizeThread`. By default all functions are instrumented, but this + `SanitizeAddress`, `SanitizeHWAddress`, `SanitizeMemory`, or `SanitizeThread`. + By default, all functions are instrumented, but this behaviour can be changed with `#[sanitize(xyz = "on|off|")]`. * The decision whether to perform instrumentation or not is possible only at a - function granularity. In the cases were those decision differ between - functions it might be necessary to inhibit inlining, both at [MIR + function granularity. + In the cases were those decision differ between + functions, it might be necessary to inhibit inlining, both at [MIR level][inline-mir] and [LLVM level][inline-llvm]. * The LLVM IR generated by rustc is instrumented by [dedicated LLVM - passes][sanitizer-pass], different for each sanitizer. Instrumentation - passes are invoked after optimization passes. + passes][sanitizer-pass], different for each sanitizer. + Instrumentation passes are invoked after optimization passes. * When producing an executable, the sanitizer specific runtime library is - [linked in][sanitizer-link]. The libraries are searched for in the target - libdir. First relative to the overridden system root and subsequently - relative to the default system root. Fall-back to the default system root + [linked in][sanitizer-link]. + The libraries are searched for in the target libdir. + First, the search is relative to the overridden system root, and subsequently, + it is relative to the default system root. + Fall-back to the default system root ensures that sanitizer runtimes remain available when using sysroot overrides constructed by cargo `-Z build-std` or xargo. @@ -80,21 +84,20 @@ Sanitizers are validated by code generation tests in [`tests/ui/sanitizer/`][test-ui] directory. Testing sanitizer functionality requires the sanitizer runtimes (built when -`sanitizer = true` in `bootstrap.toml`) and target providing support for particular -sanitizer. When sanitizer is unsupported on given target, sanitizers tests will -be ignored. This behaviour is controlled by compiletest `needs-sanitizer-*` -directives. +`sanitizer = true` in `bootstrap.toml`) and target providing support for particular a sanitizer. +When a sanitizer is unsupported on a given target, sanitizer tests will be ignored. +This behaviour is controlled by compiletest `needs-sanitizer-*` directives. [test-cg]: https://github.com/rust-lang/rust/tree/HEAD/tests/codegen-llvm [test-ui]: https://github.com/rust-lang/rust/tree/HEAD/tests/ui/sanitizer -## Enabling sanitizer on a new target +## Enabling a sanitizer on a new target To enable a sanitizer on a new target which is already supported by LLVM: 1. Include the sanitizer in the list of `supported_sanitizers` in [the target - definition][target-definition]. `rustc --target .. -Zsanitizer=..` should now - recognize sanitizer as supported. + definition][target-definition]. + `rustc --target .. -Zsanitizer=..` should now recognize the sanitizer as supported. 2. [Build the runtime for the target and include it in the libdir.][sanitizer-targets] 3. [Teach compiletest that your target now supports the sanitizer.][compiletest-definition] Tests marked with `needs-sanitizer-*` should now run on the target. diff --git a/src/doc/rustc-dev-guide/src/tests/running.md b/src/doc/rustc-dev-guide/src/tests/running.md index 0a99c847cce7..48ce9d8ad185 100644 --- a/src/doc/rustc-dev-guide/src/tests/running.md +++ b/src/doc/rustc-dev-guide/src/tests/running.md @@ -1,19 +1,19 @@ # Running tests -You can run the entire test collection using `x`. But note that running the -*entire* test collection is almost never what you want to do during local -development because it takes a really long time. For local development, see the -subsection after on how to run a subset of tests. +You can run the entire test collection using `x`. +But note that running the *entire* test collection is almost never what you want to do during local +development because it takes a really long time. +For local development, see the subsection after on how to run a subset of tests.
-Running plain `./x test` will build the stage 1 compiler and then run the whole -test suite. This not only include `tests/`, but also `library/`, `compiler/`, +Running plain `./x test` will build the stage 1 compiler and then run the whole test suite. +This not only includes `tests/`, but also `library/`, `compiler/`, `src/tools/` package tests and more. You usually only want to run a subset of the test suites (or even a smaller set -of tests than that) which you expect will exercise your changes. PR CI exercises -a subset of test collections, and merge queue CI will exercise all of the test +of tests than that) which you expect will exercise your changes. +PR CI exercises a subset of test collections, and merge queue CI will exercise all of the test collection.
@@ -22,8 +22,8 @@ collection. ./x test ``` -The test results are cached and previously successful tests are `ignored` during -testing. The stdout/stderr contents as well as a timestamp file for every test +The test results are cached and previously successful tests are `ignored` during testing. +The stdout/stderr contents as well as a timestamp file for every test can be found under `build//test/` for the given ``. To force-rerun a test (e.g. in case the test runner fails to notice a change) you can use the `--force-rerun` CLI option. @@ -40,8 +40,8 @@ notice a change) you can use the `--force-rerun` CLI option. ## Running a subset of the test suites -When working on a specific PR, you will usually want to run a smaller set of -tests. For example, a good "smoke test" that can be used after modifying rustc +When working on a specific PR, you will usually want to run a smaller set of tests. +For example, a good "smoke test" that can be used after modifying rustc to see if things are generally working correctly would be to exercise the `ui` test suite ([`tests/ui`]): @@ -49,9 +49,8 @@ test suite ([`tests/ui`]): ./x test tests/ui ``` -Of course, the choice of test suites is -somewhat arbitrary, and may not suit the task you are doing. For example, if you -are hacking on debuginfo, you may be better off with the debuginfo test suite: +Of course, the choice of test suites is somewhat arbitrary, and may not suit the task you are doing. +For example, if you are hacking on debuginfo, you may be better off with the debuginfo test suite: ```text ./x test tests/debuginfo @@ -77,8 +76,8 @@ Likewise, you can test a single file by passing its path: ./x test tests/ui/const-generics/const-test.rs ``` -`x` doesn't support running a single tool test by passing its path yet. You'll -have to use the `--test-args` argument as described +`x` doesn't support running a single tool test by passing its path yet. +You'll have to use the `--test-args` argument as described [below](#running-an-individual-test). ```text @@ -97,8 +96,8 @@ have to use the `--test-args` argument as described ./x test --stage 0 library/std ``` -Note that this only runs tests on `std`; if you want to test `core` or other -crates, you have to specify those explicitly. +Note that this only runs tests on `std`; +if you want to test `core` or other crates, you have to specify those explicitly. ### Run the tidy script and tests on the standard library @@ -117,8 +116,8 @@ you avoid having to run tests for components you did not change at all.
-Note that bors only runs the tests with the full stage 2 build; therefore, while -the tests **usually** work fine with stage 1, there are some limitations. +Note that bors only runs the tests with the full stage 2 build; +therefore, while the tests **usually** work fine with stage 1, there are some limitations.
@@ -129,7 +128,8 @@ the tests **usually** work fine with stage 1, there are some limitations. ```
-You almost never need to do this; CI will run these tests for you. +You almost never need to do this; +CI will run these tests for you.
## Run unit tests on the compiler/library @@ -140,7 +140,8 @@ You may want to run unit tests on a specific file with following: ./x test compiler/rustc_data_structures/src/thin_vec/tests.rs ``` -But unfortunately, it's impossible. You should invoke the following instead: +But unfortunately, it's impossible. +You should invoke the following instead: ```text ./x test compiler/rustc_data_structures/ --test-args thin_vec @@ -149,9 +150,9 @@ But unfortunately, it's impossible. You should invoke the following instead: ## Running an individual test Another common thing that people want to do is to run an **individual test**, -often the test they are trying to fix. As mentioned earlier, you may pass the -full file path to achieve this, or alternatively one may invoke `x` with the -`--test-args` option: +often the test they are trying to fix. +As mentioned earlier, you may pass the +full file path to achieve this, or alternatively one may invoke `x` with the `--test-args` option: ```text ./x test tests/ui --test-args issue-1234 @@ -159,14 +160,13 @@ full file path to achieve this, or alternatively one may invoke `x` with the Under the hood, the test runner invokes the standard Rust test runner (the same one you get with `#[test]`), so this command would wind up filtering for tests -that include "issue-1234" in the name. Thus, `--test-args` is a good way to run -a collection of related tests. +that include "issue-1234" in the name. +Thus, `--test-args` is a good way to run a collection of related tests. ## Passing arguments to `rustc` when running tests It can sometimes be useful to run some tests with specific compiler arguments, -without using `RUSTFLAGS` (during development of unstable features, with `-Z` -flags, for example). +without using `RUSTFLAGS` (during development of unstable features, with `-Z` flags, for example). This can be done with `./x test`'s `--compiletest-rustc-args` option, to pass additional arguments to the compiler when building the tests. @@ -176,8 +176,7 @@ additional arguments to the compiler when building the tests. If you have changed the compiler's output intentionally, or you are making a new test, you can pass `--bless` to the test subcommand. -As an example, -if some tests in `tests/ui` are failing, you can run this command: +As an example, if some tests in `tests/ui` are failing, you can run this command: ```text ./x test tests/ui --bless @@ -192,8 +191,9 @@ just like when running the tests without the `--bless` flag. There are a few options for running tests: * `bootstrap.toml` has the `rust.verbose-tests` option. If `false`, each test will - print a single dot (the default). If `true`, the name of every test will be - printed. This is equivalent to the `--quiet` option in the [Rust test + print a single dot (the default). + If `true`, the name of every test will be printed. + This is equivalent to the `--quiet` option in the [Rust test harness](https://doc.rust-lang.org/rustc/tests/). * The environment variable `RUST_TEST_THREADS` can be set to the number of concurrent threads to use for testing. @@ -202,24 +202,24 @@ There are a few options for running tests: Pass UI tests now have three modes, `check-pass`, `build-pass` and `run-pass`. When `--pass $mode` is passed, these tests will be forced to run under the given -`$mode` unless the directive `//@ ignore-pass` exists in the test file. For -example, you can run all the tests in `tests/ui` as `check-pass`: +`$mode` unless the directive `//@ ignore-pass` exists in the test file. +For example, you can run all the tests in `tests/ui` as `check-pass`: ```text ./x test tests/ui --pass check ``` -By passing `--pass $mode`, you can reduce the testing time. For each mode, -please see [Controlling pass/fail +By passing `--pass $mode`, you can reduce the testing time. +For each mode, please see [Controlling pass/fail expectations](ui.md#controlling-passfail-expectations). ## Running tests with different "compare modes" -UI tests may have different output depending on certain "modes" that the -compiler is in. For example, when using the Polonius mode, a test `foo.rs` will +UI tests may have different output depending on certain "modes" that the compiler is in. +For example, when using the Polonius mode, a test `foo.rs` will first look for expected output in `foo.polonius.stderr`, falling back to the -usual `foo.stderr` if not found. The following will run the UI test suite in -Polonius mode: +usual `foo.stderr` if not found. +The following will run the UI test suite in Polonius mode: ```text ./x test tests/ui --compare-mode=polonius @@ -229,8 +229,8 @@ See [Compare modes](compiletest.md#compare-modes) for more details. ## Running tests manually -Sometimes it's easier and faster to just run the test by hand. Most tests are -just `.rs` files, so after [creating a rustup +Sometimes it's easier and faster to just run the test by hand. +Most tests are just `.rs` files, so after [creating a rustup toolchain](../building/how-to-build-and-run.md#creating-a-rustup-toolchain), you can do something like: @@ -238,57 +238,59 @@ can do something like: rustc +stage1 tests/ui/issue-1234.rs ``` -This is much faster, but doesn't always work. For example, some tests include +This is much faster, but doesn't always work. +For example, some tests include directives that specify specific compiler flags, or which rely on other crates, and they may not run the same without those options. ## Running tests on a remote machine Tests may be run on a remote machine (e.g. to test builds for a different -architecture). This is done using `remote-test-client` on the build machine to +architecture). +This is done using `remote-test-client` on the build machine to send test programs to `remote-test-server` running on the remote machine. -`remote-test-server` executes the test programs and sends the results back to -the build machine. `remote-test-server` provides *unauthenticated remote code +`remote-test-server` executes the test programs and sends the results back to the build machine. +`remote-test-server` provides *unauthenticated remote code execution* so be careful where it is used. -To do this, first build `remote-test-server` for the remote machine, e.g. for -RISC-V +To do this, first build `remote-test-server` for the remote machine +(using RISC-V as an example): ```text ./x build src/tools/remote-test-server --target riscv64gc-unknown-linux-gnu ``` -The binary will be created at -`./build/host/stage2-tools/$TARGET_ARCH/release/remote-test-server`. Copy this -over to the remote machine. +The binary will be created at `./build/host/stage2-tools/$TARGET_ARCH/release/remote-test-server`. +Copy this over to the remote machine. On the remote machine, run the `remote-test-server` with the `--bind -0.0.0.0:12345` flag (and optionally `-v` for verbose output). Output should look -like this: +0.0.0.0:12345` flag (and optionally `--verbose` flag). +Output should look like this: -```text -$ ./remote-test-server -v --bind 0.0.0.0:12345 +```console +$ ./remote-test-server --verbose --bind 0.0.0.0:12345 starting test server listening on 0.0.0.0:12345! ``` Note that binding the server to 0.0.0.0 will allow all hosts able to reach your -machine to execute arbitrary code on your machine. We strongly recommend either +machine to execute arbitrary code on your machine. +We strongly recommend either setting up a firewall to block external access to port 12345, or to use a more restrictive IP address when binding. -You can test if the `remote-test-server` is working by connecting to it and -sending `ping\n`. It should reply `pong`: +You can test if the `remote-test-server` is working by connecting to it and sending `ping\n`. +It should reply `pong`: -```text +```console $ nc $REMOTE_IP 12345 ping pong ``` To run tests using the remote runner, set the `TEST_DEVICE_ADDR` environment -variable then use `x` as usual. For example, to run `ui` tests for a RISC-V -machine with the IP address `1.2.3.4` use +variable then use `x` as usual. +For example, to run `ui` tests for a RISC-V machine with the IP address `1.2.3.4` use ```text export TEST_DEVICE_ADDR="1.2.3.4:12345" @@ -315,34 +317,34 @@ run "/tmp/work/test1018/a" [...] ``` -Tests are built on the machine running `x` not on the remote machine. Tests -which fail to build unexpectedly (or `ui` tests producing incorrect build +Tests are built on the machine running `x` not on the remote machine. +Tests which fail to build unexpectedly (or `ui` tests producing incorrect build output) may fail without ever running on the remote machine. ## Testing on emulators -Some platforms are tested via an emulator for architectures that aren't readily -available. For architectures where the standard library is well supported and +Some platforms are tested via an emulator for architectures that aren't readily available. +For architectures where the standard library is well supported and the host operating system supports TCP/IP networking, see the above instructions for testing on a remote machine (in this case the remote machine is emulated). -There is also a set of tools for orchestrating running the tests within the -emulator. Platforms such as `arm-android` and `arm-unknown-linux-gnueabihf` are -set up to automatically run the tests under emulation on GitHub Actions. The -following will take a look at how a target's tests are run under emulation. +There is also a set of tools for orchestrating running the tests within the emulator. +Platforms such as `arm-android` and `arm-unknown-linux-gnueabihf` are +set up to automatically run the tests under emulation on GitHub Actions. +The following will take a look at how a target's tests are run under emulation. -The Docker image for [armhf-gnu] includes [QEMU] to emulate the ARM CPU -architecture. Included in the Rust tree are the tools [remote-test-client] and +The Docker image for [armhf-gnu] includes [QEMU] to emulate the ARM CPU architecture. +Included in the Rust tree are the tools [remote-test-client] and [remote-test-server] which are programs for sending test programs and libraries -to the emulator, and running the tests within the emulator, and reading the -results. The Docker image is set up to launch `remote-test-server` and the +to the emulator, and running the tests within the emulator, and reading the results. +The Docker image is set up to launch `remote-test-server` and the build tools use `remote-test-client` to communicate with the server to coordinate running tests (see [src/bootstrap/src/core/build_steps/test.rs]). -To run on the iOS/tvOS/watchOS/visionOS simulator, we can similarly treat it as -a "remote" machine. A curious detail here is that the network is shared between -the simulator instance and the host macOS, so we can use the local loopback -address `127.0.0.1`. Something like the following should work: +To run on the iOS/tvOS/watchOS/visionOS simulator, we can similarly treat it as a "remote" machine. +A curious detail here is that the network is shared between +the simulator instance and the host macOS, so we can use the local loopback address `127.0.0.1`. +Something like the following should work: ```sh # Build the test server for the iOS simulator: @@ -384,7 +386,7 @@ On the [wasm32-wasip1 target support page] a minimum version is specified that y Some cmake commands that take a while and give a lot of very concerning c++ warnings... Then, in `bootstrap.toml`, point to the sysroot like so: -``` +```toml [target.wasm32-wasip1] wasi-root = "/build/sysroot/install/share/wasi-sysroot" ``` diff --git a/src/doc/rustc/src/platform-support/aarch64-unknown-teeos.md b/src/doc/rustc/src/platform-support/aarch64-unknown-teeos.md index be11d0cdd103..6e7eeb82e4bf 100644 --- a/src/doc/rustc/src/platform-support/aarch64-unknown-teeos.md +++ b/src/doc/rustc/src/platform-support/aarch64-unknown-teeos.md @@ -5,7 +5,7 @@ Target for the TEEOS operating system. TEEOS is a mini os run in TrustZone, for trusted/security apps. The kernel of TEEOS is HongMeng/ChCore micro kernel. The libc for TEEOS is a part of musl. -It's very small that there is no RwLock, no network, no stdin, and no file system for apps in TEEOS. +It's very small that there is no network, no stdin, and no file system for apps in TEEOS. Some abbreviation: diff --git a/src/etc/lldb_batchmode.py b/src/etc/lldb_batchmode.py index 5cc9bb23628f..a6008ad66465 100644 --- a/src/etc/lldb_batchmode.py +++ b/src/etc/lldb_batchmode.py @@ -176,77 +176,85 @@ def start_watchdog(): watchdog_thread.start() +def get_env_arg(name): + value = os.environ.get(name) + if value is None: + print("must set %s" % name) + sys.exit(1) + return value + + #################################################################################################### # ~main #################################################################################################### -if len(sys.argv) != 3: - print("usage: python lldb_batchmode.py target-path script-path") - sys.exit(1) +def main(): + target_path = get_env_arg("LLDB_BATCHMODE_TARGET_PATH") + script_path = get_env_arg("LLDB_BATCHMODE_SCRIPT_PATH") -target_path = sys.argv[1] -script_path = sys.argv[2] + print("LLDB batch-mode script") + print("----------------------") + print("Debugger commands script is '%s'." % script_path) + print("Target executable is '%s'." % target_path) + print("Current working directory is '%s'" % os.getcwd()) -print("LLDB batch-mode script") -print("----------------------") -print("Debugger commands script is '%s'." % script_path) -print("Target executable is '%s'." % target_path) -print("Current working directory is '%s'" % os.getcwd()) + # Start the timeout watchdog + start_watchdog() -# Start the timeout watchdog -start_watchdog() + # Create a new debugger instance + debugger = lldb.SBDebugger.Create() -# Create a new debugger instance -debugger = lldb.SBDebugger.Create() + # When we step or continue, don't return from the function until the process + # stops. We do this by setting the async mode to false. + debugger.SetAsync(False) -# When we step or continue, don't return from the function until the process -# stops. We do this by setting the async mode to false. -debugger.SetAsync(False) + # Create a target from a file and arch + print("Creating a target for '%s'" % target_path) + target_error = lldb.SBError() + target = debugger.CreateTarget(target_path, None, None, True, target_error) -# Create a target from a file and arch -print("Creating a target for '%s'" % target_path) -target_error = lldb.SBError() -target = debugger.CreateTarget(target_path, None, None, True, target_error) + if not target: + print( + "Could not create debugging target '" + + target_path + + "': " + + str(target_error) + + ". Aborting.", + file=sys.stderr, + ) + sys.exit(1) -if not target: - print( - "Could not create debugging target '" - + target_path - + "': " - + str(target_error) - + ". Aborting.", - file=sys.stderr, - ) - sys.exit(1) + # Register the breakpoint callback for every breakpoint + start_breakpoint_listener(target) + + command_interpreter = debugger.GetCommandInterpreter() + + try: + script_file = open(script_path, "r") + + for line in script_file: + command = line.strip() + if ( + command == "run" + or command == "r" + or re.match(r"^process\s+launch.*", command) + ): + # Before starting to run the program, let the thread sleep a bit, so all + # breakpoint added events can be processed + time.sleep(0.5) + if command != "": + execute_command(command_interpreter, command) + + except IOError as e: + print("Could not read debugging script '%s'." % script_path, file=sys.stderr) + print(e, file=sys.stderr) + print("Aborting.", file=sys.stderr) + sys.exit(1) + finally: + debugger.Terminate() + script_file.close() -# Register the breakpoint callback for every breakpoint -start_breakpoint_listener(target) - -command_interpreter = debugger.GetCommandInterpreter() - -try: - script_file = open(script_path, "r") - - for line in script_file: - command = line.strip() - if ( - command == "run" - or command == "r" - or re.match(r"^process\s+launch.*", command) - ): - # Before starting to run the program, let the thread sleep a bit, so all - # breakpoint added events can be processed - time.sleep(0.5) - if command != "": - execute_command(command_interpreter, command) - -except IOError as e: - print("Could not read debugging script '%s'." % script_path, file=sys.stderr) - print(e, file=sys.stderr) - print("Aborting.", file=sys.stderr) - sys.exit(1) -finally: - debugger.Terminate() - script_file.close() +if __name__ == "__main__": + main() diff --git a/src/librustdoc/Cargo.toml b/src/librustdoc/Cargo.toml index 63412e2b9373..e1408bb7e5bc 100644 --- a/src/librustdoc/Cargo.toml +++ b/src/librustdoc/Cargo.toml @@ -24,6 +24,7 @@ smallvec = "1.8.1" stringdex = "=0.0.2" tempfile = "3" threadpool = "1.8.1" +tikv-jemalloc-sys = { version = "0.6.1", optional = true, features = ['override_allocator_on_supported_platforms'] } tracing = "0.1" tracing-tree = "0.3.0" unicode-segmentation = "1.9" @@ -42,7 +43,7 @@ minifier = { version = "0.3.2", default-features = false } expect-test = "1.4.0" [features] -jemalloc = [] +jemalloc = ["dep:tikv-jemalloc-sys"] [package.metadata.rust-analyzer] rustc_private = true diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index b470af50f68f..189d3a70ad62 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -227,6 +227,30 @@ pub(crate) fn item_relative_path(tcx: TyCtxt<'_>, def_id: DefId) -> Vec tcx.def_path(def_id).data.into_iter().filter_map(|elem| elem.data.get_opt_name()).collect() } +/// Get the public Rust path to an item. This is used to generate the URL to the item's page. +/// +/// In particular: we handle macro differently: if it's not a macro 2.0 oe a built-in macro, then +/// it is generated at the top-level of the crate and its path will be `[crate_name, macro_name]`. +pub(crate) fn get_item_path(tcx: TyCtxt<'_>, def_id: DefId, kind: ItemType) -> Vec { + let crate_name = tcx.crate_name(def_id.krate); + let relative = item_relative_path(tcx, def_id); + + if let ItemType::Macro = kind { + // Check to see if it is a macro 2.0 or built-in macro + // More information in . + if matches!( + CStore::from_tcx(tcx).load_macro_untracked(def_id, tcx), + LoadedMacro::MacroDef { def, .. } if !def.macro_rules + ) { + once(crate_name).chain(relative).collect() + } else { + vec![crate_name, *relative.last().expect("relative was empty")] + } + } else { + once(crate_name).chain(relative).collect() + } +} + /// Record an external fully qualified name in the external_paths cache. /// /// These names are used later on by HTML rendering to generate things like @@ -240,27 +264,12 @@ pub(crate) fn record_extern_fqn(cx: &mut DocContext<'_>, did: DefId, kind: ItemT return; } - let crate_name = cx.tcx.crate_name(did.krate); - - let relative = item_relative_path(cx.tcx, did); - let fqn = if let ItemType::Macro = kind { - // Check to see if it is a macro 2.0 or built-in macro - if matches!( - CStore::from_tcx(cx.tcx).load_macro_untracked(did, cx.tcx), - LoadedMacro::MacroDef { def, .. } if !def.macro_rules - ) { - once(crate_name).chain(relative).collect() - } else { - vec![crate_name, *relative.last().expect("relative was empty")] - } - } else { - once(crate_name).chain(relative).collect() - }; + let item_path = get_item_path(cx.tcx, did, kind); if did.is_local() { - cx.cache.exact_paths.insert(did, fqn); + cx.cache.exact_paths.insert(did, item_path); } else { - cx.cache.external_paths.insert(did, (fqn, kind)); + cx.cache.external_paths.insert(did, (item_path, kind)); } } @@ -497,7 +506,7 @@ pub(crate) fn build_impl( return; } - let document_hidden = cx.render_options.document_hidden; + let document_hidden = cx.document_hidden(); let (trait_items, generics) = match impl_item { Some(impl_) => ( impl_ diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 02559ecc7675..a4f754912aea 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -71,7 +71,7 @@ pub(crate) fn clean_doc_module<'tcx>(doc: &DocModule<'tcx>, cx: &mut DocContext< items.extend(doc.foreigns.iter().map(|(item, renamed, import_id)| { let item = clean_maybe_renamed_foreign_item(cx, item, *renamed, *import_id); if let Some(name) = item.name - && (cx.render_options.document_hidden || !item.is_doc_hidden()) + && (cx.document_hidden() || !item.is_doc_hidden()) { inserted.insert((item.type_(), name)); } @@ -82,7 +82,7 @@ pub(crate) fn clean_doc_module<'tcx>(doc: &DocModule<'tcx>, cx: &mut DocContext< return None; } let item = clean_doc_module(x, cx); - if !cx.render_options.document_hidden && item.is_doc_hidden() { + if !cx.document_hidden() && item.is_doc_hidden() { // Hidden modules are stripped at a later stage. // If a hidden module has the same name as a visible one, we want // to keep both of them around. @@ -104,7 +104,7 @@ pub(crate) fn clean_doc_module<'tcx>(doc: &DocModule<'tcx>, cx: &mut DocContext< let v = clean_maybe_renamed_item(cx, item, *renamed, import_ids); for item in &v { if let Some(name) = item.name - && (cx.render_options.document_hidden || !item.is_doc_hidden()) + && (cx.document_hidden() || !item.is_doc_hidden()) { inserted.insert((item.type_(), name)); } @@ -203,7 +203,7 @@ fn generate_item_with_correct_attrs( .get_word_attr(sym::inline) .is_some() || (is_glob_import(cx.tcx, import_id) - && (cx.render_options.document_hidden || !cx.tcx.is_doc_hidden(def_id))); + && (cx.document_hidden() || !cx.tcx.is_doc_hidden(def_id))); attrs.extend(get_all_import_attributes(cx, import_id, def_id, is_inline)); is_inline = is_inline || import_is_inline; } @@ -1588,9 +1588,9 @@ fn first_non_private<'tcx>( if let Res::Def(DefKind::Ctor(..), _) | Res::SelfCtor(..) = res { continue; } - if (cx.render_options.document_hidden || + if (cx.document_hidden() || !cx.tcx.is_doc_hidden(use_def_id)) && - // We never check for "cx.render_options.document_private" + // We never check for "cx.document_private()" // because if a re-export is not fully public, it's never // documented. cx.tcx.local_visibility(local_use_def_id).is_public() @@ -2634,7 +2634,7 @@ fn get_all_import_attributes<'hir>( attrs = import_attrs.iter().map(|attr| (Cow::Borrowed(attr), Some(def_id))).collect(); first = false; // We don't add attributes of an intermediate re-export if it has `#[doc(hidden)]`. - } else if cx.render_options.document_hidden || !cx.tcx.is_doc_hidden(def_id) { + } else if cx.document_hidden() || !cx.tcx.is_doc_hidden(def_id) { add_without_unwanted_attributes(&mut attrs, import_attrs, is_inline, Some(def_id)); } } @@ -3075,8 +3075,7 @@ fn clean_use_statement_inner<'tcx>( // #[doc(no_inline)] attribute is present. // Don't inline doc(hidden) imports so they can be stripped at a later stage. let mut denied = cx.is_json_output() - || !(visibility.is_public() - || (cx.render_options.document_private && is_visible_from_parent_mod)) + || !(visibility.is_public() || (cx.document_private() && is_visible_from_parent_mod)) || pub_underscore || attrs.iter().any(|a| { a.has_name(sym::doc) diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 73d0f4027540..6e4c65dc9127 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -40,6 +40,7 @@ use crate::clean::utils::{is_literal_expr, print_evaluated_const}; use crate::core::DocContext; use crate::formats::cache::Cache; use crate::formats::item_type::ItemType; +use crate::html::format::HrefInfo; use crate::html::render::Context; use crate::passes::collect_intra_doc_links::UrlFragment; @@ -519,16 +520,16 @@ impl Item { .iter() .filter_map(|ItemLink { link: s, link_text, page_id: id, fragment }| { debug!(?id); - if let Ok((mut href, ..)) = href(*id, cx) { - debug!(?href); + if let Ok(HrefInfo { mut url, .. }) = href(*id, cx) { + debug!(?url); if let Some(ref fragment) = *fragment { - fragment.render(&mut href, cx.tcx()) + fragment.render(&mut url, cx.tcx()) } Some(RenderedLink { original_text: s.clone(), new_text: link_text.clone(), tooltip: link_tooltip(*id, fragment, cx).to_string(), - href, + href: url, }) } else { None diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index 23aaa6cf9860..060abfd05e04 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -303,7 +303,7 @@ pub(crate) fn name_from_pat(p: &hir::Pat<'_>) -> Symbol { return kw::Underscore; } PatKind::Binding(_, _, ident, _) => return ident.name, - PatKind::Box(p) | PatKind::Ref(p, _) | PatKind::Guard(p, _) => return name_from_pat(p), + PatKind::Box(p) | PatKind::Ref(p, _, _) | PatKind::Guard(p, _) => return name_from_pat(p), PatKind::TupleStruct(p, ..) | PatKind::Expr(PatExpr { kind: PatExprKind::Path(p), .. }) => { qpath_to_string(p) } diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 451d0b4f5be9..6e70f5b41c42 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -62,8 +62,6 @@ pub(crate) struct DocContext<'tcx> { // FIXME(eddyb) make this a `ty::TraitRef<'tcx>` set. pub(crate) generated_synthetics: FxHashSet<(Ty<'tcx>, DefId)>, pub(crate) auto_traits: Vec, - /// The options given to rustdoc that could be relevant to a pass. - pub(crate) render_options: RenderOptions, /// This same cache is used throughout rustdoc, including in [`crate::html::render`]. pub(crate) cache: Cache, /// Used by [`clean::inline`] to tell if an item has already been inlined. @@ -139,6 +137,16 @@ impl<'tcx> DocContext<'tcx> { pub(crate) fn is_json_output(&self) -> bool { self.output_format.is_json() && !self.show_coverage } + + /// If `--document-private-items` was passed to rustdoc. + pub(crate) fn document_private(&self) -> bool { + self.cache.document_private + } + + /// If `--document-hidden-items` was passed to rustdoc. + pub(crate) fn document_hidden(&self) -> bool { + self.cache.document_hidden + } } /// Creates a new `DiagCtxt` that can be used to emit warnings and errors. @@ -379,7 +387,6 @@ pub(crate) fn run_global_ctxt( cache: Cache::new(render_options.document_private, render_options.document_hidden), inlined: FxHashSet::default(), output_format, - render_options, show_coverage, }; @@ -416,14 +423,6 @@ pub(crate) fn run_global_ctxt( ); } - // Process all of the crate attributes, extracting plugin metadata along - // with the passes which we are supposed to run. - for attr in krate.module.attrs.lists(sym::doc) { - if attr.is_word() && attr.has_name(sym::document_private_items) { - ctxt.render_options.document_private = true; - } - } - info!("Executing passes"); let mut visited = FxHashMap::default(); @@ -432,9 +431,9 @@ pub(crate) fn run_global_ctxt( for p in passes::defaults(show_coverage) { let run = match p.condition { Always => true, - WhenDocumentPrivate => ctxt.render_options.document_private, - WhenNotDocumentPrivate => !ctxt.render_options.document_private, - WhenNotDocumentHidden => !ctxt.render_options.document_hidden, + WhenDocumentPrivate => ctxt.document_private(), + WhenNotDocumentPrivate => !ctxt.document_private(), + WhenNotDocumentHidden => !ctxt.document_hidden(), }; if run { debug!("running pass {}", p.pass.name); @@ -452,7 +451,8 @@ pub(crate) fn run_global_ctxt( tcx.sess.time("check_lint_expectations", || tcx.check_expectations(Some(sym::rustdoc))); - krate = tcx.sess.time("create_format_cache", || Cache::populate(&mut ctxt, krate)); + krate = + tcx.sess.time("create_format_cache", || Cache::populate(&mut ctxt, krate, &render_options)); let mut collector = LinkCollector { cx: &mut ctxt, visited_links: visited, ambiguous_links: ambiguous }; @@ -460,7 +460,7 @@ pub(crate) fn run_global_ctxt( tcx.dcx().abort_if_errors(); - (krate, ctxt.render_options, ctxt.cache, expanded_macros) + (krate, render_options, ctxt.cache, expanded_macros) } /// Due to , diff --git a/src/librustdoc/display.rs b/src/librustdoc/display.rs index d62ea4c36880..550be1ae8958 100644 --- a/src/librustdoc/display.rs +++ b/src/librustdoc/display.rs @@ -10,19 +10,18 @@ pub(crate) trait Joined: IntoIterator { /// /// The performance of `joined` is slightly better than `format`, since it doesn't need to use a `Cell` to keep track of whether [`fmt`](Display::fmt) /// was already called (`joined`'s API doesn't allow it be called more than once). - fn joined(self, sep: impl Display, f: &mut Formatter<'_>) -> fmt::Result; + fn joined(&mut self, sep: impl Display, f: &mut Formatter<'_>) -> fmt::Result; } impl Joined for I where - I: IntoIterator, + I: Iterator, T: Display, { - fn joined(self, sep: impl Display, f: &mut Formatter<'_>) -> fmt::Result { - let mut iter = self.into_iter(); - let Some(first) = iter.next() else { return Ok(()) }; + fn joined(&mut self, sep: impl Display, f: &mut Formatter<'_>) -> fmt::Result { + let Some(first) = self.next() else { return Ok(()) }; first.fmt(f)?; - for item in iter { + for item in self { sep.fmt(f)?; item.fmt(f)?; } diff --git a/src/librustdoc/doctest/make.rs b/src/librustdoc/doctest/make.rs index 6c177f942fb0..e9f5024e494d 100644 --- a/src/librustdoc/doctest/make.rs +++ b/src/librustdoc/doctest/make.rs @@ -8,8 +8,8 @@ use std::sync::Arc; use rustc_ast::token::{Delimiter, TokenKind}; use rustc_ast::tokenstream::TokenTree; use rustc_ast::{self as ast, AttrStyle, HasAttrs, StmtKind}; -use rustc_errors::emitter::stderr_destination; -use rustc_errors::{AutoStream, ColorConfig, DiagCtxtHandle}; +use rustc_errors::emitter::get_stderr_color_choice; +use rustc_errors::{AutoStream, ColorChoice, ColorConfig, DiagCtxtHandle}; use rustc_parse::lexer::StripTokens; use rustc_parse::new_parser_from_source_str; use rustc_session::parse::ParseSess; @@ -446,7 +446,7 @@ fn parse_source( span: Span, ) -> Result { use rustc_errors::DiagCtxt; - use rustc_errors::emitter::{Emitter, HumanEmitter}; + use rustc_errors::emitter::HumanEmitter; use rustc_span::source_map::FilePathMapping; let mut info = @@ -458,9 +458,12 @@ fn parse_source( let sm = Arc::new(SourceMap::new(FilePathMapping::empty())); let translator = rustc_driver::default_translator(); - info.supports_color = - HumanEmitter::new(stderr_destination(ColorConfig::Auto), translator.clone()) - .supports_color(); + let supports_color = match get_stderr_color_choice(ColorConfig::Auto, &std::io::stderr()) { + ColorChoice::Auto => unreachable!(), + ColorChoice::AlwaysAnsi | ColorChoice::Always => true, + ColorChoice::Never => false, + }; + info.supports_color = supports_color; // Any errors in parsing should also appear when the doctest is compiled for real, so just // send all the errors that the parser emits directly into a `Sink` instead of stderr. let emitter = HumanEmitter::new(AutoStream::never(Box::new(io::sink())), translator); diff --git a/src/librustdoc/formats/cache.rs b/src/librustdoc/formats/cache.rs index 5e5592269af6..56f10b03d62d 100644 --- a/src/librustdoc/formats/cache.rs +++ b/src/librustdoc/formats/cache.rs @@ -10,6 +10,7 @@ use tracing::debug; use crate::clean::types::ExternalLocation; use crate::clean::{self, ExternalCrate, ItemId, PrimitiveType}; +use crate::config::RenderOptions; use crate::core::DocContext; use crate::fold::DocFolder; use crate::formats::Impl; @@ -156,7 +157,11 @@ impl Cache { /// Populates the `Cache` with more data. The returned `Crate` will be missing some data that was /// in `krate` due to the data being moved into the `Cache`. - pub(crate) fn populate(cx: &mut DocContext<'_>, mut krate: clean::Crate) -> clean::Crate { + pub(crate) fn populate( + cx: &mut DocContext<'_>, + mut krate: clean::Crate, + render_options: &RenderOptions, + ) -> clean::Crate { let tcx = cx.tcx; // Crawl the crate to build various caches used for the output @@ -164,7 +169,6 @@ impl Cache { assert!(cx.external_traits.is_empty()); cx.cache.traits = mem::take(&mut krate.external_traits); - let render_options = &cx.render_options; let extern_url_takes_precedence = render_options.extern_html_root_takes_precedence; let dst = &render_options.output; diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 337429a6248d..4843c20c758e 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -17,10 +17,10 @@ use rustc_abi::ExternAbi; use rustc_ast::join_path_syms; use rustc_data_structures::fx::FxHashSet; use rustc_hir as hir; -use rustc_hir::def::DefKind; +use rustc_hir::def::{DefKind, MacroKinds}; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; use rustc_hir::{ConstStability, StabilityLevel, StableSince}; -use rustc_metadata::creader::{CStore, LoadedMacro}; +use rustc_metadata::creader::CStore; use rustc_middle::ty::{self, TyCtxt, TypingMode}; use rustc_span::symbol::kw; use rustc_span::{Symbol, sym}; @@ -349,38 +349,44 @@ pub(crate) enum HrefError { UnnamableItem, } +/// Type representing information of an `href` attribute. +pub(crate) struct HrefInfo { + /// URL to the item page. + pub(crate) url: String, + /// Kind of the item (used to generate the `title` attribute). + pub(crate) kind: ItemType, + /// Rust path to the item (used to generate the `title` attribute). + pub(crate) rust_path: Vec, +} + /// This function is to get the external macro path because they are not in the cache used in /// `href_with_root_path`. fn generate_macro_def_id_path( def_id: DefId, cx: &Context<'_>, root_path: Option<&str>, -) -> Result<(String, ItemType, Vec), HrefError> { +) -> Result { let tcx = cx.tcx(); let crate_name = tcx.crate_name(def_id.krate); let cache = cx.cache(); - let fqp = clean::inline::item_relative_path(tcx, def_id); - let mut relative = fqp.iter().copied(); let cstore = CStore::from_tcx(tcx); // We need this to prevent a `panic` when this function is used from intra doc links... if !cstore.has_crate_data(def_id.krate) { debug!("No data for crate {crate_name}"); return Err(HrefError::NotInExternalCache); } - // Check to see if it is a macro 2.0 or built-in macro. - // More information in . - let is_macro_2 = match cstore.load_macro_untracked(def_id, tcx) { - // If `def.macro_rules` is `true`, then it's not a macro 2.0. - LoadedMacro::MacroDef { def, .. } => !def.macro_rules, - _ => false, + let DefKind::Macro(kinds) = tcx.def_kind(def_id) else { + unreachable!(); }; - - let mut path = if is_macro_2 { - once(crate_name).chain(relative).collect() + let item_type = if kinds == MacroKinds::DERIVE { + ItemType::ProcDerive + } else if kinds == MacroKinds::ATTR { + ItemType::ProcAttribute } else { - vec![crate_name, relative.next_back().unwrap()] + ItemType::Macro }; + let mut path = clean::inline::get_item_path(tcx, def_id, item_type); if path.len() < 2 { // The minimum we can have is the crate name followed by the macro name. If shorter, then // it means that `relative` was empty, which is an error. @@ -388,8 +394,11 @@ fn generate_macro_def_id_path( return Err(HrefError::NotInExternalCache); } - if let Some(last) = path.last_mut() { - *last = Symbol::intern(&format!("macro.{last}.html")); + // FIXME: Try to use `iter().chain().once()` instead. + let mut prev = None; + if let Some(last) = path.pop() { + path.push(Symbol::intern(&format!("{}.{last}.html", item_type.as_str()))); + prev = Some(last); } let url = match cache.extern_locations[&def_id.krate] { @@ -410,7 +419,11 @@ fn generate_macro_def_id_path( return Err(HrefError::NotInExternalCache); } }; - Ok((url, ItemType::Macro, fqp)) + if let Some(prev) = prev { + path.pop(); + path.push(prev); + } + Ok(HrefInfo { url, kind: item_type, rust_path: path }) } fn generate_item_def_id_path( @@ -419,7 +432,7 @@ fn generate_item_def_id_path( cx: &Context<'_>, root_path: Option<&str>, original_def_kind: DefKind, -) -> Result<(String, ItemType, Vec), HrefError> { +) -> Result { use rustc_middle::traits::ObligationCause; use rustc_trait_selection::infer::TyCtxtInferExt; use rustc_trait_selection::traits::query::normalize::QueryNormalizeExt; @@ -455,7 +468,7 @@ fn generate_item_def_id_path( let kind = ItemType::from_def_kind(original_def_kind, Some(def_kind)); url_parts = format!("{url_parts}#{kind}.{}", tcx.item_name(original_def_id)) }; - Ok((url_parts, shortty, fqp)) + Ok(HrefInfo { url: url_parts, kind: shortty, rust_path: fqp }) } /// Checks if the given defid refers to an item that is unnamable, such as one defined in a const block. @@ -530,7 +543,7 @@ pub(crate) fn href_with_root_path( original_did: DefId, cx: &Context<'_>, root_path: Option<&str>, -) -> Result<(String, ItemType, Vec), HrefError> { +) -> Result { let tcx = cx.tcx(); let def_kind = tcx.def_kind(original_did); let did = match def_kind { @@ -596,14 +609,14 @@ pub(crate) fn href_with_root_path( } } }; - let url_parts = make_href(root_path, shortty, url_parts, fqp, is_remote); - Ok((url_parts, shortty, fqp.clone())) + Ok(HrefInfo { + url: make_href(root_path, shortty, url_parts, fqp, is_remote), + kind: shortty, + rust_path: fqp.clone(), + }) } -pub(crate) fn href( - did: DefId, - cx: &Context<'_>, -) -> Result<(String, ItemType, Vec), HrefError> { +pub(crate) fn href(did: DefId, cx: &Context<'_>) -> Result { href_with_root_path(did, cx, None) } @@ -690,12 +703,12 @@ fn resolved_path( } else { let path = fmt::from_fn(|f| { if use_absolute { - if let Ok((_, _, fqp)) = href(did, cx) { + if let Ok(HrefInfo { rust_path, .. }) = href(did, cx) { write!( f, "{path}::{anchor}", - path = join_path_syms(&fqp[..fqp.len() - 1]), - anchor = print_anchor(did, *fqp.last().unwrap(), cx) + path = join_path_syms(&rust_path[..rust_path.len() - 1]), + anchor = print_anchor(did, *rust_path.last().unwrap(), cx) ) } else { write!(f, "{}", last.name) @@ -824,12 +837,11 @@ fn print_higher_ranked_params_with_space( pub(crate) fn print_anchor(did: DefId, text: Symbol, cx: &Context<'_>) -> impl Display { fmt::from_fn(move |f| { - let parts = href(did, cx); - if let Ok((url, short_ty, fqp)) = parts { + if let Ok(HrefInfo { url, kind, rust_path }) = href(did, cx) { write!( f, - r#"{text}"#, - path = join_path_syms(fqp), + r#"{text}"#, + path = join_path_syms(rust_path), text = EscapeBodyText(text.as_str()), ) } else { @@ -1056,14 +1068,14 @@ fn print_qpath_data(qpath_data: &clean::QPathData, cx: &Context<'_>) -> impl Dis None => self_type.def_id(cx.cache()).and_then(|did| href(did, cx).ok()), }; - if let Some((url, _, path)) = parent_href { + if let Some(HrefInfo { url, rust_path, .. }) = parent_href { write!( f, "{name}", shortty = ItemType::AssocType, name = assoc.name, - path = join_path_syms(path), + path = join_path_syms(rust_path), ) } else { write!(f, "{}", assoc.name) diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs index 798fbd284ca8..6f6345cd8666 100644 --- a/src/librustdoc/html/highlight.rs +++ b/src/librustdoc/html/highlight.rs @@ -21,6 +21,7 @@ use super::format; use crate::clean::PrimitiveType; use crate::display::Joined as _; use crate::html::escape::EscapeBodyText; +use crate::html::format::HrefInfo; use crate::html::macro_expansion::ExpandedCode; use crate::html::render::span_map::{DUMMY_SP, Span}; use crate::html::render::{Context, LinkFromSrc}; @@ -1357,7 +1358,7 @@ fn generate_link_to_def( LinkFromSrc::External(def_id) => { format::href_with_root_path(*def_id, context, Some(href_context.root_path)) .ok() - .map(|(url, _, _)| url) + .map(|HrefInfo { url, .. }| url) } LinkFromSrc::Primitive(prim) => format::href_with_root_path( PrimitiveType::primitive_locations(context.tcx())[prim], @@ -1365,11 +1366,11 @@ fn generate_link_to_def( Some(href_context.root_path), ) .ok() - .map(|(url, _, _)| url), + .map(|HrefInfo { url, .. }| url), LinkFromSrc::Doc(def_id) => { format::href_with_root_path(*def_id, context, Some(href_context.root_path)) .ok() - .map(|(doc_link, _, _)| doc_link) + .map(|HrefInfo { url, .. }| url) } } }) diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 36990332b2fc..871ed53bd338 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -74,7 +74,7 @@ use crate::formats::cache::Cache; use crate::formats::item_type::ItemType; use crate::html::escape::Escape; use crate::html::format::{ - Ending, HrefError, PrintWithSpace, full_print_fn_decl, href, print_abi_with_space, + Ending, HrefError, HrefInfo, PrintWithSpace, full_print_fn_decl, href, print_abi_with_space, print_constness_with_space, print_default_space, print_generic_bounds, print_generics, print_impl, print_path, print_type, print_where_clause, visibility_print_with_space, }; @@ -982,7 +982,7 @@ fn assoc_href_attr( }; match href(did.expect_def_id(), cx) { - Ok((url, ..)) => Href::Url(url, item_type), + Ok(HrefInfo { url, .. }) => Href::Url(url, item_type), // The link is broken since it points to an external crate that wasn't documented. // Do not create any link in such case. This is better than falling back to a // dummy anchor like `#{item_type}.{name}` representing the `id` of *this* impl item diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index 909262d563e9..edafc9e7a089 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -4,6 +4,7 @@ use rustc_abi::ExternAbi; use rustc_ast::ast; +use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::thin_vec::ThinVec; use rustc_hir as hir; use rustc_hir::attrs::{self, DeprecatedSince}; @@ -988,3 +989,55 @@ fn format_integer_type(it: rustc_abi::IntegerType) -> String { } .to_owned() } + +pub(super) fn target(sess: &rustc_session::Session) -> Target { + // Build a set of which features are enabled on this target + let globally_enabled_features: FxHashSet<&str> = + sess.unstable_target_features.iter().map(|name| name.as_str()).collect(); + + // Build a map of target feature stability by feature name + use rustc_target::target_features::Stability; + let feature_stability: FxHashMap<&str, Stability> = sess + .target + .rust_target_features() + .iter() + .copied() + .map(|(name, stability, _)| (name, stability)) + .collect(); + + Target { + triple: sess.opts.target_triple.tuple().into(), + target_features: sess + .target + .rust_target_features() + .iter() + .copied() + .filter(|(_, stability, _)| { + // Describe only target features which the user can toggle + stability.toggle_allowed().is_ok() + }) + .map(|(name, stability, implied_features)| { + TargetFeature { + name: name.into(), + unstable_feature_gate: match stability { + Stability::Unstable(feature_gate) => Some(feature_gate.as_str().into()), + _ => None, + }, + implies_features: implied_features + .iter() + .copied() + .filter(|name| { + // Imply only target features which the user can toggle + feature_stability + .get(name) + .map(|stability| stability.toggle_allowed().is_ok()) + .unwrap_or(false) + }) + .map(String::from) + .collect(), + globally_enabled: globally_enabled_features.contains(name), + } + }) + .collect(), + } +} diff --git a/src/librustdoc/json/mod.rs b/src/librustdoc/json/mod.rs index b724d7e866a0..b020e3d924a4 100644 --- a/src/librustdoc/json/mod.rs +++ b/src/librustdoc/json/mod.rs @@ -14,7 +14,6 @@ use std::io::{BufWriter, Write, stdout}; use std::path::PathBuf; use std::rc::Rc; -use rustc_data_structures::fx::FxHashSet; use rustc_hir::def_id::{DefId, DefIdSet}; use rustc_middle::ty::TyCtxt; use rustc_session::Session; @@ -123,58 +122,6 @@ impl<'tcx> JsonRenderer<'tcx> { } } -fn target(sess: &rustc_session::Session) -> types::Target { - // Build a set of which features are enabled on this target - let globally_enabled_features: FxHashSet<&str> = - sess.unstable_target_features.iter().map(|name| name.as_str()).collect(); - - // Build a map of target feature stability by feature name - use rustc_target::target_features::Stability; - let feature_stability: FxHashMap<&str, Stability> = sess - .target - .rust_target_features() - .iter() - .copied() - .map(|(name, stability, _)| (name, stability)) - .collect(); - - types::Target { - triple: sess.opts.target_triple.tuple().into(), - target_features: sess - .target - .rust_target_features() - .iter() - .copied() - .filter(|(_, stability, _)| { - // Describe only target features which the user can toggle - stability.toggle_allowed().is_ok() - }) - .map(|(name, stability, implied_features)| { - types::TargetFeature { - name: name.into(), - unstable_feature_gate: match stability { - Stability::Unstable(feature_gate) => Some(feature_gate.as_str().into()), - _ => None, - }, - implies_features: implied_features - .iter() - .copied() - .filter(|name| { - // Imply only target features which the user can toggle - feature_stability - .get(name) - .map(|stability| stability.toggle_allowed().is_ok()) - .unwrap_or(false) - }) - .map(String::from) - .collect(), - globally_enabled: globally_enabled_features.contains(name), - } - }) - .collect(), - } -} - impl<'tcx> JsonRenderer<'tcx> { pub(crate) fn init( krate: clean::Crate, @@ -317,7 +264,7 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> { // multiple targets: https://github.com/rust-lang/rust/pull/137632 // // We want to describe a single target, so pass tcx.sess rather than tcx. - let target = target(self.tcx.sess); + let target = conversions::target(self.tcx.sess); debug!("Constructing Output"); let output_crate = types::Crate { diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index e88180c3033b..57db12d2cb5d 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -61,11 +61,6 @@ extern crate rustc_target; extern crate rustc_trait_selection; extern crate test; -// See docs in https://github.com/rust-lang/rust/blob/HEAD/compiler/rustc/src/main.rs -// about jemalloc. -#[cfg(feature = "jemalloc")] -extern crate tikv_jemalloc_sys as jemalloc_sys; - use std::env::{self, VarError}; use std::io::{self, IsTerminal}; use std::path::Path; @@ -77,6 +72,10 @@ use rustc_interface::interface; use rustc_middle::ty::TyCtxt; use rustc_session::config::{ErrorOutputType, RustcOptGroup, make_crate_type_option}; use rustc_session::{EarlyDiagCtxt, getopts}; +/// See docs in https://github.com/rust-lang/rust/blob/HEAD/compiler/rustc/src/main.rs +/// and https://github.com/rust-lang/rust/pull/146627 for why we need this `use` statement. +#[cfg(feature = "jemalloc")] +use tikv_jemalloc_sys as _; use tracing::info; use crate::clean::utils::DOC_RUST_LANG_ORG_VERSION; @@ -124,37 +123,6 @@ mod visit_ast; mod visit_lib; pub fn main() { - // See docs in https://github.com/rust-lang/rust/blob/HEAD/compiler/rustc/src/main.rs - // about jemalloc. - #[cfg(feature = "jemalloc")] - { - use std::os::raw::{c_int, c_void}; - - #[used] - static _F1: unsafe extern "C" fn(usize, usize) -> *mut c_void = jemalloc_sys::calloc; - #[used] - static _F2: unsafe extern "C" fn(*mut *mut c_void, usize, usize) -> c_int = - jemalloc_sys::posix_memalign; - #[used] - static _F3: unsafe extern "C" fn(usize, usize) -> *mut c_void = jemalloc_sys::aligned_alloc; - #[used] - static _F4: unsafe extern "C" fn(usize) -> *mut c_void = jemalloc_sys::malloc; - #[used] - static _F5: unsafe extern "C" fn(*mut c_void, usize) -> *mut c_void = jemalloc_sys::realloc; - #[used] - static _F6: unsafe extern "C" fn(*mut c_void) = jemalloc_sys::free; - - #[cfg(target_os = "macos")] - { - unsafe extern "C" { - fn _rjem_je_zone_register(); - } - - #[used] - static _F7: unsafe extern "C" fn() = _rjem_je_zone_register; - } - } - let mut early_dcx = EarlyDiagCtxt::new(ErrorOutputType::default()); rustc_driver::install_ice_hook( diff --git a/src/librustdoc/passes/check_doc_test_visibility.rs b/src/librustdoc/passes/check_doc_test_visibility.rs index e0ea760cf3ba..39116061f485 100644 --- a/src/librustdoc/passes/check_doc_test_visibility.rs +++ b/src/librustdoc/passes/check_doc_test_visibility.rs @@ -102,7 +102,7 @@ pub(crate) fn should_have_doc_example(cx: &DocContext<'_>, item: &clean::Item) - return false; } - if (!cx.render_options.document_hidden + if (!cx.document_hidden() && (cx.tcx.is_doc_hidden(def_id.to_def_id()) || inherits_doc_hidden(cx.tcx, def_id, None))) || cx.tcx.def_span(def_id.to_def_id()).in_derive_expansion() { diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index d09949e6868d..e29256bb5d1a 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -1070,7 +1070,7 @@ fn preprocessed_markdown_links(s: &str) -> Vec { impl LinkCollector<'_, '_> { #[instrument(level = "debug", skip_all)] fn resolve_links(&mut self, item: &Item) { - if !self.cx.render_options.document_private + if !self.cx.document_private() && let Some(def_id) = item.item_id.as_def_id() && let Some(def_id) = def_id.as_local() && !self.cx.tcx.effective_visibilities(()).is_exported(def_id) @@ -1215,7 +1215,6 @@ impl LinkCollector<'_, '_> { || !did.is_local() } - #[allow(rustc::potential_query_instability)] pub(crate) fn resolve_ambiguities(&mut self) { let mut ambiguous_links = mem::take(&mut self.ambiguous_links); for ((item_id, path_str), info_items) in ambiguous_links.iter_mut() { @@ -2400,7 +2399,7 @@ fn privacy_error(cx: &DocContext<'_>, diag_info: &DiagnosticInfo<'_>, path_str: diag.span_label(sp, "this item is private"); } - let note_msg = if cx.render_options.document_private { + let note_msg = if cx.document_private() { "this link resolves only because you passed `--document-private-items`, but will break without" } else { "this link will resolve properly if you pass `--document-private-items`" diff --git a/src/librustdoc/passes/lint/redundant_explicit_links.rs b/src/librustdoc/passes/lint/redundant_explicit_links.rs index 855b1884cea9..e49f54f6df94 100644 --- a/src/librustdoc/passes/lint/redundant_explicit_links.rs +++ b/src/librustdoc/passes/lint/redundant_explicit_links.rs @@ -46,13 +46,13 @@ fn check_redundant_explicit_link_for_did( return; }; - let is_hidden = !cx.render_options.document_hidden + let is_hidden = !cx.document_hidden() && (item.is_doc_hidden() || inherits_doc_hidden(cx.tcx, local_item_id, None)); if is_hidden { return; } - let is_private = !cx.render_options.document_private - && !cx.cache.effective_visibilities.is_directly_public(cx.tcx, did); + let is_private = + !cx.document_private() && !cx.cache.effective_visibilities.is_directly_public(cx.tcx, did); if is_private { return; } diff --git a/src/librustdoc/passes/strip_hidden.rs b/src/librustdoc/passes/strip_hidden.rs index 525d05b6a986..27065d7675bb 100644 --- a/src/librustdoc/passes/strip_hidden.rs +++ b/src/librustdoc/passes/strip_hidden.rs @@ -43,8 +43,8 @@ pub(crate) fn strip_hidden(krate: clean::Crate, cx: &mut DocContext<'_>) -> clea retained: &retained, cache: &cx.cache, is_json_output, - document_private: cx.render_options.document_private, - document_hidden: cx.render_options.document_hidden, + document_private: cx.document_private(), + document_hidden: cx.document_hidden(), }; stripper.fold_crate(krate) } diff --git a/src/librustdoc/passes/strip_priv_imports.rs b/src/librustdoc/passes/strip_priv_imports.rs index b9b2431f06f2..a169797e00b2 100644 --- a/src/librustdoc/passes/strip_priv_imports.rs +++ b/src/librustdoc/passes/strip_priv_imports.rs @@ -14,10 +14,6 @@ pub(crate) const STRIP_PRIV_IMPORTS: Pass = Pass { pub(crate) fn strip_priv_imports(krate: clean::Crate, cx: &mut DocContext<'_>) -> clean::Crate { let is_json_output = cx.is_json_output(); - ImportStripper { - tcx: cx.tcx, - is_json_output, - document_hidden: cx.render_options.document_hidden, - } - .fold_crate(krate) + ImportStripper { tcx: cx.tcx, is_json_output, document_hidden: cx.document_hidden() } + .fold_crate(krate) } diff --git a/src/librustdoc/passes/strip_private.rs b/src/librustdoc/passes/strip_private.rs index 1bd8a7838ec0..045bf0c0be02 100644 --- a/src/librustdoc/passes/strip_private.rs +++ b/src/librustdoc/passes/strip_private.rs @@ -29,12 +29,9 @@ pub(crate) fn strip_private(mut krate: clean::Crate, cx: &mut DocContext<'_>) -> is_json_output, tcx: cx.tcx, }; - krate = ImportStripper { - tcx: cx.tcx, - is_json_output, - document_hidden: cx.render_options.document_hidden, - } - .fold_crate(stripper.fold_crate(krate)); + krate = + ImportStripper { tcx: cx.tcx, is_json_output, document_hidden: cx.document_hidden() } + .fold_crate(stripper.fold_crate(krate)); } // strip all impls referencing private items @@ -43,8 +40,8 @@ pub(crate) fn strip_private(mut krate: clean::Crate, cx: &mut DocContext<'_>) -> retained: &retained, cache: &cx.cache, is_json_output, - document_private: cx.render_options.document_private, - document_hidden: cx.render_options.document_hidden, + document_private: cx.document_private(), + document_hidden: cx.document_hidden(), }; stripper.fold_crate(krate) } diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index dc9889cec219..51b2821eb1e5 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -243,7 +243,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { return false; }; - let document_hidden = self.cx.render_options.document_hidden; + let document_hidden = self.cx.document_hidden(); let use_attrs = tcx.hir_attrs(tcx.local_def_id_to_hir_id(def_id)); // Don't inline `doc(hidden)` imports so they can be stripped at a later stage. let is_no_inline = hir_attr_lists(use_attrs, sym::doc).has_word(sym::no_inline) @@ -351,7 +351,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { import_def_id: LocalDefId, target_def_id: LocalDefId, ) -> bool { - if self.cx.render_options.document_hidden { + if self.cx.document_hidden() { return true; } let tcx = self.cx.tcx; diff --git a/src/librustdoc/visit_lib.rs b/src/librustdoc/visit_lib.rs index 369fc52860ee..297485659fa1 100644 --- a/src/librustdoc/visit_lib.rs +++ b/src/librustdoc/visit_lib.rs @@ -30,11 +30,12 @@ impl RustdocEffectiveVisibilities { pub(crate) fn lib_embargo_visit_item(cx: &mut DocContext<'_>, def_id: DefId) { assert!(!def_id.is_local()); + let document_hidden = cx.document_hidden(); LibEmbargoVisitor { tcx: cx.tcx, extern_public: &mut cx.cache.effective_visibilities.extern_public, visited_mods: Default::default(), - document_hidden: cx.render_options.document_hidden, + document_hidden, } .visit_item(def_id) } diff --git a/src/llvm-project b/src/llvm-project index 4f74b76fb696..16b5ac8b0a54 160000 --- a/src/llvm-project +++ b/src/llvm-project @@ -1 +1 @@ -Subproject commit 4f74b76fb69688474e073fb26b316d9ea571388f +Subproject commit 16b5ac8b0a5456eb23c72e1bff3fc9bd6e824f84 diff --git a/src/stage0 b/src/stage0 index 43e1a635a42c..0e4e9eb1c4b9 100644 --- a/src/stage0 +++ b/src/stage0 @@ -2,7 +2,7 @@ dist_server=https://static.rust-lang.org artifacts_server=https://ci-artifacts.rust-lang.org/rustc-builds artifacts_with_llvm_assertions_server=https://ci-artifacts.rust-lang.org/rustc-builds-alt git_merge_commit_email=bors@rust-lang.org -nightly_branch=master +nightly_branch=main # The configuration above this comment is editable, and can be changed # by forks of the repository if they have alternate values. diff --git a/src/tools/clippy/Cargo.toml b/src/tools/clippy/Cargo.toml index fee885d8fa7e..f0f9c05e4330 100644 --- a/src/tools/clippy/Cargo.toml +++ b/src/tools/clippy/Cargo.toml @@ -31,6 +31,7 @@ tempfile = { version = "3.20", optional = true } termize = "0.2" color-print = "0.3.4" anstream = "0.6.18" +tikv-jemalloc-sys = { version = "0.6.1", optional = true, features = ['override_allocator_on_supported_platforms'] } [dev-dependencies] cargo_metadata = "0.18.1" @@ -56,7 +57,7 @@ rustc_tools_util = { path = "rustc_tools_util", version = "0.4.2" } [features] integration = ["dep:tempfile"] internal = ["dep:clippy_lints_internal", "dep:tempfile"] -jemalloc = [] +jemalloc = ["dep:tikv-jemalloc-sys"] [package.metadata.rust-analyzer] # This package uses #[feature(rustc_private)] diff --git a/src/tools/clippy/clippy_lints/src/equatable_if_let.rs b/src/tools/clippy/clippy_lints/src/equatable_if_let.rs index c3fc09343dbf..9b5cd7e1731f 100644 --- a/src/tools/clippy/clippy_lints/src/equatable_if_let.rs +++ b/src/tools/clippy/clippy_lints/src/equatable_if_let.rs @@ -55,7 +55,7 @@ fn unary_pattern(pat: &Pat<'_>) -> bool { | PatKind::Err(_) => false, PatKind::Struct(_, a, etc) => etc.is_none() && a.iter().all(|x| unary_pattern(x.pat)), PatKind::Tuple(a, etc) | PatKind::TupleStruct(_, a, etc) => etc.as_opt_usize().is_none() && array_rec(a), - PatKind::Ref(x, _) | PatKind::Box(x) | PatKind::Deref(x) | PatKind::Guard(x, _) => unary_pattern(x), + PatKind::Ref(x, _, _) | PatKind::Box(x) | PatKind::Deref(x) | PatKind::Guard(x, _) => unary_pattern(x), PatKind::Expr(_) => true, } } diff --git a/src/tools/clippy/clippy_lints/src/loops/manual_find.rs b/src/tools/clippy/clippy_lints/src/loops/manual_find.rs index c38cf83f4410..3455a47ba078 100644 --- a/src/tools/clippy/clippy_lints/src/loops/manual_find.rs +++ b/src/tools/clippy/clippy_lints/src/loops/manual_find.rs @@ -43,7 +43,7 @@ pub(super) fn check<'tcx>( let mut snippet = make_iterator_snippet(cx, arg, &mut applicability); // Checks if `pat` is a single reference to a binding (`&x`) let is_ref_to_binding = - matches!(pat.kind, PatKind::Ref(inner, _) if matches!(inner.kind, PatKind::Binding(..))); + matches!(pat.kind, PatKind::Ref(inner, _, _) if matches!(inner.kind, PatKind::Binding(..))); // If `pat` is not a binding or a reference to a binding (`x` or `&x`) // we need to map it to the binding returned by the function (i.e. `.map(|(x, _)| x)`) if !(matches!(pat.kind, PatKind::Binding(..)) || is_ref_to_binding) { diff --git a/src/tools/clippy/clippy_lints/src/manual_retain.rs b/src/tools/clippy/clippy_lints/src/manual_retain.rs index 674f0da818f5..6870c9819fc0 100644 --- a/src/tools/clippy/clippy_lints/src/manual_retain.rs +++ b/src/tools/clippy/clippy_lints/src/manual_retain.rs @@ -157,7 +157,7 @@ fn check_iter( ), ); }, - hir::PatKind::Ref(pat, _) => make_span_lint_and_sugg( + hir::PatKind::Ref(pat, _, _) => make_span_lint_and_sugg( cx, parent_expr_span, format!( @@ -196,7 +196,7 @@ fn check_to_owned( && let filter_body = cx.tcx.hir_body(closure.body) && let [filter_params] = filter_body.params && msrv.meets(cx, msrvs::STRING_RETAIN) - && let hir::PatKind::Ref(pat, _) = filter_params.pat.kind + && let hir::PatKind::Ref(pat, _, _) = filter_params.pat.kind { make_span_lint_and_sugg( cx, diff --git a/src/tools/clippy/clippy_lints/src/matches/manual_ok_err.rs b/src/tools/clippy/clippy_lints/src/matches/manual_ok_err.rs index c9293412fba8..9ced6c9d452b 100644 --- a/src/tools/clippy/clippy_lints/src/matches/manual_ok_err.rs +++ b/src/tools/clippy/clippy_lints/src/matches/manual_ok_err.rs @@ -78,7 +78,7 @@ fn is_variant_or_wildcard(cx: &LateContext<'_>, pat: &Pat<'_>, can_be_wild: bool .is_lang_item(cx, ResultErr) == must_match_err }, - PatKind::Binding(_, _, _, Some(pat)) | PatKind::Ref(pat, _) => { + PatKind::Binding(_, _, _, Some(pat)) | PatKind::Ref(pat, _, _) => { is_variant_or_wildcard(cx, pat, can_be_wild, must_match_err) }, _ => false, diff --git a/src/tools/clippy/clippy_lints/src/matches/manual_utils.rs b/src/tools/clippy/clippy_lints/src/matches/manual_utils.rs index 235cb9e4ecce..19b3572bd3ae 100644 --- a/src/tools/clippy/clippy_lints/src/matches/manual_utils.rs +++ b/src/tools/clippy/clippy_lints/src/matches/manual_utils.rs @@ -254,7 +254,7 @@ pub(super) fn try_parse_pattern<'tcx>( ) -> Option> { match pat.kind { PatKind::Wild => Some(OptionPat::Wild), - PatKind::Ref(pat, _) => f(cx, pat, ref_count + 1, ctxt), + PatKind::Ref(pat, _, _) => f(cx, pat, ref_count + 1, ctxt), PatKind::Expr(PatExpr { kind: PatExprKind::Path(qpath), hir_id, diff --git a/src/tools/clippy/clippy_lints/src/matches/match_ref_pats.rs b/src/tools/clippy/clippy_lints/src/matches/match_ref_pats.rs index 5934ec409935..042817f5cdb8 100644 --- a/src/tools/clippy/clippy_lints/src/matches/match_ref_pats.rs +++ b/src/tools/clippy/clippy_lints/src/matches/match_ref_pats.rs @@ -50,7 +50,7 @@ where } let remaining_suggs = pats.filter_map(|pat| { - if let PatKind::Ref(refp, _) = pat.kind { + if let PatKind::Ref(refp, _, _) = pat.kind { Some((pat.span, snippet(cx, refp.span, "..").to_string())) } else { None diff --git a/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs b/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs index be914429edb4..c20217563d62 100644 --- a/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs +++ b/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs @@ -264,7 +264,7 @@ impl<'a> NormalizedPat<'a> { PatKind::Binding(.., Some(pat)) | PatKind::Box(pat) | PatKind::Deref(pat) - | PatKind::Ref(pat, _) + | PatKind::Ref(pat, _, _) | PatKind::Guard(pat, _) => Self::from_pat(cx, arena, pat), PatKind::Never => Self::Never, PatKind::Struct(ref path, fields, _) => { diff --git a/src/tools/clippy/clippy_lints/src/matches/redundant_guards.rs b/src/tools/clippy/clippy_lints/src/matches/redundant_guards.rs index 7a1dd94567b1..757ecf75ed45 100644 --- a/src/tools/clippy/clippy_lints/src/matches/redundant_guards.rs +++ b/src/tools/clippy/clippy_lints/src/matches/redundant_guards.rs @@ -30,7 +30,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'tcx>], msrv: && !pat_contains_disallowed_or(cx, arm.pat, msrv) { let pat_span = match (arm.pat.kind, binding.byref_ident) { - (PatKind::Ref(pat, _), Some(_)) => pat.span, + (PatKind::Ref(pat, _, _), Some(_)) => pat.span, (PatKind::Ref(..), None) | (_, Some(_)) => continue, _ => arm.pat.span, }; @@ -49,7 +49,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'tcx>], msrv: && !pat_contains_disallowed_or(cx, let_expr.pat, msrv) { let pat_span = match (let_expr.pat.kind, binding.byref_ident) { - (PatKind::Ref(pat, _), Some(_)) => pat.span, + (PatKind::Ref(pat, _, _), Some(_)) => pat.span, (PatKind::Ref(..), None) | (_, Some(_)) => continue, _ => let_expr.pat.span, }; diff --git a/src/tools/clippy/clippy_lints/src/matches/redundant_pattern_match.rs b/src/tools/clippy/clippy_lints/src/matches/redundant_pattern_match.rs index a0f88cf911d8..bc3783750e5c 100644 --- a/src/tools/clippy/clippy_lints/src/matches/redundant_pattern_match.rs +++ b/src/tools/clippy/clippy_lints/src/matches/redundant_pattern_match.rs @@ -186,7 +186,7 @@ fn find_method_sugg_for_if_let<'tcx>( // also look inside refs // if we have &None for example, peel it so we can detect "if let None = x" let check_pat = match let_pat.kind { - PatKind::Ref(inner, _mutability) => inner, + PatKind::Ref(inner, _pinnedness, _mutability) => inner, _ => let_pat, }; let op_ty = cx.typeck_results().expr_ty(let_expr); diff --git a/src/tools/clippy/clippy_lints/src/matches/single_match.rs b/src/tools/clippy/clippy_lints/src/matches/single_match.rs index 44c4d7a31ff3..57a91cf846b8 100644 --- a/src/tools/clippy/clippy_lints/src/matches/single_match.rs +++ b/src/tools/clippy/clippy_lints/src/matches/single_match.rs @@ -373,7 +373,7 @@ impl<'a> PatState<'a> { }, // Patterns for things which can only contain a single sub-pattern. - PatKind::Binding(_, _, _, Some(pat)) | PatKind::Ref(pat, _) | PatKind::Box(pat) | PatKind::Deref(pat) => { + PatKind::Binding(_, _, _, Some(pat)) | PatKind::Ref(pat, _, _) | PatKind::Box(pat) | PatKind::Deref(pat) => { self.add_pat(cx, pat) }, PatKind::Tuple([sub_pat], pos) diff --git a/src/tools/clippy/clippy_lints/src/methods/filter_map.rs b/src/tools/clippy/clippy_lints/src/methods/filter_map.rs index 26b19848fe1b..7b10c37de42d 100644 --- a/src/tools/clippy/clippy_lints/src/methods/filter_map.rs +++ b/src/tools/clippy/clippy_lints/src/methods/filter_map.rs @@ -404,7 +404,7 @@ fn is_find_or_filter<'a>( && let filter_body = cx.tcx.hir_body(filter_body_id) && let [filter_param] = filter_body.params // optional ref pattern: `filter(|&x| ..)` - && let (filter_pat, is_filter_param_ref) = if let PatKind::Ref(ref_pat, _) = filter_param.pat.kind { + && let (filter_pat, is_filter_param_ref) = if let PatKind::Ref(ref_pat, _, _) = filter_param.pat.kind { (ref_pat, true) } else { (filter_param.pat, false) diff --git a/src/tools/clippy/clippy_lints/src/methods/iter_filter.rs b/src/tools/clippy/clippy_lints/src/methods/iter_filter.rs index 8d95b70c6a4b..aaface3aa971 100644 --- a/src/tools/clippy/clippy_lints/src/methods/iter_filter.rs +++ b/src/tools/clippy/clippy_lints/src/methods/iter_filter.rs @@ -50,7 +50,7 @@ fn is_method( fn pat_is_recv(ident: Ident, param: &hir::Pat<'_>) -> bool { match param.kind { hir::PatKind::Binding(_, _, other, _) => ident == other, - hir::PatKind::Ref(pat, _) => pat_is_recv(ident, pat), + hir::PatKind::Ref(pat, _, _) => pat_is_recv(ident, pat), _ => false, } } diff --git a/src/tools/clippy/clippy_lints/src/methods/iter_overeager_cloned.rs b/src/tools/clippy/clippy_lints/src/methods/iter_overeager_cloned.rs index d43dc23a86b2..1c26648e26eb 100644 --- a/src/tools/clippy/clippy_lints/src/methods/iter_overeager_cloned.rs +++ b/src/tools/clippy/clippy_lints/src/methods/iter_overeager_cloned.rs @@ -81,7 +81,7 @@ pub(super) fn check<'tcx>( } match it.kind { - PatKind::Binding(BindingMode(_, Mutability::Mut), _, _, _) | PatKind::Ref(_, Mutability::Mut) => { + PatKind::Binding(BindingMode(_, Mutability::Mut), _, _, _) | PatKind::Ref(_, _, Mutability::Mut) => { to_be_discarded = true; false }, diff --git a/src/tools/clippy/clippy_lints/src/methods/map_clone.rs b/src/tools/clippy/clippy_lints/src/methods/map_clone.rs index 1bc29c9c1dd1..a1aac96ccf86 100644 --- a/src/tools/clippy/clippy_lints/src/methods/map_clone.rs +++ b/src/tools/clippy/clippy_lints/src/methods/map_clone.rs @@ -8,7 +8,7 @@ use rustc_errors::Applicability; use rustc_hir::def_id::DefId; use rustc_hir::{self as hir, LangItem}; use rustc_lint::LateContext; -use rustc_middle::mir::Mutability; +use rustc_middle::mir::{Mutability, Pinnedness}; use rustc_middle::ty; use rustc_middle::ty::adjustment::Adjust; use rustc_span::symbol::Ident; @@ -50,7 +50,7 @@ pub(super) fn check(cx: &LateContext<'_>, e: &hir::Expr<'_>, recv: &hir::Expr<'_ let closure_body = cx.tcx.hir_body(body); let closure_expr = peel_blocks(closure_body.value); match closure_body.params[0].pat.kind { - hir::PatKind::Ref(inner, Mutability::Not) => { + hir::PatKind::Ref(inner, Pinnedness::Not, Mutability::Not) => { if let hir::PatKind::Binding(hir::BindingMode::NONE, .., name, None) = inner.kind && ident_eq(name, closure_expr) { diff --git a/src/tools/clippy/clippy_lints/src/needless_borrowed_ref.rs b/src/tools/clippy/clippy_lints/src/needless_borrowed_ref.rs index 1b6896827fed..29b4da93b7fb 100644 --- a/src/tools/clippy/clippy_lints/src/needless_borrowed_ref.rs +++ b/src/tools/clippy/clippy_lints/src/needless_borrowed_ref.rs @@ -1,6 +1,6 @@ use clippy_utils::diagnostics::span_lint_and_then; use rustc_errors::Applicability; -use rustc_hir::{BindingMode, Mutability, Node, Pat, PatKind}; +use rustc_hir::{BindingMode, Mutability, Node, Pat, PatKind, Pinnedness}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::declare_lint_pass; @@ -37,7 +37,7 @@ declare_lint_pass!(NeedlessBorrowedRef => [NEEDLESS_BORROWED_REFERENCE]); impl<'tcx> LateLintPass<'tcx> for NeedlessBorrowedRef { fn check_pat(&mut self, cx: &LateContext<'tcx>, ref_pat: &'tcx Pat<'_>) { - if let PatKind::Ref(pat, Mutability::Not) = ref_pat.kind + if let PatKind::Ref(pat, Pinnedness::Not, Mutability::Not) = ref_pat.kind && !ref_pat.span.from_expansion() && cx .tcx diff --git a/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs b/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs index 4621c22d6b53..bbb1b831888f 100644 --- a/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs +++ b/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs @@ -7,7 +7,7 @@ use clippy_utils::msrvs::{self, MsrvStack}; use clippy_utils::over; use rustc_ast::PatKind::*; use rustc_ast::mut_visit::*; -use rustc_ast::{self as ast, DUMMY_NODE_ID, Mutability, Pat, PatKind}; +use rustc_ast::{self as ast, DUMMY_NODE_ID, Mutability, Pat, PatKind, Pinnedness}; use rustc_ast_pretty::pprust; use rustc_data_structures::thin_vec::{ThinVec, thin_vec}; use rustc_errors::Applicability; @@ -151,8 +151,8 @@ fn insert_necessary_parens(pat: &mut Box) { walk_pat(self, pat); let target = match &mut pat.kind { // `i @ a | b`, `box a | b`, and `& mut? a | b`. - Ident(.., Some(p)) | Box(p) | Ref(p, _) if matches!(&p.kind, Or(ps) if ps.len() > 1) => p, - Ref(p, Mutability::Not) if matches!(p.kind, Ident(BindingMode::MUT, ..)) => p, // `&(mut x)` + Ident(.., Some(p)) | Box(p) | Ref(p, _, _) if matches!(&p.kind, Or(ps) if ps.len() > 1) => p, + Ref(p, Pinnedness::Not, Mutability::Not) if matches!(p.kind, Ident(BindingMode::MUT, ..)) => p, // `&(mut x)` _ => return, }; target.kind = Paren(Box::new(take_pat(target))); @@ -241,7 +241,8 @@ fn transform_with_focus_on_idx(alternatives: &mut ThinVec, focus_idx: usize // Skip immutable refs, as grouping them saves few characters, // and almost always requires adding parens (increasing noisiness). // In the case of only two patterns, replacement adds net characters. - | Ref(_, Mutability::Not) + // FIXME(pin_ergonomics): handle pinned patterns + | Ref(_, _, Mutability::Not) // Dealt with elsewhere. | Or(_) | Paren(_) | Deref(_) | Guard(..) => false, // Transform `box x | ... | box y` into `box (x | y)`. @@ -254,10 +255,10 @@ fn transform_with_focus_on_idx(alternatives: &mut ThinVec, focus_idx: usize |k| always_pat!(k, Box(p) => *p), ), // Transform `&mut x | ... | &mut y` into `&mut (x | y)`. - Ref(target, Mutability::Mut) => extend_with_matching( + Ref(target, _, Mutability::Mut) => extend_with_matching( target, start, alternatives, - |k| matches!(k, Ref(_, Mutability::Mut)), - |k| always_pat!(k, Ref(p, _) => *p), + |k| matches!(k, Ref(_, _, Mutability::Mut)), + |k| always_pat!(k, Ref(p, _, _) => *p), ), // Transform `b @ p0 | ... b @ p1` into `b @ (p0 | p1)`. Ident(b1, i1, Some(target)) => extend_with_matching( diff --git a/src/tools/clippy/clippy_lints/src/utils/author.rs b/src/tools/clippy/clippy_lints/src/utils/author.rs index 7f9dbdd885a1..57f889818be3 100644 --- a/src/tools/clippy/clippy_lints/src/utils/author.rs +++ b/src/tools/clippy/clippy_lints/src/utils/author.rs @@ -793,9 +793,9 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> { kind!("Deref({pat})"); self.pat(pat); }, - PatKind::Ref(pat, muta) => { + PatKind::Ref(pat, pinn, muta) => { bind!(self, pat); - kind!("Ref({pat}, Mutability::{muta:?})"); + kind!("Ref({pat}, Pinning::{pinn:?}, Mutability::{muta:?})"); self.pat(pat); }, PatKind::Guard(pat, cond) => { diff --git a/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs b/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs index 771862ee5b96..208aa98f12f2 100644 --- a/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs +++ b/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs @@ -45,9 +45,8 @@ pub fn eq_pat(l: &Pat, r: &Pat) -> bool { && eq_expr_opt(lt.as_deref(), rt.as_deref()) && eq_range_end(&le.node, &re.node) }, - (Box(l), Box(r)) - | (Ref(l, Mutability::Not), Ref(r, Mutability::Not)) - | (Ref(l, Mutability::Mut), Ref(r, Mutability::Mut)) => eq_pat(l, r), + (Box(l), Box(r)) => eq_pat(l, r), + (Ref(l, l_pin, l_mut), Ref(r, r_pin, r_mut)) => l_pin == r_pin && l_mut == r_mut && eq_pat(l, r), (Tuple(l), Tuple(r)) | (Slice(l), Slice(r)) => over(l, r, eq_pat), (Path(lq, lp), Path(rq, rp)) => both(lq.as_deref(), rq.as_deref(), eq_qself) && eq_path(lp, rp), (TupleStruct(lqself, lp, lfs), TupleStruct(rqself, rp, rfs)) => { diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs index dd411fe21bdd..2433ca8b97f2 100644 --- a/src/tools/clippy/clippy_utils/src/hir_utils.rs +++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs @@ -8,9 +8,9 @@ use rustc_data_structures::fx::FxHasher; use rustc_hir::MatchSource::TryDesugar; use rustc_hir::def::{DefKind, Res}; use rustc_hir::{ - AssocItemConstraint, BinOpKind, BindingMode, Block, BodyId, Closure, ConstArg, ConstArgKind, Expr, ExprField, - ExprKind, FnRetTy, GenericArg, GenericArgs, HirId, HirIdMap, InlineAsmOperand, LetExpr, Lifetime, LifetimeKind, - Node, Pat, PatExpr, PatExprKind, PatField, PatKind, Path, PathSegment, PrimTy, QPath, Stmt, StmtKind, + AssocItemConstraint, BinOpKind, BindingMode, Block, BodyId, ByRef, Closure, ConstArg, ConstArgKind, Expr, + ExprField, ExprKind, FnRetTy, GenericArg, GenericArgs, HirId, HirIdMap, InlineAsmOperand, LetExpr, Lifetime, + LifetimeKind, Node, Pat, PatExpr, PatExprKind, PatField, PatKind, Path, PathSegment, PrimTy, QPath, Stmt, StmtKind, StructTailExpr, TraitBoundModifiers, Ty, TyKind, TyPat, TyPatKind, }; use rustc_lexer::{FrontmatterAllowed, TokenKind, tokenize}; @@ -538,7 +538,7 @@ impl HirEqInterExpr<'_, '_, '_> { && both(le.as_ref(), re.as_ref(), |a, b| self.eq_pat_expr(a, b)) && (li == ri) }, - (PatKind::Ref(le, lm), PatKind::Ref(re, rm)) => lm == rm && self.eq_pat(le, re), + (PatKind::Ref(le, lp, lm), PatKind::Ref(re, rp, rm)) => lp == rp && lm == rm && self.eq_pat(le, re), (PatKind::Slice(ls, li, le), PatKind::Slice(rs, ri, re)) => { over(ls, rs, |l, r| self.eq_pat(l, r)) && over(le, re, |l, r| self.eq_pat(l, r)) @@ -1131,6 +1131,10 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { PatKind::Missing => unreachable!(), PatKind::Binding(BindingMode(by_ref, mutability), _, _, pat) => { std::mem::discriminant(by_ref).hash(&mut self.s); + if let ByRef::Yes(pi, mu) = by_ref { + std::mem::discriminant(pi).hash(&mut self.s); + std::mem::discriminant(mu).hash(&mut self.s); + } std::mem::discriminant(mutability).hash(&mut self.s); if let Some(pat) = pat { self.hash_pat(pat); @@ -1152,8 +1156,9 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { } std::mem::discriminant(i).hash(&mut self.s); }, - PatKind::Ref(pat, mu) => { + PatKind::Ref(pat, pi, mu) => { self.hash_pat(pat); + std::mem::discriminant(pi).hash(&mut self.s); std::mem::discriminant(mu).hash(&mut self.s); }, PatKind::Guard(pat, guard) => { diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index 4c0d70d320b9..d98e3073b41d 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -1462,7 +1462,7 @@ pub fn is_refutable(cx: &LateContext<'_>, pat: &Pat<'_>) -> bool { PatKind::Missing => unreachable!(), PatKind::Wild | PatKind::Never => false, // If `!` typechecked then the type is empty, so not refutable. PatKind::Binding(_, _, _, pat) => pat.is_some_and(|pat| is_refutable(cx, pat)), - PatKind::Box(pat) | PatKind::Ref(pat, _) => is_refutable(cx, pat), + PatKind::Box(pat) | PatKind::Ref(pat, _, _) => is_refutable(cx, pat), PatKind::Expr(PatExpr { kind: PatExprKind::Path(qpath), hir_id, @@ -1612,7 +1612,7 @@ pub fn is_lint_allowed(cx: &LateContext<'_>, lint: &'static Lint, id: HirId) -> } pub fn strip_pat_refs<'hir>(mut pat: &'hir Pat<'hir>) -> &'hir Pat<'hir> { - while let PatKind::Ref(subpat, _) = pat.kind { + while let PatKind::Ref(subpat, _, _) = pat.kind { pat = subpat; } pat @@ -2157,7 +2157,7 @@ where /// references removed. pub fn peel_hir_pat_refs<'a>(pat: &'a Pat<'a>) -> (&'a Pat<'a>, usize) { fn peel<'a>(pat: &'a Pat<'a>, count: usize) -> (&'a Pat<'a>, usize) { - if let PatKind::Ref(pat, _) = pat.kind { + if let PatKind::Ref(pat, _, _) = pat.kind { peel(pat, count + 1) } else { (pat, count) diff --git a/src/tools/clippy/src/driver.rs b/src/tools/clippy/src/driver.rs index abc706b7772f..a8db5dddf22f 100644 --- a/src/tools/clippy/src/driver.rs +++ b/src/tools/clippy/src/driver.rs @@ -13,10 +13,10 @@ extern crate rustc_interface; extern crate rustc_session; extern crate rustc_span; -// See docs in https://github.com/rust-lang/rust/blob/HEAD/compiler/rustc/src/main.rs -// about jemalloc. +/// See docs in https://github.com/rust-lang/rust/blob/HEAD/compiler/rustc/src/main.rs +/// and https://github.com/rust-lang/rust/pull/146627 for why we need this `use` statement. #[cfg(feature = "jemalloc")] -extern crate tikv_jemalloc_sys as jemalloc_sys; +use tikv_jemalloc_sys as _; use clippy_utils::sym; use declare_clippy_lint::LintListBuilder; @@ -189,36 +189,6 @@ const BUG_REPORT_URL: &str = "https://github.com/rust-lang/rust-clippy/issues/ne #[expect(clippy::too_many_lines)] pub fn main() { - // See docs in https://github.com/rust-lang/rust/blob/HEAD/compiler/rustc/src/main.rs - // about jemalloc. - #[cfg(feature = "jemalloc")] - { - use std::os::raw::{c_int, c_void}; - - #[used] - static _F1: unsafe extern "C" fn(usize, usize) -> *mut c_void = jemalloc_sys::calloc; - #[used] - static _F2: unsafe extern "C" fn(*mut *mut c_void, usize, usize) -> c_int = jemalloc_sys::posix_memalign; - #[used] - static _F3: unsafe extern "C" fn(usize, usize) -> *mut c_void = jemalloc_sys::aligned_alloc; - #[used] - static _F4: unsafe extern "C" fn(usize) -> *mut c_void = jemalloc_sys::malloc; - #[used] - static _F5: unsafe extern "C" fn(*mut c_void, usize) -> *mut c_void = jemalloc_sys::realloc; - #[used] - static _F6: unsafe extern "C" fn(*mut c_void) = jemalloc_sys::free; - - #[cfg(target_os = "macos")] - { - unsafe extern "C" { - fn _rjem_je_zone_register(); - } - - #[used] - static _F7: unsafe extern "C" fn() = _rjem_je_zone_register; - } - } - let early_dcx = EarlyDiagCtxt::new(ErrorOutputType::default()); rustc_driver::init_rustc_env_logger(&early_dcx); diff --git a/src/tools/clippy/tests/ui/cast_enum_constructor.rs b/src/tools/clippy/tests/ui/cast_enum_constructor.rs index eecf56f71a33..6d70387b6ce2 100644 --- a/src/tools/clippy/tests/ui/cast_enum_constructor.rs +++ b/src/tools/clippy/tests/ui/cast_enum_constructor.rs @@ -1,5 +1,5 @@ #![warn(clippy::cast_enum_constructor)] -#![allow(clippy::fn_to_numeric_cast)] +#![allow(clippy::fn_to_numeric_cast, function_casts_as_integer)] fn main() { enum Foo { diff --git a/src/tools/clippy/tests/ui/confusing_method_to_numeric_cast.fixed b/src/tools/clippy/tests/ui/confusing_method_to_numeric_cast.fixed index e698b99edd5c..b9691a3284ac 100644 --- a/src/tools/clippy/tests/ui/confusing_method_to_numeric_cast.fixed +++ b/src/tools/clippy/tests/ui/confusing_method_to_numeric_cast.fixed @@ -1,5 +1,6 @@ #![feature(float_minimum_maximum)] #![warn(clippy::confusing_method_to_numeric_cast)] +#![allow(function_casts_as_integer)] fn main() { let _ = u16::MAX as usize; //~ confusing_method_to_numeric_cast diff --git a/src/tools/clippy/tests/ui/confusing_method_to_numeric_cast.rs b/src/tools/clippy/tests/ui/confusing_method_to_numeric_cast.rs index ef65c21563d9..b402cbf92cb2 100644 --- a/src/tools/clippy/tests/ui/confusing_method_to_numeric_cast.rs +++ b/src/tools/clippy/tests/ui/confusing_method_to_numeric_cast.rs @@ -1,5 +1,6 @@ #![feature(float_minimum_maximum)] #![warn(clippy::confusing_method_to_numeric_cast)] +#![allow(function_casts_as_integer)] fn main() { let _ = u16::max as usize; //~ confusing_method_to_numeric_cast diff --git a/src/tools/clippy/tests/ui/confusing_method_to_numeric_cast.stderr b/src/tools/clippy/tests/ui/confusing_method_to_numeric_cast.stderr index ba90df2059af..0d5e08f88077 100644 --- a/src/tools/clippy/tests/ui/confusing_method_to_numeric_cast.stderr +++ b/src/tools/clippy/tests/ui/confusing_method_to_numeric_cast.stderr @@ -1,5 +1,5 @@ error: casting function pointer `u16::max` to `usize` - --> tests/ui/confusing_method_to_numeric_cast.rs:5:13 + --> tests/ui/confusing_method_to_numeric_cast.rs:6:13 | LL | let _ = u16::max as usize; | ^^^^^^^^^^^^^^^^^ @@ -13,7 +13,7 @@ LL + let _ = u16::MAX as usize; | error: casting function pointer `u16::min` to `usize` - --> tests/ui/confusing_method_to_numeric_cast.rs:6:13 + --> tests/ui/confusing_method_to_numeric_cast.rs:7:13 | LL | let _ = u16::min as usize; | ^^^^^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL + let _ = u16::MIN as usize; | error: casting function pointer `u16::max_value` to `usize` - --> tests/ui/confusing_method_to_numeric_cast.rs:7:13 + --> tests/ui/confusing_method_to_numeric_cast.rs:8:13 | LL | let _ = u16::max_value as usize; | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -37,7 +37,7 @@ LL + let _ = u16::MAX as usize; | error: casting function pointer `u16::min_value` to `usize` - --> tests/ui/confusing_method_to_numeric_cast.rs:8:13 + --> tests/ui/confusing_method_to_numeric_cast.rs:9:13 | LL | let _ = u16::min_value as usize; | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -49,7 +49,7 @@ LL + let _ = u16::MIN as usize; | error: casting function pointer `f32::maximum` to `usize` - --> tests/ui/confusing_method_to_numeric_cast.rs:10:13 + --> tests/ui/confusing_method_to_numeric_cast.rs:11:13 | LL | let _ = f32::maximum as usize; | ^^^^^^^^^^^^^^^^^^^^^ @@ -61,7 +61,7 @@ LL + let _ = f32::MAX as usize; | error: casting function pointer `f32::max` to `usize` - --> tests/ui/confusing_method_to_numeric_cast.rs:11:13 + --> tests/ui/confusing_method_to_numeric_cast.rs:12:13 | LL | let _ = f32::max as usize; | ^^^^^^^^^^^^^^^^^ @@ -73,7 +73,7 @@ LL + let _ = f32::MAX as usize; | error: casting function pointer `f32::minimum` to `usize` - --> tests/ui/confusing_method_to_numeric_cast.rs:12:13 + --> tests/ui/confusing_method_to_numeric_cast.rs:13:13 | LL | let _ = f32::minimum as usize; | ^^^^^^^^^^^^^^^^^^^^^ @@ -85,7 +85,7 @@ LL + let _ = f32::MIN as usize; | error: casting function pointer `f32::min` to `usize` - --> tests/ui/confusing_method_to_numeric_cast.rs:13:13 + --> tests/ui/confusing_method_to_numeric_cast.rs:14:13 | LL | let _ = f32::min as usize; | ^^^^^^^^^^^^^^^^^ diff --git a/src/tools/clippy/tests/ui/derive.rs b/src/tools/clippy/tests/ui/derive.rs index 6b60421c3549..036f6c444b64 100644 --- a/src/tools/clippy/tests/ui/derive.rs +++ b/src/tools/clippy/tests/ui/derive.rs @@ -9,7 +9,6 @@ #![expect(incomplete_features)] // `unsafe_fields` is incomplete for the time being #![feature(unsafe_fields)] // `clone()` cannot be derived automatically on unsafe fields - #[derive(Copy)] struct Qux; diff --git a/src/tools/clippy/tests/ui/derive.stderr b/src/tools/clippy/tests/ui/derive.stderr index 2b97a58e9d6f..2701680e788d 100644 --- a/src/tools/clippy/tests/ui/derive.stderr +++ b/src/tools/clippy/tests/ui/derive.stderr @@ -1,5 +1,5 @@ error: you are implementing `Clone` explicitly on a `Copy` type - --> tests/ui/derive.rs:16:1 + --> tests/ui/derive.rs:15:1 | LL | / impl Clone for Qux { LL | | @@ -14,7 +14,7 @@ LL | | } = help: to override `-D warnings` add `#[allow(clippy::expl_impl_clone_on_copy)]` error: you are implementing `Clone` explicitly on a `Copy` type - --> tests/ui/derive.rs:42:1 + --> tests/ui/derive.rs:41:1 | LL | / impl<'a> Clone for Lt<'a> { LL | | @@ -27,7 +27,7 @@ LL | | } = help: consider deriving `Clone` or removing `Copy` error: you are implementing `Clone` explicitly on a `Copy` type - --> tests/ui/derive.rs:55:1 + --> tests/ui/derive.rs:54:1 | LL | / impl Clone for BigArray { LL | | @@ -40,7 +40,7 @@ LL | | } = help: consider deriving `Clone` or removing `Copy` error: you are implementing `Clone` explicitly on a `Copy` type - --> tests/ui/derive.rs:68:1 + --> tests/ui/derive.rs:67:1 | LL | / impl Clone for FnPtr { LL | | @@ -53,7 +53,7 @@ LL | | } = help: consider deriving `Clone` or removing `Copy` error: you are implementing `Clone` explicitly on a `Copy` type - --> tests/ui/derive.rs:90:1 + --> tests/ui/derive.rs:89:1 | LL | / impl Clone for Generic2 { LL | | diff --git a/src/tools/clippy/tests/ui/fn_to_numeric_cast.64bit.stderr b/src/tools/clippy/tests/ui/fn_to_numeric_cast.64bit.stderr index 48961d14f2bb..694690ae5bfa 100644 --- a/src/tools/clippy/tests/ui/fn_to_numeric_cast.64bit.stderr +++ b/src/tools/clippy/tests/ui/fn_to_numeric_cast.64bit.stderr @@ -1,5 +1,5 @@ error: casting function pointer `foo` to `i8`, which truncates the value - --> tests/ui/fn_to_numeric_cast.rs:12:13 + --> tests/ui/fn_to_numeric_cast.rs:13:13 | LL | let _ = foo as i8; | ^^^^^^^^^ help: try: `foo as usize` @@ -8,19 +8,19 @@ LL | let _ = foo as i8; = help: to override `-D warnings` add `#[allow(clippy::fn_to_numeric_cast_with_truncation)]` error: casting function pointer `foo` to `i16`, which truncates the value - --> tests/ui/fn_to_numeric_cast.rs:14:13 + --> tests/ui/fn_to_numeric_cast.rs:15:13 | LL | let _ = foo as i16; | ^^^^^^^^^^ help: try: `foo as usize` error: casting function pointer `foo` to `i32`, which truncates the value - --> tests/ui/fn_to_numeric_cast.rs:16:13 + --> tests/ui/fn_to_numeric_cast.rs:17:13 | LL | let _ = foo as i32; | ^^^^^^^^^^ help: try: `foo as usize` error: casting function pointer `foo` to `i64` - --> tests/ui/fn_to_numeric_cast.rs:19:13 + --> tests/ui/fn_to_numeric_cast.rs:20:13 | LL | let _ = foo as i64; | ^^^^^^^^^^ help: try: `foo as usize` @@ -29,115 +29,115 @@ LL | let _ = foo as i64; = help: to override `-D warnings` add `#[allow(clippy::fn_to_numeric_cast)]` error: casting function pointer `foo` to `i128` - --> tests/ui/fn_to_numeric_cast.rs:21:13 + --> tests/ui/fn_to_numeric_cast.rs:22:13 | LL | let _ = foo as i128; | ^^^^^^^^^^^ help: try: `foo as usize` error: casting function pointer `foo` to `isize` - --> tests/ui/fn_to_numeric_cast.rs:23:13 + --> tests/ui/fn_to_numeric_cast.rs:24:13 | LL | let _ = foo as isize; | ^^^^^^^^^^^^ help: try: `foo as usize` error: casting function pointer `foo` to `u8`, which truncates the value - --> tests/ui/fn_to_numeric_cast.rs:26:13 + --> tests/ui/fn_to_numeric_cast.rs:27:13 | LL | let _ = foo as u8; | ^^^^^^^^^ help: try: `foo as usize` error: casting function pointer `foo` to `u16`, which truncates the value - --> tests/ui/fn_to_numeric_cast.rs:28:13 + --> tests/ui/fn_to_numeric_cast.rs:29:13 | LL | let _ = foo as u16; | ^^^^^^^^^^ help: try: `foo as usize` error: casting function pointer `foo` to `u32`, which truncates the value - --> tests/ui/fn_to_numeric_cast.rs:30:13 + --> tests/ui/fn_to_numeric_cast.rs:31:13 | LL | let _ = foo as u32; | ^^^^^^^^^^ help: try: `foo as usize` error: casting function pointer `foo` to `u64` - --> tests/ui/fn_to_numeric_cast.rs:33:13 + --> tests/ui/fn_to_numeric_cast.rs:34:13 | LL | let _ = foo as u64; | ^^^^^^^^^^ help: try: `foo as usize` error: casting function pointer `foo` to `u128` - --> tests/ui/fn_to_numeric_cast.rs:35:13 + --> tests/ui/fn_to_numeric_cast.rs:36:13 | LL | let _ = foo as u128; | ^^^^^^^^^^^ help: try: `foo as usize` error: casting function pointer `abc` to `i8`, which truncates the value - --> tests/ui/fn_to_numeric_cast.rs:49:13 + --> tests/ui/fn_to_numeric_cast.rs:50:13 | LL | let _ = abc as i8; | ^^^^^^^^^ help: try: `abc as usize` error: casting function pointer `abc` to `i16`, which truncates the value - --> tests/ui/fn_to_numeric_cast.rs:51:13 + --> tests/ui/fn_to_numeric_cast.rs:52:13 | LL | let _ = abc as i16; | ^^^^^^^^^^ help: try: `abc as usize` error: casting function pointer `abc` to `i32`, which truncates the value - --> tests/ui/fn_to_numeric_cast.rs:53:13 + --> tests/ui/fn_to_numeric_cast.rs:54:13 | LL | let _ = abc as i32; | ^^^^^^^^^^ help: try: `abc as usize` error: casting function pointer `abc` to `i64` - --> tests/ui/fn_to_numeric_cast.rs:56:13 + --> tests/ui/fn_to_numeric_cast.rs:57:13 | LL | let _ = abc as i64; | ^^^^^^^^^^ help: try: `abc as usize` error: casting function pointer `abc` to `i128` - --> tests/ui/fn_to_numeric_cast.rs:58:13 + --> tests/ui/fn_to_numeric_cast.rs:59:13 | LL | let _ = abc as i128; | ^^^^^^^^^^^ help: try: `abc as usize` error: casting function pointer `abc` to `isize` - --> tests/ui/fn_to_numeric_cast.rs:60:13 + --> tests/ui/fn_to_numeric_cast.rs:61:13 | LL | let _ = abc as isize; | ^^^^^^^^^^^^ help: try: `abc as usize` error: casting function pointer `abc` to `u8`, which truncates the value - --> tests/ui/fn_to_numeric_cast.rs:63:13 + --> tests/ui/fn_to_numeric_cast.rs:64:13 | LL | let _ = abc as u8; | ^^^^^^^^^ help: try: `abc as usize` error: casting function pointer `abc` to `u16`, which truncates the value - --> tests/ui/fn_to_numeric_cast.rs:65:13 + --> tests/ui/fn_to_numeric_cast.rs:66:13 | LL | let _ = abc as u16; | ^^^^^^^^^^ help: try: `abc as usize` error: casting function pointer `abc` to `u32`, which truncates the value - --> tests/ui/fn_to_numeric_cast.rs:67:13 + --> tests/ui/fn_to_numeric_cast.rs:68:13 | LL | let _ = abc as u32; | ^^^^^^^^^^ help: try: `abc as usize` error: casting function pointer `abc` to `u64` - --> tests/ui/fn_to_numeric_cast.rs:70:13 + --> tests/ui/fn_to_numeric_cast.rs:71:13 | LL | let _ = abc as u64; | ^^^^^^^^^^ help: try: `abc as usize` error: casting function pointer `abc` to `u128` - --> tests/ui/fn_to_numeric_cast.rs:72:13 + --> tests/ui/fn_to_numeric_cast.rs:73:13 | LL | let _ = abc as u128; | ^^^^^^^^^^^ help: try: `abc as usize` error: casting function pointer `f` to `i32`, which truncates the value - --> tests/ui/fn_to_numeric_cast.rs:80:5 + --> tests/ui/fn_to_numeric_cast.rs:81:5 | LL | f as i32 | ^^^^^^^^ help: try: `f as usize` diff --git a/src/tools/clippy/tests/ui/fn_to_numeric_cast.rs b/src/tools/clippy/tests/ui/fn_to_numeric_cast.rs index f53cbacdb377..0a07aeff366e 100644 --- a/src/tools/clippy/tests/ui/fn_to_numeric_cast.rs +++ b/src/tools/clippy/tests/ui/fn_to_numeric_cast.rs @@ -3,6 +3,7 @@ //@[64bit]ignore-bitwidth: 32 //@no-rustfix #![warn(clippy::fn_to_numeric_cast, clippy::fn_to_numeric_cast_with_truncation)] +#![allow(function_casts_as_integer)] fn foo() -> String { String::new() diff --git a/src/tools/clippy/tests/ui/fn_to_numeric_cast_any.rs b/src/tools/clippy/tests/ui/fn_to_numeric_cast_any.rs index 42f2128cd378..83c1e9a8387e 100644 --- a/src/tools/clippy/tests/ui/fn_to_numeric_cast_any.rs +++ b/src/tools/clippy/tests/ui/fn_to_numeric_cast_any.rs @@ -1,5 +1,6 @@ #![warn(clippy::fn_to_numeric_cast_any)] #![allow(clippy::fn_to_numeric_cast, clippy::fn_to_numeric_cast_with_truncation)] +#![allow(function_casts_as_integer)] //@no-rustfix fn foo() -> u8 { 0 diff --git a/src/tools/clippy/tests/ui/fn_to_numeric_cast_any.stderr b/src/tools/clippy/tests/ui/fn_to_numeric_cast_any.stderr index 58fac2d406a0..f7c49b8ff88b 100644 --- a/src/tools/clippy/tests/ui/fn_to_numeric_cast_any.stderr +++ b/src/tools/clippy/tests/ui/fn_to_numeric_cast_any.stderr @@ -1,5 +1,5 @@ error: casting function pointer `foo` to `i8` - --> tests/ui/fn_to_numeric_cast_any.rs:23:13 + --> tests/ui/fn_to_numeric_cast_any.rs:24:13 | LL | let _ = foo as i8; | ^^^^^^^^^ @@ -12,7 +12,7 @@ LL | let _ = foo() as i8; | ++ error: casting function pointer `foo` to `i16` - --> tests/ui/fn_to_numeric_cast_any.rs:26:13 + --> tests/ui/fn_to_numeric_cast_any.rs:27:13 | LL | let _ = foo as i16; | ^^^^^^^^^^ @@ -23,7 +23,7 @@ LL | let _ = foo() as i16; | ++ error: casting function pointer `foo` to `i32` - --> tests/ui/fn_to_numeric_cast_any.rs:29:13 + --> tests/ui/fn_to_numeric_cast_any.rs:30:13 | LL | let _ = foo as i32; | ^^^^^^^^^^ @@ -34,7 +34,7 @@ LL | let _ = foo() as i32; | ++ error: casting function pointer `foo` to `i64` - --> tests/ui/fn_to_numeric_cast_any.rs:32:13 + --> tests/ui/fn_to_numeric_cast_any.rs:33:13 | LL | let _ = foo as i64; | ^^^^^^^^^^ @@ -45,7 +45,7 @@ LL | let _ = foo() as i64; | ++ error: casting function pointer `foo` to `i128` - --> tests/ui/fn_to_numeric_cast_any.rs:35:13 + --> tests/ui/fn_to_numeric_cast_any.rs:36:13 | LL | let _ = foo as i128; | ^^^^^^^^^^^ @@ -56,7 +56,7 @@ LL | let _ = foo() as i128; | ++ error: casting function pointer `foo` to `isize` - --> tests/ui/fn_to_numeric_cast_any.rs:38:13 + --> tests/ui/fn_to_numeric_cast_any.rs:39:13 | LL | let _ = foo as isize; | ^^^^^^^^^^^^ @@ -67,7 +67,7 @@ LL | let _ = foo() as isize; | ++ error: casting function pointer `foo` to `u8` - --> tests/ui/fn_to_numeric_cast_any.rs:41:13 + --> tests/ui/fn_to_numeric_cast_any.rs:42:13 | LL | let _ = foo as u8; | ^^^^^^^^^ @@ -78,7 +78,7 @@ LL | let _ = foo() as u8; | ++ error: casting function pointer `foo` to `u16` - --> tests/ui/fn_to_numeric_cast_any.rs:44:13 + --> tests/ui/fn_to_numeric_cast_any.rs:45:13 | LL | let _ = foo as u16; | ^^^^^^^^^^ @@ -89,7 +89,7 @@ LL | let _ = foo() as u16; | ++ error: casting function pointer `foo` to `u32` - --> tests/ui/fn_to_numeric_cast_any.rs:47:13 + --> tests/ui/fn_to_numeric_cast_any.rs:48:13 | LL | let _ = foo as u32; | ^^^^^^^^^^ @@ -100,7 +100,7 @@ LL | let _ = foo() as u32; | ++ error: casting function pointer `foo` to `u64` - --> tests/ui/fn_to_numeric_cast_any.rs:50:13 + --> tests/ui/fn_to_numeric_cast_any.rs:51:13 | LL | let _ = foo as u64; | ^^^^^^^^^^ @@ -111,7 +111,7 @@ LL | let _ = foo() as u64; | ++ error: casting function pointer `foo` to `u128` - --> tests/ui/fn_to_numeric_cast_any.rs:53:13 + --> tests/ui/fn_to_numeric_cast_any.rs:54:13 | LL | let _ = foo as u128; | ^^^^^^^^^^^ @@ -122,7 +122,7 @@ LL | let _ = foo() as u128; | ++ error: casting function pointer `foo` to `usize` - --> tests/ui/fn_to_numeric_cast_any.rs:56:13 + --> tests/ui/fn_to_numeric_cast_any.rs:57:13 | LL | let _ = foo as usize; | ^^^^^^^^^^^^ @@ -133,7 +133,7 @@ LL | let _ = foo() as usize; | ++ error: casting function pointer `Struct::static_method` to `usize` - --> tests/ui/fn_to_numeric_cast_any.rs:61:13 + --> tests/ui/fn_to_numeric_cast_any.rs:62:13 | LL | let _ = Struct::static_method as usize; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -144,7 +144,7 @@ LL | let _ = Struct::static_method() as usize; | ++ error: casting function pointer `f` to `usize` - --> tests/ui/fn_to_numeric_cast_any.rs:66:5 + --> tests/ui/fn_to_numeric_cast_any.rs:67:5 | LL | f as usize | ^^^^^^^^^^ @@ -155,7 +155,7 @@ LL | f() as usize | ++ error: casting function pointer `T::static_method` to `usize` - --> tests/ui/fn_to_numeric_cast_any.rs:71:5 + --> tests/ui/fn_to_numeric_cast_any.rs:72:5 | LL | T::static_method as usize | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -166,7 +166,7 @@ LL | T::static_method() as usize | ++ error: casting function pointer `(clos as fn(u32) -> u32)` to `usize` - --> tests/ui/fn_to_numeric_cast_any.rs:78:13 + --> tests/ui/fn_to_numeric_cast_any.rs:79:13 | LL | let _ = (clos as fn(u32) -> u32) as usize; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -177,7 +177,7 @@ LL | let _ = (clos as fn(u32) -> u32)() as usize; | ++ error: casting function pointer `foo` to `*const ()` - --> tests/ui/fn_to_numeric_cast_any.rs:83:13 + --> tests/ui/fn_to_numeric_cast_any.rs:84:13 | LL | let _ = foo as *const (); | ^^^^^^^^^^^^^^^^ diff --git a/src/tools/clippy/tests/ui/ptr_eq.fixed b/src/tools/clippy/tests/ui/ptr_eq.fixed index 9629b3eea587..d3624a129b5f 100644 --- a/src/tools/clippy/tests/ui/ptr_eq.fixed +++ b/src/tools/clippy/tests/ui/ptr_eq.fixed @@ -1,4 +1,5 @@ #![warn(clippy::ptr_eq)] +#![allow(function_casts_as_integer)] macro_rules! mac { ($a:expr, $b:expr) => { diff --git a/src/tools/clippy/tests/ui/ptr_eq.rs b/src/tools/clippy/tests/ui/ptr_eq.rs index 2b741d8df468..f06a99cabc81 100644 --- a/src/tools/clippy/tests/ui/ptr_eq.rs +++ b/src/tools/clippy/tests/ui/ptr_eq.rs @@ -1,4 +1,5 @@ #![warn(clippy::ptr_eq)] +#![allow(function_casts_as_integer)] macro_rules! mac { ($a:expr, $b:expr) => { diff --git a/src/tools/clippy/tests/ui/ptr_eq.stderr b/src/tools/clippy/tests/ui/ptr_eq.stderr index e7340624b595..f6be4c3f016b 100644 --- a/src/tools/clippy/tests/ui/ptr_eq.stderr +++ b/src/tools/clippy/tests/ui/ptr_eq.stderr @@ -1,5 +1,5 @@ error: use `std::ptr::eq` when comparing raw pointers - --> tests/ui/ptr_eq.rs:22:13 + --> tests/ui/ptr_eq.rs:23:13 | LL | let _ = a as *const _ as usize == b as *const _ as usize; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::eq(a, b)` @@ -8,31 +8,31 @@ LL | let _ = a as *const _ as usize == b as *const _ as usize; = help: to override `-D warnings` add `#[allow(clippy::ptr_eq)]` error: use `std::ptr::eq` when comparing raw pointers - --> tests/ui/ptr_eq.rs:24:13 + --> tests/ui/ptr_eq.rs:25:13 | LL | let _ = a as *const _ == b as *const _; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::eq(a, b)` error: use `std::ptr::eq` when comparing raw pointers - --> tests/ui/ptr_eq.rs:50:13 + --> tests/ui/ptr_eq.rs:51:13 | LL | let _ = x as *const u32 == y as *mut u32 as *const u32; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::eq(x, y)` error: use `std::ptr::eq` when comparing raw pointers - --> tests/ui/ptr_eq.rs:53:13 + --> tests/ui/ptr_eq.rs:54:13 | LL | let _ = x as *const u32 != y as *mut u32 as *const u32; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `!std::ptr::eq(x, y)` error: use `std::ptr::eq` when comparing raw pointers - --> tests/ui/ptr_eq.rs:61:13 + --> tests/ui/ptr_eq.rs:62:13 | LL | let _ = mac!(cast a) as *const _ == mac!(cast b) as *const _; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::eq(mac!(cast a), mac!(cast b))` error: use `std::ptr::eq` when comparing raw pointers - --> tests/ui/ptr_eq.rs:65:13 + --> tests/ui/ptr_eq.rs:66:13 | LL | let _ = mac!(cast a) as *const _ == mac!(cast b) as *const _; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::eq(mac!(cast a), mac!(cast b))` diff --git a/src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.fixed b/src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.fixed index 02f67f79e2b1..f332e02a2d32 100644 --- a/src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.fixed +++ b/src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.fixed @@ -4,6 +4,7 @@ #![warn(clippy::useless_transmute)] #![warn(clippy::transmute_ptr_to_ptr)] #![allow(unused, clippy::borrow_as_ptr, clippy::missing_transmute_annotations)] +#![allow(function_casts_as_integer)] use std::mem::{size_of, transmute}; diff --git a/src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.rs b/src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.rs index c5e156405ebc..c29a42ddca53 100644 --- a/src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.rs +++ b/src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.rs @@ -4,6 +4,7 @@ #![warn(clippy::useless_transmute)] #![warn(clippy::transmute_ptr_to_ptr)] #![allow(unused, clippy::borrow_as_ptr, clippy::missing_transmute_annotations)] +#![allow(function_casts_as_integer)] use std::mem::{size_of, transmute}; diff --git a/src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.stderr b/src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.stderr index f39a64d57eb4..5ddc3de6a039 100644 --- a/src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.stderr +++ b/src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.stderr @@ -1,5 +1,5 @@ error: transmute from a pointer to a pointer - --> tests/ui/transmutes_expressible_as_ptr_casts.rs:19:38 + --> tests/ui/transmutes_expressible_as_ptr_casts.rs:20:38 | LL | let _ptr_i8_transmute = unsafe { transmute::<*const i32, *const i8>(ptr_i32) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -13,7 +13,7 @@ LL + let _ptr_i8_transmute = unsafe { ptr_i32.cast::() }; | error: transmute from a pointer to a pointer - --> tests/ui/transmutes_expressible_as_ptr_casts.rs:26:46 + --> tests/ui/transmutes_expressible_as_ptr_casts.rs:27:46 | LL | let _ptr_to_unsized_transmute = unsafe { transmute::<*const [i32], *const [u32]>(slice_ptr) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL + let _ptr_to_unsized_transmute = unsafe { slice_ptr as *const [u32] }; | error: transmute from `*const i32` to `usize` which could be expressed as a pointer cast instead - --> tests/ui/transmutes_expressible_as_ptr_casts.rs:33:50 + --> tests/ui/transmutes_expressible_as_ptr_casts.rs:34:50 | LL | let _usize_from_int_ptr_transmute = unsafe { transmute::<*const i32, usize>(ptr_i32) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `ptr_i32 as usize` @@ -34,7 +34,7 @@ LL | let _usize_from_int_ptr_transmute = unsafe { transmute::<*const i32, us = help: to override `-D warnings` add `#[allow(clippy::transmutes_expressible_as_ptr_casts)]` error: transmute from a reference to a pointer - --> tests/ui/transmutes_expressible_as_ptr_casts.rs:40:41 + --> tests/ui/transmutes_expressible_as_ptr_casts.rs:41:41 | LL | let _array_ptr_transmute = unsafe { transmute::<&[i32; 4], *const [i32; 4]>(array_ref) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `array_ref as *const [i32; 4]` @@ -43,31 +43,31 @@ LL | let _array_ptr_transmute = unsafe { transmute::<&[i32; 4], *const [i32; = help: to override `-D warnings` add `#[allow(clippy::useless_transmute)]` error: transmute from `fn(usize) -> u8` to `*const usize` which could be expressed as a pointer cast instead - --> tests/ui/transmutes_expressible_as_ptr_casts.rs:49:41 + --> tests/ui/transmutes_expressible_as_ptr_casts.rs:50:41 | LL | let _usize_ptr_transmute = unsafe { transmute:: u8, *const usize>(foo) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `foo as *const usize` error: transmute from `fn(usize) -> u8` to `usize` which could be expressed as a pointer cast instead - --> tests/ui/transmutes_expressible_as_ptr_casts.rs:54:49 + --> tests/ui/transmutes_expressible_as_ptr_casts.rs:55:49 | LL | let _usize_from_fn_ptr_transmute = unsafe { transmute:: u8, usize>(foo) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `foo as usize` error: transmute from `*const u32` to `usize` which could be expressed as a pointer cast instead - --> tests/ui/transmutes_expressible_as_ptr_casts.rs:58:36 + --> tests/ui/transmutes_expressible_as_ptr_casts.rs:59:36 | LL | let _usize_from_ref = unsafe { transmute::<*const u32, usize>(&1u32) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&1u32 as *const u32 as usize` error: transmute from a reference to a pointer - --> tests/ui/transmutes_expressible_as_ptr_casts.rs:70:14 + --> tests/ui/transmutes_expressible_as_ptr_casts.rs:71:14 | LL | unsafe { transmute::<&[i32; 1], *const u8>(in_param) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `in_param as *const [i32; 1] as *const u8` error: transmute from `fn()` to `*const u8` which could be expressed as a pointer cast instead - --> tests/ui/transmutes_expressible_as_ptr_casts.rs:89:28 + --> tests/ui/transmutes_expressible_as_ptr_casts.rs:90:28 | LL | let _x: u8 = unsafe { *std::mem::transmute::(f) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(f as *const u8)` diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs index aa8e340ee755..6fdd2e699524 100644 --- a/src/tools/compiletest/src/common.rs +++ b/src/tools/compiletest/src/common.rs @@ -312,10 +312,7 @@ pub struct Config { /// Path to the `src/tools/coverage-dump/` bootstrap tool executable. pub coverage_dump_path: Option, - /// Path to the Python 3 executable to use for LLDB and htmldocck. - /// - /// FIXME: the `lldb` setup currently requires I believe Python 3.10 **exactly**, it can't even - /// be Python 3.11 or 3.9... + /// Path to the Python 3 executable to use for htmldocck and some run-make tests. pub python: String, /// Path to the `src/tools/jsondocck/` bootstrap tool executable. @@ -541,6 +538,9 @@ pub struct Config { /// FIXME: `gdb_version` is *derived* from gdb, but it's *not* technically a config! pub gdb_version: Option, + /// Path to or name of the LLDB executable to use for debuginfo tests. + pub lldb: Option, + /// Version of LLDB. /// /// FIXME: `lldb_version` is *derived* from lldb, but it's *not* technically a config! @@ -587,11 +587,6 @@ pub struct Config { /// FIXME: take a look at this; this also influences adb in gdb code paths in a strange way. pub adb_device_status: bool, - /// Path containing LLDB's Python module. - /// - /// FIXME: `PYTHONPATH` takes precedence over this flag...? See `runtest::run_lldb`. - pub lldb_python_dir: Option, - /// Verbose dump a lot of info. /// /// FIXME: this is *way* too coarse; the user can't select *which* info to verbosely dump. diff --git a/src/tools/compiletest/src/debuggers.rs b/src/tools/compiletest/src/debuggers.rs index 93f27fb90951..b26c45240b9f 100644 --- a/src/tools/compiletest/src/debuggers.rs +++ b/src/tools/compiletest/src/debuggers.rs @@ -49,7 +49,7 @@ pub(crate) fn configure_gdb(config: &Config) -> Option> { } pub(crate) fn configure_lldb(config: &Config) -> Option> { - config.lldb_python_dir.as_ref()?; + config.lldb.as_ref()?; Some(Arc::new(Config { debugger: Some(Debugger::Lldb), ..config.clone() })) } diff --git a/src/tools/compiletest/src/directives.rs b/src/tools/compiletest/src/directives.rs index 7c1bbe940321..8e9c28e69ea7 100644 --- a/src/tools/compiletest/src/directives.rs +++ b/src/tools/compiletest/src/directives.rs @@ -14,6 +14,7 @@ use crate::directives::directive_names::{ KNOWN_DIRECTIVE_NAMES_SET, KNOWN_HTMLDOCCK_DIRECTIVE_NAMES, KNOWN_JSONDOCCK_DIRECTIVE_NAMES, }; pub(crate) use crate::directives::file::FileDirectives; +use crate::directives::handlers::DIRECTIVE_HANDLERS_MAP; use crate::directives::line::{DirectiveLine, line_directive}; use crate::directives::needs::CachedNeedsConditions; use crate::edition::{Edition, parse_edition}; @@ -26,6 +27,7 @@ mod auxiliary; mod cfg; mod directive_names; mod file; +mod handlers; mod line; mod needs; #[cfg(test)] @@ -359,269 +361,9 @@ impl TestProps { return; } - use directives::*; - - config.push_name_value_directive( - ln, - ERROR_PATTERN, - &mut self.error_patterns, - |r| r, - ); - config.push_name_value_directive( - ln, - REGEX_ERROR_PATTERN, - &mut self.regex_error_patterns, - |r| r, - ); - - config.push_name_value_directive(ln, DOC_FLAGS, &mut self.doc_flags, |r| r); - - fn split_flags(flags: &str) -> Vec { - // Individual flags can be single-quoted to preserve spaces; see - // . - flags - .split('\'') - .enumerate() - .flat_map(|(i, f)| { - if i % 2 == 1 { vec![f] } else { f.split_whitespace().collect() } - }) - .map(move |s| s.to_owned()) - .collect::>() + if let Some(handler) = DIRECTIVE_HANDLERS_MAP.get(ln.name) { + handler.handle(config, ln, self); } - - if let Some(flags) = config.parse_name_value_directive(ln, COMPILE_FLAGS) { - let flags = split_flags(&flags); - for (i, flag) in flags.iter().enumerate() { - if flag == "--edition" || flag.starts_with("--edition=") { - panic!("you must use `//@ edition` to configure the edition"); - } - if (flag == "-C" - && flags.get(i + 1).is_some_and(|v| v.starts_with("incremental="))) - || flag.starts_with("-Cincremental=") - { - panic!( - "you must use `//@ incremental` to enable incremental compilation" - ); - } - } - self.compile_flags.extend(flags); - } - - if let Some(range) = parse_edition_range(config, ln) { - self.edition = Some(range.edition_to_test(config.edition)); - } - - config.parse_and_update_revisions(ln, &mut self.revisions); - - if let Some(flags) = config.parse_name_value_directive(ln, RUN_FLAGS) { - self.run_flags.extend(split_flags(&flags)); - } - - if self.pp_exact.is_none() { - self.pp_exact = config.parse_pp_exact(ln); - } - - config.set_name_directive(ln, SHOULD_ICE, &mut self.should_ice); - config.set_name_directive(ln, BUILD_AUX_DOCS, &mut self.build_aux_docs); - config.set_name_directive(ln, UNIQUE_DOC_OUT_DIR, &mut self.unique_doc_out_dir); - - config.set_name_directive(ln, FORCE_HOST, &mut self.force_host); - config.set_name_directive(ln, CHECK_STDOUT, &mut self.check_stdout); - config.set_name_directive(ln, CHECK_RUN_RESULTS, &mut self.check_run_results); - config.set_name_directive( - ln, - DONT_CHECK_COMPILER_STDOUT, - &mut self.dont_check_compiler_stdout, - ); - config.set_name_directive( - ln, - DONT_CHECK_COMPILER_STDERR, - &mut self.dont_check_compiler_stderr, - ); - config.set_name_directive(ln, NO_PREFER_DYNAMIC, &mut self.no_prefer_dynamic); - - if let Some(m) = config.parse_name_value_directive(ln, PRETTY_MODE) { - self.pretty_mode = m; - } - - config.set_name_directive( - ln, - PRETTY_COMPARE_ONLY, - &mut self.pretty_compare_only, - ); - - // Call a helper method to deal with aux-related directives. - parse_and_update_aux(config, ln, &mut self.aux); - - config.push_name_value_directive( - ln, - EXEC_ENV, - &mut self.exec_env, - Config::parse_env, - ); - config.push_name_value_directive( - ln, - UNSET_EXEC_ENV, - &mut self.unset_exec_env, - |r| r.trim().to_owned(), - ); - config.push_name_value_directive( - ln, - RUSTC_ENV, - &mut self.rustc_env, - Config::parse_env, - ); - config.push_name_value_directive( - ln, - UNSET_RUSTC_ENV, - &mut self.unset_rustc_env, - |r| r.trim().to_owned(), - ); - config.push_name_value_directive( - ln, - FORBID_OUTPUT, - &mut self.forbid_output, - |r| r, - ); - config.set_name_directive( - ln, - CHECK_TEST_LINE_NUMBERS_MATCH, - &mut self.check_test_line_numbers_match, - ); - - self.update_pass_mode(ln, config); - self.update_fail_mode(ln, config); - - config.set_name_directive(ln, IGNORE_PASS, &mut self.ignore_pass); - - if let Some(NormalizeRule { kind, regex, replacement }) = - config.parse_custom_normalization(ln) - { - let rule_tuple = (regex, replacement); - match kind { - NormalizeKind::Stdout => self.normalize_stdout.push(rule_tuple), - NormalizeKind::Stderr => self.normalize_stderr.push(rule_tuple), - NormalizeKind::Stderr32bit => { - if config.target_cfg().pointer_width == 32 { - self.normalize_stderr.push(rule_tuple); - } - } - NormalizeKind::Stderr64bit => { - if config.target_cfg().pointer_width == 64 { - self.normalize_stderr.push(rule_tuple); - } - } - } - } - - if let Some(code) = config - .parse_name_value_directive(ln, FAILURE_STATUS) - .and_then(|code| code.trim().parse::().ok()) - { - self.failure_status = Some(code); - } - - config.set_name_directive( - ln, - DONT_CHECK_FAILURE_STATUS, - &mut self.dont_check_failure_status, - ); - - config.set_name_directive(ln, RUN_RUSTFIX, &mut self.run_rustfix); - config.set_name_directive( - ln, - RUSTFIX_ONLY_MACHINE_APPLICABLE, - &mut self.rustfix_only_machine_applicable, - ); - config.set_name_value_directive( - ln, - ASSEMBLY_OUTPUT, - &mut self.assembly_output, - |r| r.trim().to_string(), - ); - config.set_name_directive( - ln, - STDERR_PER_BITWIDTH, - &mut self.stderr_per_bitwidth, - ); - config.set_name_directive(ln, INCREMENTAL, &mut self.incremental); - - // Unlike the other `name_value_directive`s this needs to be handled manually, - // because it sets a `bool` flag. - if let Some(known_bug) = config.parse_name_value_directive(ln, KNOWN_BUG) { - let known_bug = known_bug.trim(); - if known_bug == "unknown" - || known_bug.split(',').all(|issue_ref| { - issue_ref - .trim() - .split_once('#') - .filter(|(_, number)| { - number.chars().all(|digit| digit.is_numeric()) - }) - .is_some() - }) - { - self.known_bug = true; - } else { - panic!( - "Invalid known-bug value: {known_bug}\nIt requires comma-separated issue references (`#000` or `chalk#000`) or `known-bug: unknown`." - ); - } - } else if config.parse_name_directive(ln, KNOWN_BUG) { - panic!( - "Invalid known-bug attribute, requires comma-separated issue references (`#000` or `chalk#000`) or `known-bug: unknown`." - ); - } - - config.set_name_value_directive( - ln, - TEST_MIR_PASS, - &mut self.mir_unit_test, - |s| s.trim().to_string(), - ); - config.set_name_directive(ln, REMAP_SRC_BASE, &mut self.remap_src_base); - - if let Some(flags) = config.parse_name_value_directive(ln, LLVM_COV_FLAGS) { - self.llvm_cov_flags.extend(split_flags(&flags)); - } - - if let Some(flags) = config.parse_name_value_directive(ln, FILECHECK_FLAGS) { - self.filecheck_flags.extend(split_flags(&flags)); - } - - config.set_name_directive(ln, NO_AUTO_CHECK_CFG, &mut self.no_auto_check_cfg); - - self.update_add_minicore(ln, config); - - if let Some(flags) = - config.parse_name_value_directive(ln, MINICORE_COMPILE_FLAGS) - { - let flags = split_flags(&flags); - for flag in &flags { - if flag == "--edition" || flag.starts_with("--edition=") { - panic!("you must use `//@ edition` to configure the edition"); - } - } - self.minicore_compile_flags.extend(flags); - } - - if let Some(err_kind) = - config.parse_name_value_directive(ln, DONT_REQUIRE_ANNOTATIONS) - { - self.dont_require_annotations - .insert(ErrorKind::expect_from_user_str(err_kind.trim())); - } - - config.set_name_directive( - ln, - DISABLE_GDB_PRETTY_PRINTERS, - &mut self.disable_gdb_pretty_printers, - ); - config.set_name_directive( - ln, - COMPARE_OUTPUT_BY_LINES, - &mut self.compare_output_by_lines, - ); }, ); } @@ -1691,3 +1433,16 @@ impl EditionRange { } } } + +fn split_flags(flags: &str) -> Vec { + // Individual flags can be single-quoted to preserve spaces; see + // . + // FIXME(#147955): Replace this ad-hoc quoting with an escape/quote system that + // is closer to what actual shells do, so that it's more flexible and familiar. + flags + .split('\'') + .enumerate() + .flat_map(|(i, f)| if i % 2 == 1 { vec![f] } else { f.split_whitespace().collect() }) + .map(move |s| s.to_owned()) + .collect::>() +} diff --git a/src/tools/compiletest/src/directives/handlers.rs b/src/tools/compiletest/src/directives/handlers.rs new file mode 100644 index 000000000000..b53bda90f626 --- /dev/null +++ b/src/tools/compiletest/src/directives/handlers.rs @@ -0,0 +1,372 @@ +use std::collections::HashMap; +use std::sync::{Arc, LazyLock}; + +use crate::common::Config; +use crate::directives::{ + DirectiveLine, NormalizeKind, NormalizeRule, TestProps, parse_and_update_aux, + parse_edition_range, split_flags, +}; +use crate::errors::ErrorKind; + +pub(crate) static DIRECTIVE_HANDLERS_MAP: LazyLock> = + LazyLock::new(make_directive_handlers_map); + +#[derive(Clone)] +pub(crate) struct Handler { + handler_fn: Arc) + Send + Sync>, +} + +impl Handler { + pub(crate) fn handle(&self, config: &Config, line: &DirectiveLine<'_>, props: &mut TestProps) { + (self.handler_fn)(HandlerArgs { config, line, props }) + } +} + +struct HandlerArgs<'a> { + config: &'a Config, + line: &'a DirectiveLine<'a>, + props: &'a mut TestProps, +} + +/// Intermediate data structure, used for defining a list of handlers. +struct NamedHandler { + names: Vec<&'static str>, + handler: Handler, +} + +/// Helper function to create a simple handler, so that changes can be made +/// to the handler struct without disturbing existing handler declarations. +fn handler( + name: &'static str, + handler_fn: impl Fn(&Config, &DirectiveLine<'_>, &mut TestProps) + Send + Sync + 'static, +) -> NamedHandler { + multi_handler(&[name], handler_fn) +} + +/// Associates the same handler function with multiple directive names. +fn multi_handler( + names: &[&'static str], + handler_fn: impl Fn(&Config, &DirectiveLine<'_>, &mut TestProps) + Send + Sync + 'static, +) -> NamedHandler { + NamedHandler { + names: names.to_owned(), + handler: Handler { + handler_fn: Arc::new(move |args| handler_fn(args.config, args.line, args.props)), + }, + } +} + +fn make_directive_handlers_map() -> HashMap<&'static str, Handler> { + use crate::directives::directives::*; + + // FIXME(Zalathar): Now that most directive-processing has been extracted + // into individual handlers, there should be many opportunities to simplify + // these handlers, e.g. by getting rid of now-redundant name checks. + + let handlers: Vec = vec![ + handler(ERROR_PATTERN, |config, ln, props| { + config.push_name_value_directive(ln, ERROR_PATTERN, &mut props.error_patterns, |r| r); + }), + handler(REGEX_ERROR_PATTERN, |config, ln, props| { + config.push_name_value_directive( + ln, + REGEX_ERROR_PATTERN, + &mut props.regex_error_patterns, + |r| r, + ); + }), + handler(DOC_FLAGS, |config, ln, props| { + config.push_name_value_directive(ln, DOC_FLAGS, &mut props.doc_flags, |r| r); + }), + handler(COMPILE_FLAGS, |config, ln, props| { + if let Some(flags) = config.parse_name_value_directive(ln, COMPILE_FLAGS) { + let flags = split_flags(&flags); + // FIXME(#147955): Extract and unify this with other handlers that + // check compiler flags, e.g. MINICORE_COMPILE_FLAGS. + for (i, flag) in flags.iter().enumerate() { + if flag == "--edition" || flag.starts_with("--edition=") { + panic!("you must use `//@ edition` to configure the edition"); + } + if (flag == "-C" + && flags.get(i + 1).is_some_and(|v| v.starts_with("incremental="))) + || flag.starts_with("-Cincremental=") + { + panic!("you must use `//@ incremental` to enable incremental compilation"); + } + } + props.compile_flags.extend(flags); + } + }), + handler("edition", |config, ln, props| { + if let Some(range) = parse_edition_range(config, ln) { + props.edition = Some(range.edition_to_test(config.edition)); + } + }), + handler("revisions", |config, ln, props| { + config.parse_and_update_revisions(ln, &mut props.revisions); + }), + handler(RUN_FLAGS, |config, ln, props| { + if let Some(flags) = config.parse_name_value_directive(ln, RUN_FLAGS) { + props.run_flags.extend(split_flags(&flags)); + } + }), + handler("pp-exact", |config, ln, props| { + if props.pp_exact.is_none() { + props.pp_exact = config.parse_pp_exact(ln); + } + }), + handler(SHOULD_ICE, |config, ln, props| { + config.set_name_directive(ln, SHOULD_ICE, &mut props.should_ice); + }), + handler(BUILD_AUX_DOCS, |config, ln, props| { + config.set_name_directive(ln, BUILD_AUX_DOCS, &mut props.build_aux_docs); + }), + handler(UNIQUE_DOC_OUT_DIR, |config, ln, props| { + config.set_name_directive(ln, UNIQUE_DOC_OUT_DIR, &mut props.unique_doc_out_dir); + }), + handler(FORCE_HOST, |config, ln, props| { + config.set_name_directive(ln, FORCE_HOST, &mut props.force_host); + }), + handler(CHECK_STDOUT, |config, ln, props| { + config.set_name_directive(ln, CHECK_STDOUT, &mut props.check_stdout); + }), + handler(CHECK_RUN_RESULTS, |config, ln, props| { + config.set_name_directive(ln, CHECK_RUN_RESULTS, &mut props.check_run_results); + }), + handler(DONT_CHECK_COMPILER_STDOUT, |config, ln, props| { + config.set_name_directive( + ln, + DONT_CHECK_COMPILER_STDOUT, + &mut props.dont_check_compiler_stdout, + ); + }), + handler(DONT_CHECK_COMPILER_STDERR, |config, ln, props| { + config.set_name_directive( + ln, + DONT_CHECK_COMPILER_STDERR, + &mut props.dont_check_compiler_stderr, + ); + }), + handler(NO_PREFER_DYNAMIC, |config, ln, props| { + config.set_name_directive(ln, NO_PREFER_DYNAMIC, &mut props.no_prefer_dynamic); + }), + handler(PRETTY_MODE, |config, ln, props| { + if let Some(m) = config.parse_name_value_directive(ln, PRETTY_MODE) { + props.pretty_mode = m; + } + }), + handler(PRETTY_COMPARE_ONLY, |config, ln, props| { + config.set_name_directive(ln, PRETTY_COMPARE_ONLY, &mut props.pretty_compare_only); + }), + multi_handler( + &[AUX_BUILD, AUX_BIN, AUX_CRATE, PROC_MACRO, AUX_CODEGEN_BACKEND], + |config, ln, props| { + // Call a helper method to deal with aux-related directives. + parse_and_update_aux(config, ln, &mut props.aux); + }, + ), + handler(EXEC_ENV, |config, ln, props| { + config.push_name_value_directive(ln, EXEC_ENV, &mut props.exec_env, Config::parse_env); + }), + handler(UNSET_EXEC_ENV, |config, ln, props| { + config.push_name_value_directive(ln, UNSET_EXEC_ENV, &mut props.unset_exec_env, |r| { + r.trim().to_owned() + }); + }), + handler(RUSTC_ENV, |config, ln, props| { + config.push_name_value_directive( + ln, + RUSTC_ENV, + &mut props.rustc_env, + Config::parse_env, + ); + }), + handler(UNSET_RUSTC_ENV, |config, ln, props| { + config.push_name_value_directive( + ln, + UNSET_RUSTC_ENV, + &mut props.unset_rustc_env, + |r| r.trim().to_owned(), + ); + }), + handler(FORBID_OUTPUT, |config, ln, props| { + config.push_name_value_directive(ln, FORBID_OUTPUT, &mut props.forbid_output, |r| r); + }), + handler(CHECK_TEST_LINE_NUMBERS_MATCH, |config, ln, props| { + config.set_name_directive( + ln, + CHECK_TEST_LINE_NUMBERS_MATCH, + &mut props.check_test_line_numbers_match, + ); + }), + multi_handler(&["check-pass", "build-pass", "run-pass"], |config, ln, props| { + props.update_pass_mode(ln, config); + }), + multi_handler( + &["check-fail", "build-fail", "run-fail", "run-crash", "run-fail-or-crash"], + |config, ln, props| { + props.update_fail_mode(ln, config); + }, + ), + handler(IGNORE_PASS, |config, ln, props| { + config.set_name_directive(ln, IGNORE_PASS, &mut props.ignore_pass); + }), + multi_handler( + &[ + "normalize-stdout", + "normalize-stderr", + "normalize-stderr-32bit", + "normalize-stderr-64bit", + ], + |config, ln, props| { + if let Some(NormalizeRule { kind, regex, replacement }) = + config.parse_custom_normalization(ln) + { + let rule_tuple = (regex, replacement); + match kind { + NormalizeKind::Stdout => props.normalize_stdout.push(rule_tuple), + NormalizeKind::Stderr => props.normalize_stderr.push(rule_tuple), + NormalizeKind::Stderr32bit => { + if config.target_cfg().pointer_width == 32 { + props.normalize_stderr.push(rule_tuple); + } + } + NormalizeKind::Stderr64bit => { + if config.target_cfg().pointer_width == 64 { + props.normalize_stderr.push(rule_tuple); + } + } + } + } + }, + ), + handler(FAILURE_STATUS, |config, ln, props| { + if let Some(code) = config + .parse_name_value_directive(ln, FAILURE_STATUS) + .and_then(|code| code.trim().parse::().ok()) + { + props.failure_status = Some(code); + } + }), + handler(DONT_CHECK_FAILURE_STATUS, |config, ln, props| { + config.set_name_directive( + ln, + DONT_CHECK_FAILURE_STATUS, + &mut props.dont_check_failure_status, + ); + }), + handler(RUN_RUSTFIX, |config, ln, props| { + config.set_name_directive(ln, RUN_RUSTFIX, &mut props.run_rustfix); + }), + handler(RUSTFIX_ONLY_MACHINE_APPLICABLE, |config, ln, props| { + config.set_name_directive( + ln, + RUSTFIX_ONLY_MACHINE_APPLICABLE, + &mut props.rustfix_only_machine_applicable, + ); + }), + handler(ASSEMBLY_OUTPUT, |config, ln, props| { + config.set_name_value_directive(ln, ASSEMBLY_OUTPUT, &mut props.assembly_output, |r| { + r.trim().to_string() + }); + }), + handler(STDERR_PER_BITWIDTH, |config, ln, props| { + config.set_name_directive(ln, STDERR_PER_BITWIDTH, &mut props.stderr_per_bitwidth); + }), + handler(INCREMENTAL, |config, ln, props| { + config.set_name_directive(ln, INCREMENTAL, &mut props.incremental); + }), + handler(KNOWN_BUG, |config, ln, props| { + // Unlike the other `name_value_directive`s this needs to be handled manually, + // because it sets a `bool` flag. + if let Some(known_bug) = config.parse_name_value_directive(ln, KNOWN_BUG) { + let known_bug = known_bug.trim(); + if known_bug == "unknown" + || known_bug.split(',').all(|issue_ref| { + issue_ref + .trim() + .split_once('#') + .filter(|(_, number)| number.chars().all(|digit| digit.is_numeric())) + .is_some() + }) + { + props.known_bug = true; + } else { + panic!( + "Invalid known-bug value: {known_bug}\nIt requires comma-separated issue references (`#000` or `chalk#000`) or `known-bug: unknown`." + ); + } + } else if config.parse_name_directive(ln, KNOWN_BUG) { + panic!( + "Invalid known-bug attribute, requires comma-separated issue references (`#000` or `chalk#000`) or `known-bug: unknown`." + ); + } + }), + handler(TEST_MIR_PASS, |config, ln, props| { + config.set_name_value_directive(ln, TEST_MIR_PASS, &mut props.mir_unit_test, |s| { + s.trim().to_string() + }); + }), + handler(REMAP_SRC_BASE, |config, ln, props| { + config.set_name_directive(ln, REMAP_SRC_BASE, &mut props.remap_src_base); + }), + handler(LLVM_COV_FLAGS, |config, ln, props| { + if let Some(flags) = config.parse_name_value_directive(ln, LLVM_COV_FLAGS) { + props.llvm_cov_flags.extend(split_flags(&flags)); + } + }), + handler(FILECHECK_FLAGS, |config, ln, props| { + if let Some(flags) = config.parse_name_value_directive(ln, FILECHECK_FLAGS) { + props.filecheck_flags.extend(split_flags(&flags)); + } + }), + handler(NO_AUTO_CHECK_CFG, |config, ln, props| { + config.set_name_directive(ln, NO_AUTO_CHECK_CFG, &mut props.no_auto_check_cfg); + }), + handler(ADD_MINICORE, |config, ln, props| { + props.update_add_minicore(ln, config); + }), + handler(MINICORE_COMPILE_FLAGS, |config, ln, props| { + if let Some(flags) = config.parse_name_value_directive(ln, MINICORE_COMPILE_FLAGS) { + let flags = split_flags(&flags); + // FIXME(#147955): Extract and unify this with other handlers that + // check compiler flags, e.g. COMPILE_FLAGS. + for flag in &flags { + if flag == "--edition" || flag.starts_with("--edition=") { + panic!("you must use `//@ edition` to configure the edition"); + } + } + props.minicore_compile_flags.extend(flags); + } + }), + handler(DONT_REQUIRE_ANNOTATIONS, |config, ln, props| { + if let Some(err_kind) = config.parse_name_value_directive(ln, DONT_REQUIRE_ANNOTATIONS) + { + props + .dont_require_annotations + .insert(ErrorKind::expect_from_user_str(err_kind.trim())); + } + }), + handler(DISABLE_GDB_PRETTY_PRINTERS, |config, ln, props| { + config.set_name_directive( + ln, + DISABLE_GDB_PRETTY_PRINTERS, + &mut props.disable_gdb_pretty_printers, + ); + }), + handler(COMPARE_OUTPUT_BY_LINES, |config, ln, props| { + config.set_name_directive( + ln, + COMPARE_OUTPUT_BY_LINES, + &mut props.compare_output_by_lines, + ); + }), + ]; + + handlers + .into_iter() + .flat_map(|NamedHandler { names, handler }| { + names.into_iter().map(move |name| (name, Handler::clone(&handler))) + }) + .collect() +} diff --git a/src/tools/compiletest/src/directives/tests.rs b/src/tools/compiletest/src/directives/tests.rs index e221c3a2daf2..fe39e382ed5b 100644 --- a/src/tools/compiletest/src/directives/tests.rs +++ b/src/tools/compiletest/src/directives/tests.rs @@ -1,14 +1,31 @@ +use std::collections::BTreeSet; + use camino::Utf8Path; use semver::Version; use crate::common::{Config, Debugger, TestMode}; use crate::directives::{ - self, AuxProps, DirectivesCache, EarlyProps, Edition, EditionRange, FileDirectives, - extract_llvm_version, extract_version_range, line_directive, parse_edition, - parse_normalize_rule, + self, AuxProps, DIRECTIVE_HANDLERS_MAP, DirectivesCache, EarlyProps, Edition, EditionRange, + FileDirectives, KNOWN_DIRECTIVE_NAMES_SET, extract_llvm_version, extract_version_range, + line_directive, parse_edition, parse_normalize_rule, }; use crate::executor::{CollectedTestDesc, ShouldFail}; +/// All directive handlers should have a name that is also in `KNOWN_DIRECTIVE_NAMES_SET`. +#[test] +fn handler_names() { + let unknown_names = DIRECTIVE_HANDLERS_MAP + .keys() + .copied() + .filter(|name| !KNOWN_DIRECTIVE_NAMES_SET.contains(name)) + .collect::>(); + + assert!( + unknown_names.is_empty(), + "Directive handler names not in `directive_names.rs`: {unknown_names:#?}" + ); +} + fn make_test_description( config: &Config, name: String, diff --git a/src/tools/compiletest/src/lib.rs b/src/tools/compiletest/src/lib.rs index a3a40a1a7ee8..4dcf3ef28cde 100644 --- a/src/tools/compiletest/src/lib.rs +++ b/src/tools/compiletest/src/lib.rs @@ -141,13 +141,13 @@ fn parse_config(args: Vec) -> Config { .optopt("", "host", "the host to build for", "HOST") .optopt("", "cdb", "path to CDB to use for CDB debuginfo tests", "PATH") .optopt("", "gdb", "path to GDB to use for GDB debuginfo tests", "PATH") + .optopt("", "lldb", "path to LLDB to use for LLDB debuginfo tests", "PATH") .optopt("", "lldb-version", "the version of LLDB used", "VERSION STRING") .optopt("", "llvm-version", "the version of LLVM used", "VERSION STRING") .optflag("", "system-llvm", "is LLVM the system LLVM") .optopt("", "android-cross-path", "Android NDK standalone path", "PATH") .optopt("", "adb-path", "path to the android debugger", "PATH") .optopt("", "adb-test-dir", "path to tests for the android debugger", "PATH") - .optopt("", "lldb-python-dir", "directory containing LLDB's python module", "PATH") .reqopt("", "cc", "path to a C compiler", "PATH") .reqopt("", "cxx", "path to a C++ compiler", "PATH") .reqopt("", "cflags", "flags for the C compiler", "FLAGS") @@ -264,6 +264,7 @@ fn parse_config(args: Vec) -> Config { let gdb = debuggers::discover_gdb(matches.opt_str("gdb"), &target, &android_cross_path); let gdb_version = gdb.as_deref().and_then(debuggers::query_gdb_version); // FIXME: `lldb_version` is *derived* from lldb, but it's *not* technically a config! + let lldb = matches.opt_str("lldb").map(Utf8PathBuf::from); let lldb_version = matches.opt_str("lldb-version").as_deref().and_then(debuggers::extract_lldb_version); let color = match matches.opt_str("color").as_deref() { @@ -435,6 +436,7 @@ fn parse_config(args: Vec) -> Config { cdb_version, gdb, gdb_version, + lldb, lldb_version, llvm_version, system_llvm: matches.opt_present("system-llvm"), @@ -444,7 +446,6 @@ fn parse_config(args: Vec) -> Config { adb_device_status: opt_str2(matches.opt_str("target")).contains("android") && "(none)" != opt_str2(matches.opt_str("adb-test-dir")) && !opt_str2(matches.opt_str("adb-test-dir")).is_empty(), - lldb_python_dir: matches.opt_str("lldb-python-dir"), verbose: matches.opt_present("verbose"), only_modified: matches.opt_present("only-modified"), color, diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 8b776f7e9289..6f9fdd52fc08 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -200,10 +200,11 @@ pub fn compute_stamp_hash(config: &Config) -> String { } Some(Debugger::Lldb) => { - config.python.hash(&mut hash); - config.lldb_python_dir.hash(&mut hash); + // LLDB debuginfo tests now use LLDB's embedded Python, with an + // explicit PYTHONPATH, so they don't depend on `--python` or + // the ambient PYTHONPATH. + config.lldb.hash(&mut hash); env::var_os("PATH").hash(&mut hash); - env::var_os("PYTHONPATH").hash(&mut hash); } None => {} diff --git a/src/tools/compiletest/src/runtest/debuginfo.rs b/src/tools/compiletest/src/runtest/debuginfo.rs index bc597597ce12..15e37cda7d96 100644 --- a/src/tools/compiletest/src/runtest/debuginfo.rs +++ b/src/tools/compiletest/src/runtest/debuginfo.rs @@ -326,9 +326,9 @@ impl TestCx<'_> { } fn run_debuginfo_lldb_test(&self) { - if self.config.lldb_python_dir.is_none() { - self.fatal("Can't run LLDB test because LLDB's python path is not set."); - } + let Some(ref lldb) = self.config.lldb else { + self.fatal("Can't run LLDB test because LLDB's path is not set."); + }; // compile test file (it should have 'compile-flags:-g' in the directive) let should_run = self.run_if_enabled(); @@ -434,7 +434,7 @@ impl TestCx<'_> { let debugger_script = self.make_out_name("debugger.script"); // Let LLDB execute the script via lldb_batchmode.py - let debugger_run_result = self.run_lldb(&exe_file, &debugger_script); + let debugger_run_result = self.run_lldb(lldb, &exe_file, &debugger_script); if !debugger_run_result.status.success() { self.fatal_proc_rec("Error while running LLDB", &debugger_run_result); @@ -445,23 +445,23 @@ impl TestCx<'_> { } } - fn run_lldb(&self, test_executable: &Utf8Path, debugger_script: &Utf8Path) -> ProcRes { - // Prepare the lldb_batchmode which executes the debugger script - let lldb_script_path = self.config.src_root.join("src/etc/lldb_batchmode.py"); + fn run_lldb( + &self, + lldb: &Utf8Path, + test_executable: &Utf8Path, + debugger_script: &Utf8Path, + ) -> ProcRes { + // Path containing `lldb_batchmode.py`, so that the `script` command can import it. + let pythonpath = self.config.src_root.join("src/etc"); - // FIXME: `PYTHONPATH` takes precedence over the flag...? - let pythonpath = if let Ok(pp) = std::env::var("PYTHONPATH") { - format!("{pp}:{}", self.config.lldb_python_dir.as_ref().unwrap()) - } else { - self.config.lldb_python_dir.clone().unwrap() - }; - self.run_command_to_procres( - Command::new(&self.config.python) - .arg(&lldb_script_path) - .arg(test_executable) - .arg(debugger_script) - .env("PYTHONUNBUFFERED", "1") // Help debugging #78665 - .env("PYTHONPATH", pythonpath), - ) + let mut cmd = Command::new(lldb); + cmd.arg("--one-line") + .arg("script --language python -- import lldb_batchmode; lldb_batchmode.main()") + .env("LLDB_BATCHMODE_TARGET_PATH", test_executable) + .env("LLDB_BATCHMODE_SCRIPT_PATH", debugger_script) + .env("PYTHONUNBUFFERED", "1") // Help debugging #78665 + .env("PYTHONPATH", pythonpath); + + self.run_command_to_procres(&mut cmd) } } diff --git a/src/tools/compiletest/src/rustdoc_gui_test.rs b/src/tools/compiletest/src/rustdoc_gui_test.rs index 60a7e6d47d2f..db66d7a8febc 100644 --- a/src/tools/compiletest/src/rustdoc_gui_test.rs +++ b/src/tools/compiletest/src/rustdoc_gui_test.rs @@ -99,6 +99,7 @@ fn incomplete_config_for_rustdoc_gui_test() -> Config { cdb_version: Default::default(), gdb: Default::default(), gdb_version: Default::default(), + lldb: Default::default(), lldb_version: Default::default(), llvm_version: Default::default(), system_llvm: Default::default(), @@ -106,7 +107,6 @@ fn incomplete_config_for_rustdoc_gui_test() -> Config { adb_path: Default::default(), adb_test_dir: Default::default(), adb_device_status: Default::default(), - lldb_python_dir: Default::default(), verbose: Default::default(), color: Default::default(), remote_test_client: Default::default(), diff --git a/src/tools/miri/.github/workflows/ci.yml b/src/tools/miri/.github/workflows/ci.yml index 27d2f4a6df30..a61a467ebce1 100644 --- a/src/tools/miri/.github/workflows/ci.yml +++ b/src/tools/miri/.github/workflows/ci.yml @@ -73,7 +73,10 @@ jobs: sudo bash -c "echo 'https://ports.ubuntu.com/ priority:4' >> /etc/apt/apt-mirrors.txt" # Add architecture sudo dpkg --add-architecture ${{ matrix.multiarch }} - sudo apt update + # Ubuntu Ports often has outdated mirrors so try a few times to get the apt repo + for TRY in $(seq 3); do + { sudo apt update && break; } || sleep 30 + done # Install needed packages sudo apt install $(echo "libatomic1: zlib1g-dev:" | sed 's/:/:${{ matrix.multiarch }}/g') - uses: ./.github/workflows/setup diff --git a/src/tools/miri/Cargo.lock b/src/tools/miri/Cargo.lock index d66529a464b6..a2b02f286d65 100644 --- a/src/tools/miri/Cargo.lock +++ b/src/tools/miri/Cargo.lock @@ -1519,9 +1519,9 @@ dependencies = [ [[package]] name = "tikv-jemalloc-sys" -version = "0.6.0+5.3.0-1-ge13ca993e8ccb9ba9847cc330696e02839f328f7" +version = "0.6.1+5.3.0-1-ge13ca993e8ccb9ba9847cc330696e02839f328f7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd3c60906412afa9c2b5b5a48ca6a5abe5736aec9eb48ad05037a677e52e4e2d" +checksum = "cd8aa5b2ab86a2cefa406d889139c162cbb230092f7d1d7cbc1716405d852a3b" dependencies = [ "cc", "libc", diff --git a/src/tools/miri/Cargo.toml b/src/tools/miri/Cargo.toml index 8bb4f1c16093..5341b3a48692 100644 --- a/src/tools/miri/Cargo.toml +++ b/src/tools/miri/Cargo.toml @@ -33,8 +33,8 @@ serde_json = { version = "1.0", optional = true } # But only for some targets, it fails for others. Rustc configures this in its CI, but we can't # easily use that since we support of-tree builds. [target.'cfg(any(target_os = "linux", target_os = "macos"))'.dependencies.tikv-jemalloc-sys] -version = "0.6.0" -features = ['unprefixed_malloc_on_supported_platforms'] +version = "0.6.1" +features = ['override_allocator_on_supported_platforms'] [target.'cfg(unix)'.dependencies] libc = "0.2" diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index 04d41c96f5c0..7dde150d1e8b 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -8401398e1f14a24670ee1a3203713dc2f0f8b3a8 +0b329f801a09004dacb19aaf09d5cb8b4c51d3f8 diff --git a/src/tools/miri/src/bin/miri.rs b/src/tools/miri/src/bin/miri.rs index 920fc2948191..8b4445e379a2 100644 --- a/src/tools/miri/src/bin/miri.rs +++ b/src/tools/miri/src/bin/miri.rs @@ -20,6 +20,11 @@ extern crate rustc_middle; extern crate rustc_session; extern crate rustc_span; +/// See docs in https://github.com/rust-lang/rust/blob/HEAD/compiler/rustc/src/main.rs +/// and https://github.com/rust-lang/rust/pull/146627 for why we need this `use` statement. +#[cfg(any(target_os = "linux", target_os = "macos"))] +use tikv_jemalloc_sys as _; + mod log; use std::env; @@ -392,48 +397,7 @@ fn parse_range(val: &str) -> Result, &'static str> { Ok(from..to) } -#[cfg(any(target_os = "linux", target_os = "macos"))] -fn jemalloc_magic() { - // These magic runes are copied from - // . - // See there for further comments. - use std::os::raw::{c_int, c_void}; - - use tikv_jemalloc_sys as jemalloc_sys; - - #[used] - static _F1: unsafe extern "C" fn(usize, usize) -> *mut c_void = jemalloc_sys::calloc; - #[used] - static _F2: unsafe extern "C" fn(*mut *mut c_void, usize, usize) -> c_int = - jemalloc_sys::posix_memalign; - #[used] - static _F3: unsafe extern "C" fn(usize, usize) -> *mut c_void = jemalloc_sys::aligned_alloc; - #[used] - static _F4: unsafe extern "C" fn(usize) -> *mut c_void = jemalloc_sys::malloc; - #[used] - static _F5: unsafe extern "C" fn(*mut c_void, usize) -> *mut c_void = jemalloc_sys::realloc; - #[used] - static _F6: unsafe extern "C" fn(*mut c_void) = jemalloc_sys::free; - - // On OSX, jemalloc doesn't directly override malloc/free, but instead - // registers itself with the allocator's zone APIs in a ctor. However, - // the linker doesn't seem to consider ctors as "used" when statically - // linking, so we need to explicitly depend on the function. - #[cfg(target_os = "macos")] - { - unsafe extern "C" { - fn _rjem_je_zone_register(); - } - - #[used] - static _F7: unsafe extern "C" fn() = _rjem_je_zone_register; - } -} - fn main() { - #[cfg(any(target_os = "linux", target_os = "macos"))] - jemalloc_magic(); - let early_dcx = EarlyDiagCtxt::new(ErrorOutputType::default()); // Snapshot a copy of the environment before `rustc` starts messing with it. diff --git a/src/tools/miri/src/concurrency/thread.rs b/src/tools/miri/src/concurrency/thread.rs index 6178f87d7849..7838bd214302 100644 --- a/src/tools/miri/src/concurrency/thread.rs +++ b/src/tools/miri/src/concurrency/thread.rs @@ -15,6 +15,7 @@ use rustc_index::{Idx, IndexVec}; use rustc_middle::mir::Mutability; use rustc_middle::ty::layout::TyAndLayout; use rustc_span::Span; +use rustc_target::spec::Os; use crate::concurrency::GlobalDataRaceHandler; use crate::shims::tls; @@ -471,7 +472,7 @@ impl<'tcx> ThreadManager<'tcx> { ) { ecx.machine.threads.threads[ThreadId::MAIN_THREAD].on_stack_empty = Some(on_main_stack_empty); - if ecx.tcx.sess.target.os.as_ref() != "windows" { + if ecx.tcx.sess.target.os != Os::Windows { // The main thread can *not* be joined on except on windows. ecx.machine.threads.threads[ThreadId::MAIN_THREAD].join_status = ThreadJoinStatus::Detached; diff --git a/src/tools/miri/src/eval.rs b/src/tools/miri/src/eval.rs index 20b506bad91e..6daee0ba6969 100644 --- a/src/tools/miri/src/eval.rs +++ b/src/tools/miri/src/eval.rs @@ -14,6 +14,7 @@ use rustc_hir::def_id::DefId; use rustc_middle::ty::layout::{HasTyCtxt, HasTypingEnv, LayoutCx}; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_session::config::EntryFnType; +use rustc_target::spec::Os; use crate::concurrency::GenmcCtx; use crate::concurrency::thread::TlsAllocAction; @@ -341,7 +342,7 @@ pub fn create_ecx<'tcx>( ecx.machine.argv = Some(argv_place.ptr()); } // Store command line as UTF-16 for Windows `GetCommandLineW`. - if tcx.sess.target.os == "windows" { + if tcx.sess.target.os == Os::Windows { // Construct a command string with all the arguments. let cmd_utf16: Vec = args_to_utf16_command_string(config.args.iter()); diff --git a/src/tools/miri/src/helpers.rs b/src/tools/miri/src/helpers.rs index 18e16ddf1a5d..383a4e2ea4b0 100644 --- a/src/tools/miri/src/helpers.rs +++ b/src/tools/miri/src/helpers.rs @@ -19,6 +19,7 @@ use rustc_middle::ty::{self, IntTy, Ty, TyCtxt, UintTy}; use rustc_session::config::CrateType; use rustc_span::{Span, Symbol}; use rustc_symbol_mangling::mangle_internal_symbol; +use rustc_target::spec::Os; use crate::*; @@ -234,7 +235,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { /// Helper function to get a `libc` constant as a `Scalar`. fn eval_libc(&self, name: &str) -> Scalar { - if self.eval_context_ref().tcx.sess.target.os == "windows" { + if self.eval_context_ref().tcx.sess.target.os == Os::Windows { panic!( "`libc` crate is not reliably available on Windows targets; Miri should not use it there" ); @@ -290,7 +291,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { /// Helper function to get the `TyAndLayout` of a `libc` type fn libc_ty_layout(&self, name: &str) -> TyAndLayout<'tcx> { let this = self.eval_context_ref(); - if this.tcx.sess.target.os == "windows" { + if this.tcx.sess.target.os == Os::Windows { panic!( "`libc` crate is not reliably available on Windows targets; Miri should not use it there" ); @@ -669,7 +670,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { /// Helper function used inside the shims of foreign functions to assert that the target OS /// is `target_os`. It panics showing a message with the `name` of the foreign function /// if this is not the case. - fn assert_target_os(&self, target_os: &str, name: &str) { + fn assert_target_os(&self, target_os: Os, name: &str) { assert_eq!( self.eval_context_ref().tcx.sess.target.os, target_os, @@ -680,9 +681,9 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { /// Helper function used inside shims of foreign functions to check that the target OS /// is one of `target_oses`. It returns an error containing the `name` of the foreign function /// in a message if this is not the case. - fn check_target_os(&self, target_oses: &[&str], name: Symbol) -> InterpResult<'tcx> { - let target_os = self.eval_context_ref().tcx.sess.target.os.as_ref(); - if !target_oses.contains(&target_os) { + fn check_target_os(&self, target_oses: &[Os], name: Symbol) -> InterpResult<'tcx> { + let target_os = &self.eval_context_ref().tcx.sess.target.os; + if !target_oses.contains(target_os) { throw_unsup_format!("`{name}` is not supported on {target_os}"); } interp_ok(()) @@ -918,7 +919,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { /// Always returns a `Vec` no matter the size of `wchar_t`. fn read_wchar_t_str(&self, ptr: Pointer) -> InterpResult<'tcx, Vec> { let this = self.eval_context_ref(); - let wchar_t = if this.tcx.sess.target.os == "windows" { + let wchar_t = if this.tcx.sess.target.os == Os::Windows { // We don't have libc on Windows so we have to hard-code the type ourselves. this.machine.layouts.u16 } else { diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs index 498058a279f8..982b6c3fbbdd 100644 --- a/src/tools/miri/src/machine.rs +++ b/src/tools/miri/src/machine.rs @@ -31,7 +31,7 @@ use rustc_span::def_id::{CrateNum, DefId}; use rustc_span::{Span, SpanData, Symbol}; use rustc_symbol_mangling::mangle_internal_symbol; use rustc_target::callconv::FnAbi; -use rustc_target::spec::Arch; +use rustc_target::spec::{Arch, Os}; use crate::alloc_addresses::EvalContextExt; use crate::concurrency::cpu_affinity::{self, CpuAffinityMask}; @@ -715,7 +715,7 @@ impl<'tcx> MiriMachine<'tcx> { match target.arch { Arch::Wasm32 | Arch::Wasm64 => 64 * 1024, // https://webassembly.github.io/spec/core/exec/runtime.html#memory-instances Arch::AArch64 => { - if target.options.vendor.as_ref() == "apple" { + if target.is_like_darwin { // No "definitive" source, but see: // https://www.wwdcnotes.com/notes/wwdc20/10214/ // https://github.com/ziglang/zig/issues/11308 etc. @@ -739,7 +739,7 @@ impl<'tcx> MiriMachine<'tcx> { ); let threads = ThreadManager::new(config); let mut thread_cpu_affinity = FxHashMap::default(); - if matches!(&*tcx.sess.target.os, "linux" | "freebsd" | "android") { + if matches!(&tcx.sess.target.os, Os::Linux | Os::FreeBsd | Os::Android) { thread_cpu_affinity .insert(threads.active_thread(), CpuAffinityMask::new(&layout_cx, config.num_cpus)); } diff --git a/src/tools/miri/src/shims/alloc.rs b/src/tools/miri/src/shims/alloc.rs index 217069b8b5d9..94649dde4736 100644 --- a/src/tools/miri/src/shims/alloc.rs +++ b/src/tools/miri/src/shims/alloc.rs @@ -3,7 +3,7 @@ use rustc_ast::expand::allocator::SpecialAllocatorMethod; use rustc_middle::ty::Ty; use rustc_span::Symbol; use rustc_target::callconv::FnAbi; -use rustc_target::spec::Arch; +use rustc_target::spec::{Arch, Os}; use crate::*; @@ -19,10 +19,10 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // This is given by `alignof(max_align_t)`. The following list is taken from // `library/std/src/sys/alloc/mod.rs` (where this is called `MIN_ALIGN`) and should // be kept in sync. - let os = this.tcx.sess.target.os.as_ref(); + let os = &this.tcx.sess.target.os; let max_fundamental_align = match &this.tcx.sess.target.arch { - Arch::RiscV32 if matches!(os, "espidf" | "zkvm") => 4, - Arch::Xtensa if matches!(os, "espidf") => 4, + Arch::RiscV32 if matches!(os, Os::EspIdf | Os::Zkvm) => 4, + Arch::Xtensa if matches!(os, Os::EspIdf) => 4, Arch::X86 | Arch::Arm | Arch::M68k @@ -54,7 +54,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { | Arch::Nvptx64 | Arch::PowerPC64LE | Arch::SpirV - | Arch::Unknown(_)) => bug!("unsupported target architecture for malloc: `{arch}`"), + | Arch::Other(_)) => bug!("unsupported target architecture for malloc: `{arch}`"), }; // The C standard only requires sufficient alignment for any *type* with size less than or // equal to the size requested. Types one can define in standard C seem to never have an alignment diff --git a/src/tools/miri/src/shims/env.rs b/src/tools/miri/src/shims/env.rs index b9fb9192df4a..6915924f2a48 100644 --- a/src/tools/miri/src/shims/env.rs +++ b/src/tools/miri/src/shims/env.rs @@ -1,6 +1,7 @@ use std::ffi::{OsStr, OsString}; use rustc_data_structures::fx::FxHashMap; +use rustc_target::spec::Os; use self::shims::unix::UnixEnvVars; use self::shims::windows::WindowsEnvVars; @@ -48,7 +49,7 @@ impl<'tcx> EnvVars<'tcx> { let env_vars = if ecx.target_os_is_unix() { EnvVars::Unix(UnixEnvVars::new(ecx, env_vars)?) - } else if ecx.tcx.sess.target.os == "windows" { + } else if ecx.tcx.sess.target.os == Os::Windows { EnvVars::Windows(WindowsEnvVars::new(ecx, env_vars)?) } else { // For "none" targets (i.e., without an OS). @@ -118,7 +119,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let this = self.eval_context_ref(); let index = thread.to_u32(); let target_os = &this.tcx.sess.target.os; - if target_os == "linux" || target_os == "netbsd" { + if matches!(target_os, Os::Linux | Os::NetBsd) { // On Linux, the main thread has PID == TID so we uphold this. NetBSD also appears // to exhibit the same behavior, though I can't find a citation. this.get_pid().strict_add(index) diff --git a/src/tools/miri/src/shims/extern_static.rs b/src/tools/miri/src/shims/extern_static.rs index c2527bf8e25d..fc9971641088 100644 --- a/src/tools/miri/src/shims/extern_static.rs +++ b/src/tools/miri/src/shims/extern_static.rs @@ -1,5 +1,7 @@ //! Provides the `extern static` that this platform expects. +use rustc_target::spec::Os; + use crate::*; impl<'tcx> MiriMachine<'tcx> { @@ -49,28 +51,28 @@ impl<'tcx> MiriMachine<'tcx> { Self::add_extern_static(ecx, "environ", environ); } - match ecx.tcx.sess.target.os.as_ref() { - "linux" => { + match &ecx.tcx.sess.target.os { + Os::Linux => { Self::null_ptr_extern_statics( ecx, &["__cxa_thread_atexit_impl", "__clock_gettime64"], )?; Self::weak_symbol_extern_statics(ecx, &["getrandom", "gettid", "statx"])?; } - "freebsd" => { + Os::FreeBsd => { Self::null_ptr_extern_statics(ecx, &["__cxa_thread_atexit_impl"])?; } - "android" => { + Os::Android => { Self::null_ptr_extern_statics(ecx, &["bsd_signal"])?; Self::weak_symbol_extern_statics(ecx, &["signal", "getrandom", "gettid"])?; } - "windows" => { + Os::Windows => { // "_tls_used" // This is some obscure hack that is part of the Windows TLS story. It's a `u8`. let val = ImmTy::from_int(0, ecx.machine.layouts.u8); Self::alloc_extern_static(ecx, "_tls_used", val)?; } - "illumos" | "solaris" => { + Os::Illumos | Os::Solaris => { Self::weak_symbol_extern_statics(ecx, &["pthread_setname_np"])?; } _ => {} // No "extern statics" supported on this target diff --git a/src/tools/miri/src/shims/foreign_items.rs b/src/tools/miri/src/shims/foreign_items.rs index bffe633f7797..440388673e7d 100644 --- a/src/tools/miri/src/shims/foreign_items.rs +++ b/src/tools/miri/src/shims/foreign_items.rs @@ -15,7 +15,7 @@ use rustc_middle::{mir, ty}; use rustc_session::config::OomStrategy; use rustc_span::Symbol; use rustc_target::callconv::FnAbi; -use rustc_target::spec::Arch; +use rustc_target::spec::{Arch, Os}; use super::alloc::EvalContextExt as _; use super::backtrace::EvalContextExt as _; @@ -101,9 +101,9 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn is_dyn_sym(&self, name: &str) -> bool { let this = self.eval_context_ref(); - match this.tcx.sess.target.os.as_ref() { + match &this.tcx.sess.target.os { os if this.target_os_is_unix() => shims::unix::foreign_items::is_dyn_sym(name, os), - "windows" => shims::windows::foreign_items::is_dyn_sym(name), + Os::Windows => shims::windows::foreign_items::is_dyn_sym(name), _ => false, } } @@ -842,12 +842,12 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { } // Platform-specific shims - return match this.tcx.sess.target.os.as_ref() { + return match &this.tcx.sess.target.os { _ if this.target_os_is_unix() => shims::unix::foreign_items::EvalContextExt::emulate_foreign_item_inner( this, link_name, abi, args, dest, ), - "windows" => + Os::Windows => shims::windows::foreign_items::EvalContextExt::emulate_foreign_item_inner( this, link_name, abi, args, dest, ), diff --git a/src/tools/miri/src/shims/native_lib/trace/parent.rs b/src/tools/miri/src/shims/native_lib/trace/parent.rs index 335188b33183..5476cccc02e3 100644 --- a/src/tools/miri/src/shims/native_lib/trace/parent.rs +++ b/src/tools/miri/src/shims/native_lib/trace/parent.rs @@ -501,7 +501,7 @@ fn handle_segfault( // Move the instr ptr into the deprotection code. #[expect(clippy::as_conversions)] - new_regs.set_ip(mempr_off as usize); + new_regs.set_ip(mempr_off as *const () as usize); // Don't mess up the stack by accident! new_regs.set_sp(stack_ptr); @@ -553,7 +553,7 @@ fn handle_segfault( // Reprotect everything and continue. #[expect(clippy::as_conversions)] - new_regs.set_ip(mempr_on as usize); + new_regs.set_ip(mempr_on as *const () as usize); new_regs.set_sp(stack_ptr); ptrace::setregs(pid, new_regs).unwrap(); wait_for_signal(Some(pid), signal::SIGSTOP, InitialCont::Yes)?; diff --git a/src/tools/miri/src/shims/os_str.rs b/src/tools/miri/src/shims/os_str.rs index b9391a0ffe07..28b03ffb88c6 100644 --- a/src/tools/miri/src/shims/os_str.rs +++ b/src/tools/miri/src/shims/os_str.rs @@ -7,6 +7,7 @@ use std::os::windows::ffi::{OsStrExt, OsStringExt}; use std::path::{Path, PathBuf}; use rustc_middle::ty::Ty; +use rustc_target::spec::Os; use crate::*; @@ -329,7 +330,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Below we assume that everything non-Windows works like Unix, at least // when it comes to file system path conventions. #[cfg(windows)] - return if target_os == "windows" { + return if *target_os == Os::Windows { // Windows-on-Windows, all fine. os_str } else { @@ -346,7 +347,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { Cow::Owned(OsString::from_wide(&path)) }; #[cfg(unix)] - return if target_os == "windows" { + return if *target_os == Os::Windows { // Windows target, Unix host. let mut path: Vec = os_str.into_owned().into_encoded_bytes(); match direction { diff --git a/src/tools/miri/src/shims/time.rs b/src/tools/miri/src/shims/time.rs index 6e56fdfe35ae..614cc75c6d58 100644 --- a/src/tools/miri/src/shims/time.rs +++ b/src/tools/miri/src/shims/time.rs @@ -5,6 +5,7 @@ use std::time::{Duration, SystemTime}; use chrono::{DateTime, Datelike, Offset, Timelike, Utc}; use chrono_tz::Tz; +use rustc_target::spec::Os; use crate::*; @@ -31,8 +32,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } // Some further platform-specific names we support. - match this.tcx.sess.target.os.as_ref() { - "linux" | "freebsd" | "android" => { + match &this.tcx.sess.target.os { + Os::Linux | Os::FreeBsd | Os::Android => { // Linux further distinguishes regular and "coarse" clocks, but the "coarse" version // is just specified to be "faster and less precise", so we treat it like normal // clocks. @@ -42,7 +43,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { return Some(TimeoutClock::Monotonic); } } - "macos" => { + Os::MacOs => { // `CLOCK_UPTIME_RAW` supposed to not increment while the system is asleep... but // that's not really something a program running inside Miri can tell, anyway. // We need to support it because std uses it. @@ -176,7 +177,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // solaris/illumos system tm struct does not have // the additional tm_zone/tm_gmtoff fields. // https://docs.oracle.com/cd/E36784_01/html/E36874/localtime-r-3c.html - if !matches!(&*this.tcx.sess.target.os, "solaris" | "illumos") { + if !matches!(&this.tcx.sess.target.os, Os::Solaris | Os::Illumos) { // tm_zone represents the timezone value in the form of: +0730, +08, -0730 or -08. // This may not be consistent with libc::localtime_r's result. @@ -215,7 +216,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { ) -> InterpResult<'tcx> { let this = self.eval_context_mut(); - this.assert_target_os("windows", shim_name); + this.assert_target_os(Os::Windows, shim_name); this.check_no_isolation(shim_name)?; let filetime = this.deref_pointer_as(LPFILETIME_op, this.windows_ty_layout("FILETIME"))?; @@ -237,7 +238,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { ) -> InterpResult<'tcx, Scalar> { let this = self.eval_context_mut(); - this.assert_target_os("windows", "QueryPerformanceCounter"); + this.assert_target_os(Os::Windows, "QueryPerformanceCounter"); // QueryPerformanceCounter uses a hardware counter as its basis. // Miri will emulate a counter with a resolution of 1 nanosecond. @@ -260,7 +261,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { ) -> InterpResult<'tcx, Scalar> { let this = self.eval_context_mut(); - this.assert_target_os("windows", "QueryPerformanceFrequency"); + this.assert_target_os(Os::Windows, "QueryPerformanceFrequency"); // Retrieves the frequency of the hardware performance counter. // The frequency of the performance counter is fixed at system boot and @@ -301,7 +302,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn mach_absolute_time(&self) -> InterpResult<'tcx, Scalar> { let this = self.eval_context_ref(); - this.assert_target_os("macos", "mach_absolute_time"); + this.assert_target_os(Os::MacOs, "mach_absolute_time"); // This returns a u64, with time units determined dynamically by `mach_timebase_info`. // We return plain nanoseconds. @@ -316,7 +317,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn mach_timebase_info(&mut self, info_op: &OpTy<'tcx>) -> InterpResult<'tcx, Scalar> { let this = self.eval_context_mut(); - this.assert_target_os("macos", "mach_timebase_info"); + this.assert_target_os(Os::MacOs, "mach_timebase_info"); let info = this.deref_pointer_as(info_op, this.libc_ty_layout("mach_timebase_info"))?; @@ -418,7 +419,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn Sleep(&mut self, timeout: &OpTy<'tcx>) -> InterpResult<'tcx> { let this = self.eval_context_mut(); - this.assert_target_os("windows", "Sleep"); + this.assert_target_os(Os::Windows, "Sleep"); let timeout_ms = this.read_scalar(timeout)?.to_u32()?; diff --git a/src/tools/miri/src/shims/tls.rs b/src/tools/miri/src/shims/tls.rs index 9dc829d7a1ee..2159c41ab16c 100644 --- a/src/tools/miri/src/shims/tls.rs +++ b/src/tools/miri/src/shims/tls.rs @@ -6,6 +6,7 @@ use std::task::Poll; use rustc_abi::{ExternAbi, HasDataLayout, Size}; use rustc_middle::ty; +use rustc_target::spec::Os; use crate::*; @@ -234,8 +235,8 @@ impl<'tcx> TlsDtorsState<'tcx> { let new_state = 'new_state: { match &mut self.0 { Init => { - match this.tcx.sess.target.os.as_ref() { - "macos" => { + match this.tcx.sess.target.os { + Os::MacOs => { // macOS has a _tlv_atexit function that allows // registering destructors without associated keys. // These are run first. @@ -245,7 +246,7 @@ impl<'tcx> TlsDtorsState<'tcx> { // All other Unixes directly jump to running the pthread dtors. break 'new_state PthreadDtors(Default::default()); } - "windows" => { + Os::Windows => { // Determine which destructors to run. let dtors = this.lookup_windows_tls_dtors()?; // And move to the next state, that runs them. diff --git a/src/tools/miri/src/shims/unix/env.rs b/src/tools/miri/src/shims/unix/env.rs index eb4365e20042..41bf70c34634 100644 --- a/src/tools/miri/src/shims/unix/env.rs +++ b/src/tools/miri/src/shims/unix/env.rs @@ -6,6 +6,7 @@ use rustc_abi::{FieldIdx, Size}; use rustc_data_structures::fx::FxHashMap; use rustc_index::IndexVec; use rustc_middle::ty::Ty; +use rustc_target::spec::Os; use crate::*; @@ -281,7 +282,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { tid_op: &OpTy<'tcx>, ) -> InterpResult<'tcx, Scalar> { let this = self.eval_context_mut(); - this.assert_target_os("macos", "pthread_threadip_np"); + this.assert_target_os(Os::MacOs, "pthread_threadip_np"); let tid_dest = this.read_pointer(tid_op)?; if this.ptr_is_null(tid_dest)? { diff --git a/src/tools/miri/src/shims/unix/fd.rs b/src/tools/miri/src/shims/unix/fd.rs index 95e26ef5d5d8..4f1d88b79954 100644 --- a/src/tools/miri/src/shims/unix/fd.rs +++ b/src/tools/miri/src/shims/unix/fd.rs @@ -6,6 +6,7 @@ use std::io::ErrorKind; use rand::Rng; use rustc_abi::Size; +use rustc_target::spec::Os; use crate::shims::files::FileDescription; use crate::shims::sig::check_min_vararg_count; @@ -197,7 +198,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fd.set_flags(flag, this) } - cmd if this.tcx.sess.target.os == "macos" + cmd if this.tcx.sess.target.os == Os::MacOs && cmd == this.eval_libc_i32("F_FULLFSYNC") => { // Reject if isolation is enabled. diff --git a/src/tools/miri/src/shims/unix/foreign_items.rs b/src/tools/miri/src/shims/unix/foreign_items.rs index 1f8e60484eda..a37a34f8df74 100644 --- a/src/tools/miri/src/shims/unix/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/foreign_items.rs @@ -5,6 +5,7 @@ use rustc_abi::{CanonAbi, Size}; use rustc_middle::ty::Ty; use rustc_span::Symbol; use rustc_target::callconv::FnAbi; +use rustc_target::spec::Os; use self::shims::unix::android::foreign_items as android; use self::shims::unix::freebsd::foreign_items as freebsd; @@ -16,7 +17,7 @@ use crate::shims::alloc::EvalContextExt as _; use crate::shims::unix::*; use crate::{shim_sig, *}; -pub fn is_dyn_sym(name: &str, target_os: &str) -> bool { +pub fn is_dyn_sym(name: &str, target_os: &Os) -> bool { match name { // Used for tests. "isatty" => true, @@ -27,12 +28,12 @@ pub fn is_dyn_sym(name: &str, target_os: &str) -> bool { "getentropy" | "getrandom" => true, // Give specific OSes a chance to allow their symbols. _ => - match target_os { - "android" => android::is_dyn_sym(name), - "freebsd" => freebsd::is_dyn_sym(name), - "linux" => linux::is_dyn_sym(name), - "macos" => macos::is_dyn_sym(name), - "solaris" | "illumos" => solarish::is_dyn_sym(name), + match *target_os { + Os::Android => android::is_dyn_sym(name), + Os::FreeBsd => freebsd::is_dyn_sym(name), + Os::Linux => linux::is_dyn_sym(name), + Os::MacOs => macos::is_dyn_sym(name), + Os::Solaris | Os::Illumos => solarish::is_dyn_sym(name), _ => false, }, } @@ -302,7 +303,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } "flock" => { // Currently this function does not exist on all Unixes, e.g. on Solaris. - this.check_target_os(&["linux", "freebsd", "macos", "illumos"], link_name)?; + this.check_target_os(&[Os::Linux, Os::FreeBsd, Os::MacOs, Os::Illumos], link_name)?; let [fd, op] = this.check_shim_sig( shim_sig!(extern "C" fn(i32, i32) -> i32), link_name, @@ -530,7 +531,10 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } "pipe2" => { // Currently this function does not exist on all Unixes, e.g. on macOS. - this.check_target_os(&["linux", "freebsd", "solaris", "illumos"], link_name)?; + this.check_target_os( + &[Os::Linux, Os::FreeBsd, Os::Solaris, Os::Illumos], + link_name, + )?; let [pipefd, flags] = this.check_shim_sig( shim_sig!(extern "C" fn(*mut _, i32) -> i32), link_name, @@ -596,7 +600,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "reallocarray" => { // Currently this function does not exist on all Unixes, e.g. on macOS. - this.check_target_os(&["linux", "freebsd", "android"], link_name)?; + this.check_target_os(&[Os::Linux, Os::FreeBsd, Os::Android], link_name)?; let [ptr, nmemb, size] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; let ptr = this.read_pointer(ptr)?; @@ -861,7 +865,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "clock_nanosleep" => { // Currently this function does not exist on all Unixes, e.g. on macOS. this.check_target_os( - &["freebsd", "linux", "android", "solaris", "illumos"], + &[Os::FreeBsd, Os::Linux, Os::Android, Os::Solaris, Os::Illumos], link_name, )?; let [clock_id, flags, req, rem] = @@ -871,7 +875,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } "sched_getaffinity" => { // Currently this function does not exist on all Unixes, e.g. on macOS. - this.check_target_os(&["linux", "freebsd", "android"], link_name)?; + this.check_target_os(&[Os::Linux, Os::FreeBsd, Os::Android], link_name)?; let [pid, cpusetsize, mask] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; let pid = this.read_scalar(pid)?.to_u32()?; @@ -909,7 +913,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } "sched_setaffinity" => { // Currently this function does not exist on all Unixes, e.g. on macOS. - this.check_target_os(&["linux", "freebsd", "android"], link_name)?; + this.check_target_os(&[Os::Linux, Os::FreeBsd, Os::Android], link_name)?; let [pid, cpusetsize, mask] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; let pid = this.read_scalar(pid)?.to_u32()?; @@ -968,7 +972,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // This function is non-standard but exists with the same signature and behavior on // Linux, macOS, FreeBSD and Solaris/Illumos. this.check_target_os( - &["linux", "macos", "freebsd", "illumos", "solaris", "android"], + &[Os::Linux, Os::MacOs, Os::FreeBsd, Os::Illumos, Os::Solaris, Os::Android], link_name, )?; let [buf, bufsize] = @@ -1000,7 +1004,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // This function is non-standard but exists with the same signature and behavior on // Linux, FreeBSD and Solaris/Illumos. this.check_target_os( - &["linux", "freebsd", "illumos", "solaris", "android"], + &[Os::Linux, Os::FreeBsd, Os::Illumos, Os::Solaris, Os::Android], link_name, )?; let [ptr, len, flags] = @@ -1015,7 +1019,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "arc4random_buf" => { // This function is non-standard but exists with the same signature and // same behavior (eg never fails) on FreeBSD and Solaris/Illumos. - this.check_target_os(&["freebsd", "illumos", "solaris"], link_name)?; + this.check_target_os(&[Os::FreeBsd, Os::Illumos, Os::Solaris], link_name)?; let [ptr, len] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; let ptr = this.read_pointer(ptr)?; let len = this.read_target_usize(len)?; @@ -1036,7 +1040,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // `_Unwind_RaiseException` impl in miri should work: // https://github.com/ARM-software/abi-aa/blob/main/ehabi32/ehabi32.rst this.check_target_os( - &["linux", "freebsd", "illumos", "solaris", "android", "macos"], + &[Os::Linux, Os::FreeBsd, Os::Illumos, Os::Solaris, Os::Android, Os::MacOs], link_name, )?; // This function looks and behaves excatly like miri_start_unwind. @@ -1146,25 +1150,25 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Platform-specific shims _ => { - let target_os = &*this.tcx.sess.target.os; + let target_os = &this.tcx.sess.target.os; return match target_os { - "android" => + Os::Android => android::EvalContextExt::emulate_foreign_item_inner( this, link_name, abi, args, dest, ), - "freebsd" => + Os::FreeBsd => freebsd::EvalContextExt::emulate_foreign_item_inner( this, link_name, abi, args, dest, ), - "linux" => + Os::Linux => linux::EvalContextExt::emulate_foreign_item_inner( this, link_name, abi, args, dest, ), - "macos" => + Os::MacOs => macos::EvalContextExt::emulate_foreign_item_inner( this, link_name, abi, args, dest, ), - "solaris" | "illumos" => + Os::Solaris | Os::Illumos => solarish::EvalContextExt::emulate_foreign_item_inner( this, link_name, abi, args, dest, ), diff --git a/src/tools/miri/src/shims/unix/fs.rs b/src/tools/miri/src/shims/unix/fs.rs index 22bec9bd8394..137e60aaba4b 100644 --- a/src/tools/miri/src/shims/unix/fs.rs +++ b/src/tools/miri/src/shims/unix/fs.rs @@ -11,6 +11,7 @@ use std::time::SystemTime; use rustc_abi::Size; use rustc_data_structures::fx::FxHashMap; +use rustc_target::spec::Os; use self::shims::time::system_time_to_duration; use crate::shims::files::FileHandle; @@ -149,7 +150,7 @@ trait EvalContextExtPrivate<'tcx>: crate::MiriInterpCxExt<'tcx> { &buf, )?; - if matches!(&*this.tcx.sess.target.os, "macos" | "freebsd") { + if matches!(&this.tcx.sess.target.os, Os::MacOs | Os::FreeBsd) { this.write_int_fields_named( &[ ("st_atime_nsec", access_nsec.into()), @@ -164,7 +165,7 @@ trait EvalContextExtPrivate<'tcx>: crate::MiriInterpCxExt<'tcx> { )?; } - if matches!(&*this.tcx.sess.target.os, "solaris" | "illumos") { + if matches!(&this.tcx.sess.target.os, Os::Solaris | Os::Illumos) { let st_fstype = this.project_field_named(&buf, "st_fstype")?; // This is an array; write 0 into first element so that it encodes the empty string. this.write_int(0, &this.project_index(&st_fstype, 0)?)?; @@ -390,7 +391,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // (Technically we do not support *not* setting this flag, but we ignore that.) mirror |= o_cloexec; } - if this.tcx.sess.target.os == "linux" { + if this.tcx.sess.target.os == Os::Linux { let o_tmpfile = this.eval_libc_i32("O_TMPFILE"); if flag & o_tmpfile == o_tmpfile { // if the flag contains `O_TMPFILE` then we return a graceful error @@ -529,7 +530,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { ) -> InterpResult<'tcx, Scalar> { let this = self.eval_context_mut(); - if !matches!(&*this.tcx.sess.target.os, "macos" | "freebsd" | "solaris" | "illumos") { + if !matches!(&this.tcx.sess.target.os, Os::MacOs | Os::FreeBsd | Os::Solaris | Os::Illumos) + { panic!("`macos_fbsd_solaris_stat` should not be called on {}", this.tcx.sess.target.os); } @@ -559,7 +561,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { ) -> InterpResult<'tcx, Scalar> { let this = self.eval_context_mut(); - if !matches!(&*this.tcx.sess.target.os, "macos" | "freebsd" | "solaris" | "illumos") { + if !matches!(&this.tcx.sess.target.os, Os::MacOs | Os::FreeBsd | Os::Solaris | Os::Illumos) + { panic!( "`macos_fbsd_solaris_lstat` should not be called on {}", this.tcx.sess.target.os @@ -590,7 +593,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { ) -> InterpResult<'tcx, Scalar> { let this = self.eval_context_mut(); - if !matches!(&*this.tcx.sess.target.os, "macos" | "freebsd" | "solaris" | "illumos") { + if !matches!(&this.tcx.sess.target.os, Os::MacOs | Os::FreeBsd | Os::Solaris | Os::Illumos) + { panic!( "`macos_fbsd_solaris_fstat` should not be called on {}", this.tcx.sess.target.os @@ -623,7 +627,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { ) -> InterpResult<'tcx, Scalar> { let this = self.eval_context_mut(); - this.assert_target_os("linux", "statx"); + this.assert_target_os(Os::Linux, "statx"); let dirfd = this.read_scalar(dirfd_op)?.to_i32()?; let pathname_ptr = this.read_pointer(pathname_op)?; @@ -824,7 +828,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let this = self.eval_context_mut(); #[cfg_attr(not(unix), allow(unused_variables))] - let mode = if matches!(&*this.tcx.sess.target.os, "macos" | "freebsd") { + let mode = if matches!(&this.tcx.sess.target.os, Os::MacOs | Os::FreeBsd) { u32::from(this.read_scalar(mode_op)?.to_u16()?) } else { this.read_scalar(mode_op)?.to_u32()? @@ -903,7 +907,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn readdir64(&mut self, dirent_type: &str, dirp_op: &OpTy<'tcx>) -> InterpResult<'tcx, Scalar> { let this = self.eval_context_mut(); - if !matches!(&*this.tcx.sess.target.os, "linux" | "solaris" | "illumos" | "freebsd") { + if !matches!(&this.tcx.sess.target.os, Os::Linux | Os::Solaris | Os::Illumos | Os::FreeBsd) + { panic!("`linux_solaris_readdir64` should not be called on {}", this.tcx.sess.target.os); } @@ -981,7 +986,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Write common fields let ino_name = - if this.tcx.sess.target.os == "freebsd" { "d_fileno" } else { "d_ino" }; + if this.tcx.sess.target.os == Os::FreeBsd { "d_fileno" } else { "d_ino" }; this.write_int_fields_named( &[(ino_name, ino.into()), ("d_reclen", size.into())], &entry, @@ -1034,7 +1039,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { ) -> InterpResult<'tcx, Scalar> { let this = self.eval_context_mut(); - if !matches!(&*this.tcx.sess.target.os, "macos" | "freebsd") { + if !matches!(&this.tcx.sess.target.os, Os::MacOs | Os::FreeBsd) { panic!("`macos_fbsd_readdir_r` should not be called on {}", this.tcx.sess.target.os); } @@ -1102,8 +1107,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { &entry_place, )?; // Special fields. - match &*this.tcx.sess.target.os { - "macos" => { + match this.tcx.sess.target.os { + Os::MacOs => { #[rustfmt::skip] this.write_int_fields_named( &[ @@ -1113,7 +1118,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { &entry_place, )?; } - "freebsd" => { + Os::FreeBsd => { #[rustfmt::skip] this.write_int_fields_named( &[ diff --git a/src/tools/miri/src/shims/unix/mem.rs b/src/tools/miri/src/shims/unix/mem.rs index 1738de4dd4fe..01aa5afafcc3 100644 --- a/src/tools/miri/src/shims/unix/mem.rs +++ b/src/tools/miri/src/shims/unix/mem.rs @@ -15,6 +15,7 @@ //! report UB. use rustc_abi::Size; +use rustc_target::spec::Os; use crate::*; @@ -46,7 +47,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // This is a horrible hack, but on MacOS and Solarish the guard page mechanism uses mmap // in a way we do not support. We just give it the return value it expects. if this.frame_in_std() - && matches!(&*this.tcx.sess.target.os, "macos" | "solaris" | "illumos") + && matches!(&this.tcx.sess.target.os, Os::MacOs | Os::Solaris | Os::Illumos) && (flags & map_fixed) != 0 { return interp_ok(Scalar::from_maybe_pointer(Pointer::without_provenance(addr), this)); diff --git a/src/tools/miri/src/shims/unix/solarish/foreign_items.rs b/src/tools/miri/src/shims/unix/solarish/foreign_items.rs index 31269bf00c94..6335e6bc9662 100644 --- a/src/tools/miri/src/shims/unix/solarish/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/solarish/foreign_items.rs @@ -2,6 +2,7 @@ use rustc_abi::CanonAbi; use rustc_middle::ty::Ty; use rustc_span::Symbol; use rustc_target::callconv::FnAbi; +use rustc_target::spec::Os; use crate::shims::unix::foreign_items::EvalContextExt as _; use crate::shims::unix::linux_like::epoll::EvalContextExt as _; @@ -26,26 +27,26 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { match link_name.as_str() { // epoll, eventfd (NOT available on Solaris!) "epoll_create1" => { - this.assert_target_os("illumos", "epoll_create1"); + this.assert_target_os(Os::Illumos, "epoll_create1"); let [flag] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; let result = this.epoll_create1(flag)?; this.write_scalar(result, dest)?; } "epoll_ctl" => { - this.assert_target_os("illumos", "epoll_ctl"); + this.assert_target_os(Os::Illumos, "epoll_ctl"); let [epfd, op, fd, event] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; let result = this.epoll_ctl(epfd, op, fd, event)?; this.write_scalar(result, dest)?; } "epoll_wait" => { - this.assert_target_os("illumos", "epoll_wait"); + this.assert_target_os(Os::Illumos, "epoll_wait"); let [epfd, events, maxevents, timeout] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; this.epoll_wait(epfd, events, maxevents, timeout, dest)?; } "eventfd" => { - this.assert_target_os("illumos", "eventfd"); + this.assert_target_os(Os::Illumos, "eventfd"); let [val, flag] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; let result = this.eventfd(val, flag)?; this.write_scalar(result, dest)?; diff --git a/src/tools/miri/src/shims/unix/sync.rs b/src/tools/miri/src/shims/unix/sync.rs index 57dbe2cd333b..39014f34c897 100644 --- a/src/tools/miri/src/shims/unix/sync.rs +++ b/src/tools/miri/src/shims/unix/sync.rs @@ -1,4 +1,5 @@ use rustc_abi::Size; +use rustc_target::spec::Os; use crate::concurrency::sync::{AccessKind, SyncObj}; use crate::*; @@ -29,8 +30,8 @@ const PTHREAD_INIT: u8 = 1; #[inline] fn mutexattr_kind_offset<'tcx>(ecx: &MiriInterpCx<'tcx>) -> InterpResult<'tcx, u64> { - interp_ok(match &*ecx.tcx.sess.target.os { - "linux" | "illumos" | "solaris" | "macos" | "freebsd" | "android" => 0, + interp_ok(match &ecx.tcx.sess.target.os { + Os::Linux | Os::Illumos | Os::Solaris | Os::MacOs | Os::FreeBsd | Os::Android => 0, os => throw_unsup_format!("`pthread_mutexattr` is not supported on {os}"), }) } @@ -128,10 +129,10 @@ impl SyncObj for PthreadMutex { /// a statically initialized mutex that is used the first time, we pick some offset within /// `pthread_mutex_t` and use it as an "initialized" flag. fn mutex_init_offset<'tcx>(ecx: &MiriInterpCx<'tcx>) -> InterpResult<'tcx, Size> { - let offset = match &*ecx.tcx.sess.target.os { - "linux" | "illumos" | "solaris" | "freebsd" | "android" => 0, + let offset = match &ecx.tcx.sess.target.os { + Os::Linux | Os::Illumos | Os::Solaris | Os::FreeBsd | Os::Android => 0, // macOS stores a signature in the first bytes, so we move to offset 4. - "macos" => 4, + Os::MacOs => 4, os => throw_unsup_format!("`pthread_mutex` is not supported on {os}"), }; let offset = Size::from_bytes(offset); @@ -152,13 +153,13 @@ fn mutex_init_offset<'tcx>(ecx: &MiriInterpCx<'tcx>) -> InterpResult<'tcx, Size> check_static_initializer("PTHREAD_MUTEX_INITIALIZER"); // Check non-standard initializers. - match &*ecx.tcx.sess.target.os { - "linux" => { + match &ecx.tcx.sess.target.os { + Os::Linux => { check_static_initializer("PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP"); check_static_initializer("PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP"); check_static_initializer("PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP"); } - "illumos" | "solaris" | "macos" | "freebsd" | "android" => { + Os::Illumos | Os::Solaris | Os::MacOs | Os::FreeBsd | Os::Android => { // No non-standard initializers. } os => throw_unsup_format!("`pthread_mutex` is not supported on {os}"), @@ -215,8 +216,8 @@ fn mutex_kind_from_static_initializer<'tcx>( return interp_ok(MutexKind::Default); } // Support additional platform-specific initializers. - match &*ecx.tcx.sess.target.os { - "linux" => + match &ecx.tcx.sess.target.os { + Os::Linux => if is_initializer("PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP")? { return interp_ok(MutexKind::Recursive); } else if is_initializer("PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP")? { @@ -254,10 +255,10 @@ impl SyncObj for PthreadRwLock { } fn rwlock_init_offset<'tcx>(ecx: &MiriInterpCx<'tcx>) -> InterpResult<'tcx, Size> { - let offset = match &*ecx.tcx.sess.target.os { - "linux" | "illumos" | "solaris" | "freebsd" | "android" => 0, + let offset = match &ecx.tcx.sess.target.os { + Os::Linux | Os::Illumos | Os::Solaris | Os::FreeBsd | Os::Android => 0, // macOS stores a signature in the first bytes, so we move to offset 4. - "macos" => 4, + Os::MacOs => 4, os => throw_unsup_format!("`pthread_rwlock` is not supported on {os}"), }; let offset = Size::from_bytes(offset); @@ -311,8 +312,8 @@ where #[inline] fn condattr_clock_offset<'tcx>(ecx: &MiriInterpCx<'tcx>) -> InterpResult<'tcx, u64> { - interp_ok(match &*ecx.tcx.sess.target.os { - "linux" | "illumos" | "solaris" | "freebsd" | "android" => 0, + interp_ok(match &ecx.tcx.sess.target.os { + Os::Linux | Os::Illumos | Os::Solaris | Os::FreeBsd | Os::Android => 0, // macOS does not have a clock attribute. os => throw_unsup_format!("`pthread_condattr` clock field is not supported on {os}"), }) @@ -349,10 +350,10 @@ fn condattr_set_clock_id<'tcx>( // - init: u8 fn cond_init_offset<'tcx>(ecx: &MiriInterpCx<'tcx>) -> InterpResult<'tcx, Size> { - let offset = match &*ecx.tcx.sess.target.os { - "linux" | "illumos" | "solaris" | "freebsd" | "android" => 0, + let offset = match &ecx.tcx.sess.target.os { + Os::Linux | Os::Illumos | Os::Solaris | Os::FreeBsd | Os::Android => 0, // macOS stores a signature in the first bytes, so we move to offset 4. - "macos" => 4, + Os::MacOs => 4, os => throw_unsup_format!("`pthread_cond` is not supported on {os}"), }; let offset = Size::from_bytes(offset); @@ -748,7 +749,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let this = self.eval_context_mut(); // no clock attribute on macOS - if this.tcx.sess.target.os != "macos" { + if this.tcx.sess.target.os != Os::MacOs { // The default value of the clock attribute shall refer to the system // clock. // https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_condattr_setclock.html @@ -798,7 +799,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Destroying an uninit pthread_condattr is UB, so check to make sure it's not uninit. // There's no clock attribute on macOS. - if this.tcx.sess.target.os != "macos" { + if this.tcx.sess.target.os != Os::MacOs { condattr_get_clock_id(this, attr_op)?; } @@ -820,7 +821,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let attr = this.read_pointer(attr_op)?; // Default clock if `attr` is null, and on macOS where there is no clock attribute. - let clock_id = if this.ptr_is_null(attr)? || this.tcx.sess.target.os == "macos" { + let clock_id = if this.ptr_is_null(attr)? || this.tcx.sess.target.os == Os::MacOs { this.eval_libc("CLOCK_REALTIME") } else { condattr_get_clock_id(this, attr_op)? diff --git a/src/tools/miri/src/shims/unix/unnamed_socket.rs b/src/tools/miri/src/shims/unix/unnamed_socket.rs index 3e2949759377..9126090d80ba 100644 --- a/src/tools/miri/src/shims/unix/unnamed_socket.rs +++ b/src/tools/miri/src/shims/unix/unnamed_socket.rs @@ -7,6 +7,8 @@ use std::collections::VecDeque; use std::io; use std::io::ErrorKind; +use rustc_target::spec::Os; + use crate::concurrency::VClock; use crate::shims::files::{ EvalContextExt as _, FdId, FileDescription, FileDescriptionRef, WeakFileDescriptionRef, @@ -457,7 +459,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Interpret the flag. Every flag we recognize is "subtracted" from `flags`, so // if there is anything left at the end, that's an unsupported flag. - if this.tcx.sess.target.os == "linux" { + if this.tcx.sess.target.os == Os::Linux { // SOCK_NONBLOCK only exists on Linux. let sock_nonblock = this.eval_libc_i32("SOCK_NONBLOCK"); let sock_cloexec = this.eval_libc_i32("SOCK_CLOEXEC"); diff --git a/src/tools/miri/src/shims/windows/env.rs b/src/tools/miri/src/shims/windows/env.rs index a7c26d601e50..aabace4b7cd3 100644 --- a/src/tools/miri/src/shims/windows/env.rs +++ b/src/tools/miri/src/shims/windows/env.rs @@ -3,6 +3,7 @@ use std::ffi::{OsStr, OsString}; use std::io::ErrorKind; use rustc_data_structures::fx::FxHashMap; +use rustc_target::spec::Os; use self::helpers::windows_check_buffer_size; use crate::*; @@ -45,7 +46,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // ^ Returns DWORD (u32 on Windows) let this = self.eval_context_mut(); - this.assert_target_os("windows", "GetEnvironmentVariableW"); + this.assert_target_os(Os::Windows, "GetEnvironmentVariableW"); let name_ptr = this.read_pointer(name_op)?; let buf_ptr = this.read_pointer(buf_op)?; @@ -73,7 +74,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { #[allow(non_snake_case)] fn GetEnvironmentStringsW(&mut self) -> InterpResult<'tcx, Pointer> { let this = self.eval_context_mut(); - this.assert_target_os("windows", "GetEnvironmentStringsW"); + this.assert_target_os(Os::Windows, "GetEnvironmentStringsW"); // Info on layout of environment blocks in Windows: // https://docs.microsoft.com/en-us/windows/win32/procthread/environment-variables @@ -95,7 +96,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { #[allow(non_snake_case)] fn FreeEnvironmentStringsW(&mut self, env_block_op: &OpTy<'tcx>) -> InterpResult<'tcx, Scalar> { let this = self.eval_context_mut(); - this.assert_target_os("windows", "FreeEnvironmentStringsW"); + this.assert_target_os(Os::Windows, "FreeEnvironmentStringsW"); let env_block_ptr = this.read_pointer(env_block_op)?; this.deallocate_ptr(env_block_ptr, None, MiriMemoryKind::Runtime.into())?; @@ -110,7 +111,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { value_op: &OpTy<'tcx>, // LPCWSTR ) -> InterpResult<'tcx, Scalar> { let this = self.eval_context_mut(); - this.assert_target_os("windows", "SetEnvironmentVariableW"); + this.assert_target_os(Os::Windows, "SetEnvironmentVariableW"); let name_ptr = this.read_pointer(name_op)?; let value_ptr = this.read_pointer(value_op)?; @@ -143,7 +144,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { buf_op: &OpTy<'tcx>, // LPTSTR ) -> InterpResult<'tcx, Scalar> { let this = self.eval_context_mut(); - this.assert_target_os("windows", "GetCurrentDirectoryW"); + this.assert_target_os(Os::Windows, "GetCurrentDirectoryW"); let size = u64::from(this.read_scalar(size_op)?.to_u32()?); let buf = this.read_pointer(buf_op)?; @@ -176,7 +177,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // ^ Returns BOOL (i32 on Windows) let this = self.eval_context_mut(); - this.assert_target_os("windows", "SetCurrentDirectoryW"); + this.assert_target_os(Os::Windows, "SetCurrentDirectoryW"); let path = this.read_path_from_wide_str(this.read_pointer(path_op)?)?; @@ -199,7 +200,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { #[allow(non_snake_case)] fn GetCurrentProcessId(&mut self) -> InterpResult<'tcx, Scalar> { let this = self.eval_context_mut(); - this.assert_target_os("windows", "GetCurrentProcessId"); + this.assert_target_os(Os::Windows, "GetCurrentProcessId"); interp_ok(Scalar::from_u32(this.get_pid())) } @@ -213,7 +214,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { ) -> InterpResult<'tcx, Scalar> // returns BOOL { let this = self.eval_context_mut(); - this.assert_target_os("windows", "GetUserProfileDirectoryW"); + this.assert_target_os(Os::Windows, "GetUserProfileDirectoryW"); this.check_no_isolation("`GetUserProfileDirectoryW`")?; let token = this.read_target_isize(token)?; diff --git a/src/tools/miri/src/shims/windows/foreign_items.rs b/src/tools/miri/src/shims/windows/foreign_items.rs index 21c9022737bc..c824147ad4be 100644 --- a/src/tools/miri/src/shims/windows/foreign_items.rs +++ b/src/tools/miri/src/shims/windows/foreign_items.rs @@ -6,7 +6,7 @@ use rustc_abi::{Align, CanonAbi, Size, X86Call}; use rustc_middle::ty::Ty; use rustc_span::Symbol; use rustc_target::callconv::FnAbi; -use rustc_target::spec::Arch; +use rustc_target::spec::{Arch, Env}; use self::shims::windows::handle::{Handle, PseudoHandle}; use crate::shims::os_str::bytes_to_os_str; @@ -826,7 +826,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // It was originally specified as part of the Itanium C++ ABI: // https://itanium-cxx-abi.github.io/cxx-abi/abi-eh.html#base-throw. // MinGW implements _Unwind_RaiseException on top of SEH exceptions. - if this.tcx.sess.target.env != "gnu" { + if this.tcx.sess.target.env != Env::Gnu { throw_unsup_format!( "`_Unwind_RaiseException` is not supported on non-MinGW Windows", ); diff --git a/src/tools/miri/src/shims/windows/fs.rs b/src/tools/miri/src/shims/windows/fs.rs index 7192d8aec851..775c08388c07 100644 --- a/src/tools/miri/src/shims/windows/fs.rs +++ b/src/tools/miri/src/shims/windows/fs.rs @@ -5,6 +5,7 @@ use std::path::PathBuf; use std::time::SystemTime; use bitflags::bitflags; +use rustc_target::spec::Os; use crate::shims::files::{FdId, FileDescription, FileHandle}; use crate::shims::windows::handle::{EvalContextExt as _, Handle}; @@ -166,7 +167,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { use CreationDisposition::*; let this = self.eval_context_mut(); - this.assert_target_os("windows", "CreateFileW"); + this.assert_target_os(Os::Windows, "CreateFileW"); this.check_no_isolation("`CreateFileW`")?; // This function appears to always set the error to 0. This is important for some flag @@ -311,7 +312,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { ) -> InterpResult<'tcx, Scalar> { // ^ Returns BOOL (i32 on Windows) let this = self.eval_context_mut(); - this.assert_target_os("windows", "GetFileInformationByHandle"); + this.assert_target_os(Os::Windows, "GetFileInformationByHandle"); this.check_no_isolation("`GetFileInformationByHandle`")?; let file = this.read_handle(file, "GetFileInformationByHandle")?; @@ -381,7 +382,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { ) -> InterpResult<'tcx, Scalar> { // ^ Returns BOOL (i32 on Windows) let this = self.eval_context_mut(); - this.assert_target_os("windows", "DeleteFileW"); + this.assert_target_os(Os::Windows, "DeleteFileW"); this.check_no_isolation("`DeleteFileW`")?; let file_name = this.read_path_from_wide_str(this.read_pointer(file_name)?)?; diff --git a/src/tools/rustbook/Cargo.lock b/src/tools/rustbook/Cargo.lock index 7990ca2325c0..d5aa7a671636 100644 --- a/src/tools/rustbook/Cargo.lock +++ b/src/tools/rustbook/Cargo.lock @@ -10,18 +10,18 @@ checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" [[package]] name = "aho-corasick" -version = "1.1.3" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" dependencies = [ "memchr", ] [[package]] name = "ammonia" -version = "4.1.1" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6b346764dd0814805de8abf899fe03065bcee69bb1a4771c785817e39f3978f" +checksum = "17e913097e1a2124b46746c980134e8c954bc17a6a59bb3fde96f088d126dde6" dependencies = [ "cssparser", "html5ever", @@ -30,12 +30,6 @@ dependencies = [ "url", ] -[[package]] -name = "android-tzdata" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" - [[package]] name = "android_system_properties" version = "0.1.5" @@ -47,9 +41,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.20" +version = "0.6.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ae563653d1938f79b1ab1b5e668c87c76a9930414574a6583a7b7e11a8e6192" +checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" dependencies = [ "anstyle", "anstyle-parse", @@ -62,9 +56,9 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.11" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd" +checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" [[package]] name = "anstyle-parse" @@ -97,9 +91,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.99" +version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0674a1ddeecb70197781e945de4b3b8ffb61fa939a5597bcf48503737663100" +checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" [[package]] name = "autocfg" @@ -118,15 +112,9 @@ dependencies = [ [[package]] name = "bitflags" -version = "1.3.2" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "bitflags" -version = "2.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a65b545ab31d687cff52899d4890855fec459eb6afe0da6417b8a18da87aa29" +checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" [[package]] name = "block-buffer" @@ -139,9 +127,9 @@ dependencies = [ [[package]] name = "bstr" -version = "1.12.0" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "234113d19d0d7d613b40e86fb654acf958910802bcceab913a4f9e7cda03b1a4" +checksum = "63044e1ae8e69f3b5a92c736ca6269b8d12fa7efe39bf34ddb06d102cf0e2cab" dependencies = [ "memchr", "regex-automata", @@ -156,26 +144,26 @@ checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" [[package]] name = "cc" -version = "1.2.33" +version = "1.2.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ee0f8803222ba5a7e2777dd72ca451868909b1ac410621b676adf07280e9b5f" +checksum = "35900b6c8d709fb1d854671ae27aeaa9eec2f8b01b364e1619a40da3e6fe2afe" dependencies = [ + "find-msvc-tools", "shlex", ] [[package]] name = "cfg-if" -version = "1.0.1" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] name = "chrono" -version = "0.4.41" +version = "0.4.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d" +checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2" dependencies = [ - "android-tzdata", "iana-time-zone", "js-sys", "num-traits", @@ -185,9 +173,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.45" +version = "4.5.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fc0e74a703892159f5ae7d3aac52c8e6c392f5ae5f359c70b5881d60aaac318" +checksum = "4c26d721170e0295f191a69bd9a1f93efcdb0aff38684b61ab5750468972e5f5" dependencies = [ "clap_builder", "clap_derive", @@ -195,9 +183,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.44" +version = "4.5.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3e7f4214277f3c7aa526a59dd3fbe306a370daee1f8b7b8c987069cd8e888a8" +checksum = "75835f0c7bf681bfd05abe44e965760fea999a5286c6eb2d59883634fd02011a" dependencies = [ "anstream", "anstyle", @@ -208,18 +196,18 @@ dependencies = [ [[package]] name = "clap_complete" -version = "4.5.57" +version = "4.5.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d9501bd3f5f09f7bbee01da9a511073ed30a80cd7a509f1214bb74eadea71ad" +checksum = "8e602857739c5a4291dfa33b5a298aeac9006185229a700e5810a3ef7272d971" dependencies = [ "clap", ] [[package]] name = "clap_derive" -version = "4.5.45" +version = "4.5.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14cb31bb0a7d536caef2639baa7fad459e15c3144efefa6dbd1c84562c4739f6" +checksum = "2a0b5487afeab2deb2ff4e03a807ad1a03ac532ff5a2cee5d86884440c7f7671" dependencies = [ "heck", "proc-macro2", @@ -229,9 +217,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.7.5" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675" +checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d" [[package]] name = "colorchoice" @@ -282,7 +270,7 @@ dependencies = [ "cssparser-macros", "dtoa-short", "itoa", - "phf", + "phf 0.11.3", "smallvec", ] @@ -397,9 +385,9 @@ dependencies = [ [[package]] name = "doc-comment" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" +checksum = "780955b8b195a21ab8e4ac6b60dd1dbdcec1dc6c51c0617964b08c81785e12c9" [[package]] name = "dtoa" @@ -430,9 +418,9 @@ dependencies = [ [[package]] name = "env_filter" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "186e05a59d4c50738528153b83b0b0194d3a29507dfec16eccd4b342903397d0" +checksum = "1bf3c259d255ca70051b30e2e95b5446cdb8949ac4cd22c0d7fd634d89f568e2" dependencies = [ "log", "regex", @@ -459,12 +447,12 @@ checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] name = "errno" -version = "0.3.13" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -481,10 +469,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" [[package]] -name = "flate2" -version = "1.1.2" +name = "find-msvc-tools" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a3d7db9596fecd151c5f638c0ee5d5bd487b6e0ea232e5dc96d5250f6f94b1d" +checksum = "52051878f80a721bb68ebfbc930e07b65ba72f2da88968ea5c06fd6ca3d3a127" + +[[package]] +name = "flate2" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfe33edd8e85a12a67454e37f8c75e730830d83e313556ab9ebf9ee7fbeb3bfb" dependencies = [ "crc32fast", "miniz_oxide", @@ -498,9 +492,9 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "form_urlencoded" -version = "1.2.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" dependencies = [ "percent-encoding", ] @@ -517,9 +511,9 @@ dependencies = [ [[package]] name = "generic-array" -version = "0.14.7" +version = "0.14.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +checksum = "4bb6743198531e02858aeaea5398fcc883e71851fcbcb5a2f773e2fb6cb1edf2" dependencies = [ "typenum", "version_check", @@ -527,23 +521,23 @@ dependencies = [ [[package]] name = "getopts" -version = "0.2.23" +version = "0.2.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cba6ae63eb948698e300f645f87c70f76630d505f23b8907cf1e193ee85048c1" +checksum = "cfe4fbac503b8d1f88e6676011885f34b7174f46e59956bba534ba83abded4df" dependencies = [ "unicode-width", ] [[package]] name = "getrandom" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" dependencies = [ "cfg-if", "libc", "r-efi", - "wasi", + "wasip2", ] [[package]] @@ -559,14 +553,14 @@ dependencies = [ "pest_derive", "serde", "serde_json", - "thiserror 2.0.15", + "thiserror 2.0.17", ] [[package]] name = "hashbrown" -version = "0.15.5" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" +checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d" [[package]] name = "heck" @@ -608,9 +602,9 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.63" +version = "0.1.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8" +checksum = "33e57f83510bb73707521ebaffa789ec8caf86f9657cad665b092b581d40e9fb" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -632,9 +626,9 @@ dependencies = [ [[package]] name = "icu_collections" -version = "2.0.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47" +checksum = "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43" dependencies = [ "displaydoc", "potential_utf", @@ -645,9 +639,9 @@ dependencies = [ [[package]] name = "icu_locale_core" -version = "2.0.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a" +checksum = "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6" dependencies = [ "displaydoc", "litemap", @@ -658,11 +652,10 @@ dependencies = [ [[package]] name = "icu_normalizer" -version = "2.0.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979" +checksum = "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599" dependencies = [ - "displaydoc", "icu_collections", "icu_normalizer_data", "icu_properties", @@ -673,42 +666,38 @@ dependencies = [ [[package]] name = "icu_normalizer_data" -version = "2.0.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3" +checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" [[package]] name = "icu_properties" -version = "2.0.1" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "016c619c1eeb94efb86809b015c58f479963de65bdb6253345c1a1276f22e32b" +checksum = "e93fcd3157766c0c8da2f8cff6ce651a31f0810eaa1c51ec363ef790bbb5fb99" dependencies = [ - "displaydoc", "icu_collections", "icu_locale_core", "icu_properties_data", "icu_provider", - "potential_utf", "zerotrie", "zerovec", ] [[package]] name = "icu_properties_data" -version = "2.0.1" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "298459143998310acd25ffe6810ed544932242d3f07083eee1084d83a71bd632" +checksum = "02845b3647bb045f1100ecd6480ff52f34c35f82d9880e029d329c21d1054899" [[package]] name = "icu_provider" -version = "2.0.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af" +checksum = "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614" dependencies = [ "displaydoc", "icu_locale_core", - "stable_deref_trait", - "tinystr", "writeable", "yoke", "zerofrom", @@ -724,9 +713,9 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] name = "idna" -version = "1.0.3" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" +checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" dependencies = [ "idna_adapter", "smallvec", @@ -745,9 +734,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.10.0" +version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe4cd85333e22411419a0bcae1297d25e58c9443848b11dc6a86fefe8c78a661" +checksum = "6717a8d2a5a929a1a2eb43a12812498ed141a0bcfb7e8f7844fbdbe4303bba9f" dependencies = [ "equivalent", "hashbrown", @@ -755,9 +744,9 @@ dependencies = [ [[package]] name = "is_terminal_polyfill" -version = "1.70.1" +version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" +checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" [[package]] name = "itoa" @@ -767,22 +756,22 @@ checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" [[package]] name = "jiff" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be1f93b8b1eb69c77f24bbb0afdf66f54b632ee39af40ca21c4365a1d7347e49" +checksum = "49cce2b81f2098e7e3efc35bc2e0a6b7abec9d34128283d7a26fa8f32a6dbb35" dependencies = [ "jiff-static", "log", "portable-atomic", "portable-atomic-util", - "serde", + "serde_core", ] [[package]] name = "jiff-static" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03343451ff899767262ec32146f6d559dd759fdadf42ff0e227c7c48f72594b4" +checksum = "980af8b43c3ad5d8d349ace167ec8170839f753a42d233ba19e08afe1850fa69" dependencies = [ "proc-macro2", "quote", @@ -791,9 +780,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.77" +version = "0.3.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" +checksum = "b011eec8cc36da2aab2d5cff675ec18454fad408585853910a202391cf9f8e65" dependencies = [ "once_cell", "wasm-bindgen", @@ -828,25 +817,24 @@ checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" [[package]] name = "litemap" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" +checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77" [[package]] name = "lock_api" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" dependencies = [ - "autocfg", "scopeguard", ] [[package]] name = "log" -version = "0.4.27" +version = "0.4.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" +checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" [[package]] name = "mac" @@ -976,6 +964,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" dependencies = [ "adler2", + "simd-adler32", ] [[package]] @@ -986,11 +975,11 @@ checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" [[package]] name = "normpath" -version = "1.3.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8911957c4b1549ac0dc74e30db9c8b0e66ddcd6d7acc33098f4c63a64a6d7ed" +checksum = "bf23ab2b905654b4cb177e30b629937b3868311d4e1cba859f899c041046e69b" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -1025,9 +1014,9 @@ checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" [[package]] name = "once_cell_polyfill" -version = "1.70.1" +version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad" +checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" [[package]] name = "onig" @@ -1035,7 +1024,7 @@ version = "6.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "336b9c63443aceef14bea841b899035ae3abe89b7c486aaf4c5bd8aafedac3f0" dependencies = [ - "bitflags 2.9.2", + "bitflags", "libc", "once_cell", "onig_sys", @@ -1053,20 +1042,20 @@ dependencies = [ [[package]] name = "opener" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "771b9704f8cd8b424ec747a320b30b47517a6966ba2c7da90047c16f4a962223" +checksum = "cb9024962ab91e00c89d2a14352a8d0fc1a64346bf96f1839b45c09149564e47" dependencies = [ "bstr", "normpath", - "windows-sys 0.59.0", + "windows-sys 0.60.2", ] [[package]] name = "parking_lot" -version = "0.12.4" +version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" dependencies = [ "lock_api", "parking_lot_core", @@ -1074,15 +1063,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.11" +version = "0.9.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" dependencies = [ "cfg-if", "libc", "redox_syscall", "smallvec", - "windows-targets 0.52.6", + "windows-link", ] [[package]] @@ -1093,26 +1082,25 @@ checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3" [[package]] name = "percent-encoding" -version = "2.3.1" +version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] name = "pest" -version = "2.8.1" +version = "2.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1db05f56d34358a8b1066f67cbb203ee3e7ed2ba674a6263a1d5ec6db2204323" +checksum = "989e7521a040efde50c3ab6bbadafbe15ab6dc042686926be59ac35d74607df4" dependencies = [ "memchr", - "thiserror 2.0.15", "ucd-trie", ] [[package]] name = "pest_derive" -version = "2.8.1" +version = "2.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb056d9e8ea77922845ec74a1c4e8fb17e7c218cc4fc11a15c5d25e189aa40bc" +checksum = "187da9a3030dbafabbbfb20cb323b976dc7b7ce91fcd84f2f74d6e31d378e2de" dependencies = [ "pest", "pest_generator", @@ -1120,9 +1108,9 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.8.1" +version = "2.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87e404e638f781eb3202dc82db6760c8ae8a1eeef7fb3fa8264b2ef280504966" +checksum = "49b401d98f5757ebe97a26085998d6c0eecec4995cad6ab7fc30ffdf4b052843" dependencies = [ "pest", "pest_meta", @@ -1133,9 +1121,9 @@ dependencies = [ [[package]] name = "pest_meta" -version = "2.8.1" +version = "2.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edd1101f170f5903fde0914f899bb503d9ff5271d7ba76bbb70bea63690cc0d5" +checksum = "72f27a2cfee9f9039c4d86faa5af122a0ac3851441a34865b8a043b46be0065a" dependencies = [ "pest", "sha2", @@ -1148,17 +1136,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078" dependencies = [ "phf_macros", - "phf_shared", + "phf_shared 0.11.3", +] + +[[package]] +name = "phf" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1562dc717473dbaa4c1f85a36410e03c047b2e7df7f45ee938fbef64ae7fadf" +dependencies = [ + "phf_shared 0.13.1", + "serde", ] [[package]] name = "phf_codegen" -version = "0.11.3" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aef8048c789fa5e851558d709946d6d79a8ff88c0440c587967f8e94bfb1216a" +checksum = "49aa7f9d80421bca176ca8dbfebe668cc7a2684708594ec9f3c0db0805d5d6e1" dependencies = [ - "phf_generator", - "phf_shared", + "phf_generator 0.13.1", + "phf_shared 0.13.1", ] [[package]] @@ -1167,18 +1165,28 @@ version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d" dependencies = [ - "phf_shared", + "phf_shared 0.11.3", "rand", ] +[[package]] +name = "phf_generator" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "135ace3a761e564ec88c03a77317a7c6b80bb7f7135ef2544dbe054243b89737" +dependencies = [ + "fastrand", + "phf_shared 0.13.1", +] + [[package]] name = "phf_macros" version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f84ac04429c13a7ff43785d75ad27569f2951ce0ffd30a3321230db2fc727216" dependencies = [ - "phf_generator", - "phf_shared", + "phf_generator 0.11.3", + "phf_shared 0.11.3", "proc-macro2", "quote", "syn", @@ -1193,6 +1201,15 @@ dependencies = [ "siphasher", ] +[[package]] +name = "phf_shared" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e57fef6bc5981e38c2ce2d63bfa546861309f875b8a75f092d1d54ae2d64f266" +dependencies = [ + "siphasher", +] + [[package]] name = "pkg-config" version = "0.3.32" @@ -1225,9 +1242,9 @@ dependencies = [ [[package]] name = "potential_utf" -version = "0.1.2" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5a7c30837279ca13e7c867e9e40053bc68740f988cb07f7ca6df43cc734b585" +checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77" dependencies = [ "zerovec", ] @@ -1240,9 +1257,9 @@ checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" [[package]] name = "proc-macro2" -version = "1.0.101" +version = "1.0.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de" +checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8" dependencies = [ "unicode-ident", ] @@ -1253,7 +1270,7 @@ version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "76979bea66e7875e7509c4ec5300112b316af87fa7a252ca91c448b32dfe3993" dependencies = [ - "bitflags 2.9.2", + "bitflags", "memchr", "pulldown-cmark-escape 0.10.1", "unicase", @@ -1265,7 +1282,7 @@ version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f86ba2052aebccc42cbbb3ed234b8b13ce76f75c3551a303cb2bcffcff12bb14" dependencies = [ - "bitflags 2.9.2", + "bitflags", "getopts", "memchr", "pulldown-cmark-escape 0.11.0", @@ -1304,9 +1321,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.40" +version = "1.0.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +checksum = "a338cc41d27e6cc6dce6cefc13a0729dfbb81c262b1f519331575dd80ef3067f" dependencies = [ "proc-macro2", ] @@ -1343,18 +1360,18 @@ checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" [[package]] name = "redox_syscall" -version = "0.5.17" +version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5407465600fb0548f1442edf71dd20683c6ed326200ace4b1ef0763521bb3b77" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ - "bitflags 2.9.2", + "bitflags", ] [[package]] name = "regex" -version = "1.11.1" +version = "1.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" +checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" dependencies = [ "aho-corasick", "memchr", @@ -1364,9 +1381,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.9" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" +checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" dependencies = [ "aho-corasick", "memchr", @@ -1375,9 +1392,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.5" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" +checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" [[package]] name = "rustbook" @@ -1398,11 +1415,11 @@ version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" dependencies = [ - "bitflags 2.9.2", + "bitflags", "errno", "libc", "linux-raw-sys", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -1434,24 +1451,34 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "semver" -version = "1.0.26" +version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0" +checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" [[package]] name = "serde" -version = "1.0.219" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.219" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", @@ -1460,14 +1487,15 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.142" +version = "1.0.145" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "030fedb782600dcbd6f02d479bf0d817ac3bb40d644745b769d6a96bc3afc5a7" +checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" dependencies = [ "itoa", "memchr", "ryu", "serde", + "serde_core", ] [[package]] @@ -1496,6 +1524,12 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +[[package]] +name = "simd-adler32" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" + [[package]] name = "siphasher" version = "1.0.1" @@ -1510,31 +1544,31 @@ checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" [[package]] name = "stable_deref_trait" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" [[package]] name = "string_cache" -version = "0.8.9" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf776ba3fa74f83bf4b63c3dcbbf82173db2632ed8452cb2d891d33f459de70f" +checksum = "a18596f8c785a729f2819c0f6a7eae6ebeebdfffbfe4214ae6b087f690e31901" dependencies = [ "new_debug_unreachable", "parking_lot", - "phf_shared", + "phf_shared 0.13.1", "precomputed-hash", "serde", ] [[package]] name = "string_cache_codegen" -version = "0.5.4" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c711928715f1fe0fe509c53b43e993a9a557babc2d0a3567d0a3006f1ac931a0" +checksum = "585635e46db231059f76c5849798146164652513eb9e8ab2685939dd90f29b69" dependencies = [ - "phf_generator", - "phf_shared", + "phf_generator 0.13.1", + "phf_shared 0.13.1", "proc-macro2", "quote", ] @@ -1547,9 +1581,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "syn" -version = "2.0.106" +version = "2.0.110" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6" +checksum = "a99801b5bd34ede4cf3fc688c5919368fea4e4814a4664359503e6015b280aea" dependencies = [ "proc-macro2", "quote", @@ -1569,12 +1603,11 @@ dependencies = [ [[package]] name = "syntect" -version = "5.2.0" +version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "874dcfa363995604333cf947ae9f751ca3af4522c60886774c4963943b4746b1" +checksum = "656b45c05d95a5704399aeef6bd0ddec7b2b3531b7c9e900abbf7c4d2190c925" dependencies = [ "bincode", - "bitflags 1.3.2", "flate2", "fnv", "once_cell", @@ -1582,22 +1615,21 @@ dependencies = [ "regex-syntax", "serde", "serde_derive", - "serde_json", - "thiserror 1.0.69", + "thiserror 2.0.17", "walkdir", ] [[package]] name = "tempfile" -version = "3.20.0" +version = "3.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8a64e3985349f2441a1a9ef0b853f869006c3855f2cda6862a94d26ebb9d6a1" +checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16" dependencies = [ "fastrand", "getrandom", "once_cell", "rustix", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -1638,11 +1670,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.15" +version = "2.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80d76d3f064b981389ecb4b6b7f45a0bf9fdac1d5b9204c7bd6714fecc302850" +checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8" dependencies = [ - "thiserror-impl 2.0.15", + "thiserror-impl 2.0.17", ] [[package]] @@ -1658,9 +1690,9 @@ dependencies = [ [[package]] name = "thiserror-impl" -version = "2.0.15" +version = "2.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d29feb33e986b6ea906bd9c3559a856983f92371b3eaa5e83782a351623de0" +checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" dependencies = [ "proc-macro2", "quote", @@ -1669,9 +1701,9 @@ dependencies = [ [[package]] name = "tinystr" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b" +checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869" dependencies = [ "displaydoc", "zerovec", @@ -1735,9 +1767,9 @@ checksum = "ea68304e134ecd095ac6c3574494fc62b909f416c4fca77e440530221e549d3d" [[package]] name = "typenum" -version = "1.18.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" +checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" [[package]] name = "ucd-trie" @@ -1753,25 +1785,26 @@ checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539" [[package]] name = "unicode-ident" -version = "1.0.18" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" +checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" [[package]] name = "unicode-width" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a1a07cc7db3810833284e8d372ccdc6da29741639ecc70c9ec107df0fa6154c" +checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" [[package]] name = "url" -version = "2.5.4" +version = "2.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" +checksum = "08bc136a29a3d1758e07a9cca267be308aeebf5cfd5a10f3f67ab2097683ef5b" dependencies = [ "form_urlencoded", "idna", "percent-encoding", + "serde", ] [[package]] @@ -1809,45 +1842,32 @@ dependencies = [ ] [[package]] -name = "wasi" -version = "0.14.2+wasi-0.2.4" +name = "wasip2" +version = "1.0.1+wasi-0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" +checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" dependencies = [ - "wit-bindgen-rt", + "wit-bindgen", ] [[package]] name = "wasm-bindgen" -version = "0.2.100" +version = "0.2.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" +checksum = "da95793dfc411fbbd93f5be7715b0578ec61fe87cb1a42b12eb625caa5c5ea60" dependencies = [ "cfg-if", "once_cell", "rustversion", "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.100" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" -dependencies = [ - "bumpalo", - "log", - "proc-macro2", - "quote", - "syn", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.100" +version = "0.2.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" +checksum = "04264334509e04a7bf8690f2384ef5265f05143a4bff3889ab7a3269adab59c2" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1855,33 +1875,33 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.100" +version = "0.2.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" +checksum = "420bc339d9f322e562942d52e115d57e950d12d88983a14c79b86859ee6c7ebc" dependencies = [ + "bumpalo", "proc-macro2", "quote", "syn", - "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.100" +version = "0.2.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +checksum = "76f218a38c84bcb33c25ec7059b07847d465ce0e0a76b995e134a45adcb6af76" dependencies = [ "unicode-ident", ] [[package]] name = "web_atoms" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57ffde1dc01240bdf9992e3205668b235e59421fd085e8a317ed98da0178d414" +checksum = "44b72896d90cfd22c495d0ee4960d3dd20ca64180895cb92cd5342ff7482a579" dependencies = [ - "phf", + "phf 0.13.1", "phf_codegen", "string_cache", "string_cache_codegen", @@ -1889,18 +1909,18 @@ dependencies = [ [[package]] name = "winapi-util" -version = "0.1.9" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] name = "windows-core" -version = "0.61.2" +version = "0.62.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" +checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" dependencies = [ "windows-implement", "windows-interface", @@ -1911,9 +1931,9 @@ dependencies = [ [[package]] name = "windows-implement" -version = "0.60.0" +version = "0.60.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" +checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", "quote", @@ -1922,9 +1942,9 @@ dependencies = [ [[package]] name = "windows-interface" -version = "0.59.1" +version = "0.59.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" +checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", "quote", @@ -1933,206 +1953,138 @@ dependencies = [ [[package]] name = "windows-link" -version = "0.1.3" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" [[package]] name = "windows-result" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" +checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" dependencies = [ "windows-link", ] [[package]] name = "windows-strings" -version = "0.4.2" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" +checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" dependencies = [ "windows-link", ] -[[package]] -name = "windows-sys" -version = "0.59.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" -dependencies = [ - "windows-targets 0.52.6", -] - [[package]] name = "windows-sys" version = "0.60.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" dependencies = [ - "windows-targets 0.53.3", + "windows-targets", ] [[package]] -name = "windows-targets" -version = "0.52.6" +name = "windows-sys" +version = "0.61.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" -dependencies = [ - "windows_aarch64_gnullvm 0.52.6", - "windows_aarch64_msvc 0.52.6", - "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm 0.52.6", - "windows_i686_msvc 0.52.6", - "windows_x86_64_gnu 0.52.6", - "windows_x86_64_gnullvm 0.52.6", - "windows_x86_64_msvc 0.52.6", -] - -[[package]] -name = "windows-targets" -version = "0.53.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" dependencies = [ "windows-link", - "windows_aarch64_gnullvm 0.53.0", - "windows_aarch64_msvc 0.53.0", - "windows_i686_gnu 0.53.0", - "windows_i686_gnullvm 0.53.0", - "windows_i686_msvc 0.53.0", - "windows_x86_64_gnu 0.53.0", - "windows_x86_64_gnullvm 0.53.0", - "windows_x86_64_msvc 0.53.0", +] + +[[package]] +name = "windows-targets" +version = "0.53.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" +dependencies = [ + "windows-link", + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", ] [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.6" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" +checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" [[package]] name = "windows_aarch64_msvc" -version = "0.52.6" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" +checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" [[package]] name = "windows_i686_gnu" -version = "0.52.6" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" - -[[package]] -name = "windows_i686_gnu" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" +checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" [[package]] name = "windows_i686_gnullvm" -version = "0.52.6" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" +checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" [[package]] name = "windows_i686_msvc" -version = "0.52.6" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" - -[[package]] -name = "windows_i686_msvc" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" +checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" [[package]] name = "windows_x86_64_gnu" -version = "0.52.6" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" +checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.6" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" +checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" [[package]] name = "windows_x86_64_msvc" -version = "0.52.6" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" +checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" [[package]] name = "winnow" -version = "0.7.12" +version = "0.7.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3edebf492c8125044983378ecb5766203ad3b4c2f7a922bd7dd207f6d443e95" +checksum = "21a0236b59786fed61e2a80582dd500fe61f18b5dca67a4a067d0bc9039339cf" dependencies = [ "memchr", ] [[package]] -name = "wit-bindgen-rt" -version = "0.39.0" +name = "wit-bindgen" +version = "0.46.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" -dependencies = [ - "bitflags 2.9.2", -] +checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" [[package]] name = "writeable" -version = "0.6.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb" +checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9" [[package]] name = "yoke" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc" +checksum = "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954" dependencies = [ - "serde", "stable_deref_trait", "yoke-derive", "zerofrom", @@ -2140,9 +2092,9 @@ dependencies = [ [[package]] name = "yoke-derive" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6" +checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" dependencies = [ "proc-macro2", "quote", @@ -2173,9 +2125,9 @@ dependencies = [ [[package]] name = "zerotrie" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595" +checksum = "2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851" dependencies = [ "displaydoc", "yoke", @@ -2184,9 +2136,9 @@ dependencies = [ [[package]] name = "zerovec" -version = "0.11.4" +version = "0.11.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7aa2bd55086f1ab526693ecbe444205da57e25f4489879da80635a46d90e73b" +checksum = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002" dependencies = [ "yoke", "zerofrom", @@ -2195,9 +2147,9 @@ dependencies = [ [[package]] name = "zerovec-derive" -version = "0.11.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f" +checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" dependencies = [ "proc-macro2", "quote", diff --git a/src/tools/rustfmt/src/patterns.rs b/src/tools/rustfmt/src/patterns.rs index 03752c371ae1..285bc9a9e421 100644 --- a/src/tools/rustfmt/src/patterns.rs +++ b/src/tools/rustfmt/src/patterns.rs @@ -17,7 +17,9 @@ use crate::shape::Shape; use crate::source_map::SpanUtils; use crate::spanned::Spanned; use crate::types::{PathContext, rewrite_path}; -use crate::utils::{format_mutability, mk_sp, mk_sp_lo_plus_one, rewrite_ident}; +use crate::utils::{ + format_mutability, format_pinnedness_and_mutability, mk_sp, mk_sp_lo_plus_one, rewrite_ident, +}; /// Returns `true` if the given pattern is "short". /// A short pattern is defined by the following grammar: @@ -69,7 +71,7 @@ fn is_short_pattern_inner(context: &RewriteContext<'_>, pat: &ast::Pat) -> bool } ast::PatKind::Box(ref p) | PatKind::Deref(ref p) - | ast::PatKind::Ref(ref p, _) + | ast::PatKind::Ref(ref p, _, _) | ast::PatKind::Paren(ref p) => is_short_pattern_inner(context, &*p), PatKind::Or(ref pats) => pats.iter().all(|p| is_short_pattern_inner(context, p)), } @@ -133,10 +135,13 @@ impl Rewrite for Pat { PatKind::Ident(BindingMode(by_ref, mutability), ident, ref sub_pat) => { let mut_prefix = format_mutability(mutability).trim(); - let (ref_kw, mut_infix) = match by_ref { - // FIXME(pin_ergonomics): format the pinnedness - ByRef::Yes(_, rmutbl) => ("ref", format_mutability(rmutbl).trim()), - ByRef::No => ("", ""), + let (ref_kw, pin_infix, mut_infix) = match by_ref { + ByRef::Yes(pinnedness, rmutbl) => { + let (pin_infix, mut_infix) = + format_pinnedness_and_mutability(pinnedness, rmutbl); + ("ref", pin_infix.trim(), mut_infix.trim()) + } + ByRef::No => ("", "", ""), }; let id_str = rewrite_ident(context, ident); let sub_pat = match *sub_pat { @@ -147,6 +152,7 @@ impl Rewrite for Pat { .checked_sub( mut_prefix.len() + ref_kw.len() + + pin_infix.len() + mut_infix.len() + id_str.len() + 2, @@ -193,18 +199,17 @@ impl Rewrite for Pat { (true, true) => (self.span.lo(), "".to_owned()), }; - // combine result of above and mut - let (second_lo, second) = match (first.is_empty(), mut_infix.is_empty()) { + // combine result of above and pin + let (second_lo, second) = match (first.is_empty(), pin_infix.is_empty()) { (false, false) => { let lo = context.snippet_provider.span_after(self.span, "ref"); - let end_span = mk_sp(first_lo, self.span.hi()); - let hi = context.snippet_provider.span_before(end_span, "mut"); + let hi = context.snippet_provider.span_before(self.span, "pin"); ( - context.snippet_provider.span_after(end_span, "mut"), + context.snippet_provider.span_after(self.span, "pin"), combine_strs_with_missing_comments( context, &first, - mut_infix, + pin_infix, mk_sp(lo, hi), shape, true, @@ -212,7 +217,33 @@ impl Rewrite for Pat { ) } (false, true) => (first_lo, first), - (true, false) => unreachable!("mut_infix necessarily follows a ref"), + (true, false) => unreachable!("pin_infix necessarily follows a ref"), + (true, true) => (self.span.lo(), "".to_owned()), + }; + + // combine result of above and const|mut + let (third_lo, third) = match (second.is_empty(), mut_infix.is_empty()) { + (false, false) => { + let lo = context.snippet_provider.span_after( + self.span, + if pin_infix.is_empty() { "ref" } else { "pin" }, + ); + let end_span = mk_sp(second_lo, self.span.hi()); + let hi = context.snippet_provider.span_before(end_span, mut_infix); + ( + context.snippet_provider.span_after(end_span, mut_infix), + combine_strs_with_missing_comments( + context, + &second, + mut_infix, + mk_sp(lo, hi), + shape, + true, + )?, + ) + } + (false, true) => (second_lo, second), + (true, false) => unreachable!("mut_infix necessarily follows a pin or ref"), (true, true) => (self.span.lo(), "".to_owned()), }; @@ -232,9 +263,9 @@ impl Rewrite for Pat { combine_strs_with_missing_comments( context, - &second, + &third, &next, - mk_sp(second_lo, ident.span.lo()), + mk_sp(third_lo, ident.span.lo()), shape, true, ) @@ -263,8 +294,10 @@ impl Rewrite for Pat { PatKind::Range(ref lhs, ref rhs, ref end_kind) => { rewrite_range_pat(context, shape, lhs, rhs, end_kind, self.span) } - PatKind::Ref(ref pat, mutability) => { - let prefix = format!("&{}", format_mutability(mutability)); + PatKind::Ref(ref pat, pinnedness, mutability) => { + let (pin_prefix, mut_prefix) = + format_pinnedness_and_mutability(pinnedness, mutability); + let prefix = format!("&{}{}", pin_prefix, mut_prefix); rewrite_unary_prefix(context, &prefix, &**pat, shape) } PatKind::Tuple(ref items) => rewrite_tuple_pat(items, None, self.span, context, shape), @@ -551,7 +584,7 @@ pub(crate) fn can_be_overflowed_pat( | ast::PatKind::Tuple(..) | ast::PatKind::Struct(..) | ast::PatKind::TupleStruct(..) => context.use_block_indent() && len == 1, - ast::PatKind::Ref(ref p, _) | ast::PatKind::Box(ref p) => { + ast::PatKind::Ref(ref p, _, _) | ast::PatKind::Box(ref p) => { can_be_overflowed_pat(context, &TuplePatField::Pat(p), len) } ast::PatKind::Expr(ref expr) => can_be_overflowed_expr(context, expr, len), diff --git a/src/tools/rustfmt/src/utils.rs b/src/tools/rustfmt/src/utils.rs index b9950e94d0c3..3a2975024a33 100644 --- a/src/tools/rustfmt/src/utils.rs +++ b/src/tools/rustfmt/src/utils.rs @@ -132,6 +132,19 @@ pub(crate) fn format_mutability(mutability: ast::Mutability) -> &'static str { } } +#[inline] +pub(crate) fn format_pinnedness_and_mutability( + pinnedness: ast::Pinnedness, + mutability: ast::Mutability, +) -> (&'static str, &'static str) { + match (pinnedness, mutability) { + (ast::Pinnedness::Pinned, ast::Mutability::Mut) => ("pin ", "mut "), + (ast::Pinnedness::Pinned, ast::Mutability::Not) => ("pin ", "const "), + (ast::Pinnedness::Not, ast::Mutability::Mut) => ("", "mut "), + (ast::Pinnedness::Not, ast::Mutability::Not) => ("", ""), + } +} + #[inline] pub(crate) fn format_extern(ext: ast::Extern, explicit_abi: bool) -> Cow<'static, str> { match ext { diff --git a/src/tools/rustfmt/tests/source/pin_sugar.rs b/src/tools/rustfmt/tests/source/pin_sugar.rs index e5b47339b928..5f52e2449260 100644 --- a/src/tools/rustfmt/tests/source/pin_sugar.rs +++ b/src/tools/rustfmt/tests/source/pin_sugar.rs @@ -28,3 +28,22 @@ fn borrows() { pin const foo; } + +fn patterns<'a>( + &pin mut x: &pin + mut + i32, + & + pin + const + y: & + 'a pin + const + i32, + ref pin mut z: i32, + mut + ref + pin + const + w: i32, +) {} diff --git a/src/tools/rustfmt/tests/target/pin_sugar.rs b/src/tools/rustfmt/tests/target/pin_sugar.rs index 09ad23a5807f..f366ab4da953 100644 --- a/src/tools/rustfmt/tests/target/pin_sugar.rs +++ b/src/tools/rustfmt/tests/target/pin_sugar.rs @@ -23,3 +23,11 @@ fn borrows() { let x: Pin<&_> = &pin const foo; } + +fn patterns<'a>( + &pin mut x: &pin mut i32, + &pin const y: &'a pin const i32, + ref pin mut z: i32, + mut ref pin const w: i32, +) { +} diff --git a/tests/codegen-llvm/deduced-param-attrs.rs b/tests/codegen-llvm/deduced-param-attrs.rs index eec15a434645..b24c74a2f840 100644 --- a/tests/codegen-llvm/deduced-param-attrs.rs +++ b/tests/codegen-llvm/deduced-param-attrs.rs @@ -99,8 +99,9 @@ pub static A1: fn(BigCell) = shared_borrow; // The parameter can be mutated through a raw const borrow. // // CHECK-LABEL: ; deduced_param_attrs::raw_const_borrow +// CHECK-NEXT: ; // CHECK-NOT: readonly -// CHECK-NEXT : %a) +// CHECK-NEXT: %a) #[inline(never)] pub fn raw_const_borrow(a: Big) { black_box(&raw const a); diff --git a/tests/coverage/async_block.cov-map b/tests/coverage/async_block.cov-map index 07d4c0eb3cd6..08f5a7b5d79e 100644 --- a/tests/coverage/async_block.cov-map +++ b/tests/coverage/async_block.cov-map @@ -1,5 +1,5 @@ Function name: async_block::main -Raw bytes (41): 0x[01, 01, 01, 05, 01, 07, 01, 07, 01, 00, 0a, 02, 01, 09, 00, 0a, 05, 00, 0e, 00, 13, 02, 01, 0d, 00, 13, 02, 07, 09, 00, 1b, 02, 00, 1c, 00, 22, 01, 02, 01, 00, 02] +Raw bytes (41): 0x[01, 01, 01, 05, 01, 07, 01, 07, 01, 00, 0a, 02, 01, 09, 00, 0a, 01, 00, 0e, 00, 13, 02, 01, 0d, 00, 13, 02, 07, 09, 00, 1b, 02, 00, 1c, 00, 22, 01, 02, 01, 00, 02] Number of files: 1 - file 0 => $DIR/async_block.rs Number of expressions: 1 @@ -8,7 +8,7 @@ Number of file 0 mappings: 7 - Code(Counter(0)) at (prev + 7, 1) to (start + 0, 10) - Code(Expression(0, Sub)) at (prev + 1, 9) to (start + 0, 10) = (c1 - c0) -- Code(Counter(1)) at (prev + 0, 14) to (start + 0, 19) +- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 19) - Code(Expression(0, Sub)) at (prev + 1, 13) to (start + 0, 19) = (c1 - c0) - Code(Expression(0, Sub)) at (prev + 7, 9) to (start + 0, 27) @@ -16,7 +16,7 @@ Number of file 0 mappings: 7 - Code(Expression(0, Sub)) at (prev + 0, 28) to (start + 0, 34) = (c1 - c0) - Code(Counter(0)) at (prev + 2, 1) to (start + 0, 2) -Highest counter ID seen: c1 +Highest counter ID seen: c0 Function name: async_block::main::{closure#0} Raw bytes (31): 0x[01, 01, 01, 01, 05, 05, 01, 09, 1c, 00, 1d, 01, 01, 10, 00, 17, 05, 00, 18, 02, 0e, 02, 02, 14, 02, 0e, 01, 03, 09, 00, 0a] diff --git a/tests/coverage/async_block.coverage b/tests/coverage/async_block.coverage index 4e00024aebd2..29d90931fa8d 100644 --- a/tests/coverage/async_block.coverage +++ b/tests/coverage/async_block.coverage @@ -5,8 +5,8 @@ LL| |extern crate executor; LL| | LL| 1|fn main() { - LL| 17| for i in 0..16 { - ^16 + LL| 16| for i in 0..16 { + ^1 LL| 16| let future = async { LL| 16| if i >= 12 { LL| 4| println!("big"); diff --git a/tests/coverage/continue.cov-map b/tests/coverage/continue.cov-map index 1a839f19a0f5..05efd2707817 100644 --- a/tests/coverage/continue.cov-map +++ b/tests/coverage/continue.cov-map @@ -1,5 +1,5 @@ Function name: continue::main -Raw bytes (241): 0x[01, 01, 1a, 05, 01, 05, 13, 01, 09, 05, 13, 01, 09, 0d, 01, 0d, 27, 01, 11, 0d, 27, 01, 11, 15, 01, 15, 33, 01, 19, 1d, 01, 1d, 47, 01, 21, 1d, 47, 01, 21, 25, 01, 25, 53, 01, 29, 25, 01, 2d, 01, 63, 2d, 01, 31, 2d, 01, 25, 01, 03, 01, 00, 0a, 01, 01, 09, 00, 10, 01, 00, 13, 00, 2e, 01, 02, 09, 00, 0e, 01, 00, 11, 00, 12, 05, 01, 0e, 00, 13, 02, 01, 0f, 00, 16, 09, 02, 11, 00, 19, 0e, 02, 12, 02, 0e, 0e, 04, 09, 00, 0e, 0d, 02, 0e, 00, 13, 16, 01, 0f, 00, 16, 22, 01, 16, 02, 0e, 11, 04, 11, 00, 19, 22, 03, 09, 00, 0e, 15, 02, 0e, 00, 13, 2a, 01, 0f, 00, 16, 19, 01, 15, 02, 0e, 2e, 04, 11, 00, 19, 19, 03, 09, 00, 0e, 1d, 02, 0e, 00, 13, 36, 01, 0c, 00, 13, 21, 01, 0d, 00, 15, 42, 01, 09, 00, 0a, 42, 01, 09, 00, 0e, 25, 02, 0e, 00, 13, 56, 01, 0f, 00, 16, 4e, 01, 16, 02, 0e, 29, 03, 12, 02, 0e, 56, 04, 09, 00, 0e, 2d, 02, 0e, 00, 13, 31, 01, 0f, 00, 16, 66, 01, 16, 02, 0e, 5e, 04, 11, 00, 16, 66, 03, 09, 00, 0e, 01, 02, 0d, 00, 0e, 01, 01, 01, 00, 02] +Raw bytes (241): 0x[01, 01, 1a, 05, 01, 05, 13, 01, 09, 05, 13, 01, 09, 0d, 01, 0d, 27, 01, 11, 0d, 27, 01, 11, 15, 01, 15, 33, 01, 19, 1d, 01, 1d, 47, 01, 21, 1d, 47, 01, 21, 25, 01, 25, 53, 01, 29, 25, 01, 31, 01, 63, 31, 01, 2d, 31, 01, 25, 01, 03, 01, 00, 0a, 01, 01, 09, 00, 10, 01, 00, 13, 00, 2e, 01, 02, 09, 00, 0e, 01, 00, 11, 00, 12, 01, 01, 0e, 00, 13, 02, 01, 0f, 00, 16, 09, 02, 11, 00, 19, 0e, 02, 12, 02, 0e, 0e, 04, 09, 00, 0e, 01, 02, 0e, 00, 13, 16, 01, 0f, 00, 16, 22, 01, 16, 02, 0e, 11, 04, 11, 00, 19, 22, 03, 09, 00, 0e, 01, 02, 0e, 00, 13, 2a, 01, 0f, 00, 16, 19, 01, 15, 02, 0e, 2e, 04, 11, 00, 19, 19, 03, 09, 00, 0e, 01, 02, 0e, 00, 13, 36, 01, 0c, 00, 13, 21, 01, 0d, 00, 15, 42, 01, 09, 00, 0a, 42, 01, 09, 00, 0e, 01, 02, 0e, 00, 13, 56, 01, 0f, 00, 16, 4e, 01, 16, 02, 0e, 29, 03, 12, 02, 0e, 56, 04, 09, 00, 0e, 01, 02, 0e, 00, 13, 2d, 01, 0f, 00, 16, 66, 01, 16, 02, 0e, 5e, 04, 11, 00, 16, 66, 03, 09, 00, 0e, 01, 02, 0d, 00, 0e, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/continue.rs Number of expressions: 26 @@ -25,17 +25,17 @@ Number of expressions: 26 - expression 19 operands: lhs = Counter(9), rhs = Expression(20, Add) - expression 20 operands: lhs = Counter(0), rhs = Counter(10) - expression 21 operands: lhs = Counter(9), rhs = Counter(0) -- expression 22 operands: lhs = Counter(11), rhs = Counter(0) -- expression 23 operands: lhs = Expression(24, Add), rhs = Counter(11) -- expression 24 operands: lhs = Counter(0), rhs = Counter(12) -- expression 25 operands: lhs = Counter(11), rhs = Counter(0) +- expression 22 operands: lhs = Counter(12), rhs = Counter(0) +- expression 23 operands: lhs = Expression(24, Add), rhs = Counter(12) +- expression 24 operands: lhs = Counter(0), rhs = Counter(11) +- expression 25 operands: lhs = Counter(12), rhs = Counter(0) Number of file 0 mappings: 37 - Code(Counter(0)) at (prev + 3, 1) to (start + 0, 10) - Code(Counter(0)) at (prev + 1, 9) to (start + 0, 16) - Code(Counter(0)) at (prev + 0, 19) to (start + 0, 46) - Code(Counter(0)) at (prev + 2, 9) to (start + 0, 14) - Code(Counter(0)) at (prev + 0, 17) to (start + 0, 18) -- Code(Counter(1)) at (prev + 1, 14) to (start + 0, 19) +- Code(Counter(0)) at (prev + 1, 14) to (start + 0, 19) - Code(Expression(0, Sub)) at (prev + 1, 15) to (start + 0, 22) = (c1 - c0) - Code(Counter(2)) at (prev + 2, 17) to (start + 0, 25) @@ -43,7 +43,7 @@ Number of file 0 mappings: 37 = (c1 - (c0 + c2)) - Code(Expression(3, Sub)) at (prev + 4, 9) to (start + 0, 14) = (c1 - (c0 + c2)) -- Code(Counter(3)) at (prev + 2, 14) to (start + 0, 19) +- Code(Counter(0)) at (prev + 2, 14) to (start + 0, 19) - Code(Expression(5, Sub)) at (prev + 1, 15) to (start + 0, 22) = (c3 - c0) - Code(Expression(8, Sub)) at (prev + 1, 22) to (start + 2, 14) @@ -51,14 +51,14 @@ Number of file 0 mappings: 37 - Code(Counter(4)) at (prev + 4, 17) to (start + 0, 25) - Code(Expression(8, Sub)) at (prev + 3, 9) to (start + 0, 14) = (c3 - (c0 + c4)) -- Code(Counter(5)) at (prev + 2, 14) to (start + 0, 19) +- Code(Counter(0)) at (prev + 2, 14) to (start + 0, 19) - Code(Expression(10, Sub)) at (prev + 1, 15) to (start + 0, 22) = (c5 - c0) - Code(Counter(6)) at (prev + 1, 21) to (start + 2, 14) - Code(Expression(11, Sub)) at (prev + 4, 17) to (start + 0, 25) = (c5 - (c0 + c6)) - Code(Counter(6)) at (prev + 3, 9) to (start + 0, 14) -- Code(Counter(7)) at (prev + 2, 14) to (start + 0, 19) +- Code(Counter(0)) at (prev + 2, 14) to (start + 0, 19) - Code(Expression(13, Sub)) at (prev + 1, 12) to (start + 0, 19) = (c7 - c0) - Code(Counter(8)) at (prev + 1, 13) to (start + 0, 21) @@ -66,7 +66,7 @@ Number of file 0 mappings: 37 = (c7 - (c0 + c8)) - Code(Expression(16, Sub)) at (prev + 1, 9) to (start + 0, 14) = (c7 - (c0 + c8)) -- Code(Counter(9)) at (prev + 2, 14) to (start + 0, 19) +- Code(Counter(0)) at (prev + 2, 14) to (start + 0, 19) - Code(Expression(21, Sub)) at (prev + 1, 15) to (start + 0, 22) = (c9 - c0) - Code(Expression(19, Sub)) at (prev + 1, 22) to (start + 2, 14) @@ -74,15 +74,15 @@ Number of file 0 mappings: 37 - Code(Counter(10)) at (prev + 3, 18) to (start + 2, 14) - Code(Expression(21, Sub)) at (prev + 4, 9) to (start + 0, 14) = (c9 - c0) -- Code(Counter(11)) at (prev + 2, 14) to (start + 0, 19) -- Code(Counter(12)) at (prev + 1, 15) to (start + 0, 22) +- Code(Counter(0)) at (prev + 2, 14) to (start + 0, 19) +- Code(Counter(11)) at (prev + 1, 15) to (start + 0, 22) - Code(Expression(25, Sub)) at (prev + 1, 22) to (start + 2, 14) - = (c11 - c0) + = (c12 - c0) - Code(Expression(23, Sub)) at (prev + 4, 17) to (start + 0, 22) - = ((c0 + c12) - c11) + = ((c0 + c11) - c12) - Code(Expression(25, Sub)) at (prev + 3, 9) to (start + 0, 14) - = (c11 - c0) + = (c12 - c0) - Code(Counter(0)) at (prev + 2, 13) to (start + 0, 14) - Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) -Highest counter ID seen: c12 +Highest counter ID seen: c11 diff --git a/tests/coverage/continue.coverage b/tests/coverage/continue.coverage index 17fe4874d151..310701a1543c 100644 --- a/tests/coverage/continue.coverage +++ b/tests/coverage/continue.coverage @@ -4,7 +4,7 @@ LL| 1| let is_true = std::env::args().len() == 1; LL| | LL| 1| let mut x = 0; - LL| 11| for _ in 0..10 { + LL| 1| for _ in 0..10 { LL| 10| match is_true { LL| | true => { LL| 10| continue; @@ -15,7 +15,7 @@ LL| | } LL| 0| x = 3; LL| | } - LL| 11| for _ in 0..10 { + LL| 1| for _ in 0..10 { LL| 10| match is_true { LL| 0| false => { LL| 0| x = 1; @@ -26,7 +26,7 @@ LL| | } LL| 0| x = 3; LL| | } - LL| 11| for _ in 0..10 { + LL| 1| for _ in 0..10 { LL| 10| match is_true { LL| 10| true => { LL| 10| x = 1; @@ -37,13 +37,13 @@ LL| | } LL| 10| x = 3; LL| | } - LL| 11| for _ in 0..10 { + LL| 1| for _ in 0..10 { LL| 10| if is_true { LL| 10| continue; LL| 0| } LL| 0| x = 3; LL| | } - LL| 11| for _ in 0..10 { + LL| 1| for _ in 0..10 { LL| 10| match is_true { LL| 0| false => { LL| 0| x = 1; diff --git a/tests/coverage/inline.cov-map b/tests/coverage/inline.cov-map index 4c67dd96ac2f..55f4b8484c02 100644 --- a/tests/coverage/inline.cov-map +++ b/tests/coverage/inline.cov-map @@ -1,5 +1,5 @@ Function name: inline::display:: -Raw bytes (36): 0x[01, 01, 01, 05, 01, 06, 01, 29, 01, 00, 21, 02, 01, 09, 00, 0a, 05, 00, 0e, 00, 10, 02, 00, 11, 02, 06, 01, 03, 05, 00, 0d, 01, 01, 01, 00, 02] +Raw bytes (36): 0x[01, 01, 01, 05, 01, 06, 01, 29, 01, 00, 21, 02, 01, 09, 00, 0a, 01, 00, 0e, 00, 10, 02, 00, 11, 02, 06, 01, 03, 05, 00, 0d, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/inline.rs Number of expressions: 1 @@ -8,12 +8,12 @@ Number of file 0 mappings: 6 - Code(Counter(0)) at (prev + 41, 1) to (start + 0, 33) - Code(Expression(0, Sub)) at (prev + 1, 9) to (start + 0, 10) = (c1 - c0) -- Code(Counter(1)) at (prev + 0, 14) to (start + 0, 16) +- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 16) - Code(Expression(0, Sub)) at (prev + 0, 17) to (start + 2, 6) = (c1 - c0) - Code(Counter(0)) at (prev + 3, 5) to (start + 0, 13) - Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) -Highest counter ID seen: c1 +Highest counter ID seen: c0 Function name: inline::error Raw bytes (14): 0x[01, 01, 00, 02, 01, 31, 01, 00, 0b, 01, 01, 05, 00, 0b] @@ -50,7 +50,7 @@ Number of file 0 mappings: 4 Highest counter ID seen: c0 Function name: inline::permutate:: -Raw bytes (142): 0x[01, 01, 0e, 01, 05, 0d, 09, 0d, 09, 0d, 09, 0d, 09, 0d, 09, 0d, 09, 0d, 09, 0d, 09, 0d, 09, 0d, 09, 0d, 09, 01, 37, 05, 09, 16, 01, 0f, 01, 00, 38, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 13, 01, 00, 14, 00, 16, 01, 01, 08, 00, 0e, 05, 00, 0f, 02, 06, 02, 02, 0f, 00, 14, 2e, 01, 0d, 00, 0e, 09, 00, 12, 00, 13, 09, 00, 15, 00, 16, 2e, 00, 17, 04, 0a, 2e, 01, 0d, 00, 11, 2e, 00, 12, 00, 14, 2e, 00, 16, 00, 17, 2e, 00, 19, 00, 1a, 2e, 01, 0d, 00, 16, 2e, 00, 17, 00, 19, 2e, 00, 1b, 00, 20, 2e, 01, 0d, 00, 11, 2e, 00, 12, 00, 14, 32, 02, 0c, 02, 06, 01, 03, 01, 00, 02] +Raw bytes (137): 0x[01, 01, 0e, 01, 05, 0d, 09, 0d, 09, 0d, 09, 0d, 09, 0d, 09, 0d, 09, 0d, 09, 0d, 09, 0d, 09, 0d, 09, 0d, 09, 01, 37, 05, 09, 15, 01, 0f, 01, 00, 38, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 13, 01, 00, 14, 00, 16, 01, 01, 08, 00, 0e, 05, 00, 0f, 02, 06, 02, 02, 0f, 00, 14, 2e, 01, 0d, 00, 0e, 09, 00, 12, 00, 16, 2e, 00, 17, 04, 0a, 2e, 01, 0d, 00, 11, 2e, 00, 12, 00, 14, 2e, 00, 16, 00, 17, 2e, 00, 19, 00, 1a, 2e, 01, 0d, 00, 16, 2e, 00, 17, 00, 19, 2e, 00, 1b, 00, 20, 2e, 01, 0d, 00, 11, 2e, 00, 12, 00, 14, 32, 02, 0c, 02, 06, 01, 03, 01, 00, 02] Number of files: 1 - file 0 => $DIR/inline.rs Number of expressions: 14 @@ -68,7 +68,7 @@ Number of expressions: 14 - expression 11 operands: lhs = Counter(3), rhs = Counter(2) - expression 12 operands: lhs = Counter(0), rhs = Expression(13, Add) - expression 13 operands: lhs = Counter(1), rhs = Counter(2) -Number of file 0 mappings: 22 +Number of file 0 mappings: 21 - Code(Counter(0)) at (prev + 15, 1) to (start + 0, 56) - Code(Counter(0)) at (prev + 1, 9) to (start + 0, 10) - Code(Counter(0)) at (prev + 0, 13) to (start + 0, 19) @@ -79,8 +79,7 @@ Number of file 0 mappings: 22 = (c0 - c1) - Code(Expression(11, Sub)) at (prev + 1, 13) to (start + 0, 14) = (c3 - c2) -- Code(Counter(2)) at (prev + 0, 18) to (start + 0, 19) -- Code(Counter(2)) at (prev + 0, 21) to (start + 0, 22) +- Code(Counter(2)) at (prev + 0, 18) to (start + 0, 22) - Code(Expression(11, Sub)) at (prev + 0, 23) to (start + 4, 10) = (c3 - c2) - Code(Expression(11, Sub)) at (prev + 1, 13) to (start + 0, 17) diff --git a/tests/coverage/inline.coverage b/tests/coverage/inline.coverage index 5fe069d5389d..190d5a3a22b1 100644 --- a/tests/coverage/inline.coverage +++ b/tests/coverage/inline.coverage @@ -18,7 +18,7 @@ LL| 6| display(xs); LL| 10| } else if k < n { LL| 15| for i in k..n { - ^10^10 + ^10 LL| 15| swap(xs, i, k); LL| 15| permutate(xs, k + 1); LL| 15| swap(xs, i, k); @@ -40,8 +40,8 @@ LL| 30|} LL| | LL| 6|fn display(xs: &[T]) { - LL| 24| for x in xs { - ^18 + LL| 18| for x in xs { + ^6 LL| 18| print!("{}", x); LL| 18| } LL| 6| println!(); diff --git a/tests/coverage/loops_branches.cov-map b/tests/coverage/loops_branches.cov-map index 78fdaa53f46f..96dd70504413 100644 --- a/tests/coverage/loops_branches.cov-map +++ b/tests/coverage/loops_branches.cov-map @@ -1,12 +1,13 @@ Function name: ::fmt -Raw bytes (137): 0x[01, 01, 04, 07, 0b, 01, 0d, 05, 09, 09, 0d, 19, 01, 09, 05, 00, 43, 01, 01, 0c, 00, 10, 01, 01, 10, 00, 15, 00, 01, 17, 00, 1b, 00, 00, 1c, 00, 1e, 01, 01, 0d, 00, 0e, 01, 01, 0d, 00, 13, 01, 00, 14, 00, 15, 01, 00, 17, 00, 1d, 05, 00, 1e, 00, 1f, 00, 01, 10, 01, 0a, 0d, 03, 0d, 00, 0e, 09, 00, 12, 00, 17, 0d, 01, 10, 00, 14, 0d, 01, 14, 00, 19, 00, 01, 1b, 00, 1f, 00, 00, 20, 00, 22, 0d, 01, 11, 00, 12, 0d, 01, 11, 00, 17, 0d, 00, 18, 00, 19, 0d, 00, 1b, 00, 21, 02, 00, 22, 00, 23, 00, 01, 14, 01, 0e, 0e, 03, 09, 00, 0f, 01, 01, 05, 00, 06] +Raw bytes (139): 0x[01, 01, 05, 01, 05, 0b, 0f, 01, 09, 05, 0d, 0d, 09, 19, 01, 09, 05, 00, 43, 01, 01, 0c, 00, 10, 01, 01, 10, 00, 15, 00, 01, 17, 00, 1b, 00, 00, 1c, 00, 1e, 01, 01, 0d, 00, 0e, 01, 01, 0d, 00, 13, 01, 00, 14, 00, 15, 01, 00, 17, 00, 1d, 05, 00, 1e, 00, 1f, 00, 01, 10, 01, 0a, 09, 03, 0d, 00, 0e, 02, 00, 12, 00, 17, 09, 01, 10, 00, 14, 09, 01, 14, 00, 19, 00, 01, 1b, 00, 1f, 00, 00, 20, 00, 22, 09, 01, 11, 00, 12, 09, 01, 11, 00, 17, 09, 00, 18, 00, 19, 09, 00, 1b, 00, 21, 06, 00, 22, 00, 23, 00, 01, 14, 01, 0e, 12, 03, 09, 00, 0f, 01, 01, 05, 00, 06] Number of files: 1 - file 0 => $DIR/loops_branches.rs -Number of expressions: 4 -- expression 0 operands: lhs = Expression(1, Add), rhs = Expression(2, Add) -- expression 1 operands: lhs = Counter(0), rhs = Counter(3) -- expression 2 operands: lhs = Counter(1), rhs = Counter(2) -- expression 3 operands: lhs = Counter(2), rhs = Counter(3) +Number of expressions: 5 +- expression 0 operands: lhs = Counter(0), rhs = Counter(1) +- expression 1 operands: lhs = Expression(2, Add), rhs = Expression(3, Add) +- expression 2 operands: lhs = Counter(0), rhs = Counter(2) +- expression 3 operands: lhs = Counter(1), rhs = Counter(3) +- expression 4 operands: lhs = Counter(3), rhs = Counter(2) Number of file 0 mappings: 25 - Code(Counter(0)) at (prev + 9, 5) to (start + 0, 67) - Code(Counter(0)) at (prev + 1, 12) to (start + 0, 16) @@ -19,33 +20,35 @@ Number of file 0 mappings: 25 - Code(Counter(0)) at (prev + 0, 23) to (start + 0, 29) - Code(Counter(1)) at (prev + 0, 30) to (start + 0, 31) - Code(Zero) at (prev + 1, 16) to (start + 1, 10) -- Code(Counter(3)) at (prev + 3, 13) to (start + 0, 14) -- Code(Counter(2)) at (prev + 0, 18) to (start + 0, 23) -- Code(Counter(3)) at (prev + 1, 16) to (start + 0, 20) -- Code(Counter(3)) at (prev + 1, 20) to (start + 0, 25) +- Code(Counter(2)) at (prev + 3, 13) to (start + 0, 14) +- Code(Expression(0, Sub)) at (prev + 0, 18) to (start + 0, 23) + = (c0 - c1) +- Code(Counter(2)) at (prev + 1, 16) to (start + 0, 20) +- Code(Counter(2)) at (prev + 1, 20) to (start + 0, 25) - Code(Zero) at (prev + 1, 27) to (start + 0, 31) - Code(Zero) at (prev + 0, 32) to (start + 0, 34) -- Code(Counter(3)) at (prev + 1, 17) to (start + 0, 18) -- Code(Counter(3)) at (prev + 1, 17) to (start + 0, 23) -- Code(Counter(3)) at (prev + 0, 24) to (start + 0, 25) -- Code(Counter(3)) at (prev + 0, 27) to (start + 0, 33) -- Code(Expression(0, Sub)) at (prev + 0, 34) to (start + 0, 35) - = ((c0 + c3) - (c1 + c2)) +- Code(Counter(2)) at (prev + 1, 17) to (start + 0, 18) +- Code(Counter(2)) at (prev + 1, 17) to (start + 0, 23) +- Code(Counter(2)) at (prev + 0, 24) to (start + 0, 25) +- Code(Counter(2)) at (prev + 0, 27) to (start + 0, 33) +- Code(Expression(1, Sub)) at (prev + 0, 34) to (start + 0, 35) + = ((c0 + c2) - (c1 + c3)) - Code(Zero) at (prev + 1, 20) to (start + 1, 14) -- Code(Expression(3, Sub)) at (prev + 3, 9) to (start + 0, 15) - = (c2 - c3) +- Code(Expression(4, Sub)) at (prev + 3, 9) to (start + 0, 15) + = (c3 - c2) - Code(Counter(0)) at (prev + 1, 5) to (start + 0, 6) -Highest counter ID seen: c3 +Highest counter ID seen: c2 Function name: ::fmt -Raw bytes (137): 0x[01, 01, 04, 07, 0b, 01, 09, 05, 0d, 05, 09, 19, 01, 22, 05, 00, 43, 01, 01, 0c, 00, 11, 00, 00, 12, 01, 0a, 01, 02, 10, 00, 15, 00, 01, 17, 00, 1b, 00, 00, 1c, 00, 1e, 01, 01, 0d, 00, 0e, 01, 01, 0d, 00, 13, 01, 00, 14, 00, 15, 01, 00, 17, 00, 1d, 0d, 00, 1e, 00, 1f, 09, 02, 0d, 00, 0e, 05, 00, 12, 00, 17, 09, 01, 10, 00, 15, 00, 00, 16, 01, 0e, 09, 02, 14, 00, 19, 00, 01, 1b, 00, 1f, 00, 00, 20, 00, 22, 09, 01, 11, 00, 12, 09, 01, 11, 00, 17, 09, 00, 18, 00, 19, 09, 00, 1b, 00, 21, 02, 00, 22, 00, 23, 0e, 03, 09, 00, 0f, 01, 01, 05, 00, 06] +Raw bytes (139): 0x[01, 01, 05, 01, 05, 0b, 0f, 01, 09, 0d, 05, 0d, 09, 19, 01, 22, 05, 00, 43, 01, 01, 0c, 00, 11, 00, 00, 12, 01, 0a, 01, 02, 10, 00, 15, 00, 01, 17, 00, 1b, 00, 00, 1c, 00, 1e, 01, 01, 0d, 00, 0e, 01, 01, 0d, 00, 13, 01, 00, 14, 00, 15, 01, 00, 17, 00, 1d, 05, 00, 1e, 00, 1f, 09, 02, 0d, 00, 0e, 02, 00, 12, 00, 17, 09, 01, 10, 00, 15, 00, 00, 16, 01, 0e, 09, 02, 14, 00, 19, 00, 01, 1b, 00, 1f, 00, 00, 20, 00, 22, 09, 01, 11, 00, 12, 09, 01, 11, 00, 17, 09, 00, 18, 00, 19, 09, 00, 1b, 00, 21, 06, 00, 22, 00, 23, 12, 03, 09, 00, 0f, 01, 01, 05, 00, 06] Number of files: 1 - file 0 => $DIR/loops_branches.rs -Number of expressions: 4 -- expression 0 operands: lhs = Expression(1, Add), rhs = Expression(2, Add) -- expression 1 operands: lhs = Counter(0), rhs = Counter(2) -- expression 2 operands: lhs = Counter(1), rhs = Counter(3) -- expression 3 operands: lhs = Counter(1), rhs = Counter(2) +Number of expressions: 5 +- expression 0 operands: lhs = Counter(0), rhs = Counter(1) +- expression 1 operands: lhs = Expression(2, Add), rhs = Expression(3, Add) +- expression 2 operands: lhs = Counter(0), rhs = Counter(2) +- expression 3 operands: lhs = Counter(3), rhs = Counter(1) +- expression 4 operands: lhs = Counter(3), rhs = Counter(2) Number of file 0 mappings: 25 - Code(Counter(0)) at (prev + 34, 5) to (start + 0, 67) - Code(Counter(0)) at (prev + 1, 12) to (start + 0, 17) @@ -57,9 +60,10 @@ Number of file 0 mappings: 25 - Code(Counter(0)) at (prev + 1, 13) to (start + 0, 19) - Code(Counter(0)) at (prev + 0, 20) to (start + 0, 21) - Code(Counter(0)) at (prev + 0, 23) to (start + 0, 29) -- Code(Counter(3)) at (prev + 0, 30) to (start + 0, 31) +- Code(Counter(1)) at (prev + 0, 30) to (start + 0, 31) - Code(Counter(2)) at (prev + 2, 13) to (start + 0, 14) -- Code(Counter(1)) at (prev + 0, 18) to (start + 0, 23) +- Code(Expression(0, Sub)) at (prev + 0, 18) to (start + 0, 23) + = (c0 - c1) - Code(Counter(2)) at (prev + 1, 16) to (start + 0, 21) - Code(Zero) at (prev + 0, 22) to (start + 1, 14) - Code(Counter(2)) at (prev + 2, 20) to (start + 0, 25) @@ -69,12 +73,12 @@ Number of file 0 mappings: 25 - Code(Counter(2)) at (prev + 1, 17) to (start + 0, 23) - Code(Counter(2)) at (prev + 0, 24) to (start + 0, 25) - Code(Counter(2)) at (prev + 0, 27) to (start + 0, 33) -- Code(Expression(0, Sub)) at (prev + 0, 34) to (start + 0, 35) - = ((c0 + c2) - (c1 + c3)) -- Code(Expression(3, Sub)) at (prev + 3, 9) to (start + 0, 15) - = (c1 - c2) +- Code(Expression(1, Sub)) at (prev + 0, 34) to (start + 0, 35) + = ((c0 + c2) - (c3 + c1)) +- Code(Expression(4, Sub)) at (prev + 3, 9) to (start + 0, 15) + = (c3 - c2) - Code(Counter(0)) at (prev + 1, 5) to (start + 0, 6) -Highest counter ID seen: c3 +Highest counter ID seen: c2 Function name: loops_branches::main Raw bytes (54): 0x[01, 01, 00, 0a, 01, 37, 01, 00, 0a, 01, 01, 09, 00, 13, 01, 00, 16, 00, 1f, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 14, 01, 01, 09, 00, 15, 01, 00, 18, 00, 23, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 12, 01, 01, 01, 00, 02] diff --git a/tests/coverage/loops_branches.coverage b/tests/coverage/loops_branches.coverage index 8cd6f1be3f7a..7bd1a680f00e 100644 --- a/tests/coverage/loops_branches.coverage +++ b/tests/coverage/loops_branches.coverage @@ -16,8 +16,8 @@ LL| 0| } else { LL| 0| } LL| | - LL| 11| for i in 0..10 { - ^10 + LL| 10| for i in 0..10 { + ^1 LL| 10| if true { LL| 10| if false { LL| 0| while true {} @@ -43,8 +43,8 @@ LL| 1| write!(f, "cool")?; ^0 LL| | } - LL| 11| for i in 0..10 { - ^10 + LL| 10| for i in 0..10 { + ^1 LL| 10| if false { LL| 0| } else { LL| 10| if false { diff --git a/tests/coverage/nested_loops.cov-map b/tests/coverage/nested_loops.cov-map index 649c65d8590b..598068714b9a 100644 --- a/tests/coverage/nested_loops.cov-map +++ b/tests/coverage/nested_loops.cov-map @@ -1,26 +1,26 @@ Function name: nested_loops::main -Raw bytes (164): 0x[01, 01, 14, 07, 47, 05, 11, 01, 0d, 47, 05, 01, 0d, 47, 05, 01, 0d, 47, 05, 01, 0d, 47, 05, 01, 0d, 3f, 05, 01, 09, 4b, 3f, 05, 15, 01, 09, 47, 4b, 01, 0d, 05, 15, 05, 01, 18, 01, 01, 01, 00, 0a, 01, 01, 09, 00, 10, 01, 00, 13, 00, 2e, 01, 01, 09, 00, 16, 01, 00, 19, 00, 1b, 05, 02, 13, 00, 20, 09, 01, 0d, 00, 12, 09, 00, 15, 00, 18, 09, 01, 0d, 00, 12, 09, 00, 15, 00, 18, 0d, 01, 12, 00, 17, 11, 01, 10, 00, 16, 02, 01, 11, 00, 16, 26, 01, 0d, 00, 0e, 26, 01, 0d, 00, 13, 26, 01, 0d, 00, 13, 26, 01, 10, 00, 16, 15, 01, 11, 00, 18, 15, 01, 14, 00, 1b, 2e, 01, 15, 00, 21, 36, 01, 18, 02, 12, 42, 03, 0d, 00, 0e, 4e, 02, 09, 00, 17, 01, 02, 01, 00, 02] +Raw bytes (164): 0x[01, 01, 14, 07, 47, 05, 0d, 01, 11, 47, 05, 01, 11, 47, 05, 01, 11, 47, 05, 01, 11, 47, 05, 01, 11, 3f, 05, 01, 09, 4b, 3f, 05, 15, 01, 09, 47, 4b, 01, 11, 05, 15, 05, 01, 18, 01, 01, 01, 00, 0a, 01, 01, 09, 00, 10, 01, 00, 13, 00, 2e, 01, 01, 09, 00, 16, 01, 00, 19, 00, 1b, 05, 02, 13, 00, 20, 09, 01, 0d, 00, 12, 09, 00, 15, 00, 18, 09, 01, 0d, 00, 12, 09, 00, 15, 00, 18, 09, 01, 12, 00, 17, 0d, 01, 10, 00, 16, 02, 01, 11, 00, 16, 26, 01, 0d, 00, 0e, 26, 01, 0d, 00, 13, 26, 01, 0d, 00, 13, 26, 01, 10, 00, 16, 15, 01, 11, 00, 18, 15, 01, 14, 00, 1b, 2e, 01, 15, 00, 21, 36, 01, 18, 02, 12, 42, 03, 0d, 00, 0e, 4e, 02, 09, 00, 17, 01, 02, 01, 00, 02] Number of files: 1 - file 0 => $DIR/nested_loops.rs Number of expressions: 20 - expression 0 operands: lhs = Expression(1, Add), rhs = Expression(17, Add) -- expression 1 operands: lhs = Counter(1), rhs = Counter(4) -- expression 2 operands: lhs = Counter(0), rhs = Counter(3) +- expression 1 operands: lhs = Counter(1), rhs = Counter(3) +- expression 2 operands: lhs = Counter(0), rhs = Counter(4) - expression 3 operands: lhs = Expression(17, Add), rhs = Counter(1) -- expression 4 operands: lhs = Counter(0), rhs = Counter(3) +- expression 4 operands: lhs = Counter(0), rhs = Counter(4) - expression 5 operands: lhs = Expression(17, Add), rhs = Counter(1) -- expression 6 operands: lhs = Counter(0), rhs = Counter(3) +- expression 6 operands: lhs = Counter(0), rhs = Counter(4) - expression 7 operands: lhs = Expression(17, Add), rhs = Counter(1) -- expression 8 operands: lhs = Counter(0), rhs = Counter(3) +- expression 8 operands: lhs = Counter(0), rhs = Counter(4) - expression 9 operands: lhs = Expression(17, Add), rhs = Counter(1) -- expression 10 operands: lhs = Counter(0), rhs = Counter(3) +- expression 10 operands: lhs = Counter(0), rhs = Counter(4) - expression 11 operands: lhs = Expression(15, Add), rhs = Counter(1) - expression 12 operands: lhs = Counter(0), rhs = Counter(2) - expression 13 operands: lhs = Expression(18, Add), rhs = Expression(15, Add) - expression 14 operands: lhs = Counter(1), rhs = Counter(5) - expression 15 operands: lhs = Counter(0), rhs = Counter(2) - expression 16 operands: lhs = Expression(17, Add), rhs = Expression(18, Add) -- expression 17 operands: lhs = Counter(0), rhs = Counter(3) +- expression 17 operands: lhs = Counter(0), rhs = Counter(4) - expression 18 operands: lhs = Counter(1), rhs = Counter(5) - expression 19 operands: lhs = Counter(1), rhs = Counter(0) Number of file 0 mappings: 24 @@ -34,18 +34,18 @@ Number of file 0 mappings: 24 - Code(Counter(2)) at (prev + 0, 21) to (start + 0, 24) - Code(Counter(2)) at (prev + 1, 13) to (start + 0, 18) - Code(Counter(2)) at (prev + 0, 21) to (start + 0, 24) -- Code(Counter(3)) at (prev + 1, 18) to (start + 0, 23) -- Code(Counter(4)) at (prev + 1, 16) to (start + 0, 22) +- Code(Counter(2)) at (prev + 1, 18) to (start + 0, 23) +- Code(Counter(3)) at (prev + 1, 16) to (start + 0, 22) - Code(Expression(0, Sub)) at (prev + 1, 17) to (start + 0, 22) - = ((c1 + c4) - (c0 + c3)) + = ((c1 + c3) - (c0 + c4)) - Code(Expression(9, Sub)) at (prev + 1, 13) to (start + 0, 14) - = ((c0 + c3) - c1) + = ((c0 + c4) - c1) - Code(Expression(9, Sub)) at (prev + 1, 13) to (start + 0, 19) - = ((c0 + c3) - c1) + = ((c0 + c4) - c1) - Code(Expression(9, Sub)) at (prev + 1, 13) to (start + 0, 19) - = ((c0 + c3) - c1) + = ((c0 + c4) - c1) - Code(Expression(9, Sub)) at (prev + 1, 16) to (start + 0, 22) - = ((c0 + c3) - c1) + = ((c0 + c4) - c1) - Code(Counter(5)) at (prev + 1, 17) to (start + 0, 24) - Code(Counter(5)) at (prev + 1, 20) to (start + 0, 27) - Code(Expression(11, Sub)) at (prev + 1, 21) to (start + 0, 33) @@ -53,7 +53,7 @@ Number of file 0 mappings: 24 - Code(Expression(13, Sub)) at (prev + 1, 24) to (start + 2, 18) = ((c1 + c5) - (c0 + c2)) - Code(Expression(16, Sub)) at (prev + 3, 13) to (start + 0, 14) - = ((c0 + c3) - (c1 + c5)) + = ((c0 + c4) - (c1 + c5)) - Code(Expression(19, Sub)) at (prev + 2, 9) to (start + 0, 23) = (c1 - c0) - Code(Counter(0)) at (prev + 2, 1) to (start + 0, 2) diff --git a/tests/coverage/nested_loops.coverage b/tests/coverage/nested_loops.coverage index 143d0d26aa7f..fbbec43309ed 100644 --- a/tests/coverage/nested_loops.coverage +++ b/tests/coverage/nested_loops.coverage @@ -5,7 +5,7 @@ LL| 1| 'outer: while countdown > 0 { LL| 1| let mut a = 100; LL| 1| let mut b = 100; - LL| 3| for _ in 0..50 { + LL| 1| for _ in 0..50 { LL| 3| if a < 30 { LL| 0| break; LL| 3| } diff --git a/tests/coverage/simple_match.cov-map b/tests/coverage/simple_match.cov-map index cbd6c7ca52fd..bc5a7e7b4bef 100644 --- a/tests/coverage/simple_match.cov-map +++ b/tests/coverage/simple_match.cov-map @@ -1,5 +1,5 @@ Function name: simple_match::main -Raw bytes (99): 0x[01, 01, 05, 01, 05, 09, 01, 09, 01, 09, 13, 01, 0d, 11, 01, 04, 01, 00, 0a, 01, 04, 09, 00, 10, 01, 00, 13, 00, 2e, 01, 02, 09, 00, 16, 01, 00, 19, 00, 1a, 01, 01, 08, 00, 0f, 05, 00, 10, 02, 06, 02, 02, 05, 00, 06, 09, 05, 09, 00, 0d, 0a, 05, 0d, 00, 16, 0d, 02, 0d, 00, 0e, 0a, 02, 11, 02, 12, 0d, 04, 0d, 07, 0e, 0d, 01, 11, 00, 1e, 0d, 02, 15, 00, 16, 0e, 07, 0d, 00, 0f, 01, 03, 01, 00, 02] +Raw bytes (99): 0x[01, 01, 05, 01, 05, 09, 01, 09, 01, 09, 13, 01, 0d, 11, 01, 04, 01, 00, 0a, 01, 04, 09, 00, 10, 01, 00, 13, 00, 2e, 01, 02, 09, 00, 16, 01, 00, 19, 00, 1a, 01, 01, 08, 00, 0f, 05, 00, 10, 02, 06, 02, 02, 05, 00, 06, 01, 05, 09, 00, 0d, 0a, 05, 0d, 00, 16, 0d, 02, 0d, 00, 0e, 0a, 02, 11, 02, 12, 0d, 04, 0d, 07, 0e, 0d, 01, 11, 00, 1e, 0d, 02, 15, 00, 16, 0e, 07, 0d, 00, 0f, 01, 03, 01, 00, 02] Number of files: 1 - file 0 => $DIR/simple_match.rs Number of expressions: 5 @@ -18,7 +18,7 @@ Number of file 0 mappings: 17 - Code(Counter(1)) at (prev + 0, 16) to (start + 2, 6) - Code(Expression(0, Sub)) at (prev + 2, 5) to (start + 0, 6) = (c0 - c1) -- Code(Counter(2)) at (prev + 5, 9) to (start + 0, 13) +- Code(Counter(0)) at (prev + 5, 9) to (start + 0, 13) - Code(Expression(2, Sub)) at (prev + 5, 13) to (start + 0, 22) = (c2 - c0) - Code(Counter(3)) at (prev + 2, 13) to (start + 0, 14) diff --git a/tests/coverage/simple_match.coverage b/tests/coverage/simple_match.coverage index 0ed7e8dc7887..bd3f81aa8a1e 100644 --- a/tests/coverage/simple_match.coverage +++ b/tests/coverage/simple_match.coverage @@ -16,7 +16,7 @@ LL| | for LL| | _ LL| | in - LL| 3| 0..2 + LL| 1| 0..2 LL| | { LL| | let z LL| | ; diff --git a/tests/coverage/try_error_result.cov-map b/tests/coverage/try_error_result.cov-map index e08f42961532..53757ef8a9bd 100644 --- a/tests/coverage/try_error_result.cov-map +++ b/tests/coverage/try_error_result.cov-map @@ -62,77 +62,77 @@ Number of file 0 mappings: 8 Highest counter ID seen: c1 Function name: try_error_result::test1 -Raw bytes (82): 0x[01, 01, 04, 07, 05, 01, 09, 05, 01, 05, 09, 0e, 01, 0d, 01, 00, 1d, 01, 01, 09, 01, 12, 01, 01, 15, 00, 17, 05, 05, 09, 00, 0e, 09, 02, 09, 01, 11, 09, 04, 0d, 00, 1a, 02, 02, 0d, 00, 11, 02, 00, 29, 00, 2a, 00, 01, 0d, 00, 11, 00, 00, 2a, 00, 2b, 0a, 04, 0d, 00, 11, 00, 00, 2a, 00, 2b, 0e, 03, 05, 00, 0b, 01, 01, 01, 00, 02] +Raw bytes (82): 0x[01, 01, 04, 07, 09, 01, 05, 09, 01, 09, 05, 0e, 01, 0d, 01, 00, 1d, 01, 01, 09, 01, 12, 01, 01, 15, 00, 17, 01, 05, 09, 00, 0e, 05, 02, 09, 01, 11, 05, 04, 0d, 00, 1a, 02, 02, 0d, 00, 11, 02, 00, 29, 00, 2a, 00, 01, 0d, 00, 11, 00, 00, 2a, 00, 2b, 0a, 04, 0d, 00, 11, 00, 00, 2a, 00, 2b, 0e, 03, 05, 00, 0b, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/try_error_result.rs Number of expressions: 4 -- expression 0 operands: lhs = Expression(1, Add), rhs = Counter(1) -- expression 1 operands: lhs = Counter(0), rhs = Counter(2) -- expression 2 operands: lhs = Counter(1), rhs = Counter(0) -- expression 3 operands: lhs = Counter(1), rhs = Counter(2) +- expression 0 operands: lhs = Expression(1, Add), rhs = Counter(2) +- expression 1 operands: lhs = Counter(0), rhs = Counter(1) +- expression 2 operands: lhs = Counter(2), rhs = Counter(0) +- expression 3 operands: lhs = Counter(2), rhs = Counter(1) Number of file 0 mappings: 14 - Code(Counter(0)) at (prev + 13, 1) to (start + 0, 29) - Code(Counter(0)) at (prev + 1, 9) to (start + 1, 18) - Code(Counter(0)) at (prev + 1, 21) to (start + 0, 23) -- Code(Counter(1)) at (prev + 5, 9) to (start + 0, 14) -- Code(Counter(2)) at (prev + 2, 9) to (start + 1, 17) -- Code(Counter(2)) at (prev + 4, 13) to (start + 0, 26) +- Code(Counter(0)) at (prev + 5, 9) to (start + 0, 14) +- Code(Counter(1)) at (prev + 2, 9) to (start + 1, 17) +- Code(Counter(1)) at (prev + 4, 13) to (start + 0, 26) - Code(Expression(0, Sub)) at (prev + 2, 13) to (start + 0, 17) - = ((c0 + c2) - c1) + = ((c0 + c1) - c2) - Code(Expression(0, Sub)) at (prev + 0, 41) to (start + 0, 42) - = ((c0 + c2) - c1) + = ((c0 + c1) - c2) - Code(Zero) at (prev + 1, 13) to (start + 0, 17) - Code(Zero) at (prev + 0, 42) to (start + 0, 43) - Code(Expression(2, Sub)) at (prev + 4, 13) to (start + 0, 17) - = (c1 - c0) + = (c2 - c0) - Code(Zero) at (prev + 0, 42) to (start + 0, 43) - Code(Expression(3, Sub)) at (prev + 3, 5) to (start + 0, 11) - = (c1 - c2) + = (c2 - c1) - Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) -Highest counter ID seen: c2 +Highest counter ID seen: c1 Function name: try_error_result::test2 -Raw bytes (443): 0x[01, 01, 3d, 0d, 11, 0d, 57, 11, 15, 0d, 57, 11, 15, 0d, 57, 11, 15, 0d, 4f, 53, 1d, 57, 19, 11, 15, 0d, 57, 11, 15, 0d, 57, 11, 15, 0d, 53, 57, 19, 11, 15, 0d, 4f, 53, 1d, 57, 19, 11, 15, 41, 6b, 21, 25, 41, 21, 41, 6b, 21, 25, 09, 8f, 01, 93, 01, 2d, 0d, 29, 09, 0d, 09, 0d, 09, 93, 01, 0d, 29, 09, 8f, 01, 93, 01, 2d, 0d, 29, 45, a7, 01, 31, 35, 45, 31, 45, a7, 01, 31, 35, 49, bb, 01, 39, 3d, 49, 39, 49, bb, 01, 39, 3d, 05, 09, c7, 01, 09, cb, 01, 3d, cf, 01, 39, d3, 01, 35, d7, 01, 31, db, 01, 2d, df, 01, 29, e3, 01, 25, e7, 01, 21, eb, 01, 1d, ef, 01, 19, f3, 01, 15, 05, 11, 39, 01, 3d, 01, 00, 1d, 01, 01, 09, 00, 0f, 01, 00, 12, 00, 1a, 01, 01, 09, 01, 12, 01, 01, 15, 00, 17, 05, 05, 09, 00, 0e, 09, 02, 09, 01, 11, 09, 04, 0d, 00, 1a, 0d, 02, 0d, 00, 13, 0d, 00, 14, 00, 1f, 11, 00, 2f, 00, 30, 02, 00, 31, 00, 35, 02, 00, 45, 00, 4f, 02, 00, 50, 00, 62, 02, 01, 0d, 00, 13, 02, 02, 11, 00, 1c, 15, 01, 11, 00, 12, 36, 02, 11, 00, 15, 36, 02, 11, 00, 1b, 36, 01, 15, 00, 27, 4a, 02, 11, 00, 14, 36, 00, 17, 00, 1d, 36, 00, 1e, 00, 29, 19, 00, 41, 00, 42, 3e, 00, 43, 00, 47, 1d, 00, 5f, 00, 60, 4a, 01, 0d, 00, 17, 66, 01, 11, 00, 14, 41, 00, 17, 00, 1d, 41, 00, 1e, 00, 29, 21, 00, 41, 00, 42, 62, 00, 43, 00, 47, 25, 00, 60, 00, 61, 66, 01, 0d, 00, 17, 8a, 01, 04, 11, 00, 14, 7e, 00, 17, 00, 1d, 7e, 00, 1e, 00, 29, 29, 00, 42, 00, 43, 82, 01, 00, 44, 00, 48, 2d, 00, 61, 00, 62, 8a, 01, 01, 0d, 00, 17, a2, 01, 01, 11, 00, 14, 45, 00, 17, 00, 1d, 45, 01, 12, 00, 1d, 31, 00, 36, 00, 37, 9e, 01, 01, 12, 00, 16, 35, 00, 2f, 00, 30, a2, 01, 01, 0d, 00, 17, b6, 01, 01, 11, 00, 14, 49, 00, 17, 00, 1d, 49, 01, 12, 00, 1d, 39, 01, 11, 00, 12, b2, 01, 01, 12, 00, 16, 3d, 01, 11, 00, 12, b6, 01, 02, 0d, 00, 17, be, 01, 03, 05, 00, 0b, c2, 01, 01, 01, 00, 02] +Raw bytes (443): 0x[01, 01, 3d, 09, 0d, 09, 57, 0d, 15, 09, 57, 0d, 15, 09, 57, 0d, 15, 09, 4f, 53, 1d, 57, 19, 0d, 15, 09, 57, 0d, 15, 09, 57, 0d, 15, 09, 53, 57, 19, 0d, 15, 09, 4f, 53, 1d, 57, 19, 0d, 15, 41, 6b, 21, 25, 41, 21, 41, 6b, 21, 25, 05, 8f, 01, 93, 01, 2d, 09, 29, 05, 09, 05, 09, 05, 93, 01, 09, 29, 05, 8f, 01, 93, 01, 2d, 09, 29, 45, a7, 01, 31, 35, 45, 31, 45, a7, 01, 31, 35, 49, bb, 01, 39, 3d, 49, 39, 49, bb, 01, 39, 3d, 11, 05, c7, 01, 05, cb, 01, 3d, cf, 01, 39, d3, 01, 35, d7, 01, 31, db, 01, 2d, df, 01, 29, e3, 01, 25, e7, 01, 21, eb, 01, 1d, ef, 01, 19, f3, 01, 15, 11, 0d, 39, 01, 3d, 01, 00, 1d, 01, 01, 09, 00, 0f, 01, 00, 12, 00, 1a, 01, 01, 09, 01, 12, 01, 01, 15, 00, 17, 01, 05, 09, 00, 0e, 05, 02, 09, 01, 11, 05, 04, 0d, 00, 1a, 09, 02, 0d, 00, 13, 09, 00, 14, 00, 1f, 0d, 00, 2f, 00, 30, 02, 00, 31, 00, 35, 02, 00, 45, 00, 4f, 02, 00, 50, 00, 62, 02, 01, 0d, 00, 13, 02, 02, 11, 00, 1c, 15, 01, 11, 00, 12, 36, 02, 11, 00, 15, 36, 02, 11, 00, 1b, 36, 01, 15, 00, 27, 4a, 02, 11, 00, 14, 36, 00, 17, 00, 1d, 36, 00, 1e, 00, 29, 19, 00, 41, 00, 42, 3e, 00, 43, 00, 47, 1d, 00, 5f, 00, 60, 4a, 01, 0d, 00, 17, 66, 01, 11, 00, 14, 41, 00, 17, 00, 1d, 41, 00, 1e, 00, 29, 21, 00, 41, 00, 42, 62, 00, 43, 00, 47, 25, 00, 60, 00, 61, 66, 01, 0d, 00, 17, 8a, 01, 04, 11, 00, 14, 7e, 00, 17, 00, 1d, 7e, 00, 1e, 00, 29, 29, 00, 42, 00, 43, 82, 01, 00, 44, 00, 48, 2d, 00, 61, 00, 62, 8a, 01, 01, 0d, 00, 17, a2, 01, 01, 11, 00, 14, 45, 00, 17, 00, 1d, 45, 01, 12, 00, 1d, 31, 00, 36, 00, 37, 9e, 01, 01, 12, 00, 16, 35, 00, 2f, 00, 30, a2, 01, 01, 0d, 00, 17, b6, 01, 01, 11, 00, 14, 49, 00, 17, 00, 1d, 49, 01, 12, 00, 1d, 39, 01, 11, 00, 12, b2, 01, 01, 12, 00, 16, 3d, 01, 11, 00, 12, b6, 01, 02, 0d, 00, 17, be, 01, 03, 05, 00, 0b, c2, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/try_error_result.rs Number of expressions: 61 -- expression 0 operands: lhs = Counter(3), rhs = Counter(4) -- expression 1 operands: lhs = Counter(3), rhs = Expression(21, Add) -- expression 2 operands: lhs = Counter(4), rhs = Counter(5) -- expression 3 operands: lhs = Counter(3), rhs = Expression(21, Add) -- expression 4 operands: lhs = Counter(4), rhs = Counter(5) -- expression 5 operands: lhs = Counter(3), rhs = Expression(21, Add) -- expression 6 operands: lhs = Counter(4), rhs = Counter(5) -- expression 7 operands: lhs = Counter(3), rhs = Expression(19, Add) +- expression 0 operands: lhs = Counter(2), rhs = Counter(3) +- expression 1 operands: lhs = Counter(2), rhs = Expression(21, Add) +- expression 2 operands: lhs = Counter(3), rhs = Counter(5) +- expression 3 operands: lhs = Counter(2), rhs = Expression(21, Add) +- expression 4 operands: lhs = Counter(3), rhs = Counter(5) +- expression 5 operands: lhs = Counter(2), rhs = Expression(21, Add) +- expression 6 operands: lhs = Counter(3), rhs = Counter(5) +- expression 7 operands: lhs = Counter(2), rhs = Expression(19, Add) - expression 8 operands: lhs = Expression(20, Add), rhs = Counter(7) - expression 9 operands: lhs = Expression(21, Add), rhs = Counter(6) -- expression 10 operands: lhs = Counter(4), rhs = Counter(5) -- expression 11 operands: lhs = Counter(3), rhs = Expression(21, Add) -- expression 12 operands: lhs = Counter(4), rhs = Counter(5) -- expression 13 operands: lhs = Counter(3), rhs = Expression(21, Add) -- expression 14 operands: lhs = Counter(4), rhs = Counter(5) -- expression 15 operands: lhs = Counter(3), rhs = Expression(20, Add) +- expression 10 operands: lhs = Counter(3), rhs = Counter(5) +- expression 11 operands: lhs = Counter(2), rhs = Expression(21, Add) +- expression 12 operands: lhs = Counter(3), rhs = Counter(5) +- expression 13 operands: lhs = Counter(2), rhs = Expression(21, Add) +- expression 14 operands: lhs = Counter(3), rhs = Counter(5) +- expression 15 operands: lhs = Counter(2), rhs = Expression(20, Add) - expression 16 operands: lhs = Expression(21, Add), rhs = Counter(6) -- expression 17 operands: lhs = Counter(4), rhs = Counter(5) -- expression 18 operands: lhs = Counter(3), rhs = Expression(19, Add) +- expression 17 operands: lhs = Counter(3), rhs = Counter(5) +- expression 18 operands: lhs = Counter(2), rhs = Expression(19, Add) - expression 19 operands: lhs = Expression(20, Add), rhs = Counter(7) - expression 20 operands: lhs = Expression(21, Add), rhs = Counter(6) -- expression 21 operands: lhs = Counter(4), rhs = Counter(5) +- expression 21 operands: lhs = Counter(3), rhs = Counter(5) - expression 22 operands: lhs = Counter(16), rhs = Expression(26, Add) - expression 23 operands: lhs = Counter(8), rhs = Counter(9) - expression 24 operands: lhs = Counter(16), rhs = Counter(8) - expression 25 operands: lhs = Counter(16), rhs = Expression(26, Add) - expression 26 operands: lhs = Counter(8), rhs = Counter(9) -- expression 27 operands: lhs = Counter(2), rhs = Expression(35, Add) +- expression 27 operands: lhs = Counter(1), rhs = Expression(35, Add) - expression 28 operands: lhs = Expression(36, Add), rhs = Counter(11) -- expression 29 operands: lhs = Counter(3), rhs = Counter(10) -- expression 30 operands: lhs = Counter(2), rhs = Counter(3) -- expression 31 operands: lhs = Counter(2), rhs = Counter(3) -- expression 32 operands: lhs = Counter(2), rhs = Expression(36, Add) -- expression 33 operands: lhs = Counter(3), rhs = Counter(10) -- expression 34 operands: lhs = Counter(2), rhs = Expression(35, Add) +- expression 29 operands: lhs = Counter(2), rhs = Counter(10) +- expression 30 operands: lhs = Counter(1), rhs = Counter(2) +- expression 31 operands: lhs = Counter(1), rhs = Counter(2) +- expression 32 operands: lhs = Counter(1), rhs = Expression(36, Add) +- expression 33 operands: lhs = Counter(2), rhs = Counter(10) +- expression 34 operands: lhs = Counter(1), rhs = Expression(35, Add) - expression 35 operands: lhs = Expression(36, Add), rhs = Counter(11) -- expression 36 operands: lhs = Counter(3), rhs = Counter(10) +- expression 36 operands: lhs = Counter(2), rhs = Counter(10) - expression 37 operands: lhs = Counter(17), rhs = Expression(41, Add) - expression 38 operands: lhs = Counter(12), rhs = Counter(13) - expression 39 operands: lhs = Counter(17), rhs = Counter(12) @@ -143,8 +143,8 @@ Number of expressions: 61 - expression 44 operands: lhs = Counter(18), rhs = Counter(14) - expression 45 operands: lhs = Counter(18), rhs = Expression(46, Add) - expression 46 operands: lhs = Counter(14), rhs = Counter(15) -- expression 47 operands: lhs = Counter(1), rhs = Counter(2) -- expression 48 operands: lhs = Expression(49, Add), rhs = Counter(2) +- expression 47 operands: lhs = Counter(4), rhs = Counter(1) +- expression 48 operands: lhs = Expression(49, Add), rhs = Counter(1) - expression 49 operands: lhs = Expression(50, Add), rhs = Counter(15) - expression 50 operands: lhs = Expression(51, Add), rhs = Counter(14) - expression 51 operands: lhs = Expression(52, Add), rhs = Counter(13) @@ -156,48 +156,48 @@ Number of expressions: 61 - expression 57 operands: lhs = Expression(58, Add), rhs = Counter(7) - expression 58 operands: lhs = Expression(59, Add), rhs = Counter(6) - expression 59 operands: lhs = Expression(60, Add), rhs = Counter(5) -- expression 60 operands: lhs = Counter(1), rhs = Counter(4) +- expression 60 operands: lhs = Counter(4), rhs = Counter(3) Number of file 0 mappings: 57 - Code(Counter(0)) at (prev + 61, 1) to (start + 0, 29) - Code(Counter(0)) at (prev + 1, 9) to (start + 0, 15) - Code(Counter(0)) at (prev + 0, 18) to (start + 0, 26) - Code(Counter(0)) at (prev + 1, 9) to (start + 1, 18) - Code(Counter(0)) at (prev + 1, 21) to (start + 0, 23) -- Code(Counter(1)) at (prev + 5, 9) to (start + 0, 14) -- Code(Counter(2)) at (prev + 2, 9) to (start + 1, 17) -- Code(Counter(2)) at (prev + 4, 13) to (start + 0, 26) -- Code(Counter(3)) at (prev + 2, 13) to (start + 0, 19) -- Code(Counter(3)) at (prev + 0, 20) to (start + 0, 31) -- Code(Counter(4)) at (prev + 0, 47) to (start + 0, 48) +- Code(Counter(0)) at (prev + 5, 9) to (start + 0, 14) +- Code(Counter(1)) at (prev + 2, 9) to (start + 1, 17) +- Code(Counter(1)) at (prev + 4, 13) to (start + 0, 26) +- Code(Counter(2)) at (prev + 2, 13) to (start + 0, 19) +- Code(Counter(2)) at (prev + 0, 20) to (start + 0, 31) +- Code(Counter(3)) at (prev + 0, 47) to (start + 0, 48) - Code(Expression(0, Sub)) at (prev + 0, 49) to (start + 0, 53) - = (c3 - c4) + = (c2 - c3) - Code(Expression(0, Sub)) at (prev + 0, 69) to (start + 0, 79) - = (c3 - c4) + = (c2 - c3) - Code(Expression(0, Sub)) at (prev + 0, 80) to (start + 0, 98) - = (c3 - c4) + = (c2 - c3) - Code(Expression(0, Sub)) at (prev + 1, 13) to (start + 0, 19) - = (c3 - c4) + = (c2 - c3) - Code(Expression(0, Sub)) at (prev + 2, 17) to (start + 0, 28) - = (c3 - c4) + = (c2 - c3) - Code(Counter(5)) at (prev + 1, 17) to (start + 0, 18) - Code(Expression(13, Sub)) at (prev + 2, 17) to (start + 0, 21) - = (c3 - (c4 + c5)) + = (c2 - (c3 + c5)) - Code(Expression(13, Sub)) at (prev + 2, 17) to (start + 0, 27) - = (c3 - (c4 + c5)) + = (c2 - (c3 + c5)) - Code(Expression(13, Sub)) at (prev + 1, 21) to (start + 0, 39) - = (c3 - (c4 + c5)) + = (c2 - (c3 + c5)) - Code(Expression(18, Sub)) at (prev + 2, 17) to (start + 0, 20) - = (c3 - (((c4 + c5) + c6) + c7)) + = (c2 - (((c3 + c5) + c6) + c7)) - Code(Expression(13, Sub)) at (prev + 0, 23) to (start + 0, 29) - = (c3 - (c4 + c5)) + = (c2 - (c3 + c5)) - Code(Expression(13, Sub)) at (prev + 0, 30) to (start + 0, 41) - = (c3 - (c4 + c5)) + = (c2 - (c3 + c5)) - Code(Counter(6)) at (prev + 0, 65) to (start + 0, 66) - Code(Expression(15, Sub)) at (prev + 0, 67) to (start + 0, 71) - = (c3 - ((c4 + c5) + c6)) + = (c2 - ((c3 + c5) + c6)) - Code(Counter(7)) at (prev + 0, 95) to (start + 0, 96) - Code(Expression(18, Sub)) at (prev + 1, 13) to (start + 0, 23) - = (c3 - (((c4 + c5) + c6) + c7)) + = (c2 - (((c3 + c5) + c6) + c7)) - Code(Expression(25, Sub)) at (prev + 1, 17) to (start + 0, 20) = (c16 - (c8 + c9)) - Code(Counter(16)) at (prev + 0, 23) to (start + 0, 29) @@ -209,17 +209,17 @@ Number of file 0 mappings: 57 - Code(Expression(25, Sub)) at (prev + 1, 13) to (start + 0, 23) = (c16 - (c8 + c9)) - Code(Expression(34, Sub)) at (prev + 4, 17) to (start + 0, 20) - = (c2 - ((c3 + c10) + c11)) + = (c1 - ((c2 + c10) + c11)) - Code(Expression(31, Sub)) at (prev + 0, 23) to (start + 0, 29) - = (c2 - c3) + = (c1 - c2) - Code(Expression(31, Sub)) at (prev + 0, 30) to (start + 0, 41) - = (c2 - c3) + = (c1 - c2) - Code(Counter(10)) at (prev + 0, 66) to (start + 0, 67) - Code(Expression(32, Sub)) at (prev + 0, 68) to (start + 0, 72) - = (c2 - (c3 + c10)) + = (c1 - (c2 + c10)) - Code(Counter(11)) at (prev + 0, 97) to (start + 0, 98) - Code(Expression(34, Sub)) at (prev + 1, 13) to (start + 0, 23) - = (c2 - ((c3 + c10) + c11)) + = (c1 - ((c2 + c10) + c11)) - Code(Expression(40, Sub)) at (prev + 1, 17) to (start + 0, 20) = (c17 - (c12 + c13)) - Code(Counter(17)) at (prev + 0, 23) to (start + 0, 29) @@ -241,8 +241,8 @@ Number of file 0 mappings: 57 - Code(Expression(45, Sub)) at (prev + 2, 13) to (start + 0, 23) = (c18 - (c14 + c15)) - Code(Expression(47, Sub)) at (prev + 3, 5) to (start + 0, 11) - = (c1 - c2) + = (c4 - c1) - Code(Expression(48, Sub)) at (prev + 1, 1) to (start + 0, 2) - = (((((((((((((c1 + c4) + c5) + c6) + c7) + c8) + c9) + c10) + c11) + c12) + c13) + c14) + c15) - c2) + = (((((((((((((c4 + c3) + c5) + c6) + c7) + c8) + c9) + c10) + c11) + c12) + c13) + c14) + c15) - c1) Highest counter ID seen: c18 diff --git a/tests/coverage/try_error_result.coverage b/tests/coverage/try_error_result.coverage index f2ec82f20fa2..193c92cad48f 100644 --- a/tests/coverage/try_error_result.coverage +++ b/tests/coverage/try_error_result.coverage @@ -17,7 +17,7 @@ LL| | for LL| | _ LL| | in - LL| 6| 0..10 + LL| 1| 0..10 LL| | { LL| 6| countdown LL| 6| -= 1 @@ -67,7 +67,7 @@ LL| | for LL| | _ LL| | in - LL| 6| 0..10 + LL| 1| 0..10 LL| | { LL| 6| countdown LL| 6| -= 1 diff --git a/tests/coverage/unicode.cov-map b/tests/coverage/unicode.cov-map index bbfa8b940c6d..b118c847e8ff 100644 --- a/tests/coverage/unicode.cov-map +++ b/tests/coverage/unicode.cov-map @@ -1,5 +1,5 @@ Function name: unicode::main -Raw bytes (58): 0x[01, 01, 02, 05, 01, 01, 0d, 0a, 01, 0e, 01, 00, 0a, 02, 01, 09, 00, 0c, 05, 00, 10, 00, 1b, 02, 00, 1c, 00, 28, 01, 02, 08, 00, 23, 09, 00, 29, 00, 44, 0d, 00, 47, 02, 06, 06, 02, 05, 00, 06, 01, 02, 05, 00, 0b, 01, 01, 01, 00, 02] +Raw bytes (58): 0x[01, 01, 02, 05, 01, 01, 0d, 0a, 01, 0e, 01, 00, 0a, 02, 01, 09, 00, 0c, 01, 00, 10, 00, 1b, 02, 00, 1c, 00, 28, 01, 02, 08, 00, 23, 09, 00, 29, 00, 44, 0d, 00, 47, 02, 06, 06, 02, 05, 00, 06, 01, 02, 05, 00, 0b, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/unicode.rs Number of expressions: 2 @@ -9,7 +9,7 @@ Number of file 0 mappings: 10 - Code(Counter(0)) at (prev + 14, 1) to (start + 0, 10) - Code(Expression(0, Sub)) at (prev + 1, 9) to (start + 0, 12) = (c1 - c0) -- Code(Counter(1)) at (prev + 0, 16) to (start + 0, 27) +- Code(Counter(0)) at (prev + 0, 16) to (start + 0, 27) - Code(Expression(0, Sub)) at (prev + 0, 28) to (start + 0, 40) = (c1 - c0) - Code(Counter(0)) at (prev + 2, 8) to (start + 0, 35) diff --git a/tests/coverage/unicode.coverage b/tests/coverage/unicode.coverage index 4646cc92e8e4..188848889d30 100644 --- a/tests/coverage/unicode.coverage +++ b/tests/coverage/unicode.coverage @@ -12,8 +12,8 @@ LL| |// points or bytes. LL| | LL| 1|fn main() { - LL| 33| for _İ in 'А'..='Я' { /* Я */ } - ^32 ^32 + LL| 32| for _İ in 'А'..='Я' { /* Я */ } + ^1 LL| | LL| 1| if 申し訳ございません() && 申し訳ございません() { ^0 diff --git a/tests/incremental/circular-dependencies.rs b/tests/incremental/circular-dependencies.rs index c7b5b931fbbe..15e21089c904 100644 --- a/tests/incremental/circular-dependencies.rs +++ b/tests/incremental/circular-dependencies.rs @@ -6,12 +6,12 @@ //@ [cfail2] compile-flags: --test --extern aux={{build-base}}/circular-dependencies/auxiliary/libcircular_dependencies_aux.rmeta -L dependency={{build-base}}/circular-dependencies pub struct Foo; -//[cfail2]~^ NOTE the crate `circular_dependencies` is compiled multiple times, possibly with different configurations -//[cfail2]~| NOTE the crate `circular_dependencies` is compiled multiple times, possibly with different configurations -//[cfail2]~| NOTE this is the expected type `Foo` -//[cfail2]~| NOTE this is the expected type `circular_dependencies::Foo` -//[cfail2]~| NOTE this is the found type `Foo` -//[cfail2]~| NOTE this is the found type `circular_dependencies::Foo` +//[cfail2]~^ NOTE there are multiple different versions of crate `circular_dependencies` in the dependency graph +//[cfail2]~| NOTE there are multiple different versions of crate `circular_dependencies` in the dependency graph +//[cfail2]~| NOTE this is the expected type +//[cfail2]~| NOTE this is the expected type +//[cfail2]~| NOTE this is the found type +//[cfail2]~| NOTE this is the found type pub fn consume_foo(_: Foo) {} //[cfail2]~^ NOTE function defined here @@ -27,8 +27,6 @@ fn test() { //[cfail2]~| NOTE expected `circular_dependencies::Foo`, found `Foo` //[cfail2]~| NOTE arguments to this function are incorrect //[cfail2]~| NOTE function defined here - //[cfail2]~| NOTE one version of crate `circular_dependencies` used here, as a dependency of crate `circular_dependencies_aux` - //[cfail2]~| NOTE one version of crate `circular_dependencies` used here, as a dependency of crate `circular_dependencies_aux` consume_foo(aux::produce_foo()); //[cfail2]~^ ERROR mismatched types [E0308] diff --git a/tests/mir-opt/gvn_loop.rs b/tests/mir-opt/gvn_loop.rs index 4a94d516cca2..ce23f7930f1b 100644 --- a/tests/mir-opt/gvn_loop.rs +++ b/tests/mir-opt/gvn_loop.rs @@ -16,9 +16,9 @@ fn loop_deref_mut(val: &mut Value) -> Value { // CHECK-LABEL: fn loop_deref_mut( // CHECK: [[VAL_REF:_.*]] = get::( // CHECK: [[V:_.*]] = copy (((*[[VAL_REF]]) as V0).0: i32); - // CEHCK-NOT: copy (*[[VAL_REF]]); + // CHECK-NOT: copy (*[[VAL_REF]]); // CHECK: [[RET:_*]] = Value::V0(copy [[V]]); - // CEHCK-NOT: copy (*[[VAL_REF]]); + // CHECK-NOT: copy (*[[VAL_REF]]); // CHECK: _0 = move [[RET]] let val_alias: &Value = get(val); let mut stop = false; diff --git a/tests/pretty/hir-fn-variadic.pp b/tests/pretty/hir-fn-variadic.pp index c0f5b7069a2d..8cbd8f41b646 100644 --- a/tests/pretty/hir-fn-variadic.pp +++ b/tests/pretty/hir-fn-variadic.pp @@ -16,12 +16,12 @@ unsafe extern "C" fn bar(_: i32, mut va2: ...) -> usize { va2.arg::() } fn main() { fn g1(_: extern "C" fn(_: u8, va: ...)) { } - fn g2(_: extern "C" fn(_: u8, ...)) { } + fn g2(_: extern "C" fn(_: u8, _: ...)) { } fn g3(_: extern "C" fn(u8, va: ...)) { } - fn g4(_: extern "C" fn(u8, ...)) { } + fn g4(_: extern "C" fn(u8, _: ...)) { } fn g5(_: extern "C" fn(va: ...)) { } - fn g6(_: extern "C" fn(...)) { } + fn g6(_: extern "C" fn(_: ...)) { } { let _ = diff --git a/tests/pretty/hir-fn-variadic.rs b/tests/pretty/hir-fn-variadic.rs index 99aa402c480b..ce1b0f835ab2 100644 --- a/tests/pretty/hir-fn-variadic.rs +++ b/tests/pretty/hir-fn-variadic.rs @@ -14,16 +14,16 @@ pub unsafe extern "C" fn bar(_: i32, mut va2: ...) -> usize { fn main() { fn g1(_: extern "C" fn(_: u8, va: ...)) {} - fn g2(_: extern "C" fn(_: u8, ...)) {} + fn g2(_: extern "C" fn(_: u8, _: ...)) {} fn g3(_: extern "C" fn(u8, va: ...)) {} - fn g4(_: extern "C" fn(u8, ...)) {} + fn g4(_: extern "C" fn(u8, _: ...)) {} fn g5(_: extern "C" fn(va: ...)) {} - fn g6(_: extern "C" fn(...)) {} + fn g6(_: extern "C" fn(_: ...)) {} _ = { unsafe extern "C" fn f1(_: u8, va: ...) {} }; - _ = { unsafe extern "C" fn f2(_: u8, ...) {} }; + _ = { unsafe extern "C" fn f2(_: u8, _: ...) {} }; _ = { unsafe extern "C" fn f5(va: ...) {} }; - _ = { unsafe extern "C" fn f6(...) {} }; + _ = { unsafe extern "C" fn f6(_: ...) {} }; } diff --git a/tests/pretty/pin-ergonomics-hir.pp b/tests/pretty/pin-ergonomics-hir.pp index beca5988017d..127cb531cece 100644 --- a/tests/pretty/pin-ergonomics-hir.pp +++ b/tests/pretty/pin-ergonomics-hir.pp @@ -41,4 +41,7 @@ fn bar() { foo_const(x); } +fn patterns<'a>(&pin mut x: Pin<&'_ mut i32>, &pin const y: Pin<&'a i32>, + ref pin mut z: i32, ref pin const w: i32) { } + fn main() { } diff --git a/tests/pretty/pin-ergonomics-hir.rs b/tests/pretty/pin-ergonomics-hir.rs index 5f2158258f07..a5ccf7253a8e 100644 --- a/tests/pretty/pin-ergonomics-hir.rs +++ b/tests/pretty/pin-ergonomics-hir.rs @@ -37,4 +37,11 @@ fn bar() { foo_const(x); } +fn patterns<'a>( + &pin mut x: Pin<&mut i32>, + &pin const y: Pin<&'a i32>, + ref pin mut z: i32, + ref pin const w: i32, +) {} + fn main() { } diff --git a/tests/pretty/pin-ergonomics.rs b/tests/pretty/pin-ergonomics.rs index 8e8ced791b13..87f102d7c890 100644 --- a/tests/pretty/pin-ergonomics.rs +++ b/tests/pretty/pin-ergonomics.rs @@ -34,4 +34,7 @@ fn bar() { foo_const(x); } +fn patterns<'a>(&pin mut x: &pin mut i32, &pin const y: &'a pin const i32, + ref pin mut z: i32, ref pin const w: i32) {} + fn main() {} diff --git a/tests/run-make/crate-loading-crate-depends-on-itself/foo.stderr b/tests/run-make/crate-loading-crate-depends-on-itself/foo.stderr index 9433a0ba00e8..fa71a3142b05 100644 --- a/tests/run-make/crate-loading-crate-depends-on-itself/foo.stderr +++ b/tests/run-make/crate-loading-crate-depends-on-itself/foo.stderr @@ -7,22 +7,19 @@ error[E0277]: the trait bound `foo::Struct: Trait` is not satisfied note: there are multiple different versions of crate `foo` in the dependency graph --> foo-current.rs:7:1 | - 4 | extern crate foo; - | ----------------- one version of crate `foo` used here, as a direct dependency of the current crate - 5 | - 6 | pub struct Struct; - | ----------------- this type implements the required trait 7 | pub trait Trait {} - | ^^^^^^^^^^^^^^^ this is the required trait + | ^^^^^^^^^^^^^^^ this is the expected trait | ::: foo-prev.rs:X:Y | - 4 | pub struct Struct; - | ----------------- this type doesn't implement the required trait 5 | pub trait Trait {} | --------------- this is the found trait - = note: two types coming from two different versions of the same crate are different types even if they look the same = help: you can use `cargo tree` to explore your dependency tree +help: the trait `Trait` is implemented for `Struct` + --> foo-current.rs:8:1 + | + 8 | impl Trait for Struct {} + | ^^^^^^^^^^^^^^^^^^^^^ note: required by a bound in `check_trait` --> foo-current.rs:10:19 | diff --git a/tests/run-make/crate-loading/multiple-dep-versions.stderr b/tests/run-make/crate-loading/multiple-dep-versions.stderr index dea08bb96c97..235a44a8ce89 100644 --- a/tests/run-make/crate-loading/multiple-dep-versions.stderr +++ b/tests/run-make/crate-loading/multiple-dep-versions.stderr @@ -9,26 +9,19 @@ LL | do_something(Type); note: there are multiple different versions of crate `dependency` in the dependency graph --> replaced | -LL | pub struct Type(pub i32); - | --------------- this type implements the required trait LL | pub trait Trait { - | ^^^^^^^^^^^^^^^ this is the required trait + | ^^^^^^^^^^^^^^^ this is the expected trait | ::: replaced | -LL | extern crate dep_2_reexport; - | ---------------------------- one version of crate `dependency` used here, as a dependency of crate `foo` -LL | extern crate dependency; - | ------------------------ one version of crate `dependency` used here, as a direct dependency of the current crate - | - ::: replaced - | -LL | pub struct Type; - | --------------- this type doesn't implement the required trait LL | pub trait Trait { | --------------- this is the found trait - = note: two types coming from two different versions of the same crate are different types even if they look the same = help: you can use `cargo tree` to explore your dependency tree +help: the trait `Trait` is implemented for `dependency::Type` + --> replaced + | +LL | impl Trait for Type { + | ^^^^^^^^^^^^^^^^^^^ note: required by a bound in `do_something` --> replaced | @@ -45,19 +38,13 @@ note: there are multiple different versions of crate `dependency` in the depende --> replaced | LL | pub trait Trait { - | ^^^^^^^^^^^^^^^ this is the trait that is needed -LL | fn foo(&self); - | -------------- the method is available for `dep_2_reexport::Type` here - | - ::: replaced - | -LL | use dependency::{Trait, do_something, do_something_trait, do_something_type}; - | ----- `Trait` imported here doesn't correspond to the right version of crate `dependency` + | ^^^^^^^^^^^^^^^ this is the expected trait | ::: replaced | LL | pub trait Trait { | --------------- this is the trait that was imported + = help: you can use `cargo tree` to explore your dependency tree error[E0599]: no function or associated item named `bar` found for struct `dep_2_reexport::Type` in the current scope --> replaced @@ -69,20 +56,13 @@ note: there are multiple different versions of crate `dependency` in the depende --> replaced | LL | pub trait Trait { - | ^^^^^^^^^^^^^^^ this is the trait that is needed -LL | fn foo(&self); -LL | fn bar(); - | --------- the associated function is available for `dep_2_reexport::Type` here - | - ::: replaced - | -LL | use dependency::{Trait, do_something, do_something_trait, do_something_type}; - | ----- `Trait` imported here doesn't correspond to the right version of crate `dependency` + | ^^^^^^^^^^^^^^^ this is the expected trait | ::: replaced | LL | pub trait Trait { | --------------- this is the trait that was imported + = help: you can use `cargo tree` to explore your dependency tree error[E0277]: the trait bound `OtherType: Trait` is not satisfied --> replaced @@ -96,25 +76,18 @@ note: there are multiple different versions of crate `dependency` in the depende --> replaced | LL | pub trait Trait { - | ^^^^^^^^^^^^^^^ this is the required trait - | - ::: replaced - | -LL | extern crate dep_2_reexport; - | ---------------------------- one version of crate `dependency` used here, as a dependency of crate `foo` -LL | extern crate dependency; - | ------------------------ one version of crate `dependency` used here, as a direct dependency of the current crate - | - ::: replaced - | -LL | pub struct OtherType; - | -------------------- this type doesn't implement the required trait + | ^^^^^^^^^^^^^^^ this is the expected trait | ::: replaced | LL | pub trait Trait { | --------------- this is the found trait = help: you can use `cargo tree` to explore your dependency tree +help: the trait `Trait` is implemented for `dependency::Type` + --> replaced + | +LL | impl Trait for Type { + | ^^^^^^^^^^^^^^^^^^^ note: required by a bound in `do_something` --> replaced | @@ -129,23 +102,16 @@ LL | do_something_type(Type); | | | arguments to this function are incorrect | -note: two different versions of crate `dependency` are being used; two types coming from two different versions of the same crate are different types even if they look the same +note: there are multiple different versions of crate `dependency` in the dependency graph --> replaced | LL | pub struct Type(pub i32); - | ^^^^^^^^^^^^^^^ this is the expected type `dependency::Type` + | ^^^^^^^^^^^^^^^ this is the expected type | ::: replaced | LL | pub struct Type; - | ^^^^^^^^^^^^^^^ this is the found type `dep_2_reexport::Type` - | - ::: replaced - | -LL | extern crate dep_2_reexport; - | ---------------------------- one version of crate `dependency` used here, as a dependency of crate `foo` -LL | extern crate dependency; - | ------------------------ one version of crate `dependency` used here, as a direct dependency of the current crate + | --------------- this is the found type = help: you can use `cargo tree` to explore your dependency tree note: function defined here --> replaced @@ -161,23 +127,16 @@ LL | do_something_trait(Box::new(Type) as Box); | | | arguments to this function are incorrect | -note: two different versions of crate `dependency` are being used; two types coming from two different versions of the same crate are different types even if they look the same +note: there are multiple different versions of crate `dependency` in the dependency graph --> replaced | LL | pub trait Trait2 {} - | ^^^^^^^^^^^^^^^^ this is the expected trait `dependency::Trait2` + | ^^^^^^^^^^^^^^^^ this is the expected trait | ::: replaced | LL | pub trait Trait2 {} - | ^^^^^^^^^^^^^^^^ this is the found trait `dep_2_reexport::Trait2` - | - ::: replaced - | -LL | extern crate dep_2_reexport; - | ---------------------------- one version of crate `dependency` used here, as a dependency of crate `foo` -LL | extern crate dependency; - | ------------------------ one version of crate `dependency` used here, as a direct dependency of the current crate + | ---------------- this is the found trait = help: you can use `cargo tree` to explore your dependency tree note: function defined here --> replaced diff --git a/tests/run-make/duplicate-dependency/main.stderr b/tests/run-make/duplicate-dependency/main.stderr index 36d54988788f..7c43dc261e7b 100644 --- a/tests/run-make/duplicate-dependency/main.stderr +++ b/tests/run-make/duplicate-dependency/main.stderr @@ -11,7 +11,7 @@ help: item with same name found | LL | pub struct Foo; | ^^^^^^^^^^^^^^ - = note: perhaps two different versions of crate `foo` are being used? + = note: there are multiple different versions of crate `foo` in the dependency graph = note: required for `Bar` to implement `Into` note: required by a bound in `into_foo` --> $DIR/re-export-foo.rs:3:25 diff --git a/tests/run-make/rustdoc-test-builder/builder.rs b/tests/run-make/rustdoc-test-builder/builder.rs new file mode 100644 index 000000000000..b5a2c8ae346e --- /dev/null +++ b/tests/run-make/rustdoc-test-builder/builder.rs @@ -0,0 +1,23 @@ +use std::ffi::OsString; +use std::path::PathBuf; +use std::process::{self, Command}; +use std::{env, fs}; + +fn main() { + let args: Vec = env::args_os().collect(); + let log_path = env::var_os("BUILDER_LOG").map(PathBuf::from).expect("BUILDER_LOG must be set"); + let real_rustc = env::var_os("REAL_RUSTC").expect("REAL_RUSTC must be set"); + + let log_contents = + args.iter().skip(1).map(|arg| arg.to_string_lossy()).collect::>().join("\n"); + fs::write(&log_path, log_contents).expect("failed to write builder log"); + + let status = Command::new(real_rustc) + .args(args.iter().skip(1)) + .status() + .expect("failed to invoke real rustc"); + + if !status.success() { + process::exit(status.code().unwrap_or(1)); + } +} diff --git a/tests/run-make/rustdoc-test-builder/doctest.rs b/tests/run-make/rustdoc-test-builder/doctest.rs new file mode 100644 index 000000000000..1a4ff6a2fdd7 --- /dev/null +++ b/tests/run-make/rustdoc-test-builder/doctest.rs @@ -0,0 +1,3 @@ +//! ```rust +//! assert_eq!(2 + 2, 4); +//! ``` diff --git a/tests/run-make/rustdoc-test-builder/rmake.rs b/tests/run-make/rustdoc-test-builder/rmake.rs index 9aa8143dc1dc..d10a3c92cae4 100644 --- a/tests/run-make/rustdoc-test-builder/rmake.rs +++ b/tests/run-make/rustdoc-test-builder/rmake.rs @@ -1,11 +1,14 @@ -// This test ensures that if the rustdoc test binary is not executable, it will -// gracefully fail and not panic. +// This test validates the `--test-builder` rustdoc option. +// It ensures that: +// 1. When the test-builder path points to a non-executable file, rustdoc gracefully fails +// 2. When the test-builder path points to a valid executable, it receives rustc arguments //@ needs-target-std -use run_make_support::{path, rfs, rustdoc}; +use run_make_support::{bare_rustc, path, rfs, rustc_path, rustdoc, target}; fn main() { + // Test 1: Verify that a non-executable test-builder fails gracefully let absolute_path = path("foo.rs").canonicalize().expect("failed to get absolute path"); let output = rustdoc() .input("foo.rs") @@ -19,4 +22,37 @@ fn main() { output.assert_stdout_contains("Failed to spawn "); // ... and that we didn't panic. output.assert_not_ice(); + + // Some targets (for example wasm) cannot execute doctests directly even with a runner, + // so only exercise the success path when the target can run on the host. + if target().contains("wasm") || std::env::var_os("REMOTE_TEST_CLIENT").is_some() { + return; + } + + // Test 2: Verify that a valid test-builder is invoked with correct arguments + // Build a custom test-builder that logs its arguments and forwards to rustc. + // Use `bare_rustc` so we compile for the host architecture even in cross builds. + let builder_bin = path("builder-bin"); + bare_rustc().input("builder.rs").output(&builder_bin).run(); + + let log_path = path("builder.log"); + let _ = std::fs::remove_file(&log_path); + + // Run rustdoc with our custom test-builder + rustdoc() + .input("doctest.rs") + .arg("--test") + .arg("-Zunstable-options") + .arg("--test-builder") + .arg(&builder_bin) + .env("REAL_RUSTC", rustc_path()) + .env("BUILDER_LOG", &log_path) + .run(); + + // Verify the custom builder was invoked with rustc-style arguments + let log_contents = rfs::read_to_string(&log_path); + assert!( + log_contents.contains("--crate-type"), + "expected builder to receive rustc arguments, got:\n{log_contents}" + ); } diff --git a/tests/rustdoc-ui/deprecated-attrs.rs b/tests/rustdoc-ui/deprecated-attrs.rs index dcf8a52de41d..26aaf0d46808 100644 --- a/tests/rustdoc-ui/deprecated-attrs.rs +++ b/tests/rustdoc-ui/deprecated-attrs.rs @@ -4,14 +4,12 @@ //~^ ERROR unknown `doc` attribute `no_default_passes` //~| NOTE no longer functions //~| NOTE see issue #44136 -//~| HELP you may want to use `doc(document_private_items)` //~| NOTE `doc(no_default_passes)` is now a no-op //~| NOTE `#[deny(invalid_doc_attributes)]` on by default #![doc(passes = "collapse-docs unindent-comments")] //~^ ERROR unknown `doc` attribute `passes` //~| NOTE no longer functions //~| NOTE see issue #44136 -//~| HELP you may want to use `doc(document_private_items)` //~| NOTE `doc(passes)` is now a no-op #![doc(plugins = "xxx")] //~^ ERROR unknown `doc` attribute `plugins` diff --git a/tests/rustdoc-ui/deprecated-attrs.stderr b/tests/rustdoc-ui/deprecated-attrs.stderr index 3e9820522338..323257f944ce 100644 --- a/tests/rustdoc-ui/deprecated-attrs.stderr +++ b/tests/rustdoc-ui/deprecated-attrs.stderr @@ -10,22 +10,20 @@ LL | #![doc(no_default_passes)] | ^^^^^^^^^^^^^^^^^ no longer functions | = note: `doc` attribute `no_default_passes` no longer functions; see issue #44136 - = help: you may want to use `doc(document_private_items)` = note: `doc(no_default_passes)` is now a no-op = note: `#[deny(invalid_doc_attributes)]` on by default error: unknown `doc` attribute `passes` - --> $DIR/deprecated-attrs.rs:10:8 + --> $DIR/deprecated-attrs.rs:9:8 | LL | #![doc(passes = "collapse-docs unindent-comments")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no longer functions | = note: `doc` attribute `passes` no longer functions; see issue #44136 - = help: you may want to use `doc(document_private_items)` = note: `doc(passes)` is now a no-op error: unknown `doc` attribute `plugins` - --> $DIR/deprecated-attrs.rs:16:8 + --> $DIR/deprecated-attrs.rs:14:8 | LL | #![doc(plugins = "xxx")] | ^^^^^^^^^^^^^^^ no longer functions diff --git a/tests/rustdoc/jump-to-def-assoc-items.rs b/tests/rustdoc/jump-to-def/assoc-items.rs similarity index 75% rename from tests/rustdoc/jump-to-def-assoc-items.rs rename to tests/rustdoc/jump-to-def/assoc-items.rs index 0dfe3c7bdc15..a434fa7e6053 100644 --- a/tests/rustdoc/jump-to-def-assoc-items.rs +++ b/tests/rustdoc/jump-to-def/assoc-items.rs @@ -4,7 +4,7 @@ #![crate_name = "foo"] -//@ has 'src/foo/jump-to-def-assoc-items.rs.html' +//@ has 'src/foo/assoc-items.rs.html' pub trait Trait { type T; @@ -26,8 +26,9 @@ impl C { pub fn wat() {} } -//@ has - '//a[@href="{{channel}}/core/fmt/macros/macro.Debug.html"]' 'Debug' -//@ has - '//a[@href="{{channel}}/core/cmp/macro.PartialEq.html"]' 'PartialEq' +// These two links must not change and in particular must contain `/derive.`! +//@ has - '//a[@href="{{channel}}/core/fmt/macros/derive.Debug.html"]' 'Debug' +//@ has - '//a[@href="{{channel}}/core/cmp/derive.PartialEq.html"]' 'PartialEq' #[derive(Debug, PartialEq)] pub struct Bar; impl Trait for Bar { diff --git a/tests/rustdoc/jump-to-def-ice-assoc-types.rs b/tests/rustdoc/jump-to-def/assoc-types.rs similarity index 85% rename from tests/rustdoc/jump-to-def-ice-assoc-types.rs rename to tests/rustdoc/jump-to-def/assoc-types.rs index 9915c53668f0..f430eaf16389 100644 --- a/tests/rustdoc/jump-to-def-ice-assoc-types.rs +++ b/tests/rustdoc/jump-to-def/assoc-types.rs @@ -5,7 +5,7 @@ #![crate_name = "foo"] -//@ has 'src/foo/jump-to-def-ice-assoc-types.rs.html' +//@ has 'src/foo/assoc-types.rs.html' pub trait Trait { type Node; diff --git a/tests/rustdoc/jump-to-def/auxiliary/jump-to-def-macro.rs b/tests/rustdoc/jump-to-def/auxiliary/symbols.rs similarity index 100% rename from tests/rustdoc/jump-to-def/auxiliary/jump-to-def-macro.rs rename to tests/rustdoc/jump-to-def/auxiliary/symbols.rs diff --git a/tests/rustdoc/jump-to-def/derive-macro.rs b/tests/rustdoc/jump-to-def/derive-macro.rs new file mode 100644 index 000000000000..24deac047883 --- /dev/null +++ b/tests/rustdoc/jump-to-def/derive-macro.rs @@ -0,0 +1,24 @@ +// This test ensures that the same link is generated in both intra-doc links +// and in jump to def links. + +//@ compile-flags: -Zunstable-options --generate-link-to-definition + +#![crate_name = "foo"] + +// First we check intra-doc links. +//@ has 'foo/struct.Bar.html' +//@ has - '//a[@href="{{channel}}/core/fmt/macros/derive.Debug.html"]' 'Debug' +//@ has - '//a[@href="{{channel}}/core/cmp/derive.PartialEq.html"]' 'PartialEq' + +// We also check the "title" attributes. +//@ has - '//a[@href="{{channel}}/core/fmt/macros/derive.Debug.html"]/@title' 'derive core::fmt::macros::Debug' +//@ has - '//a[@href="{{channel}}/core/cmp/derive.PartialEq.html"]/@title' 'derive core::cmp::PartialEq' + +// Then we check that they are the same in jump to def. + +/// [Debug][derive@Debug] and [PartialEq][derive@PartialEq] +//@ has 'src/foo/derive-macro.rs.html' +//@ has - '//a[@href="{{channel}}/core/fmt/macros/derive.Debug.html"]' 'Debug' +//@ has - '//a[@href="{{channel}}/core/cmp/derive.PartialEq.html"]' 'PartialEq' +#[derive(Debug, PartialEq)] +pub struct Bar; diff --git a/tests/rustdoc/jump-to-def/jump-to-def-doc-links-calls.rs b/tests/rustdoc/jump-to-def/doc-links-calls.rs similarity index 90% rename from tests/rustdoc/jump-to-def/jump-to-def-doc-links-calls.rs rename to tests/rustdoc/jump-to-def/doc-links-calls.rs index 55e59f23b6f2..05a5051a762e 100644 --- a/tests/rustdoc/jump-to-def/jump-to-def-doc-links-calls.rs +++ b/tests/rustdoc/jump-to-def/doc-links-calls.rs @@ -2,7 +2,7 @@ #![crate_name = "foo"] -//@ has 'src/foo/jump-to-def-doc-links-calls.rs.html' +//@ has 'src/foo/doc-links-calls.rs.html' //@ has - '//a[@href="../../foo/struct.Bar.html"]' 'Bar' pub struct Bar; diff --git a/tests/rustdoc/jump-to-def/jump-to-def-doc-links.rs b/tests/rustdoc/jump-to-def/doc-links.rs similarity index 95% rename from tests/rustdoc/jump-to-def/jump-to-def-doc-links.rs rename to tests/rustdoc/jump-to-def/doc-links.rs index 2abb52e0a009..f1c5c5066382 100644 --- a/tests/rustdoc/jump-to-def/jump-to-def-doc-links.rs +++ b/tests/rustdoc/jump-to-def/doc-links.rs @@ -2,7 +2,7 @@ #![crate_name = "foo"] -//@ has 'src/foo/jump-to-def-doc-links.rs.html' +//@ has 'src/foo/doc-links.rs.html' //@ has - '//a[@href="../../foo/struct.Bar.html"]' 'Bar' //@ has - '//a[@href="../../foo/struct.Foo.html"]' 'Foo' diff --git a/tests/rustdoc/jump-to-def/jump-to-def-macro.rs b/tests/rustdoc/jump-to-def/jump-to-def-macro.rs deleted file mode 100644 index 680477937c67..000000000000 --- a/tests/rustdoc/jump-to-def/jump-to-def-macro.rs +++ /dev/null @@ -1,15 +0,0 @@ -//@ aux-build:jump-to-def-macro.rs -//@ build-aux-docs -//@ compile-flags: -Zunstable-options --generate-link-to-definition - -#![crate_name = "foo"] - -//@ has 'src/foo/jump-to-def-macro.rs.html' - -#[macro_use] -extern crate jump_to_def_macro; - -//@ has - '//a[@href="../../jump_to_def_macro/macro.symbols.html"]' 'symbols!' -symbols! { - A = 12 -} diff --git a/tests/rustdoc/jump-to-def/macro.rs b/tests/rustdoc/jump-to-def/macro.rs new file mode 100644 index 000000000000..fcf0c7f570d4 --- /dev/null +++ b/tests/rustdoc/jump-to-def/macro.rs @@ -0,0 +1,15 @@ +//@ aux-build:symbols.rs +//@ build-aux-docs +//@ compile-flags: -Zunstable-options --generate-link-to-definition + +#![crate_name = "foo"] + +//@ has 'src/foo/macro.rs.html' + +#[macro_use] +extern crate symbols; + +//@ has - '//a[@href="../../symbols/macro.symbols.html"]' 'symbols!' +symbols! { + A = 12 +} diff --git a/tests/rustdoc/jump-to-def-ice.rs b/tests/rustdoc/jump-to-def/no-body-items.rs similarity index 89% rename from tests/rustdoc/jump-to-def-ice.rs rename to tests/rustdoc/jump-to-def/no-body-items.rs index 5578b9af3d74..e74640072146 100644 --- a/tests/rustdoc/jump-to-def-ice.rs +++ b/tests/rustdoc/jump-to-def/no-body-items.rs @@ -5,7 +5,7 @@ #![crate_name = "foo"] -//@ has 'src/foo/jump-to-def-ice.rs.html' +//@ has 'src/foo/no-body-items.rs.html' pub trait A { type T; diff --git a/tests/rustdoc/jump-to-def/jump-to-non-local-method.rs b/tests/rustdoc/jump-to-def/non-local-method.rs similarity index 96% rename from tests/rustdoc/jump-to-def/jump-to-non-local-method.rs rename to tests/rustdoc/jump-to-def/non-local-method.rs index 1d6d6b8d18fa..c601f3259c4d 100644 --- a/tests/rustdoc/jump-to-def/jump-to-non-local-method.rs +++ b/tests/rustdoc/jump-to-def/non-local-method.rs @@ -2,7 +2,7 @@ #![crate_name = "foo"] -//@ has 'src/foo/jump-to-non-local-method.rs.html' +//@ has 'src/foo/non-local-method.rs.html' //@ has - '//a[@href="{{channel}}/core/sync/atomic/struct.AtomicIsize.html"]' 'std::sync::atomic::AtomicIsize' use std::sync::atomic::AtomicIsize; diff --git a/tests/rustdoc/jump-to-def/jump-to-def-pats.rs b/tests/rustdoc/jump-to-def/patterns.rs similarity index 96% rename from tests/rustdoc/jump-to-def/jump-to-def-pats.rs rename to tests/rustdoc/jump-to-def/patterns.rs index 852eba208db0..e6b354eacd12 100644 --- a/tests/rustdoc/jump-to-def/jump-to-def-pats.rs +++ b/tests/rustdoc/jump-to-def/patterns.rs @@ -4,7 +4,7 @@ #![crate_name = "foo"] -//@ has 'src/foo/jump-to-def-pats.rs.html' +//@ has 'src/foo/patterns.rs.html' use std::fmt; diff --git a/tests/rustdoc/jump-to-def/jump-to-def-prelude-types.rs b/tests/rustdoc/jump-to-def/prelude-types.rs similarity index 94% rename from tests/rustdoc/jump-to-def/jump-to-def-prelude-types.rs rename to tests/rustdoc/jump-to-def/prelude-types.rs index 43617b1bc9df..2476d18e0b62 100644 --- a/tests/rustdoc/jump-to-def/jump-to-def-prelude-types.rs +++ b/tests/rustdoc/jump-to-def/prelude-types.rs @@ -4,7 +4,7 @@ #![crate_name = "foo"] -//@ has 'src/foo/jump-to-def-prelude-types.rs.html' +//@ has 'src/foo/prelude-types.rs.html' // FIXME: would be nice to be able to check both the class and the href at the same time so // we could check the text as well... //@ has - '//a[@class="prelude-ty"]/@href' '{{channel}}/core/result/enum.Result.html' diff --git a/tests/ui/abi/stack-protector.rs b/tests/ui/abi/stack-protector.rs index 928b49c0eea5..dd0d0d43182e 100644 --- a/tests/ui/abi/stack-protector.rs +++ b/tests/ui/abi/stack-protector.rs @@ -6,6 +6,8 @@ //@ compile-flags: -g //@ ignore-backends: gcc +#![allow(function_casts_as_integer)] + use std::env; use std::process::{Command, ExitStatus}; diff --git a/tests/ui/array-slice-vec/slice-mut-2.stderr b/tests/ui/array-slice-vec/slice-mut-2.stderr index 228417c873db..49639ff1d227 100644 --- a/tests/ui/array-slice-vec/slice-mut-2.stderr +++ b/tests/ui/array-slice-vec/slice-mut-2.stderr @@ -2,7 +2,7 @@ error[E0596]: cannot borrow `*x` as mutable, as it is behind a `&` reference --> $DIR/slice-mut-2.rs:7:18 | LL | let _ = &mut x[2..4]; - | ^ `x` is a `&` reference, so the data it refers to cannot be borrowed as mutable + | ^ `x` is a `&` reference, so it cannot be borrowed as mutable | help: consider changing this binding's type | diff --git a/tests/ui/associated-consts/traits-associated-consts-ice-56870.rs b/tests/ui/associated-consts/traits-associated-consts-ice-56870.rs index 0c5a2b847730..8dec3982ef20 100644 --- a/tests/ui/associated-consts/traits-associated-consts-ice-56870.rs +++ b/tests/ui/associated-consts/traits-associated-consts-ice-56870.rs @@ -2,6 +2,8 @@ //@ build-pass // Regression test for #56870: Internal compiler error (traits & associated consts) +#![allow(function_casts_as_integer)] + use std::fmt::Debug; pub trait Foo { diff --git a/tests/ui/associated-inherent-types/fall-back-to-trait-candidate.rs b/tests/ui/associated-inherent-types/fall-back-to-trait-candidate.rs new file mode 100644 index 000000000000..6c3eee0f7ec7 --- /dev/null +++ b/tests/ui/associated-inherent-types/fall-back-to-trait-candidate.rs @@ -0,0 +1,25 @@ +// Ensure that IAT selection doesn't hard error on associated type paths that could refer to +// an inherent associated type if we can't find an applicable inherent candidate since there +// might still be valid trait associated type candidates. +// +// FIXME(#142006): This only covers the bare minimum, we also need to disqualify inherent +// candidates if they're inaccessible or if the impl headers don't match / apply. +// +// issue: +//@ check-pass + +#![feature(inherent_associated_types)] +#![expect(incomplete_features)] + +struct Type; +trait Trait { type AssocTy; fn scope(); } + +impl Trait for Type { + type AssocTy = (); + + fn scope() { + let (): Self::AssocTy; + } +} + +fn main() { ::scope(); } diff --git a/tests/ui/associated-inherent-types/not-found-self-type-differs-shadowing-trait-item.rs b/tests/ui/associated-inherent-types/not-found-self-type-differs-shadowing-trait-item.rs deleted file mode 100644 index 337fd8fa00c5..000000000000 --- a/tests/ui/associated-inherent-types/not-found-self-type-differs-shadowing-trait-item.rs +++ /dev/null @@ -1,31 +0,0 @@ -#![feature(inherent_associated_types)] -#![allow(incomplete_features)] - -// Check that it's okay to report “[inherent] associated type […] not found” for inherent associated -// type candidates that are not applicable (due to unsuitable Self type) even if there exists a -// “shadowed” associated type from a trait with the same name since its use would be ambiguous -// anyway if the IAT didn't exist. -// FIXME(inherent_associated_types): Figure out which error would be more helpful here. - -//@ revisions: shadowed uncovered - -struct S(T); - -trait Tr { - type Pr; -} - -impl Tr for S { - type Pr = (); -} - -#[cfg(shadowed)] -impl S<()> { - type Pr = i32; -} - -fn main() { - let _: S::::Pr = (); - //[shadowed]~^ ERROR associated type `Pr` not found - //[uncovered]~^^ ERROR associated type `Pr` not found -} diff --git a/tests/ui/associated-inherent-types/not-found-self-type-differs-shadowing-trait-item.shadowed.stderr b/tests/ui/associated-inherent-types/not-found-self-type-differs-shadowing-trait-item.shadowed.stderr deleted file mode 100644 index a247d6d5b45b..000000000000 --- a/tests/ui/associated-inherent-types/not-found-self-type-differs-shadowing-trait-item.shadowed.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error[E0220]: associated type `Pr` not found for `S` in the current scope - --> $DIR/not-found-self-type-differs-shadowing-trait-item.rs:28:23 - | -LL | struct S(T); - | ----------- associated type `Pr` not found for this struct -... -LL | let _: S::::Pr = (); - | ^^ associated item not found in `S` - | - = note: the associated type was found for - - `S<()>` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0220`. diff --git a/tests/ui/associated-inherent-types/not-found-self-type-differs-shadowing-trait-item.uncovered.stderr b/tests/ui/associated-inherent-types/not-found-self-type-differs-shadowing-trait-item.uncovered.stderr deleted file mode 100644 index f35158c5b410..000000000000 --- a/tests/ui/associated-inherent-types/not-found-self-type-differs-shadowing-trait-item.uncovered.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error[E0220]: associated type `Pr` not found for `S` in the current scope - --> $DIR/not-found-self-type-differs-shadowing-trait-item.rs:28:23 - | -LL | struct S(T); - | ----------- associated type `Pr` not found for this struct -... -LL | let _: S::::Pr = (); - | ^^ associated item not found in `S` - | - = note: the associated type was found for - - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0220`. diff --git a/tests/ui/associated-inherent-types/prefer-inherent-over-trait.rs b/tests/ui/associated-inherent-types/prefer-inherent-over-trait.rs new file mode 100644 index 000000000000..6c81ef7409d4 --- /dev/null +++ b/tests/ui/associated-inherent-types/prefer-inherent-over-trait.rs @@ -0,0 +1,28 @@ +#![feature(inherent_associated_types)] +#![expect(incomplete_features)] + +// Ensure that prefer inherent associated types over trait associated types +// (assuming the impl headers match and they're accessible). +//@ check-pass + +struct Adt; + +impl Adt { + type Ty = (); +} + +trait Trait { + type Ty; + fn scope(); +} + +impl Trait for Adt { + type Ty = i32; + fn scope() { + // We prefer the inherent assoc ty `Adt::Ty` (`()`) over the + // trait assoc ty `::Ty` (`i32`). + let (): Self::Ty; + } +} + +fn main() {} diff --git a/tests/ui/attributes/proc-macro-unsafe.rs b/tests/ui/attributes/proc-macro-unsafe.rs new file mode 100644 index 000000000000..7849df825609 --- /dev/null +++ b/tests/ui/attributes/proc-macro-unsafe.rs @@ -0,0 +1,9 @@ +//@ proc-macro: external-macro-use.rs + +extern crate external_macro_use; + +#[unsafe(external_macro_use::a)] +//~^ ERROR unnecessary `unsafe` on safe attribute +fn f() {} + +fn main() {} diff --git a/tests/ui/attributes/proc-macro-unsafe.stderr b/tests/ui/attributes/proc-macro-unsafe.stderr new file mode 100644 index 000000000000..ccc19bb01d2f --- /dev/null +++ b/tests/ui/attributes/proc-macro-unsafe.stderr @@ -0,0 +1,8 @@ +error: unnecessary `unsafe` on safe attribute + --> $DIR/proc-macro-unsafe.rs:5:3 + | +LL | #[unsafe(external_macro_use::a)] + | ^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/attributes/unsafe/double-unsafe-attributes.rs b/tests/ui/attributes/unsafe/double-unsafe-attributes.rs index c0181d960539..894d1327da79 100644 --- a/tests/ui/attributes/unsafe/double-unsafe-attributes.rs +++ b/tests/ui/attributes/unsafe/double-unsafe-attributes.rs @@ -1,7 +1,7 @@ #[unsafe(unsafe(no_mangle))] //~^ ERROR expected identifier, found keyword `unsafe` //~| ERROR cannot find attribute `r#unsafe` in this scope -//~| ERROR unnecessary `unsafe` +//~| ERROR `r#unsafe` is not an unsafe attribute fn a() {} fn main() {} diff --git a/tests/ui/attributes/unsafe/double-unsafe-attributes.stderr b/tests/ui/attributes/unsafe/double-unsafe-attributes.stderr index 846800daa546..0825cf794083 100644 --- a/tests/ui/attributes/unsafe/double-unsafe-attributes.stderr +++ b/tests/ui/attributes/unsafe/double-unsafe-attributes.stderr @@ -9,11 +9,13 @@ help: escape `unsafe` to use it as an identifier LL | #[unsafe(r#unsafe(no_mangle))] | ++ -error: unnecessary `unsafe` on safe attribute +error: `r#unsafe` is not an unsafe attribute --> $DIR/double-unsafe-attributes.rs:1:3 | LL | #[unsafe(unsafe(no_mangle))] - | ^^^^^^ + | ^^^^^^ this is not an unsafe attribute + | + = note: extraneous unsafe is not allowed in attributes error: cannot find attribute `r#unsafe` in this scope --> $DIR/double-unsafe-attributes.rs:1:10 diff --git a/tests/ui/attributes/unsafe/unsafe-safe-attribute_diagnostic.rs b/tests/ui/attributes/unsafe/unsafe-safe-attribute_diagnostic.rs index d9054248a292..b74dffe9eb18 100644 --- a/tests/ui/attributes/unsafe/unsafe-safe-attribute_diagnostic.rs +++ b/tests/ui/attributes/unsafe/unsafe-safe-attribute_diagnostic.rs @@ -1,4 +1,4 @@ -#[unsafe(diagnostic::on_unimplemented( //~ ERROR: unnecessary `unsafe` +#[unsafe(diagnostic::on_unimplemented( //~ ERROR: `diagnostic::on_unimplemented` is not an unsafe attribute message = "testing", ))] trait Foo {} diff --git a/tests/ui/attributes/unsafe/unsafe-safe-attribute_diagnostic.stderr b/tests/ui/attributes/unsafe/unsafe-safe-attribute_diagnostic.stderr index a7662f5ee6c7..3bc291db5acf 100644 --- a/tests/ui/attributes/unsafe/unsafe-safe-attribute_diagnostic.stderr +++ b/tests/ui/attributes/unsafe/unsafe-safe-attribute_diagnostic.stderr @@ -1,8 +1,10 @@ -error: unnecessary `unsafe` on safe attribute +error: `diagnostic::on_unimplemented` is not an unsafe attribute --> $DIR/unsafe-safe-attribute_diagnostic.rs:1:3 | LL | #[unsafe(diagnostic::on_unimplemented( - | ^^^^^^ + | ^^^^^^ this is not an unsafe attribute + | + = note: extraneous unsafe is not allowed in attributes error: aborting due to 1 previous error diff --git a/tests/ui/borrowck/accidentally-cloning-ref-borrow-error.stderr b/tests/ui/borrowck/accidentally-cloning-ref-borrow-error.stderr index 7e51a4819eef..e7b103eef934 100644 --- a/tests/ui/borrowck/accidentally-cloning-ref-borrow-error.stderr +++ b/tests/ui/borrowck/accidentally-cloning-ref-borrow-error.stderr @@ -2,7 +2,7 @@ error[E0596]: cannot borrow `sm.x` as mutable, as it is behind a `&` reference --> $DIR/accidentally-cloning-ref-borrow-error.rs:32:9 | LL | foo(&mut sm.x); - | ^^^^^^^^^ `sm` is a `&` reference, so the data it refers to cannot be borrowed as mutable + | ^^^^^^^^^ `sm` is a `&` reference, so it cannot be borrowed as mutable | help: `Str` doesn't implement `Clone`, so this call clones the reference `&Str` --> $DIR/accidentally-cloning-ref-borrow-error.rs:31:21 diff --git a/tests/ui/borrowck/argument_number_mismatch_ice.stderr b/tests/ui/borrowck/argument_number_mismatch_ice.stderr index 702cebb86bae..f2f4567f7150 100644 --- a/tests/ui/borrowck/argument_number_mismatch_ice.stderr +++ b/tests/ui/borrowck/argument_number_mismatch_ice.stderr @@ -11,7 +11,7 @@ error[E0594]: cannot assign to `*input`, which is behind a `&` reference --> $DIR/argument_number_mismatch_ice.rs:10:9 | LL | *input = self.0; - | ^^^^^^^^^^^^^^^ `input` is a `&` reference, so the data it refers to cannot be written + | ^^^^^^^^^^^^^^^ `input` is a `&` reference, so it cannot be written to | help: consider changing this to be a mutable reference in the `impl` method and the `trait` definition | diff --git a/tests/ui/borrowck/borrow-raw-address-of-deref-mutability.stderr b/tests/ui/borrowck/borrow-raw-address-of-deref-mutability.stderr index 0a32cccff1d4..d796d541ab20 100644 --- a/tests/ui/borrowck/borrow-raw-address-of-deref-mutability.stderr +++ b/tests/ui/borrowck/borrow-raw-address-of-deref-mutability.stderr @@ -2,7 +2,7 @@ error[E0596]: cannot borrow `*x` as mutable, as it is behind a `&` reference --> $DIR/borrow-raw-address-of-deref-mutability.rs:6:13 | LL | let q = &raw mut *x; - | ^^^^^^^^^^^ `x` is a `&` reference, so the data it refers to cannot be borrowed as mutable + | ^^^^^^^^^^^ `x` is a `&` reference, so it cannot be borrowed as mutable | help: consider changing this to be a mutable reference | @@ -13,7 +13,7 @@ error[E0596]: cannot borrow `*x` as mutable, as it is behind a `*const` pointer --> $DIR/borrow-raw-address-of-deref-mutability.rs:12:13 | LL | let q = &raw mut *x; - | ^^^^^^^^^^^ `x` is a `*const` pointer, so the data it refers to cannot be borrowed as mutable + | ^^^^^^^^^^^ `x` is a `*const` pointer, so it cannot be borrowed as mutable | help: consider specifying this binding's type | diff --git a/tests/ui/borrowck/borrowck-access-permissions.stderr b/tests/ui/borrowck/borrowck-access-permissions.stderr index 87717a532905..376b6bd27126 100644 --- a/tests/ui/borrowck/borrowck-access-permissions.stderr +++ b/tests/ui/borrowck/borrowck-access-permissions.stderr @@ -12,6 +12,9 @@ LL | let mut x = 1; error[E0596]: cannot borrow immutable static item `static_x` as mutable --> $DIR/borrowck-access-permissions.rs:16:19 | +LL | static static_x: i32 = 1; + | -------------------- this `static` cannot be borrowed as mutable +... LL | let _y1 = &mut static_x; | ^^^^^^^^^^^^^ cannot borrow as mutable @@ -30,7 +33,7 @@ error[E0596]: cannot borrow `*ref_x` as mutable, as it is behind a `&` reference --> $DIR/borrowck-access-permissions.rs:36:19 | LL | let _y1 = &mut *ref_x; - | ^^^^^^^^^^^ `ref_x` is a `&` reference, so the data it refers to cannot be borrowed as mutable + | ^^^^^^^^^^^ `ref_x` is a `&` reference, so it cannot be borrowed as mutable | help: consider changing this to be a mutable reference | @@ -41,7 +44,7 @@ error[E0596]: cannot borrow `*ptr_x` as mutable, as it is behind a `*const` poin --> $DIR/borrowck-access-permissions.rs:46:23 | LL | let _y1 = &mut *ptr_x; - | ^^^^^^^^^^^ `ptr_x` is a `*const` pointer, so the data it refers to cannot be borrowed as mutable + | ^^^^^^^^^^^ `ptr_x` is a `*const` pointer, so it cannot be borrowed as mutable | help: consider changing this binding's type | @@ -53,7 +56,7 @@ error[E0596]: cannot borrow `*foo_ref.f` as mutable, as it is behind a `&` refer --> $DIR/borrowck-access-permissions.rs:59:18 | LL | let _y = &mut *foo_ref.f; - | ^^^^^^^^^^^^^^^ `foo_ref` is a `&` reference, so the data it refers to cannot be borrowed as mutable + | ^^^^^^^^^^^^^^^ `foo_ref` is a `&` reference, so it cannot be borrowed as mutable | help: consider changing this to be a mutable reference | diff --git a/tests/ui/borrowck/borrowck-assign-to-andmut-in-aliasable-loc.stderr b/tests/ui/borrowck/borrowck-assign-to-andmut-in-aliasable-loc.stderr index cf0c4127d82f..62d456c5510a 100644 --- a/tests/ui/borrowck/borrowck-assign-to-andmut-in-aliasable-loc.stderr +++ b/tests/ui/borrowck/borrowck-assign-to-andmut-in-aliasable-loc.stderr @@ -2,7 +2,7 @@ error[E0594]: cannot assign to `*s.pointer`, which is behind a `&` reference --> $DIR/borrowck-assign-to-andmut-in-aliasable-loc.rs:9:5 | LL | *s.pointer += 1; - | ^^^^^^^^^^^^^^^ `s` is a `&` reference, so the data it refers to cannot be written + | ^^^^^^^^^^^^^^^ `s` is a `&` reference, so it cannot be written to | help: consider changing this to be a mutable reference | @@ -13,7 +13,7 @@ error[E0594]: cannot assign to `*s.pointer`, which is behind a `&` reference --> $DIR/borrowck-assign-to-andmut-in-aliasable-loc.rs:17:5 | LL | *s.pointer += 1; - | ^^^^^^^^^^^^^^^ `s` is a `&` reference, so the data it refers to cannot be written + | ^^^^^^^^^^^^^^^ `s` is a `&` reference, so it cannot be written to | help: consider changing this to be a mutable reference | diff --git a/tests/ui/borrowck/borrowck-assign-to-constants.stderr b/tests/ui/borrowck/borrowck-assign-to-constants.stderr index 82972b573c6f..6bfed855f95a 100644 --- a/tests/ui/borrowck/borrowck-assign-to-constants.stderr +++ b/tests/ui/borrowck/borrowck-assign-to-constants.stderr @@ -1,6 +1,9 @@ error[E0594]: cannot assign to immutable static item `foo` --> $DIR/borrowck-assign-to-constants.rs:5:5 | +LL | static foo: isize = 5; + | ----------------- this `static` cannot be written to +... LL | foo = 6; | ^^^^^^^ cannot assign diff --git a/tests/ui/borrowck/borrowck-borrow-mut-base-ptr-in-aliasable-loc.stderr b/tests/ui/borrowck/borrowck-borrow-mut-base-ptr-in-aliasable-loc.stderr index 59ef61b19d50..7e516fe89b40 100644 --- a/tests/ui/borrowck/borrowck-borrow-mut-base-ptr-in-aliasable-loc.stderr +++ b/tests/ui/borrowck/borrowck-borrow-mut-base-ptr-in-aliasable-loc.stderr @@ -2,7 +2,7 @@ error[E0594]: cannot assign to `**t1`, which is behind a `&` reference --> $DIR/borrowck-borrow-mut-base-ptr-in-aliasable-loc.rs:9:5 | LL | **t1 = 22; - | ^^^^^^^^^ `t1` is a `&` reference, so the data it refers to cannot be written + | ^^^^^^^^^ `t1` is a `&` reference, so it cannot be written to | help: consider specifying this binding's type | @@ -23,7 +23,7 @@ error[E0596]: cannot borrow `**t0` as mutable, as it is behind a `&` reference --> $DIR/borrowck-borrow-mut-base-ptr-in-aliasable-loc.rs:19:26 | LL | let x: &mut isize = &mut **t0; - | ^^^^^^^^^ `t0` is a `&` reference, so the data it refers to cannot be borrowed as mutable + | ^^^^^^^^^ `t0` is a `&` reference, so it cannot be borrowed as mutable | help: consider changing this to be a mutable reference | diff --git a/tests/ui/borrowck/borrowck-issue-14498.stderr b/tests/ui/borrowck/borrowck-issue-14498.stderr index 12d67d536d95..a79fd3c74f89 100644 --- a/tests/ui/borrowck/borrowck-issue-14498.stderr +++ b/tests/ui/borrowck/borrowck-issue-14498.stderr @@ -2,7 +2,7 @@ error[E0594]: cannot assign to `***p`, which is behind a `&` reference --> $DIR/borrowck-issue-14498.rs:16:5 | LL | ***p = 2; - | ^^^^^^^^ `p` is a `&` reference, so the data it refers to cannot be written + | ^^^^^^^^ `p` is a `&` reference, so it cannot be written to | help: consider changing this to be a mutable reference | diff --git a/tests/ui/borrowck/borrowck-reborrow-from-mut.stderr b/tests/ui/borrowck/borrowck-reborrow-from-mut.stderr index fb3db4e14463..cd576aafb383 100644 --- a/tests/ui/borrowck/borrowck-reborrow-from-mut.stderr +++ b/tests/ui/borrowck/borrowck-reborrow-from-mut.stderr @@ -106,7 +106,7 @@ error[E0596]: cannot borrow `foo.bar1` as mutable, as it is behind a `&` referen --> $DIR/borrowck-reborrow-from-mut.rs:88:17 | LL | let _bar1 = &mut foo.bar1; - | ^^^^^^^^^^^^^ `foo` is a `&` reference, so the data it refers to cannot be borrowed as mutable + | ^^^^^^^^^^^^^ `foo` is a `&` reference, so it cannot be borrowed as mutable | help: consider changing this to be a mutable reference | diff --git a/tests/ui/borrowck/buffer-reuse-pattern-issue-147694.rs b/tests/ui/borrowck/buffer-reuse-pattern-issue-147694.rs new file mode 100644 index 000000000000..c30e21d220e2 --- /dev/null +++ b/tests/ui/borrowck/buffer-reuse-pattern-issue-147694.rs @@ -0,0 +1,63 @@ +fn process_data(_: &[&[u8]]) {} + +fn test_buffer_cleared_after_use() { + let sources = vec![vec![1u8, 2, 3, 4, 5], vec![6, 7, 8, 9]]; + let mut buffer: Vec<&[u8]> = vec![]; + //~^ NOTE variable `buffer` declared here + + for source in sources { + let data: Vec = source; + //~^ NOTE binding `data` declared here + buffer.extend(data.split(|x| *x == 3)); + //~^ ERROR `data` does not live long enough + //~| NOTE borrowed value does not live long enough + //~| NOTE borrow later used here + //~| NOTE `buffer` is a collection that stores borrowed references, but `data` does not live long enough to be stored in it + //~| HELP buffer reuse with borrowed references requires unsafe code or restructuring + process_data(&buffer); + buffer.clear(); + } //~ NOTE `data` dropped here while still borrowed +} + +fn test_buffer_cleared_at_start() { + let sources = vec![vec![1u8, 2, 3, 4, 5], vec![6, 7, 8, 9]]; + let mut buffer: Vec<&[u8]> = vec![]; + //~^ NOTE variable `buffer` declared here + + for source in sources { + buffer.clear(); + //~^ NOTE borrow later used here + let data: Vec = source; + //~^ NOTE binding `data` declared here + buffer.extend(data.split(|x| *x == 3)); + //~^ ERROR `data` does not live long enough + //~| NOTE borrowed value does not live long enough + //~| NOTE `buffer` is a collection that stores borrowed references, but `data` does not live long enough to be stored in it + //~| HELP buffer reuse with borrowed references requires unsafe code or restructuring + process_data(&buffer); + } //~ NOTE `data` dropped here while still borrowed +} + +fn test_no_explicit_clear() { + let sources = vec![vec![1u8, 2, 3, 4, 5], vec![6, 7, 8, 9]]; + let mut buffer: Vec<&[u8]> = vec![]; + //~^ NOTE variable `buffer` declared here + + for source in sources { + let data: Vec = source; + //~^ NOTE binding `data` declared here + buffer.extend(data.split(|x| *x == 3)); + //~^ ERROR `data` does not live long enough + //~| NOTE borrowed value does not live long enough + //~| NOTE borrow later used here + //~| NOTE `buffer` is a collection that stores borrowed references, but `data` does not live long enough to be stored in it + //~| HELP buffer reuse with borrowed references requires unsafe code or restructuring + process_data(&buffer); + } //~ NOTE `data` dropped here while still borrowed +} + +fn main() { + test_buffer_cleared_after_use(); + test_buffer_cleared_at_start(); + test_no_explicit_clear(); +} diff --git a/tests/ui/borrowck/buffer-reuse-pattern-issue-147694.stderr b/tests/ui/borrowck/buffer-reuse-pattern-issue-147694.stderr new file mode 100644 index 000000000000..e8b4b06604c3 --- /dev/null +++ b/tests/ui/borrowck/buffer-reuse-pattern-issue-147694.stderr @@ -0,0 +1,64 @@ +error[E0597]: `data` does not live long enough + --> $DIR/buffer-reuse-pattern-issue-147694.rs:11:23 + | +LL | let mut buffer: Vec<&[u8]> = vec![]; + | ---------- variable `buffer` declared here +... +LL | let data: Vec = source; + | ---- binding `data` declared here +LL | +LL | buffer.extend(data.split(|x| *x == 3)); + | ------ ^^^^ borrowed value does not live long enough + | | + | borrow later used here +... +LL | } + | - `data` dropped here while still borrowed + | + = note: `buffer` is a collection that stores borrowed references, but `data` does not live long enough to be stored in it + = help: buffer reuse with borrowed references requires unsafe code or restructuring + +error[E0597]: `data` does not live long enough + --> $DIR/buffer-reuse-pattern-issue-147694.rs:32:23 + | +LL | let mut buffer: Vec<&[u8]> = vec![]; + | ---------- variable `buffer` declared here +... +LL | buffer.clear(); + | ------ borrow later used here +LL | +LL | let data: Vec = source; + | ---- binding `data` declared here +LL | +LL | buffer.extend(data.split(|x| *x == 3)); + | ^^^^ borrowed value does not live long enough +... +LL | } + | - `data` dropped here while still borrowed + | + = note: `buffer` is a collection that stores borrowed references, but `data` does not live long enough to be stored in it + = help: buffer reuse with borrowed references requires unsafe code or restructuring + +error[E0597]: `data` does not live long enough + --> $DIR/buffer-reuse-pattern-issue-147694.rs:49:23 + | +LL | let mut buffer: Vec<&[u8]> = vec![]; + | ---------- variable `buffer` declared here +... +LL | let data: Vec = source; + | ---- binding `data` declared here +LL | +LL | buffer.extend(data.split(|x| *x == 3)); + | ------ ^^^^ borrowed value does not live long enough + | | + | borrow later used here +... +LL | } + | - `data` dropped here while still borrowed + | + = note: `buffer` is a collection that stores borrowed references, but `data` does not live long enough to be stored in it + = help: buffer reuse with borrowed references requires unsafe code or restructuring + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0597`. diff --git a/tests/ui/borrowck/issue-115259-suggest-iter-mut.stderr b/tests/ui/borrowck/issue-115259-suggest-iter-mut.stderr index 61c01f0f024f..8191f1f4394b 100644 --- a/tests/ui/borrowck/issue-115259-suggest-iter-mut.stderr +++ b/tests/ui/borrowck/issue-115259-suggest-iter-mut.stderr @@ -2,7 +2,7 @@ error[E0596]: cannot borrow `**layer` as mutable, as it is behind a `&` referenc --> $DIR/issue-115259-suggest-iter-mut.rs:15:65 | LL | self.layers.iter().fold(0, |result, mut layer| result + layer.process()) - | --------- ^^^^^ `layer` is a `&` reference, so the data it refers to cannot be borrowed as mutable + | --------- ^^^^^ `layer` is a `&` reference, so it cannot be borrowed as mutable | | | consider changing this binding's type to be: `&mut Box` | diff --git a/tests/ui/borrowck/issue-42344.stderr b/tests/ui/borrowck/issue-42344.stderr index bf82d462b51b..e7e98d281302 100644 --- a/tests/ui/borrowck/issue-42344.stderr +++ b/tests/ui/borrowck/issue-42344.stderr @@ -1,6 +1,9 @@ error[E0596]: cannot borrow `*TAB[_]` as mutable, as `TAB` is an immutable static item --> $DIR/issue-42344.rs:4:5 | +LL | static TAB: [&mut [u8]; 0] = []; + | -------------------------- this `static` cannot be borrowed as mutable +... LL | TAB[0].iter_mut(); | ^^^^^^ cannot borrow as mutable diff --git a/tests/ui/borrowck/issue-62387-suggest-iter-mut-2.stderr b/tests/ui/borrowck/issue-62387-suggest-iter-mut-2.stderr index c6955317d87d..29121b85f3a0 100644 --- a/tests/ui/borrowck/issue-62387-suggest-iter-mut-2.stderr +++ b/tests/ui/borrowck/issue-62387-suggest-iter-mut-2.stderr @@ -2,7 +2,7 @@ error[E0596]: cannot borrow `*container` as mutable, as it is behind a `&` refer --> $DIR/issue-62387-suggest-iter-mut-2.rs:30:45 | LL | vec.iter().flat_map(|container| container.things()).cloned().collect::>(); - | --------- ^^^^^^^^^ `container` is a `&` reference, so the data it refers to cannot be borrowed as mutable + | --------- ^^^^^^^^^ `container` is a `&` reference, so it cannot be borrowed as mutable | | | consider changing this binding's type to be: `&mut Container` | diff --git a/tests/ui/borrowck/issue-62387-suggest-iter-mut.stderr b/tests/ui/borrowck/issue-62387-suggest-iter-mut.stderr index ae4920b2a8cb..55c17ab6cdea 100644 --- a/tests/ui/borrowck/issue-62387-suggest-iter-mut.stderr +++ b/tests/ui/borrowck/issue-62387-suggest-iter-mut.stderr @@ -2,7 +2,7 @@ error[E0596]: cannot borrow `*a` as mutable, as it is behind a `&` reference --> $DIR/issue-62387-suggest-iter-mut.rs:18:27 | LL | v.iter().for_each(|a| a.double()); - | - ^ `a` is a `&` reference, so the data it refers to cannot be borrowed as mutable + | - ^ `a` is a `&` reference, so it cannot be borrowed as mutable | | | consider changing this binding's type to be: `&mut A` | @@ -15,7 +15,7 @@ error[E0596]: cannot borrow `*a` as mutable, as it is behind a `&` reference --> $DIR/issue-62387-suggest-iter-mut.rs:25:39 | LL | v.iter().rev().rev().for_each(|a| a.double()); - | - ^ `a` is a `&` reference, so the data it refers to cannot be borrowed as mutable + | - ^ `a` is a `&` reference, so it cannot be borrowed as mutable | | | consider changing this binding's type to be: `&mut A` | diff --git a/tests/ui/borrowck/issue-69789-iterator-mut-suggestion.stderr b/tests/ui/borrowck/issue-69789-iterator-mut-suggestion.stderr index 87b8e0591352..048ed80fd82f 100644 --- a/tests/ui/borrowck/issue-69789-iterator-mut-suggestion.stderr +++ b/tests/ui/borrowck/issue-69789-iterator-mut-suggestion.stderr @@ -5,7 +5,7 @@ LL | for item in &mut std::iter::empty::<&'static ()>() { | -------------------------------------- this iterator yields `&` references LL | LL | *item = (); - | ^^^^^^^^^^ `item` is a `&` reference, so the data it refers to cannot be written + | ^^^^^^^^^^ `item` is a `&` reference, so it cannot be written to error: aborting due to 1 previous error diff --git a/tests/ui/borrowck/issue-82032.stderr b/tests/ui/borrowck/issue-82032.stderr index 2ac785cd1e3b..d44b5e1b35f5 100644 --- a/tests/ui/borrowck/issue-82032.stderr +++ b/tests/ui/borrowck/issue-82032.stderr @@ -7,7 +7,7 @@ LL | for v in self.0.values() { | | help: use mutable method: `values_mut()` | this iterator yields `&` references LL | v.flush(); - | ^ `v` is a `&` reference, so the data it refers to cannot be borrowed as mutable + | ^ `v` is a `&` reference, so it cannot be borrowed as mutable error: aborting due to 1 previous error diff --git a/tests/ui/borrowck/issue-83309-ice-immut-in-for-loop.rs b/tests/ui/borrowck/issue-83309-ice-immut-in-for-loop.rs index d301e7b3524b..f11eb65614a6 100644 --- a/tests/ui/borrowck/issue-83309-ice-immut-in-for-loop.rs +++ b/tests/ui/borrowck/issue-83309-ice-immut-in-for-loop.rs @@ -10,7 +10,7 @@ fn main() { //~^ NOTE this iterator yields `&` references *v -= 1; //~^ ERROR cannot assign to `*v`, which is behind a `&` reference - //~| NOTE `v` is a `&` reference, so the data it refers to cannot be written + //~| NOTE `v` is a `&` reference, so it cannot be written to } } diff --git a/tests/ui/borrowck/issue-83309-ice-immut-in-for-loop.stderr b/tests/ui/borrowck/issue-83309-ice-immut-in-for-loop.stderr index 4e7a9b695e17..0860f0c3afdf 100644 --- a/tests/ui/borrowck/issue-83309-ice-immut-in-for-loop.stderr +++ b/tests/ui/borrowck/issue-83309-ice-immut-in-for-loop.stderr @@ -5,7 +5,7 @@ LL | for v in Query.iter_mut() { | ---------------- this iterator yields `&` references LL | LL | *v -= 1; - | ^^^^^^^ `v` is a `&` reference, so the data it refers to cannot be written + | ^^^^^^^ `v` is a `&` reference, so it cannot be written to error: aborting due to 1 previous error diff --git a/tests/ui/borrowck/issue-85765-closure.rs b/tests/ui/borrowck/issue-85765-closure.rs index f2d1dd0fbc3f..09b2d6c939a2 100644 --- a/tests/ui/borrowck/issue-85765-closure.rs +++ b/tests/ui/borrowck/issue-85765-closure.rs @@ -5,27 +5,27 @@ fn main() { //~^ HELP consider changing this binding's type rofl.push(Vec::new()); //~^ ERROR cannot borrow `*rofl` as mutable, as it is behind a `&` reference - //~| NOTE `rofl` is a `&` reference, so the data it refers to cannot be borrowed as mutable + //~| NOTE `rofl` is a `&` reference, so it cannot be borrowed as mutable let mut mutvar = 42; let r = &mutvar; //~^ HELP consider changing this to be a mutable reference *r = 0; //~^ ERROR cannot assign to `*r`, which is behind a `&` reference - //~| NOTE `r` is a `&` reference, so the data it refers to cannot be written + //~| NOTE `r` is a `&` reference, so it cannot be written to #[rustfmt::skip] let x: &usize = &mut{0}; //~^ HELP consider changing this binding's type *x = 1; //~^ ERROR cannot assign to `*x`, which is behind a `&` reference - //~| NOTE `x` is a `&` reference, so the data it refers to cannot be written + //~| NOTE `x` is a `&` reference, so it cannot be written to #[rustfmt::skip] let y: &usize = &mut(0); //~^ HELP consider changing this binding's type *y = 1; //~^ ERROR cannot assign to `*y`, which is behind a `&` reference - //~| NOTE `y` is a `&` reference, so the data it refers to cannot be written + //~| NOTE `y` is a `&` reference, so it cannot be written to }; } diff --git a/tests/ui/borrowck/issue-85765-closure.stderr b/tests/ui/borrowck/issue-85765-closure.stderr index cd2544ec5c95..1b1cd9cabb68 100644 --- a/tests/ui/borrowck/issue-85765-closure.stderr +++ b/tests/ui/borrowck/issue-85765-closure.stderr @@ -2,7 +2,7 @@ error[E0596]: cannot borrow `*rofl` as mutable, as it is behind a `&` reference --> $DIR/issue-85765-closure.rs:6:9 | LL | rofl.push(Vec::new()); - | ^^^^ `rofl` is a `&` reference, so the data it refers to cannot be borrowed as mutable + | ^^^^ `rofl` is a `&` reference, so it cannot be borrowed as mutable | help: consider changing this binding's type | @@ -13,7 +13,7 @@ error[E0594]: cannot assign to `*r`, which is behind a `&` reference --> $DIR/issue-85765-closure.rs:13:9 | LL | *r = 0; - | ^^^^^^ `r` is a `&` reference, so the data it refers to cannot be written + | ^^^^^^ `r` is a `&` reference, so it cannot be written to | help: consider changing this to be a mutable reference | @@ -24,7 +24,7 @@ error[E0594]: cannot assign to `*x`, which is behind a `&` reference --> $DIR/issue-85765-closure.rs:20:9 | LL | *x = 1; - | ^^^^^^ `x` is a `&` reference, so the data it refers to cannot be written + | ^^^^^^ `x` is a `&` reference, so it cannot be written to | help: consider changing this binding's type | @@ -35,7 +35,7 @@ error[E0594]: cannot assign to `*y`, which is behind a `&` reference --> $DIR/issue-85765-closure.rs:27:9 | LL | *y = 1; - | ^^^^^^ `y` is a `&` reference, so the data it refers to cannot be written + | ^^^^^^ `y` is a `&` reference, so it cannot be written to | help: consider changing this binding's type | diff --git a/tests/ui/borrowck/issue-85765.rs b/tests/ui/borrowck/issue-85765.rs index 76e0b5173541..22e3882a8c78 100644 --- a/tests/ui/borrowck/issue-85765.rs +++ b/tests/ui/borrowck/issue-85765.rs @@ -4,26 +4,26 @@ fn main() { //~^ HELP consider changing this binding's type rofl.push(Vec::new()); //~^ ERROR cannot borrow `*rofl` as mutable, as it is behind a `&` reference - //~| NOTE `rofl` is a `&` reference, so the data it refers to cannot be borrowed as mutable + //~| NOTE `rofl` is a `&` reference, so it cannot be borrowed as mutable let mut mutvar = 42; let r = &mutvar; //~^ HELP consider changing this to be a mutable reference *r = 0; //~^ ERROR cannot assign to `*r`, which is behind a `&` reference - //~| NOTE `r` is a `&` reference, so the data it refers to cannot be written + //~| NOTE `r` is a `&` reference, so it cannot be written to #[rustfmt::skip] let x: &usize = &mut{0}; //~^ HELP consider changing this binding's type *x = 1; //~^ ERROR cannot assign to `*x`, which is behind a `&` reference - //~| NOTE `x` is a `&` reference, so the data it refers to cannot be written + //~| NOTE `x` is a `&` reference, so it cannot be written to #[rustfmt::skip] let y: &usize = &mut(0); //~^ HELP consider changing this binding's type *y = 1; //~^ ERROR cannot assign to `*y`, which is behind a `&` reference - //~| NOTE `y` is a `&` reference, so the data it refers to cannot be written + //~| NOTE `y` is a `&` reference, so it cannot be written to } diff --git a/tests/ui/borrowck/issue-85765.stderr b/tests/ui/borrowck/issue-85765.stderr index e252f3d44d97..6567891fde61 100644 --- a/tests/ui/borrowck/issue-85765.stderr +++ b/tests/ui/borrowck/issue-85765.stderr @@ -2,7 +2,7 @@ error[E0596]: cannot borrow `*rofl` as mutable, as it is behind a `&` reference --> $DIR/issue-85765.rs:5:5 | LL | rofl.push(Vec::new()); - | ^^^^ `rofl` is a `&` reference, so the data it refers to cannot be borrowed as mutable + | ^^^^ `rofl` is a `&` reference, so it cannot be borrowed as mutable | help: consider changing this binding's type | @@ -13,7 +13,7 @@ error[E0594]: cannot assign to `*r`, which is behind a `&` reference --> $DIR/issue-85765.rs:12:5 | LL | *r = 0; - | ^^^^^^ `r` is a `&` reference, so the data it refers to cannot be written + | ^^^^^^ `r` is a `&` reference, so it cannot be written to | help: consider changing this to be a mutable reference | @@ -24,7 +24,7 @@ error[E0594]: cannot assign to `*x`, which is behind a `&` reference --> $DIR/issue-85765.rs:19:5 | LL | *x = 1; - | ^^^^^^ `x` is a `&` reference, so the data it refers to cannot be written + | ^^^^^^ `x` is a `&` reference, so it cannot be written to | help: consider changing this binding's type | @@ -35,7 +35,7 @@ error[E0594]: cannot assign to `*y`, which is behind a `&` reference --> $DIR/issue-85765.rs:26:5 | LL | *y = 1; - | ^^^^^^ `y` is a `&` reference, so the data it refers to cannot be written + | ^^^^^^ `y` is a `&` reference, so it cannot be written to | help: consider changing this binding's type | diff --git a/tests/ui/borrowck/issue-91206.rs b/tests/ui/borrowck/issue-91206.rs index e062a253767d..4f876853610e 100644 --- a/tests/ui/borrowck/issue-91206.rs +++ b/tests/ui/borrowck/issue-91206.rs @@ -12,5 +12,5 @@ fn main() { //~^ HELP consider specifying this binding's type inner.clear(); //~^ ERROR cannot borrow `*inner` as mutable, as it is behind a `&` reference [E0596] - //~| NOTE `inner` is a `&` reference, so the data it refers to cannot be borrowed as mutable + //~| NOTE `inner` is a `&` reference, so it cannot be borrowed as mutable } diff --git a/tests/ui/borrowck/issue-91206.stderr b/tests/ui/borrowck/issue-91206.stderr index f96b0c7d9e1a..ebd9ace34bcd 100644 --- a/tests/ui/borrowck/issue-91206.stderr +++ b/tests/ui/borrowck/issue-91206.stderr @@ -2,7 +2,7 @@ error[E0596]: cannot borrow `*inner` as mutable, as it is behind a `&` reference --> $DIR/issue-91206.rs:13:5 | LL | inner.clear(); - | ^^^^^ `inner` is a `&` reference, so the data it refers to cannot be borrowed as mutable + | ^^^^^ `inner` is a `&` reference, so it cannot be borrowed as mutable | help: consider specifying this binding's type | diff --git a/tests/ui/borrowck/issue-92015.stderr b/tests/ui/borrowck/issue-92015.stderr index 167a5cf5863c..cfd30b833784 100644 --- a/tests/ui/borrowck/issue-92015.stderr +++ b/tests/ui/borrowck/issue-92015.stderr @@ -2,7 +2,7 @@ error[E0594]: cannot assign to `*foo`, which is behind a `&` reference --> $DIR/issue-92015.rs:6:5 | LL | *foo = 1; - | ^^^^^^^^ `foo` is a `&` reference, so the data it refers to cannot be written + | ^^^^^^^^ `foo` is a `&` reference, so it cannot be written to | help: consider specifying this binding's type | diff --git a/tests/ui/borrowck/issue-93093.stderr b/tests/ui/borrowck/issue-93093.stderr index d788ce331973..02239627a893 100644 --- a/tests/ui/borrowck/issue-93093.stderr +++ b/tests/ui/borrowck/issue-93093.stderr @@ -2,7 +2,7 @@ error[E0594]: cannot assign to `self.foo`, which is behind a `&` reference --> $DIR/issue-93093.rs:8:9 | LL | self.foo += 1; - | ^^^^^^^^^^^^^ `self` is a `&` reference, so the data it refers to cannot be written + | ^^^^^^^^^^^^^ `self` is a `&` reference, so it cannot be written to | help: consider changing this to be a mutable reference | diff --git a/tests/ui/borrowck/mutability-errors.stderr b/tests/ui/borrowck/mutability-errors.stderr index 7307e1f2a86b..18d8e6eb1a6e 100644 --- a/tests/ui/borrowck/mutability-errors.stderr +++ b/tests/ui/borrowck/mutability-errors.stderr @@ -2,7 +2,7 @@ error[E0594]: cannot assign to `*x`, which is behind a `&` reference --> $DIR/mutability-errors.rs:9:5 | LL | *x = (1,); - | ^^^^^^^^^ `x` is a `&` reference, so the data it refers to cannot be written + | ^^^^^^^^^ `x` is a `&` reference, so it cannot be written to | help: consider changing this to be a mutable reference | @@ -13,7 +13,7 @@ error[E0594]: cannot assign to `x.0`, which is behind a `&` reference --> $DIR/mutability-errors.rs:10:5 | LL | x.0 = 1; - | ^^^^^^^ `x` is a `&` reference, so the data it refers to cannot be written + | ^^^^^^^ `x` is a `&` reference, so it cannot be written to | help: consider changing this to be a mutable reference | @@ -24,7 +24,7 @@ error[E0596]: cannot borrow `*x` as mutable, as it is behind a `&` reference --> $DIR/mutability-errors.rs:11:5 | LL | &mut *x; - | ^^^^^^^ `x` is a `&` reference, so the data it refers to cannot be borrowed as mutable + | ^^^^^^^ `x` is a `&` reference, so it cannot be borrowed as mutable | help: consider changing this to be a mutable reference | @@ -35,7 +35,7 @@ error[E0596]: cannot borrow `x.0` as mutable, as it is behind a `&` reference --> $DIR/mutability-errors.rs:12:5 | LL | &mut x.0; - | ^^^^^^^^ `x` is a `&` reference, so the data it refers to cannot be borrowed as mutable + | ^^^^^^^^ `x` is a `&` reference, so it cannot be borrowed as mutable | help: consider changing this to be a mutable reference | @@ -70,7 +70,7 @@ error[E0594]: cannot assign to `*x`, which is behind a `*const` pointer --> $DIR/mutability-errors.rs:23:5 | LL | *x = (1,); - | ^^^^^^^^^ `x` is a `*const` pointer, so the data it refers to cannot be written + | ^^^^^^^^^ `x` is a `*const` pointer, so it cannot be written to | help: consider changing this to be a mutable pointer | @@ -81,7 +81,7 @@ error[E0594]: cannot assign to `x.0`, which is behind a `*const` pointer --> $DIR/mutability-errors.rs:24:5 | LL | (*x).0 = 1; - | ^^^^^^^^^^ `x` is a `*const` pointer, so the data it refers to cannot be written + | ^^^^^^^^^^ `x` is a `*const` pointer, so it cannot be written to | help: consider changing this to be a mutable pointer | @@ -92,7 +92,7 @@ error[E0596]: cannot borrow `*x` as mutable, as it is behind a `*const` pointer --> $DIR/mutability-errors.rs:25:5 | LL | &mut *x; - | ^^^^^^^ `x` is a `*const` pointer, so the data it refers to cannot be borrowed as mutable + | ^^^^^^^ `x` is a `*const` pointer, so it cannot be borrowed as mutable | help: consider changing this to be a mutable pointer | @@ -103,7 +103,7 @@ error[E0596]: cannot borrow `x.0` as mutable, as it is behind a `*const` pointer --> $DIR/mutability-errors.rs:26:5 | LL | &mut (*x).0; - | ^^^^^^^^^^^ `x` is a `*const` pointer, so the data it refers to cannot be borrowed as mutable + | ^^^^^^^^^^^ `x` is a `*const` pointer, so it cannot be borrowed as mutable | help: consider changing this to be a mutable pointer | @@ -358,24 +358,36 @@ LL | fn imm_capture(mut x: (i32,)) { error[E0594]: cannot assign to immutable static item `X` --> $DIR/mutability-errors.rs:76:5 | +LL | static X: (i32,) = (0,); + | ---------------- this `static` cannot be written to +... LL | X = (1,); | ^^^^^^^^ cannot assign error[E0594]: cannot assign to `X.0`, as `X` is an immutable static item --> $DIR/mutability-errors.rs:77:5 | +LL | static X: (i32,) = (0,); + | ---------------- this `static` cannot be written to +... LL | X.0 = 1; | ^^^^^^^ cannot assign error[E0596]: cannot borrow immutable static item `X` as mutable --> $DIR/mutability-errors.rs:78:5 | +LL | static X: (i32,) = (0,); + | ---------------- this `static` cannot be borrowed as mutable +... LL | &mut X; | ^^^^^^ cannot borrow as mutable error[E0596]: cannot borrow `X.0` as mutable, as `X` is an immutable static item --> $DIR/mutability-errors.rs:79:5 | +LL | static X: (i32,) = (0,); + | ---------------- this `static` cannot be borrowed as mutable +... LL | &mut X.0; | ^^^^^^^^ cannot borrow as mutable diff --git a/tests/ui/borrowck/mutable-borrow-behind-reference-61623.stderr b/tests/ui/borrowck/mutable-borrow-behind-reference-61623.stderr index cc7761acda9d..0357b7c6df8c 100644 --- a/tests/ui/borrowck/mutable-borrow-behind-reference-61623.stderr +++ b/tests/ui/borrowck/mutable-borrow-behind-reference-61623.stderr @@ -2,7 +2,7 @@ error[E0596]: cannot borrow `*x.1` as mutable, as it is behind a `&` reference --> $DIR/mutable-borrow-behind-reference-61623.rs:7:19 | LL | f2(|| x.0, f1(x.1)) - | ^^^ `x` is a `&` reference, so the data it refers to cannot be borrowed as mutable + | ^^^ `x` is a `&` reference, so it cannot be borrowed as mutable | help: consider changing this to be a mutable reference | diff --git a/tests/ui/borrowck/no-invalid-mut-suggestion-for-raw-pointer-issue-127562.stderr b/tests/ui/borrowck/no-invalid-mut-suggestion-for-raw-pointer-issue-127562.stderr index 9bcfbd337955..208e73235873 100644 --- a/tests/ui/borrowck/no-invalid-mut-suggestion-for-raw-pointer-issue-127562.stderr +++ b/tests/ui/borrowck/no-invalid-mut-suggestion-for-raw-pointer-issue-127562.stderr @@ -2,7 +2,7 @@ error[E0594]: cannot assign to `*ptr`, which is behind a `*const` pointer --> $DIR/no-invalid-mut-suggestion-for-raw-pointer-issue-127562.rs:7:14 | LL | unsafe { *ptr = 3; } - | ^^^^^^^^ `ptr` is a `*const` pointer, so the data it refers to cannot be written + | ^^^^^^^^ `ptr` is a `*const` pointer, so it cannot be written to | help: consider changing this to be a mutable pointer | diff --git a/tests/ui/borrowck/suggest-as-ref-on-mut-closure.stderr b/tests/ui/borrowck/suggest-as-ref-on-mut-closure.stderr index 1e98006a9a71..ca0d0bd8a3ca 100644 --- a/tests/ui/borrowck/suggest-as-ref-on-mut-closure.stderr +++ b/tests/ui/borrowck/suggest-as-ref-on-mut-closure.stderr @@ -18,7 +18,7 @@ error[E0596]: cannot borrow `*cb` as mutable, as it is behind a `&` reference --> $DIR/suggest-as-ref-on-mut-closure.rs:12:26 | LL | cb.as_ref().map(|cb| cb()); - | -- ^^ `cb` is a `&` reference, so the data it refers to cannot be borrowed as mutable + | -- ^^ `cb` is a `&` reference, so it cannot be borrowed as mutable | | | consider changing this binding's type to be: `&mut &mut dyn FnMut()` diff --git a/tests/ui/borrowck/suggest-mut-iterator.stderr b/tests/ui/borrowck/suggest-mut-iterator.stderr index b396bb7b5ec4..bdb5fbfd2bcd 100644 --- a/tests/ui/borrowck/suggest-mut-iterator.stderr +++ b/tests/ui/borrowck/suggest-mut-iterator.stderr @@ -4,7 +4,7 @@ error[E0596]: cannot borrow `*test` as mutable, as it is behind a `&` reference LL | for test in &tests { | ------ this iterator yields `&` references LL | test.add(2); - | ^^^^ `test` is a `&` reference, so the data it refers to cannot be borrowed as mutable + | ^^^^ `test` is a `&` reference, so it cannot be borrowed as mutable | help: use a mutable iterator instead | diff --git a/tests/ui/borrowck/suggestions/overloaded-index-not-mut-but-should-be-mut.stderr b/tests/ui/borrowck/suggestions/overloaded-index-not-mut-but-should-be-mut.stderr index 44cc9aefcf18..8ddc7368793c 100644 --- a/tests/ui/borrowck/suggestions/overloaded-index-not-mut-but-should-be-mut.stderr +++ b/tests/ui/borrowck/suggestions/overloaded-index-not-mut-but-should-be-mut.stderr @@ -2,7 +2,7 @@ error[E0596]: cannot borrow `*string` as mutable, as it is behind a `&` referenc --> $DIR/overloaded-index-not-mut-but-should-be-mut.rs:7:5 | LL | string.push_str("test"); - | ^^^^^^ `string` is a `&` reference, so the data it refers to cannot be borrowed as mutable + | ^^^^^^ `string` is a `&` reference, so it cannot be borrowed as mutable | help: consider using `get_mut` | @@ -14,7 +14,7 @@ error[E0596]: cannot borrow `*string` as mutable, as it is behind a `&` referenc --> $DIR/overloaded-index-not-mut-but-should-be-mut.rs:14:5 | LL | string.push_str("test"); - | ^^^^^^ `string` is a `&` reference, so the data it refers to cannot be borrowed as mutable + | ^^^^^^ `string` is a `&` reference, so it cannot be borrowed as mutable | help: consider using `get_mut` | @@ -26,7 +26,7 @@ error[E0596]: cannot borrow `*string` as mutable, as it is behind a `&` referenc --> $DIR/overloaded-index-not-mut-but-should-be-mut.rs:19:5 | LL | string.push_str("test"); - | ^^^^^^ `string` is a `&` reference, so the data it refers to cannot be borrowed as mutable + | ^^^^^^ `string` is a `&` reference, so it cannot be borrowed as mutable | help: consider changing this to be a mutable reference | diff --git a/tests/ui/borrowck/suggestions/overloaded-index-without-indexmut.stderr b/tests/ui/borrowck/suggestions/overloaded-index-without-indexmut.stderr index 6a46332a5d7b..7e952d69945c 100644 --- a/tests/ui/borrowck/suggestions/overloaded-index-without-indexmut.stderr +++ b/tests/ui/borrowck/suggestions/overloaded-index-without-indexmut.stderr @@ -2,7 +2,7 @@ error[E0596]: cannot borrow `*y` as mutable, as it is behind a `&` reference --> $DIR/overloaded-index-without-indexmut.rs:14:5 | LL | y.push_str(""); - | ^ `y` is a `&` reference, so the data it refers to cannot be borrowed as mutable + | ^ `y` is a `&` reference, so it cannot be borrowed as mutable error: aborting due to 1 previous error diff --git a/tests/ui/borrowck/trait-impl-argument-difference-ice.stderr b/tests/ui/borrowck/trait-impl-argument-difference-ice.stderr index 3d54d5269ae2..90d9ee3f32af 100644 --- a/tests/ui/borrowck/trait-impl-argument-difference-ice.stderr +++ b/tests/ui/borrowck/trait-impl-argument-difference-ice.stderr @@ -36,7 +36,7 @@ error[E0596]: cannot borrow `*self` as mutable, as it is behind a `&` reference --> $DIR/trait-impl-argument-difference-ice.rs:16:19 | LL | let a16 = self.read_word() as u16; - | ^^^^ `self` is a `&` reference, so the data it refers to cannot be borrowed as mutable + | ^^^^ `self` is a `&` reference, so it cannot be borrowed as mutable | help: consider changing this to be a mutable reference in the `impl` method and the `trait` definition | @@ -47,7 +47,7 @@ error[E0596]: cannot borrow `*self` as mutable, as it is behind a `&` reference --> $DIR/trait-impl-argument-difference-ice.rs:18:19 | LL | let b16 = self.read_word() as u16; - | ^^^^ `self` is a `&` reference, so the data it refers to cannot be borrowed as mutable + | ^^^^ `self` is a `&` reference, so it cannot be borrowed as mutable | help: consider changing this to be a mutable reference in the `impl` method and the `trait` definition | diff --git a/tests/ui/c-variadic/issue-86053-1.rs b/tests/ui/c-variadic/issue-86053-1.rs index 58dfee55cf88..e63d348dbb3b 100644 --- a/tests/ui/c-variadic/issue-86053-1.rs +++ b/tests/ui/c-variadic/issue-86053-1.rs @@ -8,7 +8,7 @@ fn ordering4 < 'a , 'b > ( a : , self , self , self , //~| ERROR unexpected `self` parameter in function //~| ERROR unexpected `self` parameter in function //~| ERROR unexpected `self` parameter in function - self , ... , self , self , ... ) where F : FnOnce ( & 'a & 'b usize ) { + self , _: ... , self , self , _: ... ) where F : FnOnce ( & 'a & 'b usize ) { //~^ ERROR unexpected `self` parameter in function //~| ERROR unexpected `self` parameter in function //~| ERROR unexpected `self` parameter in function diff --git a/tests/ui/c-variadic/issue-86053-1.stderr b/tests/ui/c-variadic/issue-86053-1.stderr index adbc04d3a65a..05b19624129e 100644 --- a/tests/ui/c-variadic/issue-86053-1.stderr +++ b/tests/ui/c-variadic/issue-86053-1.stderr @@ -25,48 +25,48 @@ LL | fn ordering4 < 'a , 'b > ( a : , self , self , self , error: unexpected `self` parameter in function --> $DIR/issue-86053-1.rs:11:5 | -LL | self , ... , self , self , ... ) where F : FnOnce ( & 'a & 'b usize ) { +LL | self , _: ... , self , self , _: ... ) where F : FnOnce ( & 'a & 'b usize ) { | ^^^^ must be the first parameter of an associated function error: unexpected `self` parameter in function - --> $DIR/issue-86053-1.rs:11:20 + --> $DIR/issue-86053-1.rs:11:23 | -LL | self , ... , self , self , ... ) where F : FnOnce ( & 'a & 'b usize ) { - | ^^^^ must be the first parameter of an associated function +LL | self , _: ... , self , self , _: ... ) where F : FnOnce ( & 'a & 'b usize ) { + | ^^^^ must be the first parameter of an associated function error: unexpected `self` parameter in function - --> $DIR/issue-86053-1.rs:11:29 + --> $DIR/issue-86053-1.rs:11:32 | -LL | self , ... , self , self , ... ) where F : FnOnce ( & 'a & 'b usize ) { - | ^^^^ must be the first parameter of an associated function +LL | self , _: ... , self , self , _: ... ) where F : FnOnce ( & 'a & 'b usize ) { + | ^^^^ must be the first parameter of an associated function error: `...` must be the last argument of a C-variadic function --> $DIR/issue-86053-1.rs:11:12 | -LL | self , ... , self , self , ... ) where F : FnOnce ( & 'a & 'b usize ) { - | ^^^ +LL | self , _: ... , self , self , _: ... ) where F : FnOnce ( & 'a & 'b usize ) { + | ^^^^^^ error: `...` is not supported for non-extern functions - --> $DIR/issue-86053-1.rs:11:36 + --> $DIR/issue-86053-1.rs:11:39 | -LL | self , ... , self , self , ... ) where F : FnOnce ( & 'a & 'b usize ) { - | ^^^ +LL | self , _: ... , self , self , _: ... ) where F : FnOnce ( & 'a & 'b usize ) { + | ^^^^^^ | = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list error[E0412]: cannot find type `F` in this scope - --> $DIR/issue-86053-1.rs:11:48 + --> $DIR/issue-86053-1.rs:11:54 | -LL | self , ... , self , self , ... ) where F : FnOnce ( & 'a & 'b usize ) { - | ^ +LL | self , _: ... , self , self , _: ... ) where F : FnOnce ( & 'a & 'b usize ) { + | ^ | --> $SRC_DIR/core/src/ops/function.rs:LL:COL | = note: similarly named trait `Fn` defined here help: a trait with a similar name exists | -LL | self , ... , self , self , ... ) where Fn : FnOnce ( & 'a & 'b usize ) { - | + +LL | self , _: ... , self , self , _: ... ) where Fn : FnOnce ( & 'a & 'b usize ) { + | + help: you might be missing a type parameter | LL | fn ordering4 < 'a , 'b, F > ( a : , self , self , self , diff --git a/tests/ui/c-variadic/issue-86053-2.rs b/tests/ui/c-variadic/issue-86053-2.rs index c545831f7171..0914676a35f4 100644 --- a/tests/ui/c-variadic/issue-86053-2.rs +++ b/tests/ui/c-variadic/issue-86053-2.rs @@ -5,7 +5,7 @@ trait H {} -unsafe extern "C" fn ordering4<'a, F: H<&'static &'a ()>>(_: (), ...) {} +unsafe extern "C" fn ordering4<'a, F: H<&'static &'a ()>>(_: (), _: ...) {} //~^ ERROR: in type `&'static &'a ()`, reference has a longer lifetime than the data it references [E0491] fn main() {} diff --git a/tests/ui/c-variadic/issue-86053-2.stderr b/tests/ui/c-variadic/issue-86053-2.stderr index 2c4be2522f61..823dadff6f89 100644 --- a/tests/ui/c-variadic/issue-86053-2.stderr +++ b/tests/ui/c-variadic/issue-86053-2.stderr @@ -1,14 +1,14 @@ error[E0491]: in type `&'static &'a ()`, reference has a longer lifetime than the data it references --> $DIR/issue-86053-2.rs:8:39 | -LL | unsafe extern "C" fn ordering4<'a, F: H<&'static &'a ()>>(_: (), ...) {} +LL | unsafe extern "C" fn ordering4<'a, F: H<&'static &'a ()>>(_: (), _: ...) {} | ^^^^^^^^^^^^^^^^^^ | = note: the pointer is valid for the static lifetime note: but the referenced data is only valid for the lifetime `'a` as defined here --> $DIR/issue-86053-2.rs:8:32 | -LL | unsafe extern "C" fn ordering4<'a, F: H<&'static &'a ()>>(_: (), ...) {} +LL | unsafe extern "C" fn ordering4<'a, F: H<&'static &'a ()>>(_: (), _: ...) {} | ^^ error: aborting due to 1 previous error diff --git a/tests/ui/c-variadic/naked-invalid.rs b/tests/ui/c-variadic/naked-invalid.rs new file mode 100644 index 000000000000..2cc4aaafbfcc --- /dev/null +++ b/tests/ui/c-variadic/naked-invalid.rs @@ -0,0 +1,44 @@ +//@ add-minicore +//@ compile-flags: --target x86_64-unknown-linux-gnu +//@ needs-llvm-components: x86 +//@ ignore-backends: gcc + +#![feature(no_core, lang_items, rustc_attrs)] +#![feature(c_variadic, c_variadic_naked_functions, abi_x86_interrupt, naked_functions_rustic_abi)] +#![crate_type = "rlib"] +#![no_core] + +extern crate minicore; +use minicore::*; + +#[repr(C)] +#[lang = "va_list"] +pub struct VaList; + +#[unsafe(naked)] +unsafe extern "sysv64" fn c_variadic_sysv64(_: ...) { + naked_asm!("ret") +} + +#[unsafe(naked)] +unsafe extern "C" fn c_variadic_c(_: ...) { + naked_asm!("ret") +} + +#[unsafe(naked)] +unsafe extern "Rust" fn c_variadic_rust(_: ...) { + //~^ ERROR `...` is not supported for `extern "Rust"` naked functions + naked_asm!("ret") +} + +#[unsafe(naked)] +unsafe extern "x86-interrupt" fn c_variadic_x86_interrupt(_: ...) { + //~^ ERROR `...` is not supported for `extern "x86-interrupt"` naked functions + naked_asm!("ret") +} + +#[unsafe(naked)] +unsafe extern "nonsense" fn c_variadic_x86_nonsense(_: ...) { + //~^ ERROR invalid ABI: found `nonsense` + naked_asm!("ret") +} diff --git a/tests/ui/c-variadic/naked-invalid.stderr b/tests/ui/c-variadic/naked-invalid.stderr new file mode 100644 index 000000000000..a1fc8c166427 --- /dev/null +++ b/tests/ui/c-variadic/naked-invalid.stderr @@ -0,0 +1,31 @@ +error: `...` is not supported for `extern "Rust"` naked functions + --> $DIR/naked-invalid.rs:29:41 + | +LL | unsafe extern "Rust" fn c_variadic_rust(_: ...) { + | ------------- ^^^^^^ + | | + | `extern "Rust"` because of this + | + = help: C-variadic function must have a compatible calling convention + +error: `...` is not supported for `extern "x86-interrupt"` naked functions + --> $DIR/naked-invalid.rs:35:59 + | +LL | unsafe extern "x86-interrupt" fn c_variadic_x86_interrupt(_: ...) { + | ---------------------- ^^^^^^ + | | + | `extern "x86-interrupt"` because of this + | + = help: C-variadic function must have a compatible calling convention + +error[E0703]: invalid ABI: found `nonsense` + --> $DIR/naked-invalid.rs:41:15 + | +LL | unsafe extern "nonsense" fn c_variadic_x86_nonsense(_: ...) { + | ^^^^^^^^^^ invalid ABI + | + = note: invoke `rustc --print=calling-conventions` for a full list of supported calling conventions + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0703`. diff --git a/tests/ui/c-variadic/naked.rs b/tests/ui/c-variadic/naked.rs index 46b59395485c..73664206d9ce 100644 --- a/tests/ui/c-variadic/naked.rs +++ b/tests/ui/c-variadic/naked.rs @@ -1,14 +1,14 @@ //@ run-pass //@ only-x86_64 //@ only-linux -#![feature(c_variadic)] +#![feature(c_variadic, c_variadic_naked_functions)] #[repr(C)] #[derive(Debug, PartialEq)] struct Data(i32, f64); #[unsafe(naked)] -unsafe extern "C" fn c_variadic(_: ...) -> Data { +unsafe extern "sysv64" fn c_variadic_sysv64(_: ...) -> Data { // This assembly was generated with GCC, because clang/LLVM is unable to // optimize out the spilling of all registers to the stack. core::arch::naked_asm!( @@ -32,9 +32,20 @@ unsafe extern "C" fn c_variadic(_: ...) -> Data { ) } +#[unsafe(naked)] +unsafe extern "C" fn c_variadic_c(_: ...) -> Data { + core::arch::naked_asm!( + "jmp {}", + sym c_variadic_sysv64, + ) +} + fn main() { unsafe { - assert_eq!(c_variadic(1, 2.0), Data(1, 2.0)); - assert_eq!(c_variadic(123, 4.56), Data(123, 4.56)); + assert_eq!(c_variadic_sysv64(1, 2.0), Data(1, 2.0)); + assert_eq!(c_variadic_sysv64(123, 4.56), Data(123, 4.56)); + + assert_eq!(c_variadic_c(1, 2.0), Data(1, 2.0)); + assert_eq!(c_variadic_c(123, 4.56), Data(123, 4.56)); } } diff --git a/tests/ui/c-variadic/not-async.rs b/tests/ui/c-variadic/not-async.rs index bdb51a9a4323..a4ad9c6bceb5 100644 --- a/tests/ui/c-variadic/not-async.rs +++ b/tests/ui/c-variadic/not-async.rs @@ -2,14 +2,14 @@ #![feature(c_variadic)] #![crate_type = "lib"] -async unsafe extern "C" fn fn_cannot_be_async(x: isize, ...) {} +async unsafe extern "C" fn fn_cannot_be_async(x: isize, _: ...) {} //~^ ERROR functions cannot be both `async` and C-variadic //~| ERROR hidden type for `impl Future` captures lifetime that does not appear in bounds struct S; impl S { - async unsafe extern "C" fn method_cannot_be_async(x: isize, ...) {} + async unsafe extern "C" fn method_cannot_be_async(x: isize, _: ...) {} //~^ ERROR functions cannot be both `async` and C-variadic //~| ERROR hidden type for `impl Future` captures lifetime that does not appear in bounds } diff --git a/tests/ui/c-variadic/not-async.stderr b/tests/ui/c-variadic/not-async.stderr index eab4c4f0822c..fc5eb10bec4f 100644 --- a/tests/ui/c-variadic/not-async.stderr +++ b/tests/ui/c-variadic/not-async.stderr @@ -1,30 +1,30 @@ error: functions cannot be both `async` and C-variadic --> $DIR/not-async.rs:5:1 | -LL | async unsafe extern "C" fn fn_cannot_be_async(x: isize, ...) {} - | ^^^^^ `async` because of this ^^^ C-variadic because of this +LL | async unsafe extern "C" fn fn_cannot_be_async(x: isize, _: ...) {} + | ^^^^^ `async` because of this ^^^^^^ C-variadic because of this error: functions cannot be both `async` and C-variadic --> $DIR/not-async.rs:12:5 | -LL | async unsafe extern "C" fn method_cannot_be_async(x: isize, ...) {} - | ^^^^^ `async` because of this ^^^ C-variadic because of this +LL | async unsafe extern "C" fn method_cannot_be_async(x: isize, _: ...) {} + | ^^^^^ `async` because of this ^^^^^^ C-variadic because of this error[E0700]: hidden type for `impl Future` captures lifetime that does not appear in bounds - --> $DIR/not-async.rs:5:62 + --> $DIR/not-async.rs:5:65 | -LL | async unsafe extern "C" fn fn_cannot_be_async(x: isize, ...) {} - | ------------------------------------------------------------ ^^ +LL | async unsafe extern "C" fn fn_cannot_be_async(x: isize, _: ...) {} + | --------------------------------------------------------------- ^^ | | | opaque type defined here | = note: hidden type `{async fn body of fn_cannot_be_async()}` captures lifetime `'_` error[E0700]: hidden type for `impl Future` captures lifetime that does not appear in bounds - --> $DIR/not-async.rs:12:70 + --> $DIR/not-async.rs:12:73 | -LL | async unsafe extern "C" fn method_cannot_be_async(x: isize, ...) {} - | ---------------------------------------------------------------- ^^ +LL | async unsafe extern "C" fn method_cannot_be_async(x: isize, _: ...) {} + | ------------------------------------------------------------------- ^^ | | | opaque type defined here | diff --git a/tests/ui/c-variadic/parse-errors.e2015.fixed b/tests/ui/c-variadic/parse-errors.e2015.fixed new file mode 100644 index 000000000000..042736cdf6c0 --- /dev/null +++ b/tests/ui/c-variadic/parse-errors.e2015.fixed @@ -0,0 +1,36 @@ +//@ check-fail +//@ run-rustfix +//@ revisions: e2015 e2018 +//@[e2015] edition: 2015 +//@[e2018] edition: 2018 +#![crate_type = "lib"] +#![deny(varargs_without_pattern)] + +#[cfg(false)] +mod module { + unsafe extern "C" fn f(_: ...) { + //~^ ERROR missing pattern for `...` argument + //~| WARN this was previously accepted by the compiler + unsafe extern "C" fn f(_: ...) {} + //~^ ERROR missing pattern for `...` argument + //~| WARN this was previously accepted by the compiler + } + + impl A { + unsafe extern "C" fn f(_: ...) {} + //~^ ERROR missing pattern for `...` argument + //~| WARN this was previously accepted by the compiler + } + + trait A { + unsafe extern "C" fn f(...) {} + //[e2018]~^ ERROR missing pattern for `...` argument + //[e2018]~| WARN this was previously accepted by the compiler + } + + unsafe extern "C" { + fn f(...); // no error + } + + type A = unsafe extern "C" fn(...); // no error +} diff --git a/tests/ui/c-variadic/parse-errors.e2015.stderr b/tests/ui/c-variadic/parse-errors.e2015.stderr new file mode 100644 index 000000000000..de9362c4380d --- /dev/null +++ b/tests/ui/c-variadic/parse-errors.e2015.stderr @@ -0,0 +1,46 @@ +error: missing pattern for `...` argument + --> $DIR/parse-errors.rs:11:28 + | +LL | unsafe extern "C" fn f(...) { + | ^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #145544 +note: the lint level is defined here + --> $DIR/parse-errors.rs:7:9 + | +LL | #![deny(varargs_without_pattern)] + | ^^^^^^^^^^^^^^^^^^^^^^^ +help: name the argument, or use `_` to continue ignoring it + | +LL | unsafe extern "C" fn f(_: ...) { + | ++ + +error: missing pattern for `...` argument + --> $DIR/parse-errors.rs:14:32 + | +LL | unsafe extern "C" fn f(...) {} + | ^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #145544 +help: name the argument, or use `_` to continue ignoring it + | +LL | unsafe extern "C" fn f(_: ...) {} + | ++ + +error: missing pattern for `...` argument + --> $DIR/parse-errors.rs:20:32 + | +LL | unsafe extern "C" fn f(...) {} + | ^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #145544 +help: name the argument, or use `_` to continue ignoring it + | +LL | unsafe extern "C" fn f(_: ...) {} + | ++ + +error: aborting due to 3 previous errors + diff --git a/tests/ui/c-variadic/parse-errors.e2018.fixed b/tests/ui/c-variadic/parse-errors.e2018.fixed new file mode 100644 index 000000000000..596e57ca5614 --- /dev/null +++ b/tests/ui/c-variadic/parse-errors.e2018.fixed @@ -0,0 +1,36 @@ +//@ check-fail +//@ run-rustfix +//@ revisions: e2015 e2018 +//@[e2015] edition: 2015 +//@[e2018] edition: 2018 +#![crate_type = "lib"] +#![deny(varargs_without_pattern)] + +#[cfg(false)] +mod module { + unsafe extern "C" fn f(_: ...) { + //~^ ERROR missing pattern for `...` argument + //~| WARN this was previously accepted by the compiler + unsafe extern "C" fn f(_: ...) {} + //~^ ERROR missing pattern for `...` argument + //~| WARN this was previously accepted by the compiler + } + + impl A { + unsafe extern "C" fn f(_: ...) {} + //~^ ERROR missing pattern for `...` argument + //~| WARN this was previously accepted by the compiler + } + + trait A { + unsafe extern "C" fn f(_: ...) {} + //[e2018]~^ ERROR missing pattern for `...` argument + //[e2018]~| WARN this was previously accepted by the compiler + } + + unsafe extern "C" { + fn f(...); // no error + } + + type A = unsafe extern "C" fn(...); // no error +} diff --git a/tests/ui/c-variadic/parse-errors.e2018.stderr b/tests/ui/c-variadic/parse-errors.e2018.stderr new file mode 100644 index 000000000000..a7d5f79bf133 --- /dev/null +++ b/tests/ui/c-variadic/parse-errors.e2018.stderr @@ -0,0 +1,59 @@ +error: missing pattern for `...` argument + --> $DIR/parse-errors.rs:11:28 + | +LL | unsafe extern "C" fn f(...) { + | ^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #145544 +note: the lint level is defined here + --> $DIR/parse-errors.rs:7:9 + | +LL | #![deny(varargs_without_pattern)] + | ^^^^^^^^^^^^^^^^^^^^^^^ +help: name the argument, or use `_` to continue ignoring it + | +LL | unsafe extern "C" fn f(_: ...) { + | ++ + +error: missing pattern for `...` argument + --> $DIR/parse-errors.rs:14:32 + | +LL | unsafe extern "C" fn f(...) {} + | ^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #145544 +help: name the argument, or use `_` to continue ignoring it + | +LL | unsafe extern "C" fn f(_: ...) {} + | ++ + +error: missing pattern for `...` argument + --> $DIR/parse-errors.rs:20:32 + | +LL | unsafe extern "C" fn f(...) {} + | ^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #145544 +help: name the argument, or use `_` to continue ignoring it + | +LL | unsafe extern "C" fn f(_: ...) {} + | ++ + +error: missing pattern for `...` argument + --> $DIR/parse-errors.rs:26:32 + | +LL | unsafe extern "C" fn f(...) {} + | ^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #145544 +help: name the argument, or use `_` to continue ignoring it + | +LL | unsafe extern "C" fn f(_: ...) {} + | ++ + +error: aborting due to 4 previous errors + diff --git a/tests/ui/c-variadic/parse-errors.rs b/tests/ui/c-variadic/parse-errors.rs new file mode 100644 index 000000000000..f8b25c545dd1 --- /dev/null +++ b/tests/ui/c-variadic/parse-errors.rs @@ -0,0 +1,36 @@ +//@ check-fail +//@ run-rustfix +//@ revisions: e2015 e2018 +//@[e2015] edition: 2015 +//@[e2018] edition: 2018 +#![crate_type = "lib"] +#![deny(varargs_without_pattern)] + +#[cfg(false)] +mod module { + unsafe extern "C" fn f(...) { + //~^ ERROR missing pattern for `...` argument + //~| WARN this was previously accepted by the compiler + unsafe extern "C" fn f(...) {} + //~^ ERROR missing pattern for `...` argument + //~| WARN this was previously accepted by the compiler + } + + impl A { + unsafe extern "C" fn f(...) {} + //~^ ERROR missing pattern for `...` argument + //~| WARN this was previously accepted by the compiler + } + + trait A { + unsafe extern "C" fn f(...) {} + //[e2018]~^ ERROR missing pattern for `...` argument + //[e2018]~| WARN this was previously accepted by the compiler + } + + unsafe extern "C" { + fn f(...); // no error + } + + type A = unsafe extern "C" fn(...); // no error +} diff --git a/tests/ui/c-variadic/same-program-multiple-abis-arm.rs b/tests/ui/c-variadic/same-program-multiple-abis-arm.rs index 1445bbb47bbd..fbc5573c5d76 100644 --- a/tests/ui/c-variadic/same-program-multiple-abis-arm.rs +++ b/tests/ui/c-variadic/same-program-multiple-abis-arm.rs @@ -2,6 +2,7 @@ //@ only-arm //@ ignore-thumb (this test uses arm assembly) //@ only-eabihf (the assembly below requires float hardware support) +#![feature(c_variadic, c_variadic_naked_functions)] // Check that multiple c-variadic calling conventions can be used in the same program. // @@ -9,14 +10,6 @@ // argument list, so C programs that use multiple c-variadic calling conventions are unlikely // to come up. Here we validate that our codegen backends do in fact generate correct code. -extern "C" { - fn variadic_c(_: f64, _: ...) -> f64; -} - -extern "aapcs" { - fn variadic_aapcs(_: f64, _: ...) -> f64; -} - fn main() { unsafe { assert_eq!(variadic_c(1.0, 2.0, 3.0), 1.0 + 2.0 + 3.0); @@ -51,10 +44,11 @@ fn main() { // // > This section applies only to non-variadic functions. For a variadic function the base standard // > is always used both for argument passing and result return. -core::arch::global_asm!( - r#" -{variadic_c}: -{variadic_aapcs}: + +#[unsafe(naked)] +unsafe extern "aapcs" fn variadic_aapcs(_: f64, _: ...) -> f64 { + core::arch::naked_asm!( + r#" sub sp, sp, #12 stmib sp, {{r2, r3}} vmov d0, r0, r1 @@ -71,6 +65,10 @@ core::arch::global_asm!( add sp, sp, #12 bx lr "#, - variadic_c = sym variadic_c, - variadic_aapcs = sym variadic_aapcs, -); + ) +} + +#[unsafe(naked)] +unsafe extern "C" fn variadic_c(_: f64, _: ...) -> f64 { + core::arch::naked_asm!("b {}", sym variadic_aapcs) +} diff --git a/tests/ui/c-variadic/same-program-multiple-abis-x86_64.rs b/tests/ui/c-variadic/same-program-multiple-abis-x86_64.rs index aff8ab613c43..b54b63289f34 100644 --- a/tests/ui/c-variadic/same-program-multiple-abis-x86_64.rs +++ b/tests/ui/c-variadic/same-program-multiple-abis-x86_64.rs @@ -1,5 +1,6 @@ //@ run-pass //@ only-x86_64 +#![feature(c_variadic, c_variadic_naked_functions)] // Check that multiple c-variadic calling conventions can be used in the same program. // @@ -7,14 +8,6 @@ // argument list, so C programs that use multiple c-variadic calling conventions are unlikely // to come up. Here we validate that our codegen backends do in fact generate correct code. -extern "sysv64" { - fn variadic_sysv64(_: u32, _: ...) -> u32; -} - -extern "win64" { - fn variadic_win64(_: u32, _: ...) -> u32; -} - fn main() { unsafe { assert_eq!(variadic_win64(1, 2, 3), 1 + 2 + 3); @@ -37,9 +30,11 @@ fn main() { // a + b + c // } // ``` -core::arch::global_asm!( - r#" -{variadic_sysv64}: + +#[unsafe(naked)] +unsafe extern "sysv64" fn variadic_sysv64(_: u32, _: ...) -> u32 { + core::arch::naked_asm!( + r#" sub rsp, 88 test al, al je .LBB0_7 @@ -93,8 +88,14 @@ core::arch::global_asm!( add eax, dword ptr [rcx] add rsp, 88 ret + "#, + ) +} -{variadic_win64}: +#[unsafe(naked)] +unsafe extern "win64" fn variadic_win64(_: u32, _: ...) -> u32 { + core::arch::naked_asm!( + r#" push rax mov qword ptr [rsp + 40], r9 mov qword ptr [rsp + 24], rdx @@ -106,6 +107,5 @@ core::arch::global_asm!( pop rcx ret "#, - variadic_win64 = sym variadic_win64, - variadic_sysv64 = sym variadic_sysv64, -); + ) +} diff --git a/tests/ui/cast/associated-type-bounds-cast-54094.rs b/tests/ui/cast/associated-type-bounds-cast-54094.rs index c9f307e95b9a..1daca9c2cd56 100644 --- a/tests/ui/cast/associated-type-bounds-cast-54094.rs +++ b/tests/ui/cast/associated-type-bounds-cast-54094.rs @@ -1,5 +1,8 @@ // https://github.com/rust-lang/rust/issues/54094 //@ check-pass + +#![allow(function_casts_as_integer)] + trait Zoo { type X; } diff --git a/tests/ui/cast/cast-rfc0401.rs b/tests/ui/cast/cast-rfc0401.rs index f917f93a1c82..cb03065f0a69 100644 --- a/tests/ui/cast/cast-rfc0401.rs +++ b/tests/ui/cast/cast-rfc0401.rs @@ -1,6 +1,6 @@ //@ run-pass -#![allow(dead_code)] +#![allow(dead_code, function_casts_as_integer)] use std::vec; diff --git a/tests/ui/closures/2229_closure_analysis/diagnostics/mut_ref.stderr b/tests/ui/closures/2229_closure_analysis/diagnostics/mut_ref.stderr index 1904faa95986..930659a2c909 100644 --- a/tests/ui/closures/2229_closure_analysis/diagnostics/mut_ref.stderr +++ b/tests/ui/closures/2229_closure_analysis/diagnostics/mut_ref.stderr @@ -2,7 +2,7 @@ error[E0596]: cannot borrow `**ref_mref_x` as mutable, as it is behind a `&` ref --> $DIR/mut_ref.rs:12:13 | LL | let c = || { - | ^^ `ref_mref_x` is a `&` reference, so the data it refers to cannot be borrowed as mutable + | ^^ `ref_mref_x` is a `&` reference, so it cannot be borrowed as mutable LL | LL | **ref_mref_x = y; | ------------ mutable borrow occurs due to use of `**ref_mref_x` in closure diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/c-variadic.rs b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/c-variadic.rs index b3da4ff0120c..d921f5cff627 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/c-variadic.rs +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/c-variadic.rs @@ -21,6 +21,11 @@ async unsafe extern "cmse-nonsecure-entry" fn async_and_c_variadic(_: ...) { //~| ERROR functions cannot be both `async` and C-variadic } +// Async on its own is also not allowed. +async unsafe extern "cmse-nonsecure-entry" fn async_is_not_allowed() { + //~^ ERROR `impl Trait` is not allowed in `extern "cmse-nonsecure-entry"` signatures +} + // Below are the lang items that are required for a program that defines an `async` function. // Without them, the ICE that is tested for here is not reached for this target. For now they are in // this file, but they may be moved into `minicore` if/when other `#[no_core]` tests want to use diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/c-variadic.stderr b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/c-variadic.stderr index 948f8f5747b0..5b0924d6f2af 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/c-variadic.stderr +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/c-variadic.stderr @@ -24,5 +24,12 @@ LL | async unsafe extern "cmse-nonsecure-entry" fn async_and_c_variadic(_: ...) | = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list -error: aborting due to 3 previous errors +error[E0798]: `impl Trait` is not allowed in `extern "cmse-nonsecure-entry"` signatures + --> $DIR/c-variadic.rs:25:1 + | +LL | async unsafe extern "cmse-nonsecure-entry" fn async_is_not_allowed() { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0798`. diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.rs b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.rs index 4b320ded7943..023f50d636bf 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.rs +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.rs @@ -89,3 +89,13 @@ extern "cmse-nonsecure-entry" fn identity_impl_trait_nested( //~^ ERROR `impl Trait` is not allowed in `extern "cmse-nonsecure-entry"` signatures v } + +const extern "cmse-nonsecure-entry" fn const_fn_works(x: u8) -> u8 { + x +} + +const CONST: u8 = const_fn_works(0); + +fn fn_ptr_works(f: extern "cmse-nonsecure-entry" fn(_: u8) -> u8) -> u8 { + f(0) +} diff --git a/tests/ui/consts/const-eval/const_prop_errors.rs b/tests/ui/consts/const-eval/const_prop_errors.rs index 4580944e1bc5..68118da20e5d 100644 --- a/tests/ui/consts/const-eval/const_prop_errors.rs +++ b/tests/ui/consts/const-eval/const_prop_errors.rs @@ -1,5 +1,7 @@ //@ check-pass +#![allow(function_casts_as_integer)] + pub trait Foo { fn foo(self) -> u32; } diff --git a/tests/ui/consts/miri_unleashed/mutable_references.stderr b/tests/ui/consts/miri_unleashed/mutable_references.stderr index b35076b669e2..9bff2711e5f1 100644 --- a/tests/ui/consts/miri_unleashed/mutable_references.stderr +++ b/tests/ui/consts/miri_unleashed/mutable_references.stderr @@ -131,6 +131,9 @@ LL | const RAW_MUT_COERCE: SyncPtr = SyncPtr { x: &mut 0 }; error[E0594]: cannot assign to `*OH_YES`, as `OH_YES` is an immutable static item --> $DIR/mutable_references.rs:109:5 | +LL | static OH_YES: &mut i32 = &mut 42; + | ----------------------- this `static` cannot be written to +... LL | *OH_YES = 99; | ^^^^^^^^^^^^ cannot assign diff --git a/tests/ui/consts/write_to_static_via_mut_ref.stderr b/tests/ui/consts/write_to_static_via_mut_ref.stderr index 1bcd7b81fe05..ce44047f1550 100644 --- a/tests/ui/consts/write_to_static_via_mut_ref.stderr +++ b/tests/ui/consts/write_to_static_via_mut_ref.stderr @@ -11,6 +11,9 @@ LL | static OH_NO: &mut i32 = &mut 42; error[E0594]: cannot assign to `*OH_NO`, as `OH_NO` is an immutable static item --> $DIR/write_to_static_via_mut_ref.rs:4:5 | +LL | static OH_NO: &mut i32 = &mut 42; + | ---------------------- this `static` cannot be written to +... LL | *OH_NO = 43; | ^^^^^^^^^^^ cannot assign diff --git a/tests/ui/deriving/deriving-all-codegen.rs b/tests/ui/deriving/deriving-all-codegen.rs index db58f12d60c2..9f2183196049 100644 --- a/tests/ui/deriving/deriving-all-codegen.rs +++ b/tests/ui/deriving/deriving-all-codegen.rs @@ -24,7 +24,7 @@ use std::from::From; #[derive(Clone, Copy, Debug, Default, Hash, PartialEq, Eq, PartialOrd, Ord)] struct Empty; -// A basic struct. Note: because this derives `Copy`, it gets the simple +// A basic struct. Note: because this derives `Copy`, it gets the trivial // `clone` implemention that just does `*self`. #[derive(Clone, Copy, Debug, Default, Hash, PartialEq, Eq, PartialOrd, Ord)] struct Point { @@ -32,7 +32,7 @@ struct Point { y: u32, } -// A basic packed struct. Note: because this derives `Copy`, it gets the simple +// A basic packed struct. Note: because this derives `Copy`, it gets the trivial // `clone` implemention that just does `*self`. #[derive(Clone, Copy, Debug, Default, Hash, PartialEq, Eq, PartialOrd, Ord)] #[repr(packed)] @@ -49,7 +49,7 @@ struct SingleField { foo: bool, } -// A large struct. Note: because this derives `Copy`, it gets the simple +// A large struct. Note: because this derives `Copy`, it gets the trivial // `clone` implemention that just does `*self`. #[derive(Clone, Copy, Debug, Default, Hash, PartialEq, Eq, PartialOrd, Ord)] struct Big { @@ -79,25 +79,25 @@ struct Reorder { b10: &'static *const bool, } -// A struct that doesn't impl `Copy`, which means it gets the non-simple +// A struct that doesn't impl `Copy`, which means it gets the non-trivial // `clone` implemention that clones the fields individually. #[derive(Clone)] struct NonCopy(u32); -// A packed struct that doesn't impl `Copy`, which means it gets the non-simple +// A packed struct that doesn't impl `Copy`, which means it gets the non-trivial // `clone` implemention that clones the fields individually. #[derive(Clone)] #[repr(packed)] struct PackedNonCopy(u32); -// A struct that impls `Copy` manually, which means it gets the non-simple +// A struct that impls `Copy` manually, which means it gets the non-trivial // `clone` implemention that clones the fields individually. #[derive(Clone)] struct ManualCopy(u32); impl Copy for ManualCopy {} // A packed struct that impls `Copy` manually, which means it gets the -// non-simple `clone` implemention that clones the fields individually. +// non-trivial `clone` implemention that clones the fields individually. #[derive(Clone)] #[repr(packed)] struct PackedManualCopy(u32); @@ -218,3 +218,20 @@ pub union Union { pub u: u32, pub i: i32, } + +#[derive(Copy, Clone)] +struct FooCopyClone(i32); + +#[derive(Clone, Copy)] +struct FooCloneCopy(i32); + +#[derive(Copy)] +#[derive(Clone)] +struct FooCopyAndClone(i32); + +// FIXME(#124794): the previous three structs all have a trivial `Copy`-aware +// `clone`. But this one doesn't because when the `clone` is generated the +// `derive(Copy)` hasn't yet been seen. +#[derive(Clone)] +#[derive(Copy)] +struct FooCloneAndCopy(i32); diff --git a/tests/ui/deriving/deriving-all-codegen.stdout b/tests/ui/deriving/deriving-all-codegen.stdout index 4c60b1cf4275..a40dece22a26 100644 --- a/tests/ui/deriving/deriving-all-codegen.stdout +++ b/tests/ui/deriving/deriving-all-codegen.stdout @@ -28,6 +28,9 @@ use std::from::From; // Empty struct. struct Empty; #[automatically_derived] +#[doc(hidden)] +unsafe impl ::core::clone::TrivialClone for Empty { } +#[automatically_derived] impl ::core::clone::Clone for Empty { #[inline] fn clone(&self) -> Empty { *self } @@ -81,13 +84,16 @@ impl ::core::cmp::Ord for Empty { } } -// A basic struct. Note: because this derives `Copy`, it gets the simple +// A basic struct. Note: because this derives `Copy`, it gets the trivial // `clone` implemention that just does `*self`. struct Point { x: u32, y: u32, } #[automatically_derived] +#[doc(hidden)] +unsafe impl ::core::clone::TrivialClone for Point { } +#[automatically_derived] impl ::core::clone::Clone for Point { #[inline] fn clone(&self) -> Point { @@ -165,7 +171,7 @@ impl ::core::cmp::Ord for Point { } } -// A basic packed struct. Note: because this derives `Copy`, it gets the simple +// A basic packed struct. Note: because this derives `Copy`, it gets the trivial // `clone` implemention that just does `*self`. #[repr(packed)] struct PackedPoint { @@ -173,6 +179,9 @@ struct PackedPoint { y: u32, } #[automatically_derived] +#[doc(hidden)] +unsafe impl ::core::clone::TrivialClone for PackedPoint { } +#[automatically_derived] impl ::core::clone::Clone for PackedPoint { #[inline] fn clone(&self) -> PackedPoint { @@ -254,6 +263,9 @@ impl ::core::cmp::Ord for PackedPoint { struct TupleSingleField(u32); #[automatically_derived] +#[doc(hidden)] +unsafe impl ::core::clone::TrivialClone for TupleSingleField { } +#[automatically_derived] impl ::core::clone::Clone for TupleSingleField { #[inline] fn clone(&self) -> TupleSingleField { @@ -326,6 +338,9 @@ struct SingleField { foo: bool, } #[automatically_derived] +#[doc(hidden)] +unsafe impl ::core::clone::TrivialClone for SingleField { } +#[automatically_derived] impl ::core::clone::Clone for SingleField { #[inline] fn clone(&self) -> SingleField { @@ -394,7 +409,7 @@ impl ::core::cmp::Ord for SingleField { } } -// A large struct. Note: because this derives `Copy`, it gets the simple +// A large struct. Note: because this derives `Copy`, it gets the trivial // `clone` implemention that just does `*self`. struct Big { b1: u32, @@ -407,6 +422,9 @@ struct Big { b8: u32, } #[automatically_derived] +#[doc(hidden)] +unsafe impl ::core::clone::TrivialClone for Big { } +#[automatically_derived] impl ::core::clone::Clone for Big { #[inline] fn clone(&self) -> Big { @@ -658,7 +676,7 @@ impl ::core::cmp::PartialOrd for Reorder { } } -// A struct that doesn't impl `Copy`, which means it gets the non-simple +// A struct that doesn't impl `Copy`, which means it gets the non-trivial // `clone` implemention that clones the fields individually. struct NonCopy(u32); #[automatically_derived] @@ -669,7 +687,7 @@ impl ::core::clone::Clone for NonCopy { } } -// A packed struct that doesn't impl `Copy`, which means it gets the non-simple +// A packed struct that doesn't impl `Copy`, which means it gets the non-trivial // `clone` implemention that clones the fields individually. #[repr(packed)] struct PackedNonCopy(u32); @@ -681,7 +699,7 @@ impl ::core::clone::Clone for PackedNonCopy { } } -// A struct that impls `Copy` manually, which means it gets the non-simple +// A struct that impls `Copy` manually, which means it gets the non-trivial // `clone` implemention that clones the fields individually. struct ManualCopy(u32); #[automatically_derived] @@ -694,7 +712,7 @@ impl ::core::clone::Clone for ManualCopy { impl Copy for ManualCopy {} // A packed struct that impls `Copy` manually, which means it gets the -// non-simple `clone` implemention that clones the fields individually. +// non-trivial `clone` implemention that clones the fields individually. #[repr(packed)] struct PackedManualCopy(u32); #[automatically_derived] @@ -1007,6 +1025,9 @@ impl Enum0 { *self } @@ -1202,6 +1223,9 @@ enum Fieldless { C, } #[automatically_derived] +#[doc(hidden)] +unsafe impl ::core::clone::TrivialClone for Fieldless { } +#[automatically_derived] impl ::core::clone::Clone for Fieldless { #[inline] fn clone(&self) -> Fieldless { *self } @@ -1284,6 +1308,9 @@ enum Mixed { }, } #[automatically_derived] +#[doc(hidden)] +unsafe impl ::core::clone::TrivialClone for Mixed { } +#[automatically_derived] impl ::core::clone::Clone for Mixed { #[inline] fn clone(&self) -> Mixed { @@ -1752,6 +1779,9 @@ pub union Union { pub i: i32, } #[automatically_derived] +#[doc(hidden)] +unsafe impl ::core::clone::TrivialClone for Union { } +#[automatically_derived] impl ::core::clone::Clone for Union { #[inline] fn clone(&self) -> Union { @@ -1761,3 +1791,62 @@ impl ::core::clone::Clone for Union { } #[automatically_derived] impl ::core::marker::Copy for Union { } + +struct FooCopyClone(i32); +#[automatically_derived] +impl ::core::marker::Copy for FooCopyClone { } +#[automatically_derived] +#[doc(hidden)] +unsafe impl ::core::clone::TrivialClone for FooCopyClone { } +#[automatically_derived] +impl ::core::clone::Clone for FooCopyClone { + #[inline] + fn clone(&self) -> FooCopyClone { + let _: ::core::clone::AssertParamIsClone; + *self + } +} + +struct FooCloneCopy(i32); +#[automatically_derived] +#[doc(hidden)] +unsafe impl ::core::clone::TrivialClone for FooCloneCopy { } +#[automatically_derived] +impl ::core::clone::Clone for FooCloneCopy { + #[inline] + fn clone(&self) -> FooCloneCopy { + let _: ::core::clone::AssertParamIsClone; + *self + } +} +#[automatically_derived] +impl ::core::marker::Copy for FooCloneCopy { } + +struct FooCopyAndClone(i32); +#[automatically_derived] +#[doc(hidden)] +unsafe impl ::core::clone::TrivialClone for FooCopyAndClone { } +#[automatically_derived] +impl ::core::clone::Clone for FooCopyAndClone { + #[inline] + fn clone(&self) -> FooCopyAndClone { + let _: ::core::clone::AssertParamIsClone; + *self + } +} +#[automatically_derived] +impl ::core::marker::Copy for FooCopyAndClone { } + +// FIXME(#124794): the previous three structs all have a trivial `Copy`-aware +// `clone`. But this one doesn't because when the `clone` is generated the +// `derive(Copy)` hasn't yet been seen. +struct FooCloneAndCopy(i32); +#[automatically_derived] +impl ::core::marker::Copy for FooCloneAndCopy { } +#[automatically_derived] +impl ::core::clone::Clone for FooCloneAndCopy { + #[inline] + fn clone(&self) -> FooCloneAndCopy { + FooCloneAndCopy(::core::clone::Clone::clone(&self.0)) + } +} diff --git a/tests/ui/did_you_mean/issue-38147-1.stderr b/tests/ui/did_you_mean/issue-38147-1.stderr index 6def86e4ba8f..1a6d1986c55b 100644 --- a/tests/ui/did_you_mean/issue-38147-1.stderr +++ b/tests/ui/did_you_mean/issue-38147-1.stderr @@ -2,7 +2,7 @@ error[E0596]: cannot borrow `*self.s` as mutable, as it is behind a `&` referenc --> $DIR/issue-38147-1.rs:17:9 | LL | self.s.push('x'); - | ^^^^^^ `self` is a `&` reference, so the data it refers to cannot be borrowed as mutable + | ^^^^^^ `self` is a `&` reference, so it cannot be borrowed as mutable | help: consider changing this to be a mutable reference | diff --git a/tests/ui/did_you_mean/issue-38147-4.stderr b/tests/ui/did_you_mean/issue-38147-4.stderr index 57309172194f..1592238d6bed 100644 --- a/tests/ui/did_you_mean/issue-38147-4.stderr +++ b/tests/ui/did_you_mean/issue-38147-4.stderr @@ -2,7 +2,7 @@ error[E0596]: cannot borrow `*f.s` as mutable, as it is behind a `&` reference --> $DIR/issue-38147-4.rs:6:5 | LL | f.s.push('x'); - | ^^^ `f` is a `&` reference, so the data it refers to cannot be borrowed as mutable + | ^^^ `f` is a `&` reference, so it cannot be borrowed as mutable | help: consider changing this to be a mutable reference | diff --git a/tests/ui/did_you_mean/issue-39544.stderr b/tests/ui/did_you_mean/issue-39544.stderr index 62dc027e31f2..745ff2bac06d 100644 --- a/tests/ui/did_you_mean/issue-39544.stderr +++ b/tests/ui/did_you_mean/issue-39544.stderr @@ -13,7 +13,7 @@ error[E0596]: cannot borrow `self.x` as mutable, as it is behind a `&` reference --> $DIR/issue-39544.rs:16:17 | LL | let _ = &mut self.x; - | ^^^^^^^^^^^ `self` is a `&` reference, so the data it refers to cannot be borrowed as mutable + | ^^^^^^^^^^^ `self` is a `&` reference, so it cannot be borrowed as mutable | help: consider changing this to be a mutable reference | @@ -24,7 +24,7 @@ error[E0596]: cannot borrow `self.x` as mutable, as it is behind a `&` reference --> $DIR/issue-39544.rs:20:17 | LL | let _ = &mut self.x; - | ^^^^^^^^^^^ `self` is a `&` reference, so the data it refers to cannot be borrowed as mutable + | ^^^^^^^^^^^ `self` is a `&` reference, so it cannot be borrowed as mutable | help: consider changing this to be a mutable reference | @@ -35,7 +35,7 @@ error[E0596]: cannot borrow `other.x` as mutable, as it is behind a `&` referenc --> $DIR/issue-39544.rs:21:17 | LL | let _ = &mut other.x; - | ^^^^^^^^^^^^ `other` is a `&` reference, so the data it refers to cannot be borrowed as mutable + | ^^^^^^^^^^^^ `other` is a `&` reference, so it cannot be borrowed as mutable | help: consider changing this to be a mutable reference | @@ -46,7 +46,7 @@ error[E0596]: cannot borrow `self.x` as mutable, as it is behind a `&` reference --> $DIR/issue-39544.rs:25:17 | LL | let _ = &mut self.x; - | ^^^^^^^^^^^ `self` is a `&` reference, so the data it refers to cannot be borrowed as mutable + | ^^^^^^^^^^^ `self` is a `&` reference, so it cannot be borrowed as mutable | help: consider changing this to be a mutable reference | @@ -57,7 +57,7 @@ error[E0596]: cannot borrow `other.x` as mutable, as it is behind a `&` referenc --> $DIR/issue-39544.rs:26:17 | LL | let _ = &mut other.x; - | ^^^^^^^^^^^^ `other` is a `&` reference, so the data it refers to cannot be borrowed as mutable + | ^^^^^^^^^^^^ `other` is a `&` reference, so it cannot be borrowed as mutable | help: consider changing this to be a mutable reference | @@ -68,7 +68,7 @@ error[E0596]: cannot borrow `self.x` as mutable, as it is behind a `&` reference --> $DIR/issue-39544.rs:30:17 | LL | let _ = &mut self.x; - | ^^^^^^^^^^^ `self` is a `&` reference, so the data it refers to cannot be borrowed as mutable + | ^^^^^^^^^^^ `self` is a `&` reference, so it cannot be borrowed as mutable | help: consider changing this to be a mutable reference | @@ -79,7 +79,7 @@ error[E0596]: cannot borrow `other.x` as mutable, as it is behind a `&` referenc --> $DIR/issue-39544.rs:31:17 | LL | let _ = &mut other.x; - | ^^^^^^^^^^^^ `other` is a `&` reference, so the data it refers to cannot be borrowed as mutable + | ^^^^^^^^^^^^ `other` is a `&` reference, so it cannot be borrowed as mutable | help: consider changing this to be a mutable reference | @@ -90,7 +90,7 @@ error[E0596]: cannot borrow `other.x` as mutable, as it is behind a `&` referenc --> $DIR/issue-39544.rs:35:17 | LL | let _ = &mut other.x; - | ^^^^^^^^^^^^ `other` is a `&` reference, so the data it refers to cannot be borrowed as mutable + | ^^^^^^^^^^^^ `other` is a `&` reference, so it cannot be borrowed as mutable | help: consider changing this to be a mutable reference | @@ -112,7 +112,7 @@ error[E0596]: cannot borrow `w.x` as mutable, as it is behind a `&` reference --> $DIR/issue-39544.rs:42:13 | LL | let _ = &mut w.x; - | ^^^^^^^^ `w` is a `&` reference, so the data it refers to cannot be borrowed as mutable + | ^^^^^^^^ `w` is a `&` reference, so it cannot be borrowed as mutable | help: consider changing this to be a mutable reference | diff --git a/tests/ui/did_you_mean/issue-40823.stderr b/tests/ui/did_you_mean/issue-40823.stderr index d9f69eb47d24..cf75b20c8145 100644 --- a/tests/ui/did_you_mean/issue-40823.stderr +++ b/tests/ui/did_you_mean/issue-40823.stderr @@ -2,7 +2,7 @@ error[E0596]: cannot borrow `*buf` as mutable, as it is behind a `&` reference --> $DIR/issue-40823.rs:3:5 | LL | buf.iter_mut(); - | ^^^ `buf` is a `&` reference, so the data it refers to cannot be borrowed as mutable + | ^^^ `buf` is a `&` reference, so it cannot be borrowed as mutable | help: consider changing this to be a mutable reference | diff --git a/tests/ui/error-codes/E0017.stderr b/tests/ui/error-codes/E0017.stderr index 2039e5564701..fcc57b9e5c3c 100644 --- a/tests/ui/error-codes/E0017.stderr +++ b/tests/ui/error-codes/E0017.stderr @@ -26,6 +26,9 @@ LL | const CR: &'static mut i32 = &mut C; error[E0596]: cannot borrow immutable static item `X` as mutable --> $DIR/E0017.rs:11:39 | +LL | static X: i32 = 1; + | ------------- this `static` cannot be borrowed as mutable +... LL | static STATIC_REF: &'static mut i32 = &mut X; | ^^^^^^ cannot borrow as mutable diff --git a/tests/ui/error-codes/E0389.stderr b/tests/ui/error-codes/E0389.stderr index 156bff7f0223..c4dcab886a11 100644 --- a/tests/ui/error-codes/E0389.stderr +++ b/tests/ui/error-codes/E0389.stderr @@ -2,7 +2,7 @@ error[E0594]: cannot assign to `fancy_ref.num`, which is behind a `&` reference --> $DIR/E0389.rs:8:5 | LL | fancy_ref.num = 6; - | ^^^^^^^^^^^^^^^^^ `fancy_ref` is a `&` reference, so the data it refers to cannot be written + | ^^^^^^^^^^^^^^^^^ `fancy_ref` is a `&` reference, so it cannot be written to | help: consider changing this to be a mutable reference | diff --git a/tests/ui/error-codes/E0594.stderr b/tests/ui/error-codes/E0594.stderr index e010cda83ff9..3519d0881fad 100644 --- a/tests/ui/error-codes/E0594.stderr +++ b/tests/ui/error-codes/E0594.stderr @@ -1,6 +1,9 @@ error[E0594]: cannot assign to immutable static item `NUM` --> $DIR/E0594.rs:4:5 | +LL | static NUM: i32 = 18; + | --------------- this `static` cannot be written to +... LL | NUM = 20; | ^^^^^^^^ cannot assign diff --git a/tests/ui/extern/extern-C-non-FFI-safe-arg-ice-52334.rs b/tests/ui/extern/extern-C-non-FFI-safe-arg-ice-52334.rs index 33d295f7ebe1..084c5ba73fcb 100644 --- a/tests/ui/extern/extern-C-non-FFI-safe-arg-ice-52334.rs +++ b/tests/ui/extern/extern-C-non-FFI-safe-arg-ice-52334.rs @@ -4,6 +4,8 @@ //@ normalize-stderr: "\[i8\]" -> "[i8 or u8 (arch dependant)]" //@ normalize-stderr: "\[u8\]" -> "[i8 or u8 (arch dependant)]" +#![allow(function_casts_as_integer)] + type Foo = extern "C" fn(::std::ffi::CStr); //~^ WARN `extern` fn uses type extern "C" { diff --git a/tests/ui/extern/extern-C-non-FFI-safe-arg-ice-52334.stderr b/tests/ui/extern/extern-C-non-FFI-safe-arg-ice-52334.stderr index 044c1ae2dd42..3b98f9a55f8e 100644 --- a/tests/ui/extern/extern-C-non-FFI-safe-arg-ice-52334.stderr +++ b/tests/ui/extern/extern-C-non-FFI-safe-arg-ice-52334.stderr @@ -1,5 +1,5 @@ warning: `extern` fn uses type `CStr`, which is not FFI-safe - --> $DIR/extern-C-non-FFI-safe-arg-ice-52334.rs:7:12 + --> $DIR/extern-C-non-FFI-safe-arg-ice-52334.rs:9:12 | LL | type Foo = extern "C" fn(::std::ffi::CStr); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -9,7 +9,7 @@ LL | type Foo = extern "C" fn(::std::ffi::CStr); = note: `#[warn(improper_ctypes_definitions)]` on by default warning: `extern` block uses type `CStr`, which is not FFI-safe - --> $DIR/extern-C-non-FFI-safe-arg-ice-52334.rs:10:18 + --> $DIR/extern-C-non-FFI-safe-arg-ice-52334.rs:12:18 | LL | fn meh(blah: Foo); | ^^^ not FFI-safe diff --git a/tests/ui/feature-gates/feature-gate-c_variadic-naked-functions.rs b/tests/ui/feature-gates/feature-gate-c_variadic-naked-functions.rs new file mode 100644 index 000000000000..bf52c4d0cf52 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-c_variadic-naked-functions.rs @@ -0,0 +1,27 @@ +//@ add-minicore +//@ compile-flags: --target x86_64-unknown-linux-gnu +//@ needs-llvm-components: x86 +//@ ignore-backends: gcc + +#![feature(no_core, lang_items, rustc_attrs)] +#![feature(c_variadic, abi_x86_interrupt, naked_functions_rustic_abi)] +#![crate_type = "rlib"] +#![no_core] + +extern crate minicore; +use minicore::*; + +#[repr(C)] +#[lang = "va_list"] +pub struct VaList; + +#[unsafe(naked)] +unsafe extern "sysv64" fn c_variadic_sysv64(_: ...) { + //~^ ERROR Naked c-variadic `extern "sysv64"` functions are unstable + naked_asm!("ret") +} + +#[unsafe(naked)] +unsafe extern "C" fn c_variadic_c(_: ...) { + naked_asm!("ret") +} diff --git a/tests/ui/feature-gates/feature-gate-c_variadic-naked-functions.stderr b/tests/ui/feature-gates/feature-gate-c_variadic-naked-functions.stderr new file mode 100644 index 000000000000..fc44747a4fad --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-c_variadic-naked-functions.stderr @@ -0,0 +1,13 @@ +error[E0658]: Naked c-variadic `extern "sysv64"` functions are unstable + --> $DIR/feature-gate-c_variadic-naked-functions.rs:19:1 + | +LL | unsafe extern "sysv64" fn c_variadic_sysv64(_: ...) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #148767 for more information + = help: add `#![feature(c_variadic_naked_functions)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/feature-gates/feature-gate-pin_ergonomics.rs b/tests/ui/feature-gates/feature-gate-pin_ergonomics.rs index 07aba0d1d281..7f669d0b93e5 100644 --- a/tests/ui/feature-gates/feature-gate-pin_ergonomics.rs +++ b/tests/ui/feature-gates/feature-gate-pin_ergonomics.rs @@ -47,6 +47,17 @@ fn borrows() { foo_const(x); } +fn patterns<'a>( + &pin mut x: &pin mut i32, + //~^ ERROR pinned reference syntax is experimental + //~| ERROR pinned reference syntax is experimental + &pin const y: &'a pin const i32, + //~^ ERROR pinned reference syntax is experimental + //~| ERROR pinned reference syntax is experimental + ref pin mut z: i32, //~ ERROR pinned reference syntax is experimental + ref pin const w: i32, //~ ERROR pinned reference syntax is experimental +) {} + #[cfg(any())] mod not_compiled { use std::pin::Pin; @@ -91,6 +102,17 @@ mod not_compiled { foo_const(x); foo_const(x); } + + fn patterns<'a>( + &pin mut x: &pin mut i32, + //~^ ERROR pinned reference syntax is experimental + //~| ERROR pinned reference syntax is experimental + &pin const y: &'a pin const i32, + //~^ ERROR pinned reference syntax is experimental + //~| ERROR pinned reference syntax is experimental + ref pin mut z: i32, //~ ERROR pinned reference syntax is experimental + ref pin const w: i32, //~ ERROR pinned reference syntax is experimental + ) {} } fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-pin_ergonomics.stderr b/tests/ui/feature-gates/feature-gate-pin_ergonomics.stderr index cff564c01fc6..b721654a506f 100644 --- a/tests/ui/feature-gates/feature-gate-pin_ergonomics.stderr +++ b/tests/ui/feature-gates/feature-gate-pin_ergonomics.stderr @@ -79,7 +79,67 @@ LL | let x: Pin<&_> = &pin const Foo; = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: pinned reference syntax is experimental - --> $DIR/feature-gate-pin_ergonomics.rs:59:23 + --> $DIR/feature-gate-pin_ergonomics.rs:51:6 + | +LL | &pin mut x: &pin mut i32, + | ^^^ + | + = note: see issue #130494 for more information + = help: add `#![feature(pin_ergonomics)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: pinned reference syntax is experimental + --> $DIR/feature-gate-pin_ergonomics.rs:51:18 + | +LL | &pin mut x: &pin mut i32, + | ^^^ + | + = note: see issue #130494 for more information + = help: add `#![feature(pin_ergonomics)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: pinned reference syntax is experimental + --> $DIR/feature-gate-pin_ergonomics.rs:54:6 + | +LL | &pin const y: &'a pin const i32, + | ^^^ + | + = note: see issue #130494 for more information + = help: add `#![feature(pin_ergonomics)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: pinned reference syntax is experimental + --> $DIR/feature-gate-pin_ergonomics.rs:54:23 + | +LL | &pin const y: &'a pin const i32, + | ^^^ + | + = note: see issue #130494 for more information + = help: add `#![feature(pin_ergonomics)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: pinned reference syntax is experimental + --> $DIR/feature-gate-pin_ergonomics.rs:57:9 + | +LL | ref pin mut z: i32, + | ^^^ + | + = note: see issue #130494 for more information + = help: add `#![feature(pin_ergonomics)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: pinned reference syntax is experimental + --> $DIR/feature-gate-pin_ergonomics.rs:58:9 + | +LL | ref pin const w: i32, + | ^^^ + | + = note: see issue #130494 for more information + = help: add `#![feature(pin_ergonomics)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: pinned reference syntax is experimental + --> $DIR/feature-gate-pin_ergonomics.rs:70:23 | LL | fn foo_sugar(&pin mut self) {} | ^^^ @@ -89,7 +149,7 @@ LL | fn foo_sugar(&pin mut self) {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: pinned reference syntax is experimental - --> $DIR/feature-gate-pin_ergonomics.rs:60:29 + --> $DIR/feature-gate-pin_ergonomics.rs:71:29 | LL | fn foo_sugar_const(&pin const self) {} | ^^^ @@ -99,7 +159,7 @@ LL | fn foo_sugar_const(&pin const self) {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: pinned reference syntax is experimental - --> $DIR/feature-gate-pin_ergonomics.rs:66:18 + --> $DIR/feature-gate-pin_ergonomics.rs:77:18 | LL | let _y: &pin mut Foo = x; | ^^^ @@ -109,7 +169,7 @@ LL | let _y: &pin mut Foo = x; = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: pinned reference syntax is experimental - --> $DIR/feature-gate-pin_ergonomics.rs:69:22 + --> $DIR/feature-gate-pin_ergonomics.rs:80:22 | LL | fn foo_sugar(_: &pin mut Foo) {} | ^^^ @@ -119,7 +179,7 @@ LL | fn foo_sugar(_: &pin mut Foo) {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: pinned reference syntax is experimental - --> $DIR/feature-gate-pin_ergonomics.rs:81:22 + --> $DIR/feature-gate-pin_ergonomics.rs:92:22 | LL | fn baz_sugar(_: &pin const Foo) {} | ^^^ @@ -129,7 +189,7 @@ LL | fn baz_sugar(_: &pin const Foo) {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: pinned reference syntax is experimental - --> $DIR/feature-gate-pin_ergonomics.rs:84:35 + --> $DIR/feature-gate-pin_ergonomics.rs:95:35 | LL | let mut x: Pin<&mut _> = &pin mut Foo; | ^^^ @@ -139,7 +199,7 @@ LL | let mut x: Pin<&mut _> = &pin mut Foo; = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: pinned reference syntax is experimental - --> $DIR/feature-gate-pin_ergonomics.rs:89:27 + --> $DIR/feature-gate-pin_ergonomics.rs:100:27 | LL | let x: Pin<&_> = &pin const Foo; | ^^^ @@ -148,6 +208,66 @@ LL | let x: Pin<&_> = &pin const Foo; = help: add `#![feature(pin_ergonomics)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date +error[E0658]: pinned reference syntax is experimental + --> $DIR/feature-gate-pin_ergonomics.rs:107:10 + | +LL | &pin mut x: &pin mut i32, + | ^^^ + | + = note: see issue #130494 for more information + = help: add `#![feature(pin_ergonomics)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: pinned reference syntax is experimental + --> $DIR/feature-gate-pin_ergonomics.rs:107:22 + | +LL | &pin mut x: &pin mut i32, + | ^^^ + | + = note: see issue #130494 for more information + = help: add `#![feature(pin_ergonomics)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: pinned reference syntax is experimental + --> $DIR/feature-gate-pin_ergonomics.rs:110:10 + | +LL | &pin const y: &'a pin const i32, + | ^^^ + | + = note: see issue #130494 for more information + = help: add `#![feature(pin_ergonomics)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: pinned reference syntax is experimental + --> $DIR/feature-gate-pin_ergonomics.rs:110:27 + | +LL | &pin const y: &'a pin const i32, + | ^^^ + | + = note: see issue #130494 for more information + = help: add `#![feature(pin_ergonomics)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: pinned reference syntax is experimental + --> $DIR/feature-gate-pin_ergonomics.rs:113:13 + | +LL | ref pin mut z: i32, + | ^^^ + | + = note: see issue #130494 for more information + = help: add `#![feature(pin_ergonomics)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: pinned reference syntax is experimental + --> $DIR/feature-gate-pin_ergonomics.rs:114:13 + | +LL | ref pin const w: i32, + | ^^^ + | + = note: see issue #130494 for more information + = help: add `#![feature(pin_ergonomics)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + error[E0658]: the `#[pin_v2]` attribute is an experimental feature --> $DIR/feature-gate-pin_ergonomics.rs:5:1 | @@ -196,7 +316,7 @@ help: consider reborrowing the `Pin` instead of moving it LL | x.as_mut().foo(); | +++++++++ -error: aborting due to 18 previous errors +error: aborting due to 30 previous errors Some errors have detailed explanations: E0382, E0658. For more information about an error, try `rustc --explain E0382`. diff --git a/tests/ui/for/iter_from_mac_call.rs b/tests/ui/for/iter_from_mac_call.rs new file mode 100644 index 000000000000..8df21456222c --- /dev/null +++ b/tests/ui/for/iter_from_mac_call.rs @@ -0,0 +1,26 @@ +macro_rules! deref { + ($e:expr) => { *$e }; +} + +fn f1<'a>(mut iter: Box>) { + for item in deref!(iter) { *item = 0 } + //~^ ERROR `dyn Iterator` is not an iterator +} + +fn f2(x: &mut i32) { + for _item in deref!(x) {} + //~^ ERROR `i32` is not an iterator +} + +struct Wrapped(i32); + +macro_rules! borrow_deref { + ($e:expr) => { &mut *$e }; +} + +fn f3<'a>(mut iter: Box>) { + for Wrapped(item) in borrow_deref!(iter) { *item = 0 } + //~^ ERROR mismatched types +} + +fn main() {} diff --git a/tests/ui/for/iter_from_mac_call.stderr b/tests/ui/for/iter_from_mac_call.stderr new file mode 100644 index 000000000000..e62efb250e29 --- /dev/null +++ b/tests/ui/for/iter_from_mac_call.stderr @@ -0,0 +1,35 @@ +error[E0277]: `dyn Iterator` is not an iterator + --> $DIR/iter_from_mac_call.rs:6:17 + | +LL | for item in deref!(iter) { *item = 0 } + | ^^^^^^^^^^^^ the trait `IntoIterator` is not implemented for `dyn Iterator` + | + = note: the trait bound `dyn Iterator: IntoIterator` is not satisfied + = note: required for `dyn Iterator` to implement `IntoIterator` +help: consider mutably borrowing here + | +LL | for item in &mut deref!(iter) { *item = 0 } + | ++++ + +error[E0277]: `i32` is not an iterator + --> $DIR/iter_from_mac_call.rs:11:18 + | +LL | for _item in deref!(x) {} + | ^^^^^^^^^ `i32` is not an iterator + | + = help: the trait `Iterator` is not implemented for `i32` + = note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end` + = note: required for `i32` to implement `IntoIterator` + +error[E0308]: mismatched types + --> $DIR/iter_from_mac_call.rs:22:9 + | +LL | for Wrapped(item) in borrow_deref!(iter) { *item = 0 } + | ^^^^^^^^^^^^^ ------------------- this is an iterator with items of type `&mut i32` + | | + | expected `i32`, found `Wrapped` + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0277, E0308. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/functions-closures/trivial-clone-closure.rs b/tests/ui/functions-closures/trivial-clone-closure.rs new file mode 100644 index 000000000000..5f45d500543a --- /dev/null +++ b/tests/ui/functions-closures/trivial-clone-closure.rs @@ -0,0 +1,13 @@ +//@ run-pass +// Check that closures implement `TrivialClone`. + +#![feature(trivial_clone)] + +use std::clone::TrivialClone; + +fn require_trivial_clone(_t: T) {} + +fn main() { + let some_trivial_clone_value = 42i32; + require_trivial_clone(move || some_trivial_clone_value); +} diff --git a/tests/ui/generic-associated-types/must-prove-where-clauses-on-norm.current.stderr b/tests/ui/generic-associated-types/must-prove-where-clauses-on-norm.current.stderr new file mode 100644 index 000000000000..2e7e8c12e671 --- /dev/null +++ b/tests/ui/generic-associated-types/must-prove-where-clauses-on-norm.current.stderr @@ -0,0 +1,10 @@ +error: higher-ranked lifetime error + --> $DIR/must-prove-where-clauses-on-norm.rs:23:61 + | +LL | let func: for<'a, 'b> fn((), &'b str) -> &'static str = foo::<()>; + | ^^^^^^^^^ + | + = note: could not normalize `for<'b> fn(<() as Trait>::Assoc<'_, 'b>, &'b str) -> &str` + +error: aborting due to 1 previous error + diff --git a/tests/ui/generic-associated-types/must-prove-where-clauses-on-norm.next.stderr b/tests/ui/generic-associated-types/must-prove-where-clauses-on-norm.next.stderr new file mode 100644 index 000000000000..ab51e2bdae77 --- /dev/null +++ b/tests/ui/generic-associated-types/must-prove-where-clauses-on-norm.next.stderr @@ -0,0 +1,14 @@ +error[E0308]: mismatched types + --> $DIR/must-prove-where-clauses-on-norm.rs:23:61 + | +LL | let func: for<'a, 'b> fn((), &'b str) -> &'static str = foo::<()>; + | ------------------------------------------- ^^^^^^^^^ one type is more general than the other + | | + | expected due to this + | + = note: expected fn pointer `for<'b> fn((), &'b _) -> &'static _` + found fn item `for<'b> fn(<() as Trait>::Assoc<'_, 'b>, &'b _) -> &_ {foo::<'_, ()>}` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/generic-associated-types/must-prove-where-clauses-on-norm.rs b/tests/ui/generic-associated-types/must-prove-where-clauses-on-norm.rs new file mode 100644 index 000000000000..064ed1824820 --- /dev/null +++ b/tests/ui/generic-associated-types/must-prove-where-clauses-on-norm.rs @@ -0,0 +1,28 @@ +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver + +// We have to prove implied bounds of higher-ranked types at some point. +// Normalizing associated types can drop requirements. This means we need +// to prove well-formedness when normalizing them, at least as long as +// implied bounds are implicit. + +trait Trait { + type Assoc<'a, 'b: 'a>; +} + +impl Trait for () { + type Assoc<'a, 'b: 'a> = (); +} + +fn foo<'a, 'b, T: Trait>(_: ::Assoc<'a, 'b>, x: &'b str) -> &'a str { + x +} + +fn main() { + let func: for<'a, 'b> fn((), &'b str) -> &'static str = foo::<()>; + //[current]~^ ERROR higher-ranked lifetime error + //[next]~^^ ERROR mismatched types + let x: &'static str = func((), &String::from("temporary")); + println!("{x}"); +} diff --git a/tests/ui/impl-trait/in-trait/missing-static-bound-from-impl.stderr b/tests/ui/impl-trait/in-trait/missing-static-bound-from-impl.stderr index 1f787c1842cf..d854a457485d 100644 --- a/tests/ui/impl-trait/in-trait/missing-static-bound-from-impl.stderr +++ b/tests/ui/impl-trait/in-trait/missing-static-bound-from-impl.stderr @@ -1,6 +1,8 @@ error[E0310]: the associated type `impl Fn()` may not live long enough --> $DIR/missing-static-bound-from-impl.rs:11:9 | +LL | fn f(&self) -> Box { + | -------- this `dyn Trait` has an implicit `'static` lifetime bound LL | Box::new(::f()) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | diff --git a/tests/ui/inference/note-and-explain-ReVar-124973.rs b/tests/ui/inference/note-and-explain-ReVar-124973.rs index aa4b909fa76c..8c04648d57b2 100644 --- a/tests/ui/inference/note-and-explain-ReVar-124973.rs +++ b/tests/ui/inference/note-and-explain-ReVar-124973.rs @@ -2,7 +2,7 @@ #![feature(c_variadic)] -async unsafe extern "C" fn multiple_named_lifetimes<'a, 'b>(_: u8, ...) {} +async unsafe extern "C" fn multiple_named_lifetimes<'a, 'b>(_: u8, _: ...) {} //~^ ERROR functions cannot be both `async` and C-variadic //~| ERROR hidden type for `impl Future` captures lifetime that does not appear in bounds diff --git a/tests/ui/inference/note-and-explain-ReVar-124973.stderr b/tests/ui/inference/note-and-explain-ReVar-124973.stderr index 964fbc4a4fb7..bb37e6231a32 100644 --- a/tests/ui/inference/note-and-explain-ReVar-124973.stderr +++ b/tests/ui/inference/note-and-explain-ReVar-124973.stderr @@ -1,14 +1,14 @@ error: functions cannot be both `async` and C-variadic --> $DIR/note-and-explain-ReVar-124973.rs:5:1 | -LL | async unsafe extern "C" fn multiple_named_lifetimes<'a, 'b>(_: u8, ...) {} - | ^^^^^ `async` because of this ^^^ C-variadic because of this +LL | async unsafe extern "C" fn multiple_named_lifetimes<'a, 'b>(_: u8, _: ...) {} + | ^^^^^ `async` because of this ^^^^^^ C-variadic because of this error[E0700]: hidden type for `impl Future` captures lifetime that does not appear in bounds - --> $DIR/note-and-explain-ReVar-124973.rs:5:73 + --> $DIR/note-and-explain-ReVar-124973.rs:5:76 | -LL | async unsafe extern "C" fn multiple_named_lifetimes<'a, 'b>(_: u8, ...) {} - | ----------------------------------------------------------------------- ^^ +LL | async unsafe extern "C" fn multiple_named_lifetimes<'a, 'b>(_: u8, _: ...) {} + | -------------------------------------------------------------------------- ^^ | | | opaque type defined here | diff --git a/tests/ui/issues/issue-46604.stderr b/tests/ui/issues/issue-46604.stderr index d983674995ed..abe3ad476c60 100644 --- a/tests/ui/issues/issue-46604.stderr +++ b/tests/ui/issues/issue-46604.stderr @@ -11,6 +11,9 @@ LL | static buf: &mut [u8] = &mut [1u8,2,3,4,5,7]; error[E0594]: cannot assign to `buf[_]`, as `buf` is an immutable static item --> $DIR/issue-46604.rs:6:5 | +LL | static buf: &mut [u8] = &mut [1u8,2,3,4,5,7]; + | --------------------- this `static` cannot be written to +... LL | buf[0]=2; | ^^^^^^^^ cannot assign diff --git a/tests/ui/issues/issue-51515.stderr b/tests/ui/issues/issue-51515.stderr index 88b8d2109088..5bf33b191c0e 100644 --- a/tests/ui/issues/issue-51515.stderr +++ b/tests/ui/issues/issue-51515.stderr @@ -2,7 +2,7 @@ error[E0594]: cannot assign to `*foo`, which is behind a `&` reference --> $DIR/issue-51515.rs:4:5 | LL | *foo = 32; - | ^^^^^^^^^ `foo` is a `&` reference, so the data it refers to cannot be written + | ^^^^^^^^^ `foo` is a `&` reference, so it cannot be written to | help: consider changing this to be a mutable reference | @@ -13,7 +13,7 @@ error[E0594]: cannot assign to `*bar`, which is behind a `&` reference --> $DIR/issue-51515.rs:8:5 | LL | *bar = 64; - | ^^^^^^^^^ `bar` is a `&` reference, so the data it refers to cannot be written + | ^^^^^^^^^ `bar` is a `&` reference, so it cannot be written to | help: consider specifying this binding's type | diff --git a/tests/ui/issues/issue-52126-assign-op-invariance.stderr b/tests/ui/issues/issue-52126-assign-op-invariance.stderr index af9553e5cf38..dd38a1061baa 100644 --- a/tests/ui/issues/issue-52126-assign-op-invariance.stderr +++ b/tests/ui/issues/issue-52126-assign-op-invariance.stderr @@ -4,13 +4,18 @@ error[E0597]: `line` does not live long enough LL | for line in vec!["123456789".to_string(), "12345678".to_string()] { | ---- binding `line` declared here LL | let v: Vec<&str> = line.split_whitespace().collect(); - | ^^^^ borrowed value does not live long enough + | - ^^^^ borrowed value does not live long enough + | | + | variable `v` declared here ... LL | acc += cnt2; | --- borrow later used here ... LL | } | - `line` dropped here while still borrowed + | + = note: `v` is a collection that stores borrowed references, but `line` does not live long enough to be stored in it + = help: buffer reuse with borrowed references requires unsafe code or restructuring error: aborting due to 1 previous error diff --git a/tests/ui/let-else/let-else-binding-explicit-mut.stderr b/tests/ui/let-else/let-else-binding-explicit-mut.stderr index 45f2b6b3bcee..f1ec2d663d35 100644 --- a/tests/ui/let-else/let-else-binding-explicit-mut.stderr +++ b/tests/ui/let-else/let-else-binding-explicit-mut.stderr @@ -2,19 +2,19 @@ error[E0594]: cannot assign to `*n`, which is behind a `&` reference --> $DIR/let-else-binding-explicit-mut.rs:10:5 | LL | *n += 1; - | ^^^^^^^ `n` is a `&` reference, so the data it refers to cannot be written + | ^^^^^^^ `n` is a `&` reference, so it cannot be written to error[E0594]: cannot assign to `*n`, which is behind a `&` reference --> $DIR/let-else-binding-explicit-mut.rs:14:5 | LL | *n += 1; - | ^^^^^^^ `n` is a `&` reference, so the data it refers to cannot be written + | ^^^^^^^ `n` is a `&` reference, so it cannot be written to error[E0594]: cannot assign to `*n`, which is behind a `&` reference --> $DIR/let-else-binding-explicit-mut.rs:18:5 | LL | *n += 1; - | ^^^^^^^ `n` is a `&` reference, so the data it refers to cannot be written + | ^^^^^^^ `n` is a `&` reference, so it cannot be written to error: aborting due to 3 previous errors diff --git a/tests/ui/let-else/let-else-binding-immutable.stderr b/tests/ui/let-else/let-else-binding-immutable.stderr index 0f854493b7e4..eb6c2c5c61ee 100644 --- a/tests/ui/let-else/let-else-binding-immutable.stderr +++ b/tests/ui/let-else/let-else-binding-immutable.stderr @@ -2,7 +2,7 @@ error[E0594]: cannot assign to `*x`, which is behind a `&` reference --> $DIR/let-else-binding-immutable.rs:9:5 | LL | *x += 1; - | ^^^^^^^ `x` is a `&` reference, so the data it refers to cannot be written + | ^^^^^^^ `x` is a `&` reference, so it cannot be written to error: aborting due to 1 previous error diff --git a/tests/ui/lint/function_casts_as_integer.fixed b/tests/ui/lint/function_casts_as_integer.fixed new file mode 100644 index 000000000000..e46bd6a349cf --- /dev/null +++ b/tests/ui/lint/function_casts_as_integer.fixed @@ -0,0 +1,22 @@ +//@ run-rustfix + +#![deny(function_casts_as_integer)] +#![allow(unused_variables, dead_code)] // For the rustfix-ed code. + +fn foo() {} + +enum MyEnum { + Variant(u32), +} + +struct MyStruct(u32); + +fn main() { + let x = foo as *const () as usize; //~ ERROR: function_casts_as_integer + let x = String::len as *const () as usize; //~ ERROR: function_casts_as_integer + let x = MyEnum::Variant as *const () as usize; //~ ERROR: function_casts_as_integer + let x = MyStruct as *const () as usize; //~ ERROR: function_casts_as_integer + // Ok. + let x = foo as fn() as usize; + let x = foo as *const () as usize; +} diff --git a/tests/ui/lint/function_casts_as_integer.rs b/tests/ui/lint/function_casts_as_integer.rs new file mode 100644 index 000000000000..f6f83d89463f --- /dev/null +++ b/tests/ui/lint/function_casts_as_integer.rs @@ -0,0 +1,22 @@ +//@ run-rustfix + +#![deny(function_casts_as_integer)] +#![allow(unused_variables, dead_code)] // For the rustfix-ed code. + +fn foo() {} + +enum MyEnum { + Variant(u32), +} + +struct MyStruct(u32); + +fn main() { + let x = foo as usize; //~ ERROR: function_casts_as_integer + let x = String::len as usize; //~ ERROR: function_casts_as_integer + let x = MyEnum::Variant as usize; //~ ERROR: function_casts_as_integer + let x = MyStruct as usize; //~ ERROR: function_casts_as_integer + // Ok. + let x = foo as fn() as usize; + let x = foo as *const () as usize; +} diff --git a/tests/ui/lint/function_casts_as_integer.stderr b/tests/ui/lint/function_casts_as_integer.stderr new file mode 100644 index 000000000000..dbfd54a3b56f --- /dev/null +++ b/tests/ui/lint/function_casts_as_integer.stderr @@ -0,0 +1,51 @@ +error: direct cast of function item into an integer + --> $DIR/function_casts_as_integer.rs:15:17 + | +LL | let x = foo as usize; + | ^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/function_casts_as_integer.rs:3:9 + | +LL | #![deny(function_casts_as_integer)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ +help: first cast to a pointer `as *const ()` + | +LL | let x = foo as *const () as usize; + | ++++++++++++ + +error: direct cast of function item into an integer + --> $DIR/function_casts_as_integer.rs:16:25 + | +LL | let x = String::len as usize; + | ^^^^^^^^ + | +help: first cast to a pointer `as *const ()` + | +LL | let x = String::len as *const () as usize; + | ++++++++++++ + +error: direct cast of function item into an integer + --> $DIR/function_casts_as_integer.rs:17:29 + | +LL | let x = MyEnum::Variant as usize; + | ^^^^^^^^ + | +help: first cast to a pointer `as *const ()` + | +LL | let x = MyEnum::Variant as *const () as usize; + | ++++++++++++ + +error: direct cast of function item into an integer + --> $DIR/function_casts_as_integer.rs:18:22 + | +LL | let x = MyStruct as usize; + | ^^^^^^^^ + | +help: first cast to a pointer `as *const ()` + | +LL | let x = MyStruct as *const () as usize; + | ++++++++++++ + +error: aborting due to 4 previous errors + diff --git a/tests/ui/lto/thin-lto-inlines.rs b/tests/ui/lto/thin-lto-inlines.rs index eeaae5c4c257..c36f0e1d6c0b 100644 --- a/tests/ui/lto/thin-lto-inlines.rs +++ b/tests/ui/lto/thin-lto-inlines.rs @@ -8,6 +8,8 @@ // praying two functions go into separate codegen units and then assuming that // if inlining *doesn't* happen the first byte of the functions will differ. +#![allow(function_casts_as_integer)] + pub fn foo() -> u32 { bar::bar() } diff --git a/tests/ui/lto/thin-lto-inlines2.rs b/tests/ui/lto/thin-lto-inlines2.rs index 4c7b9278b082..62d65bbe0965 100644 --- a/tests/ui/lto/thin-lto-inlines2.rs +++ b/tests/ui/lto/thin-lto-inlines2.rs @@ -11,6 +11,8 @@ // praying two functions go into separate codegen units and then assuming that // if inlining *doesn't* happen the first byte of the functions will differ. +#![allow(function_casts_as_integer)] + extern crate thin_lto_inlines_aux as bar; pub fn foo() -> u32 { diff --git a/tests/ui/macros/cfg_select.rs b/tests/ui/macros/cfg_select.rs index 9241141ef9a6..2a627cc05b93 100644 --- a/tests/ui/macros/cfg_select.rs +++ b/tests/ui/macros/cfg_select.rs @@ -60,3 +60,38 @@ cfg_select! { cfg_select! {} //~^ ERROR none of the predicates in this `cfg_select` evaluated to true + +cfg_select! { + => {} + //~^ ERROR expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found `=>` +} + +cfg_select! { + () => {} + //~^ ERROR expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found `(` +} + +cfg_select! { + "str" => {} + //~^ ERROR malformed `cfg_select` macro input [E0539] +} + +cfg_select! { + a::b => {} + //~^ ERROR malformed `cfg_select` macro input [E0539] +} + +cfg_select! { + a() => {} + //~^ ERROR invalid predicate `a` [E0537] +} + +cfg_select! { + a + 1 => {} + //~^ ERROR expected one of `(`, `::`, `=>`, or `=`, found `+` +} + +cfg_select! { + cfg!() => {} + //~^ ERROR expected one of `(`, `::`, `=>`, or `=`, found `!` +} diff --git a/tests/ui/macros/cfg_select.stderr b/tests/ui/macros/cfg_select.stderr index 7280f35c16f9..3a5d2b0a1e1e 100644 --- a/tests/ui/macros/cfg_select.stderr +++ b/tests/ui/macros/cfg_select.stderr @@ -21,5 +21,51 @@ error: none of the predicates in this `cfg_select` evaluated to true LL | cfg_select! {} | ^^^^^^^^^^^^^^ -error: aborting due to 2 previous errors; 1 warning emitted +error: expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found `=>` + --> $DIR/cfg_select.rs:65:5 + | +LL | => {} + | ^^ +error: expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found `(` + --> $DIR/cfg_select.rs:70:5 + | +LL | () => {} + | ^ + +error[E0539]: malformed `cfg_select` macro input + --> $DIR/cfg_select.rs:75:5 + | +LL | "str" => {} + | ^^^^^ expected a valid identifier here + | + +error[E0539]: malformed `cfg_select` macro input + --> $DIR/cfg_select.rs:80:5 + | +LL | a::b => {} + | ^^^^ expected a valid identifier here + | + +error[E0537]: invalid predicate `a` + --> $DIR/cfg_select.rs:85:5 + | +LL | a() => {} + | ^^^ + +error: expected one of `(`, `::`, `=>`, or `=`, found `+` + --> $DIR/cfg_select.rs:90:7 + | +LL | a + 1 => {} + | ^ expected one of `(`, `::`, `=>`, or `=` + +error: expected one of `(`, `::`, `=>`, or `=`, found `!` + --> $DIR/cfg_select.rs:95:8 + | +LL | cfg!() => {} + | ^ expected one of `(`, `::`, `=>`, or `=` + +error: aborting due to 9 previous errors; 1 warning emitted + +Some errors have detailed explanations: E0537, E0539. +For more information about an error, try `rustc --explain E0537`. diff --git a/tests/ui/mir/issue-83499-input-output-iteration-ice.rs b/tests/ui/mir/issue-83499-input-output-iteration-ice.rs index dc0d14bf9d6b..4c547356716c 100644 --- a/tests/ui/mir/issue-83499-input-output-iteration-ice.rs +++ b/tests/ui/mir/issue-83499-input-output-iteration-ice.rs @@ -4,6 +4,6 @@ fn main() {} -unsafe extern "C" fn foo(_: Bar, ...) -> impl {} +unsafe extern "C" fn foo(_: Bar, _: ...) -> impl {} //~^ ERROR cannot find type `Bar` in this scope //~| ERROR at least one trait must be specified diff --git a/tests/ui/mir/issue-83499-input-output-iteration-ice.stderr b/tests/ui/mir/issue-83499-input-output-iteration-ice.stderr index 31a393e7367a..5c5936d48e31 100644 --- a/tests/ui/mir/issue-83499-input-output-iteration-ice.stderr +++ b/tests/ui/mir/issue-83499-input-output-iteration-ice.stderr @@ -1,13 +1,13 @@ error: at least one trait must be specified - --> $DIR/issue-83499-input-output-iteration-ice.rs:7:42 + --> $DIR/issue-83499-input-output-iteration-ice.rs:7:45 | -LL | unsafe extern "C" fn foo(_: Bar, ...) -> impl {} - | ^^^^ +LL | unsafe extern "C" fn foo(_: Bar, _: ...) -> impl {} + | ^^^^ error[E0412]: cannot find type `Bar` in this scope --> $DIR/issue-83499-input-output-iteration-ice.rs:7:29 | -LL | unsafe extern "C" fn foo(_: Bar, ...) -> impl {} +LL | unsafe extern "C" fn foo(_: Bar, _: ...) -> impl {} | ^^^ not found in this scope error: aborting due to 2 previous errors diff --git a/tests/ui/mir/mir_coercions.rs b/tests/ui/mir/mir_coercions.rs index 11230c3fbb7e..17053f410778 100644 --- a/tests/ui/mir/mir_coercions.rs +++ b/tests/ui/mir/mir_coercions.rs @@ -1,5 +1,6 @@ //@ run-pass #![feature(coerce_unsized, unsize)] +#![allow(function_casts_as_integer)] use std::ops::CoerceUnsized; use std::marker::Unsize; diff --git a/tests/ui/mir/mir_misc_casts.rs b/tests/ui/mir/mir_misc_casts.rs index 35f217fceba6..c44f1751448c 100644 --- a/tests/ui/mir/mir_misc_casts.rs +++ b/tests/ui/mir/mir_misc_casts.rs @@ -1,4 +1,7 @@ //@ run-pass + +#![allow(function_casts_as_integer)] + fn func(){} const STR: &'static str = "hello"; diff --git a/tests/ui/mir/mir_refs_correct.rs b/tests/ui/mir/mir_refs_correct.rs index f1832d90a0f5..f7826202a83e 100644 --- a/tests/ui/mir/mir_refs_correct.rs +++ b/tests/ui/mir/mir_refs_correct.rs @@ -1,6 +1,7 @@ //@ run-pass //@ aux-build:mir_external_refs.rs +#![allow(function_casts_as_integer)] #![allow(unpredictable_function_pointer_comparisons)] extern crate mir_external_refs as ext; diff --git a/tests/ui/mut/mutable-class-fields-2.stderr b/tests/ui/mut/mutable-class-fields-2.stderr index 7a6ff4da2bf5..57a04bdc2144 100644 --- a/tests/ui/mut/mutable-class-fields-2.stderr +++ b/tests/ui/mut/mutable-class-fields-2.stderr @@ -2,7 +2,7 @@ error[E0594]: cannot assign to `self.how_hungry`, which is behind a `&` referenc --> $DIR/mutable-class-fields-2.rs:9:5 | LL | self.how_hungry -= 5; - | ^^^^^^^^^^^^^^^^^^^^ `self` is a `&` reference, so the data it refers to cannot be written + | ^^^^^^^^^^^^^^^^^^^^ `self` is a `&` reference, so it cannot be written to | help: consider changing this to be a mutable reference | diff --git a/tests/ui/nll/constant-thread-locals-issue-47053.stderr b/tests/ui/nll/constant-thread-locals-issue-47053.stderr index 1c6844d6e332..64cb866e758f 100644 --- a/tests/ui/nll/constant-thread-locals-issue-47053.stderr +++ b/tests/ui/nll/constant-thread-locals-issue-47053.stderr @@ -1,6 +1,9 @@ error[E0594]: cannot assign to immutable static item `FOO` --> $DIR/constant-thread-locals-issue-47053.rs:9:5 | +LL | static FOO: isize = 5; + | ----------------- this `static` cannot be written to +... LL | FOO = 6; | ^^^^^^^ cannot assign diff --git a/tests/ui/nll/dont-print-desugared.stderr b/tests/ui/nll/dont-print-desugared.stderr index 289b246e663e..9386e1f06059 100644 --- a/tests/ui/nll/dont-print-desugared.stderr +++ b/tests/ui/nll/dont-print-desugared.stderr @@ -2,7 +2,9 @@ error[E0596]: cannot borrow data in a `&` reference as mutable --> $DIR/dont-print-desugared.rs:4:10 | LL | for &ref mut x in s {} - | ^^^^^^^^^ cannot borrow as mutable + | ^^^^^^^^^ - this cannot be borrowed as mutable + | | + | cannot borrow as mutable error[E0597]: `y` does not live long enough --> $DIR/dont-print-desugared.rs:17:16 diff --git a/tests/ui/nll/issue-47388.stderr b/tests/ui/nll/issue-47388.stderr index bd8b4c1eea00..a95cc574c87f 100644 --- a/tests/ui/nll/issue-47388.stderr +++ b/tests/ui/nll/issue-47388.stderr @@ -2,7 +2,7 @@ error[E0594]: cannot assign to `fancy_ref.num`, which is behind a `&` reference --> $DIR/issue-47388.rs:8:5 | LL | fancy_ref.num = 6; - | ^^^^^^^^^^^^^^^^^ `fancy_ref` is a `&` reference, so the data it refers to cannot be written + | ^^^^^^^^^^^^^^^^^ `fancy_ref` is a `&` reference, so it cannot be written to | help: consider changing this to be a mutable reference | diff --git a/tests/ui/nll/issue-51191.stderr b/tests/ui/nll/issue-51191.stderr index 73f8aab9d141..a7f7603d2780 100644 --- a/tests/ui/nll/issue-51191.stderr +++ b/tests/ui/nll/issue-51191.stderr @@ -45,6 +45,8 @@ LL | fn imm(mut self) { error[E0596]: cannot borrow `self` as mutable, as it is not declared as mutable --> $DIR/issue-51191.rs:23:9 | +LL | fn immref(&self) { + | ----- this cannot be borrowed as mutable LL | (&mut self).bar(); | ^^^^^^^^^^^ cannot borrow as mutable diff --git a/tests/ui/nll/issue-51244.stderr b/tests/ui/nll/issue-51244.stderr index 610482f8b1a9..e86202e1aec1 100644 --- a/tests/ui/nll/issue-51244.stderr +++ b/tests/ui/nll/issue-51244.stderr @@ -2,7 +2,7 @@ error[E0594]: cannot assign to `*my_ref`, which is behind a `&` reference --> $DIR/issue-51244.rs:3:5 | LL | *my_ref = 0; - | ^^^^^^^^^^^ `my_ref` is a `&` reference, so the data it refers to cannot be written + | ^^^^^^^^^^^ `my_ref` is a `&` reference, so it cannot be written to | help: consider changing this to be a mutable reference | diff --git a/tests/ui/nll/issue-57989.stderr b/tests/ui/nll/issue-57989.stderr index 6062b31d6883..8b102f20c122 100644 --- a/tests/ui/nll/issue-57989.stderr +++ b/tests/ui/nll/issue-57989.stderr @@ -2,7 +2,7 @@ error[E0594]: cannot assign to `*x`, which is behind a `&` reference --> $DIR/issue-57989.rs:5:5 | LL | *x = 0; - | ^^^^^^ `x` is a `&` reference, so the data it refers to cannot be written + | ^^^^^^ `x` is a `&` reference, so it cannot be written to | help: consider changing this to be a mutable reference | diff --git a/tests/ui/parser/variadic-ffi-semantic-restrictions.rs b/tests/ui/parser/variadic-ffi-semantic-restrictions.rs index 415472176d9c..025c0e3ecaca 100644 --- a/tests/ui/parser/variadic-ffi-semantic-restrictions.rs +++ b/tests/ui/parser/variadic-ffi-semantic-restrictions.rs @@ -3,43 +3,43 @@ fn main() {} -fn f1_1(x: isize, ...) {} +fn f1_1(x: isize, _: ...) {} //~^ ERROR `...` is not supported for non-extern functions -fn f1_2(...) {} +fn f1_2(_: ...) {} //~^ ERROR `...` is not supported for non-extern functions -unsafe extern "Rust" fn f1_3(...) {} +unsafe extern "Rust" fn f1_3(_: ...) {} //~^ ERROR `...` is not supported for `extern "Rust"` functions -extern "C" fn f2_1(x: isize, ...) {} +extern "C" fn f2_1(x: isize, _: ...) {} //~^ ERROR functions with a C variable argument list must be unsafe -extern "C" fn f2_2(...) {} +extern "C" fn f2_2(_: ...) {} //~^ ERROR functions with a C variable argument list must be unsafe -extern "C" fn f2_3(..., x: isize) {} +extern "C" fn f2_3(_: ..., x: isize) {} //~^ ERROR `...` must be the last argument of a C-variadic function -extern "C" fn f3_1(x: isize, ...) {} +extern "C" fn f3_1(x: isize, _: ...) {} //~^ ERROR functions with a C variable argument list must be unsafe -extern "C" fn f3_2(...) {} +extern "C" fn f3_2(_: ...) {} //~^ ERROR functions with a C variable argument list must be unsafe -extern "C" fn f3_3(..., x: isize) {} +extern "C" fn f3_3(_: ..., x: isize) {} //~^ ERROR `...` must be the last argument of a C-variadic function -const unsafe extern "C" fn f4_1(x: isize, ...) {} +const unsafe extern "C" fn f4_1(x: isize, _: ...) {} //~^ ERROR functions cannot be both `const` and C-variadic //~| ERROR destructor of `VaListImpl<'_>` cannot be evaluated at compile-time -const extern "C" fn f4_2(x: isize, ...) {} +const extern "C" fn f4_2(x: isize, _: ...) {} //~^ ERROR functions cannot be both `const` and C-variadic //~| ERROR functions with a C variable argument list must be unsafe //~| ERROR destructor of `VaListImpl<'_>` cannot be evaluated at compile-time -const extern "C" fn f4_3(..., x: isize, ...) {} +const extern "C" fn f4_3(_: ..., x: isize, _: ...) {} //~^ ERROR functions cannot be both `const` and C-variadic //~| ERROR functions with a C variable argument list must be unsafe //~| ERROR `...` must be the last argument of a C-variadic function @@ -52,33 +52,33 @@ extern "C" { struct X; impl X { - fn i_f1(x: isize, ...) {} + fn i_f1(x: isize, _: ...) {} //~^ ERROR `...` is not supported for non-extern functions - fn i_f2(...) {} + fn i_f2(_: ...) {} //~^ ERROR `...` is not supported for non-extern functions - fn i_f3(..., x: isize, ...) {} + fn i_f3(_: ..., x: isize, _: ...) {} //~^ ERROR `...` is not supported for non-extern functions //~| ERROR `...` must be the last argument of a C-variadic function - fn i_f4(..., x: isize, ...) {} + fn i_f4(_: ..., x: isize, _: ...) {} //~^ ERROR `...` is not supported for non-extern functions //~| ERROR `...` must be the last argument of a C-variadic function - const fn i_f5(x: isize, ...) {} + const fn i_f5(x: isize, _: ...) {} //~^ ERROR `...` is not supported for non-extern functions //~| ERROR functions cannot be both `const` and C-variadic //~| ERROR destructor of `VaListImpl<'_>` cannot be evaluated at compile-time } trait T { - fn t_f1(x: isize, ...) {} + fn t_f1(x: isize, _: ...) {} //~^ ERROR `...` is not supported for non-extern functions - fn t_f2(x: isize, ...); + fn t_f2(x: isize, _: ...); //~^ ERROR `...` is not supported for non-extern functions - fn t_f3(...) {} + fn t_f3(_: ...) {} //~^ ERROR `...` is not supported for non-extern functions - fn t_f4(...); + fn t_f4(_: ...); //~^ ERROR `...` is not supported for non-extern functions - fn t_f5(..., x: isize) {} + fn t_f5(_: ..., x: isize) {} //~^ ERROR `...` must be the last argument of a C-variadic function - fn t_f6(..., x: isize); + fn t_f6(_: ..., x: isize); //~^ ERROR `...` must be the last argument of a C-variadic function } diff --git a/tests/ui/parser/variadic-ffi-semantic-restrictions.stderr b/tests/ui/parser/variadic-ffi-semantic-restrictions.stderr index da9c9b0f7609..0e02d4434233 100644 --- a/tests/ui/parser/variadic-ffi-semantic-restrictions.stderr +++ b/tests/ui/parser/variadic-ffi-semantic-restrictions.stderr @@ -1,24 +1,24 @@ error: `...` is not supported for non-extern functions --> $DIR/variadic-ffi-semantic-restrictions.rs:6:19 | -LL | fn f1_1(x: isize, ...) {} - | ^^^ +LL | fn f1_1(x: isize, _: ...) {} + | ^^^^^^ | = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list error: `...` is not supported for non-extern functions --> $DIR/variadic-ffi-semantic-restrictions.rs:9:9 | -LL | fn f1_2(...) {} - | ^^^ +LL | fn f1_2(_: ...) {} + | ^^^^^^ | = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list error: `...` is not supported for `extern "Rust"` functions --> $DIR/variadic-ffi-semantic-restrictions.rs:12:30 | -LL | unsafe extern "Rust" fn f1_3(...) {} - | ------------- ^^^ +LL | unsafe extern "Rust" fn f1_3(_: ...) {} + | ------------- ^^^^^^ | | | `extern "Rust"` because of this | @@ -27,103 +27,103 @@ LL | unsafe extern "Rust" fn f1_3(...) {} error: functions with a C variable argument list must be unsafe --> $DIR/variadic-ffi-semantic-restrictions.rs:15:30 | -LL | extern "C" fn f2_1(x: isize, ...) {} - | ^^^ +LL | extern "C" fn f2_1(x: isize, _: ...) {} + | ^^^^^^ | help: add the `unsafe` keyword to this definition | -LL | unsafe extern "C" fn f2_1(x: isize, ...) {} +LL | unsafe extern "C" fn f2_1(x: isize, _: ...) {} | ++++++ error: functions with a C variable argument list must be unsafe --> $DIR/variadic-ffi-semantic-restrictions.rs:18:20 | -LL | extern "C" fn f2_2(...) {} - | ^^^ +LL | extern "C" fn f2_2(_: ...) {} + | ^^^^^^ | help: add the `unsafe` keyword to this definition | -LL | unsafe extern "C" fn f2_2(...) {} +LL | unsafe extern "C" fn f2_2(_: ...) {} | ++++++ error: `...` must be the last argument of a C-variadic function --> $DIR/variadic-ffi-semantic-restrictions.rs:21:20 | -LL | extern "C" fn f2_3(..., x: isize) {} - | ^^^ +LL | extern "C" fn f2_3(_: ..., x: isize) {} + | ^^^^^^ error: functions with a C variable argument list must be unsafe --> $DIR/variadic-ffi-semantic-restrictions.rs:24:30 | -LL | extern "C" fn f3_1(x: isize, ...) {} - | ^^^ +LL | extern "C" fn f3_1(x: isize, _: ...) {} + | ^^^^^^ | help: add the `unsafe` keyword to this definition | -LL | unsafe extern "C" fn f3_1(x: isize, ...) {} +LL | unsafe extern "C" fn f3_1(x: isize, _: ...) {} | ++++++ error: functions with a C variable argument list must be unsafe --> $DIR/variadic-ffi-semantic-restrictions.rs:27:20 | -LL | extern "C" fn f3_2(...) {} - | ^^^ +LL | extern "C" fn f3_2(_: ...) {} + | ^^^^^^ | help: add the `unsafe` keyword to this definition | -LL | unsafe extern "C" fn f3_2(...) {} +LL | unsafe extern "C" fn f3_2(_: ...) {} | ++++++ error: `...` must be the last argument of a C-variadic function --> $DIR/variadic-ffi-semantic-restrictions.rs:30:20 | -LL | extern "C" fn f3_3(..., x: isize) {} - | ^^^ +LL | extern "C" fn f3_3(_: ..., x: isize) {} + | ^^^^^^ error: functions cannot be both `const` and C-variadic --> $DIR/variadic-ffi-semantic-restrictions.rs:33:1 | -LL | const unsafe extern "C" fn f4_1(x: isize, ...) {} - | ^^^^^ `const` because of this ^^^ C-variadic because of this +LL | const unsafe extern "C" fn f4_1(x: isize, _: ...) {} + | ^^^^^ `const` because of this ^^^^^^ C-variadic because of this error: functions cannot be both `const` and C-variadic --> $DIR/variadic-ffi-semantic-restrictions.rs:37:1 | -LL | const extern "C" fn f4_2(x: isize, ...) {} - | ^^^^^ `const` because of this ^^^ C-variadic because of this +LL | const extern "C" fn f4_2(x: isize, _: ...) {} + | ^^^^^ `const` because of this ^^^^^^ C-variadic because of this error: functions with a C variable argument list must be unsafe --> $DIR/variadic-ffi-semantic-restrictions.rs:37:36 | -LL | const extern "C" fn f4_2(x: isize, ...) {} - | ^^^ +LL | const extern "C" fn f4_2(x: isize, _: ...) {} + | ^^^^^^ | help: add the `unsafe` keyword to this definition | -LL | const unsafe extern "C" fn f4_2(x: isize, ...) {} +LL | const unsafe extern "C" fn f4_2(x: isize, _: ...) {} | ++++++ error: `...` must be the last argument of a C-variadic function --> $DIR/variadic-ffi-semantic-restrictions.rs:42:26 | -LL | const extern "C" fn f4_3(..., x: isize, ...) {} - | ^^^ +LL | const extern "C" fn f4_3(_: ..., x: isize, _: ...) {} + | ^^^^^^ error: functions cannot be both `const` and C-variadic --> $DIR/variadic-ffi-semantic-restrictions.rs:42:1 | -LL | const extern "C" fn f4_3(..., x: isize, ...) {} - | ^^^^^ `const` because of this ^^^ C-variadic because of this +LL | const extern "C" fn f4_3(_: ..., x: isize, _: ...) {} + | ^^^^^ `const` because of this ^^^^^^ C-variadic because of this error: functions with a C variable argument list must be unsafe - --> $DIR/variadic-ffi-semantic-restrictions.rs:42:41 + --> $DIR/variadic-ffi-semantic-restrictions.rs:42:44 | -LL | const extern "C" fn f4_3(..., x: isize, ...) {} - | ^^^ +LL | const extern "C" fn f4_3(_: ..., x: isize, _: ...) {} + | ^^^^^^ | help: add the `unsafe` keyword to this definition | -LL | const unsafe extern "C" fn f4_3(..., x: isize, ...) {} +LL | const unsafe extern "C" fn f4_3(_: ..., x: isize, _: ...) {} | ++++++ error: `...` must be the last argument of a C-variadic function @@ -135,128 +135,128 @@ LL | fn e_f2(..., x: isize); error: `...` is not supported for non-extern functions --> $DIR/variadic-ffi-semantic-restrictions.rs:55:23 | -LL | fn i_f1(x: isize, ...) {} - | ^^^ +LL | fn i_f1(x: isize, _: ...) {} + | ^^^^^^ | = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list error: `...` is not supported for non-extern functions --> $DIR/variadic-ffi-semantic-restrictions.rs:57:13 | -LL | fn i_f2(...) {} - | ^^^ +LL | fn i_f2(_: ...) {} + | ^^^^^^ | = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list error: `...` must be the last argument of a C-variadic function --> $DIR/variadic-ffi-semantic-restrictions.rs:59:13 | -LL | fn i_f3(..., x: isize, ...) {} - | ^^^ +LL | fn i_f3(_: ..., x: isize, _: ...) {} + | ^^^^^^ error: `...` is not supported for non-extern functions - --> $DIR/variadic-ffi-semantic-restrictions.rs:59:28 + --> $DIR/variadic-ffi-semantic-restrictions.rs:59:31 | -LL | fn i_f3(..., x: isize, ...) {} - | ^^^ +LL | fn i_f3(_: ..., x: isize, _: ...) {} + | ^^^^^^ | = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list error: `...` must be the last argument of a C-variadic function --> $DIR/variadic-ffi-semantic-restrictions.rs:62:13 | -LL | fn i_f4(..., x: isize, ...) {} - | ^^^ +LL | fn i_f4(_: ..., x: isize, _: ...) {} + | ^^^^^^ error: `...` is not supported for non-extern functions - --> $DIR/variadic-ffi-semantic-restrictions.rs:62:28 + --> $DIR/variadic-ffi-semantic-restrictions.rs:62:31 | -LL | fn i_f4(..., x: isize, ...) {} - | ^^^ +LL | fn i_f4(_: ..., x: isize, _: ...) {} + | ^^^^^^ | = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list error: functions cannot be both `const` and C-variadic --> $DIR/variadic-ffi-semantic-restrictions.rs:65:5 | -LL | const fn i_f5(x: isize, ...) {} - | ^^^^^ ^^^ C-variadic because of this +LL | const fn i_f5(x: isize, _: ...) {} + | ^^^^^ ^^^^^^ C-variadic because of this | | | `const` because of this error: `...` is not supported for non-extern functions --> $DIR/variadic-ffi-semantic-restrictions.rs:65:29 | -LL | const fn i_f5(x: isize, ...) {} - | ^^^ +LL | const fn i_f5(x: isize, _: ...) {} + | ^^^^^^ | = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list error: `...` is not supported for non-extern functions --> $DIR/variadic-ffi-semantic-restrictions.rs:72:23 | -LL | fn t_f1(x: isize, ...) {} - | ^^^ +LL | fn t_f1(x: isize, _: ...) {} + | ^^^^^^ | = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list error: `...` is not supported for non-extern functions --> $DIR/variadic-ffi-semantic-restrictions.rs:74:23 | -LL | fn t_f2(x: isize, ...); - | ^^^ +LL | fn t_f2(x: isize, _: ...); + | ^^^^^^ | = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list error: `...` is not supported for non-extern functions --> $DIR/variadic-ffi-semantic-restrictions.rs:76:13 | -LL | fn t_f3(...) {} - | ^^^ +LL | fn t_f3(_: ...) {} + | ^^^^^^ | = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list error: `...` is not supported for non-extern functions --> $DIR/variadic-ffi-semantic-restrictions.rs:78:13 | -LL | fn t_f4(...); - | ^^^ +LL | fn t_f4(_: ...); + | ^^^^^^ | = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list error: `...` must be the last argument of a C-variadic function --> $DIR/variadic-ffi-semantic-restrictions.rs:80:13 | -LL | fn t_f5(..., x: isize) {} - | ^^^ +LL | fn t_f5(_: ..., x: isize) {} + | ^^^^^^ error: `...` must be the last argument of a C-variadic function --> $DIR/variadic-ffi-semantic-restrictions.rs:82:13 | -LL | fn t_f6(..., x: isize); - | ^^^ +LL | fn t_f6(_: ..., x: isize); + | ^^^^^^ error[E0493]: destructor of `VaListImpl<'_>` cannot be evaluated at compile-time --> $DIR/variadic-ffi-semantic-restrictions.rs:33:43 | -LL | const unsafe extern "C" fn f4_1(x: isize, ...) {} - | ^^^ - value is dropped here +LL | const unsafe extern "C" fn f4_1(x: isize, _: ...) {} + | ^ - value is dropped here | | | the destructor for this type cannot be evaluated in constant functions error[E0493]: destructor of `VaListImpl<'_>` cannot be evaluated at compile-time --> $DIR/variadic-ffi-semantic-restrictions.rs:37:36 | -LL | const extern "C" fn f4_2(x: isize, ...) {} - | ^^^ - value is dropped here +LL | const extern "C" fn f4_2(x: isize, _: ...) {} + | ^ - value is dropped here | | | the destructor for this type cannot be evaluated in constant functions error[E0493]: destructor of `VaListImpl<'_>` cannot be evaluated at compile-time --> $DIR/variadic-ffi-semantic-restrictions.rs:65:29 | -LL | const fn i_f5(x: isize, ...) {} - | ^^^ - value is dropped here +LL | const fn i_f5(x: isize, _: ...) {} + | ^ - value is dropped here | | | the destructor for this type cannot be evaluated in constant functions diff --git a/tests/ui/parser/variadic-ffi-syntactic-pass.rs b/tests/ui/parser/variadic-ffi-syntactic-pass.rs index ebe0b6c2dd25..6a6656044e17 100644 --- a/tests/ui/parser/variadic-ffi-syntactic-pass.rs +++ b/tests/ui/parser/variadic-ffi-syntactic-pass.rs @@ -3,28 +3,28 @@ fn main() {} #[cfg(false)] -fn f1_1(x: isize, ...) {} +fn f1_1(x: isize, _: ...) {} #[cfg(false)] -fn f1_2(...) {} +fn f1_2(_: ...) {} #[cfg(false)] -extern "C" fn f2_1(x: isize, ...) {} +extern "C" fn f2_1(x: isize, _: ...) {} #[cfg(false)] -extern "C" fn f2_2(...) {} +extern "C" fn f2_2(_: ...) {} #[cfg(false)] -extern "C" fn f2_3(..., x: isize) {} +extern "C" fn f2_3(_: ..., x: isize) {} #[cfg(false)] -extern fn f3_1(x: isize, ...) {} +extern fn f3_1(x: isize, _: ...) {} #[cfg(false)] -extern fn f3_2(...) {} +extern fn f3_2(_: ...) {} #[cfg(false)] -extern fn f3_3(..., x: isize) {} +extern fn f3_3(_: ..., x: isize) {} #[cfg(false)] extern { @@ -36,18 +36,18 @@ struct X; #[cfg(false)] impl X { - fn i_f1(x: isize, ...) {} - fn i_f2(...) {} - fn i_f3(..., x: isize, ...) {} - fn i_f4(..., x: isize, ...) {} + fn i_f1(x: isize, _: ...) {} + fn i_f2(_: ...) {} + fn i_f3(_: ..., x: isize, _: ...) {} + fn i_f4(_: ..., x: isize, _: ...) {} } #[cfg(false)] trait T { - fn t_f1(x: isize, ...) {} - fn t_f2(x: isize, ...); - fn t_f3(...) {} - fn t_f4(...); - fn t_f5(..., x: isize) {} - fn t_f6(..., x: isize); + fn t_f1(x: isize, _: ...) {} + fn t_f2(x: isize, _: ...); + fn t_f3(_: ...) {} + fn t_f4(_: ...); + fn t_f5(_: ..., x: isize) {} + fn t_f6(_: ..., x: isize); } diff --git a/tests/ui/pattern/issue-52240.stderr b/tests/ui/pattern/issue-52240.stderr index dcf3da45e535..7d419dd1b9b2 100644 --- a/tests/ui/pattern/issue-52240.stderr +++ b/tests/ui/pattern/issue-52240.stderr @@ -2,7 +2,9 @@ error[E0596]: cannot borrow data in a `&` reference as mutable --> $DIR/issue-52240.rs:9:27 | LL | if let (Some(Foo::Bar(ref mut val)), _) = (&arr.get(0), 0) { - | ^^^^^^^^^^^ cannot borrow as mutable + | ^^^^^^^^^^^ ---------------- this cannot be borrowed as mutable + | | + | cannot borrow as mutable error: aborting due to 1 previous error diff --git a/tests/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.stderr b/tests/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.stderr index a1049701dc3b..5c4446cbc17b 100644 --- a/tests/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.stderr +++ b/tests/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.stderr @@ -119,7 +119,7 @@ error[E0594]: cannot assign to `*_x0`, which is behind a `&` reference --> $DIR/borrowck-move-ref-pattern.rs:26:5 | LL | *_x0 = U; - | ^^^^^^^^ `_x0` is a `&` reference, so the data it refers to cannot be written + | ^^^^^^^^ `_x0` is a `&` reference, so it cannot be written to | help: consider changing this to be a mutable reference | @@ -130,7 +130,7 @@ error[E0594]: cannot assign to `*_x2`, which is behind a `&` reference --> $DIR/borrowck-move-ref-pattern.rs:27:5 | LL | *_x2 = U; - | ^^^^^^^^ `_x2` is a `&` reference, so the data it refers to cannot be written + | ^^^^^^^^ `_x2` is a `&` reference, so it cannot be written to | help: consider changing this to be a mutable reference | diff --git a/tests/ui/pattern/mut-pattern-of-immutable-borrow.rs b/tests/ui/pattern/mut-pattern-of-immutable-borrow.rs new file mode 100644 index 000000000000..52852414da45 --- /dev/null +++ b/tests/ui/pattern/mut-pattern-of-immutable-borrow.rs @@ -0,0 +1,31 @@ +struct S { + field: Option, +} + +fn a(arg: &mut S) { + match arg.field { //~ ERROR cannot move out of `arg.field` + Some(s) => s.push('a'), //~ ERROR cannot borrow `s` as mutable + None => {} + } +} +fn b(arg: &mut S) { + match &arg.field { //~ ERROR cannot move out of a shared reference + Some(mut s) => s.push('a'), + None => {} + } +} +fn c(arg: &mut S) { + match &arg.field { + Some(ref mut s) => s.push('a'), //~ ERROR cannot borrow data in a `&` reference as mutable + None => {} + } +} + +fn main() { + let mut s = S { + field: Some("a".to_owned()), + }; + a(&mut s); + b(&mut s); + c(&mut s); +} diff --git a/tests/ui/pattern/mut-pattern-of-immutable-borrow.stderr b/tests/ui/pattern/mut-pattern-of-immutable-borrow.stderr new file mode 100644 index 000000000000..be1b5fadb0dd --- /dev/null +++ b/tests/ui/pattern/mut-pattern-of-immutable-borrow.stderr @@ -0,0 +1,55 @@ +error[E0507]: cannot move out of `arg.field` as enum variant `Some` which is behind a mutable reference + --> $DIR/mut-pattern-of-immutable-borrow.rs:6:11 + | +LL | match arg.field { + | ^^^^^^^^^ +LL | Some(s) => s.push('a'), + | - + | | + | data moved here + | move occurs because `s` has type `String`, which does not implement the `Copy` trait + | +help: consider borrowing here + | +LL | match &arg.field { + | + + +error[E0596]: cannot borrow `s` as mutable, as it is not declared as mutable + --> $DIR/mut-pattern-of-immutable-borrow.rs:7:20 + | +LL | Some(s) => s.push('a'), + | ^ cannot borrow as mutable + | +help: consider changing this to be mutable + | +LL | Some(mut s) => s.push('a'), + | +++ + +error[E0507]: cannot move out of a shared reference + --> $DIR/mut-pattern-of-immutable-borrow.rs:12:11 + | +LL | match &arg.field { + | ^^^^^^^^^^ +LL | Some(mut s) => s.push('a'), + | ----- + | | + | data moved here + | move occurs because `s` has type `String`, which does not implement the `Copy` trait + | +help: consider borrowing the pattern binding + | +LL | Some(ref mut s) => s.push('a'), + | +++ + +error[E0596]: cannot borrow data in a `&` reference as mutable + --> $DIR/mut-pattern-of-immutable-borrow.rs:19:14 + | +LL | match &arg.field { + | ---------- this cannot be borrowed as mutable +LL | Some(ref mut s) => s.push('a'), + | ^^^^^^^^^ cannot borrow as mutable + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0507, E0596. +For more information about an error, try `rustc --explain E0507`. diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.classic2021.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.classic2021.stderr index 4d795d5c3851..6391619fddf0 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.classic2021.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.classic2021.stderr @@ -17,19 +17,25 @@ error[E0596]: cannot borrow data in a `&` reference as mutable --> $DIR/borrowck-errors.rs:38:10 | LL | let &ref mut x = &0; - | ^^^^^^^^^ cannot borrow as mutable + | ^^^^^^^^^ -- this cannot be borrowed as mutable + | | + | cannot borrow as mutable error[E0596]: cannot borrow data in a `&` reference as mutable --> $DIR/borrowck-errors.rs:43:23 | LL | if let &Some(Some(x)) = &Some(&mut Some(0)) { - | ^ cannot borrow as mutable + | ^ ------------------- this cannot be borrowed as mutable + | | + | cannot borrow as mutable error[E0596]: cannot borrow data in a `&` reference as mutable --> $DIR/borrowck-errors.rs:48:11 | LL | let &[x] = &&mut [0]; - | ^ cannot borrow as mutable + | ^ --------- this cannot be borrowed as mutable + | | + | cannot borrow as mutable error: aborting due to 4 previous errors diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.classic2024.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.classic2024.stderr index 6cc6c58bf7af..1106342e62e4 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.classic2024.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.classic2024.stderr @@ -45,7 +45,9 @@ error[E0596]: cannot borrow data in a `&` reference as mutable --> $DIR/borrowck-errors.rs:38:10 | LL | let &ref mut x = &0; - | ^^^^^^^^^ cannot borrow as mutable + | ^^^^^^^^^ -- this cannot be borrowed as mutable + | | + | cannot borrow as mutable error[E0596]: cannot borrow data in a `&` reference as mutable --> $DIR/borrowck-errors.rs:43:23 @@ -57,7 +59,9 @@ error[E0596]: cannot borrow data in a `&` reference as mutable --> $DIR/borrowck-errors.rs:48:11 | LL | let &[x] = &&mut [0]; - | ^ cannot borrow as mutable + | ^ --------- this cannot be borrowed as mutable + | | + | cannot borrow as mutable error[E0508]: cannot move out of type `[&mut i32; 1]`, a non-copy array --> $DIR/borrowck-errors.rs:52:20 diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.stable2021.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.stable2021.stderr index 036b3dbeae39..ac84fdf7f95f 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.stable2021.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.stable2021.stderr @@ -49,19 +49,25 @@ error[E0596]: cannot borrow data in a `&` reference as mutable --> $DIR/borrowck-errors.rs:38:10 | LL | let &ref mut x = &0; - | ^^^^^^^^^ cannot borrow as mutable + | ^^^^^^^^^ -- this cannot be borrowed as mutable + | | + | cannot borrow as mutable error[E0596]: cannot borrow data in a `&` reference as mutable --> $DIR/borrowck-errors.rs:43:23 | LL | if let &Some(Some(x)) = &Some(&mut Some(0)) { - | ^ cannot borrow as mutable + | ^ ------------------- this cannot be borrowed as mutable + | | + | cannot borrow as mutable error[E0596]: cannot borrow data in a `&` reference as mutable --> $DIR/borrowck-errors.rs:48:11 | LL | let &[x] = &&mut [0]; - | ^ cannot borrow as mutable + | ^ --------- this cannot be borrowed as mutable + | | + | cannot borrow as mutable error: aborting due to 6 previous errors diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.structural2021.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.structural2021.stderr index e1764fa1d55d..0e431326cb91 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.structural2021.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.structural2021.stderr @@ -17,7 +17,9 @@ error[E0596]: cannot borrow data in a `&` reference as mutable --> $DIR/borrowck-errors.rs:38:10 | LL | let &ref mut x = &0; - | ^^^^^^^^^ cannot borrow as mutable + | ^^^^^^^^^ -- this cannot be borrowed as mutable + | | + | cannot borrow as mutable error: aborting due to 2 previous errors diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.structural2024.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.structural2024.stderr index e1764fa1d55d..0e431326cb91 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.structural2024.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.structural2024.stderr @@ -17,7 +17,9 @@ error[E0596]: cannot borrow data in a `&` reference as mutable --> $DIR/borrowck-errors.rs:38:10 | LL | let &ref mut x = &0; - | ^^^^^^^^^ cannot borrow as mutable + | ^^^^^^^^^ -- this cannot be borrowed as mutable + | | + | cannot borrow as mutable error: aborting due to 2 previous errors diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mixed-editions.classic2021.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mixed-editions.classic2021.stderr index fc1ca18c1202..4fa82a603a8e 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mixed-editions.classic2021.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mixed-editions.classic2021.stderr @@ -81,19 +81,25 @@ error[E0596]: cannot borrow data in a `&` reference as mutable --> $DIR/mixed-editions.rs:61:21 | LL | let match_ref!([x]) = &&mut [0]; - | ^ cannot borrow as mutable + | ^ --------- this cannot be borrowed as mutable + | | + | cannot borrow as mutable error[E0596]: cannot borrow data in a `&` reference as mutable --> $DIR/mixed-editions.rs:65:22 | LL | let &match_ctor!(y) = &&mut [0]; - | ^ cannot borrow as mutable + | ^ --------- this cannot be borrowed as mutable + | | + | cannot borrow as mutable error[E0596]: cannot borrow data in a `&` reference as mutable --> $DIR/mixed-editions.rs:69:11 | LL | let &[bind!(z)] = &&mut [0]; - | ^^^^^^^^ cannot borrow as mutable + | ^^^^^^^^ --------- this cannot be borrowed as mutable + | | + | cannot borrow as mutable | = note: this error originates in the macro `bind` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mixed-editions.classic2024.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mixed-editions.classic2024.stderr index 9377d535f187..ee152c2871f4 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mixed-editions.classic2024.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mixed-editions.classic2024.stderr @@ -75,19 +75,25 @@ error[E0596]: cannot borrow data in a `&` reference as mutable --> $DIR/mixed-editions.rs:61:21 | LL | let match_ref!([x]) = &&mut [0]; - | ^ cannot borrow as mutable + | ^ --------- this cannot be borrowed as mutable + | | + | cannot borrow as mutable error[E0596]: cannot borrow data in a `&` reference as mutable --> $DIR/mixed-editions.rs:65:22 | LL | let &match_ctor!(y) = &&mut [0]; - | ^ cannot borrow as mutable + | ^ --------- this cannot be borrowed as mutable + | | + | cannot borrow as mutable error[E0596]: cannot borrow data in a `&` reference as mutable --> $DIR/mixed-editions.rs:69:11 | LL | let &[bind!(z)] = &&mut [0]; - | ^^^^^^^^ cannot borrow as mutable + | ^^^^^^^^ --------- this cannot be borrowed as mutable + | | + | cannot borrow as mutable | = note: this error originates in the macro `bind` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.classic2021.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.classic2021.stderr index dbb8ae87b661..30c0814e1938 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.classic2021.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.classic2021.stderr @@ -2,7 +2,9 @@ error[E0596]: cannot borrow data in a `&` reference as mutable --> $DIR/ref-binding-on-inh-ref-errors.rs:73:10 | LL | let [ref mut x] = &[0]; - | ^^^^^^^^^ cannot borrow as mutable + | ^^^^^^^^^ ---- this cannot be borrowed as mutable + | | + | cannot borrow as mutable error: aborting due to 1 previous error diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.classic2024.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.classic2024.stderr index 956cd2166433..34af303b55a4 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.classic2024.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.classic2024.stderr @@ -32,7 +32,9 @@ error[E0596]: cannot borrow data in a `&` reference as mutable --> $DIR/ref-binding-on-inh-ref-errors.rs:73:10 | LL | let [ref mut x] = &[0]; - | ^^^^^^^^^ cannot borrow as mutable + | ^^^^^^^^^ ---- this cannot be borrowed as mutable + | | + | cannot borrow as mutable error: cannot explicitly borrow within an implicitly-borrowing pattern --> $DIR/ref-binding-on-inh-ref-errors.rs:81:10 diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.stable2021.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.stable2021.stderr index 33119c4447ad..508264f1a940 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.stable2021.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.stable2021.stderr @@ -34,7 +34,9 @@ error[E0596]: cannot borrow data in a `&` reference as mutable --> $DIR/ref-binding-on-inh-ref-errors.rs:73:10 | LL | let [ref mut x] = &[0]; - | ^^^^^^^^^ cannot borrow as mutable + | ^^^^^^^^^ ---- this cannot be borrowed as mutable + | | + | cannot borrow as mutable error: aborting due to 3 previous errors diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.structural2021.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.structural2021.stderr index dbb8ae87b661..30c0814e1938 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.structural2021.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.structural2021.stderr @@ -2,7 +2,9 @@ error[E0596]: cannot borrow data in a `&` reference as mutable --> $DIR/ref-binding-on-inh-ref-errors.rs:73:10 | LL | let [ref mut x] = &[0]; - | ^^^^^^^^^ cannot borrow as mutable + | ^^^^^^^^^ ---- this cannot be borrowed as mutable + | | + | cannot borrow as mutable error: aborting due to 1 previous error diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.structural2024.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.structural2024.stderr index 9753e3e5fbfe..57e3df45af4d 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.structural2024.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.structural2024.stderr @@ -138,7 +138,9 @@ error[E0596]: cannot borrow data in a `&` reference as mutable --> $DIR/ref-binding-on-inh-ref-errors.rs:73:10 | LL | let [ref mut x] = &[0]; - | ^^^^^^^^^ cannot borrow as mutable + | ^^^^^^^^^ ---- this cannot be borrowed as mutable + | | + | cannot borrow as mutable error: cannot explicitly borrow within an implicitly-borrowing pattern --> $DIR/ref-binding-on-inh-ref-errors.rs:81:10 diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.classic2021.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.classic2021.stderr index 9bf5c9544e51..b83824180bf1 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.classic2021.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.classic2021.stderr @@ -114,7 +114,9 @@ error[E0596]: cannot borrow data in a `&` reference as mutable --> $DIR/well-typed-edition-2024.rs:111:19 | LL | let [&mut ref mut x] = &mut [&0]; - | ^^^^^^^^^ cannot borrow as mutable + | ^^^^^^^^^ --------- this cannot be borrowed as mutable + | | + | cannot borrow as mutable error: aborting due to 8 previous errors diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.structural2021.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.structural2021.stderr index 9bf5c9544e51..b83824180bf1 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.structural2021.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.structural2021.stderr @@ -114,7 +114,9 @@ error[E0596]: cannot borrow data in a `&` reference as mutable --> $DIR/well-typed-edition-2024.rs:111:19 | LL | let [&mut ref mut x] = &mut [&0]; - | ^^^^^^^^^ cannot borrow as mutable + | ^^^^^^^^^ --------- this cannot be borrowed as mutable + | | + | cannot borrow as mutable error: aborting due to 8 previous errors diff --git a/tests/ui/pin-ergonomics/pin-pattern.rs b/tests/ui/pin-ergonomics/pin-pattern.rs new file mode 100644 index 000000000000..a61cc7abbf21 --- /dev/null +++ b/tests/ui/pin-ergonomics/pin-pattern.rs @@ -0,0 +1,114 @@ +//@ edition:2024 +#![feature(pin_ergonomics)] +#![allow(incomplete_features)] + +// This test verifies: +// - a `&pin mut $pat` can be used to match on a pinned reference type `&pin mut T`; +// - the subpattern can only convert the binding mode `&pin mut` to `&mut` when `T: Unpin`; +// - the subpattern can only remove the binding mode `&pin mut` when `T: Copy`; + +#[pin_v2] +struct Foo(T); + +trait IsPinMut {} +trait IsPinConst {} +trait IsMut {} +trait IsRef {} +impl IsPinMut for &pin mut T {} +impl IsPinConst for &pin const T {} +impl IsMut for &mut T {} +impl IsRef for &T {} + +fn assert_pin_mut(_: T) {} +fn assert_pin_const(_: T) {} +fn assert_mut(_: T) {} +fn assert_ref(_: T) {} +fn assert_ty(_: T) {} + +fn normal(foo_mut: &pin mut Foo, foo_const: &pin const Foo) { + let &pin mut Foo(ref pin mut x) = foo_mut; // ok + assert_pin_mut(x); + + let &pin const Foo(ref pin const x) = foo_const; // ok + assert_pin_const(x); +} + +fn by_value_copy(foo_mut: &pin mut Foo, foo_const: &pin const Foo) { + let &pin mut Foo(x) = foo_mut; + assert_ty::(x); + + let &pin const Foo(x) = foo_const; + assert_ty::(x); +} + +fn by_value_non_copy(foo_mut: &pin mut Foo, foo_const: &pin const Foo) { + let &pin mut Foo(x) = foo_mut; + //~^ ERROR cannot move out of `foo_mut.pointer` which is behind a mutable reference + assert_ty::(x); + + let &pin const Foo(x) = foo_const; + //~^ ERROR cannot move out of `foo_const.pointer` which is behind a shared reference + assert_ty::(x); +} + +fn by_ref_non_pinned_unpin(foo_mut: &pin mut Foo, foo_const: &pin const Foo) { + let &pin mut Foo(ref mut x) = foo_mut; + assert_mut(x); + + let &pin const Foo(ref x) = foo_const; + assert_ref(x); +} + +fn by_ref_non_pinned_non_unpin(foo_mut: &pin mut Foo, foo_const: &pin const Foo) { + let &pin mut Foo(ref mut x) = foo_mut; + //~^ ERROR `T` cannot be unpinned + assert_mut(x); + + let &pin const Foo(ref x) = foo_const; + //~^ ERROR `T` cannot be unpinned + assert_ref(x); +} + +// Makes sure that `ref pin` binding mode cannot be changed to a `ref` binding mode. +// +// This mimics the following code: +// ``` +// fn f<'a, T>( +// ((&x,),): &'a (&'a mut (&'a T,),), +// ) -> T { +// x +// } +// ``` +fn tuple_tuple_ref_pin_mut_pat_and_pin_mut_of_tuple_mut_of_tuple_pin_mut_ty<'a, T>( + ((&pin mut x,),): &'a pin mut (&'a mut (&'a pin mut Foo,),), + //~^ ERROR cannot explicitly dereference within an implicitly-borrowing pattern + //~| ERROR cannot move out of a mutable reference +) -> Foo { + x +} + +fn tuple_ref_pin_mut_pat_and_mut_of_tuple_pin_mut_ty<'a, T>( + (&pin mut x,): &'a mut (&'a pin mut Foo,), //~ ERROR `T` cannot be unpinned +) -> &'a mut Foo { + x +} + +fn tuple_ref_pin_mut_pat_and_mut_of_mut_tuple_pin_mut_ty<'a, T>( + (&pin mut x,): &'a mut &'a pin mut (Foo,), //~ ERROR mismatched type +) -> &'a mut Foo { + x +} + +fn ref_pin_mut_tuple_pat_and_mut_of_tuple_pin_mut_ty<'a, T>( + &pin mut (x,): &'a mut (&'a pin mut Foo,), //~ ERROR mismatched type +) -> &'a mut Foo { + x +} + +fn ref_pin_mut_tuple_pat_and_mut_of_mut_tuple_pin_mut_ty<'a, T>( + &pin mut (x,): &'a mut &'a pin mut (Foo,), //~ ERROR mismatched type +) -> &'a mut Foo { + x +} + +fn main() {} diff --git a/tests/ui/pin-ergonomics/pin-pattern.stderr b/tests/ui/pin-ergonomics/pin-pattern.stderr new file mode 100644 index 000000000000..49f7a396f3ce --- /dev/null +++ b/tests/ui/pin-ergonomics/pin-pattern.stderr @@ -0,0 +1,152 @@ +error[E0277]: `T` cannot be unpinned + --> $DIR/pin-pattern.rs:63:22 + | +LL | let &pin mut Foo(ref mut x) = foo_mut; + | ^^^^^^^^^ the trait `Unpin` is not implemented for `T` + | + = note: consider using the `pin!` macro + consider using `Box::pin` if you need to access the pinned value outside of the current scope +help: consider restricting type parameter `T` with trait `Unpin` + | +LL | fn by_ref_non_pinned_non_unpin(foo_mut: &pin mut Foo, foo_const: &pin const Foo) { + | ++++++++++++++++++++ + +error[E0277]: `T` cannot be unpinned + --> $DIR/pin-pattern.rs:67:24 + | +LL | let &pin const Foo(ref x) = foo_const; + | ^^^^^ the trait `Unpin` is not implemented for `T` + | + = note: consider using the `pin!` macro + consider using `Box::pin` if you need to access the pinned value outside of the current scope +help: consider restricting type parameter `T` with trait `Unpin` + | +LL | fn by_ref_non_pinned_non_unpin(foo_mut: &pin mut Foo, foo_const: &pin const Foo) { + | ++++++++++++++++++++ + +error[E0277]: `T` cannot be unpinned + --> $DIR/pin-pattern.rs:91:15 + | +LL | (&pin mut x,): &'a mut (&'a pin mut Foo,), + | ^ within `Foo`, the trait `Unpin` is not implemented for `T` + | + = note: consider using the `pin!` macro + consider using `Box::pin` if you need to access the pinned value outside of the current scope +note: required because it appears within the type `Foo` + --> $DIR/pin-pattern.rs:11:8 + | +LL | struct Foo(T); + | ^^^ +help: consider restricting type parameter `T` with trait `Unpin` + | +LL | fn tuple_ref_pin_mut_pat_and_mut_of_tuple_pin_mut_ty<'a, T: std::marker::Unpin>( + | ++++++++++++++++++++ + +error[E0308]: mismatched types + --> $DIR/pin-pattern.rs:97:6 + | +LL | (&pin mut x,): &'a mut &'a pin mut (Foo,), + | ^^^^^^^^^^ ----------------------------- expected due to this + | | + | expected `Foo`, found `Pin<&mut _>` + | + = note: expected struct `Foo` + found struct `Pin<&mut _>` +note: to declare a mutable binding use: `mut x` + --> $DIR/pin-pattern.rs:97:6 + | +LL | (&pin mut x,): &'a mut &'a pin mut (Foo,), + | ^^^^^^^^^^ +help: consider removing `&pin mut` from the pattern + | +LL - (&pin mut x,): &'a mut &'a pin mut (Foo,), +LL + (x,): &'a mut &'a pin mut (Foo,), + | + +error[E0308]: mismatched types + --> $DIR/pin-pattern.rs:103:5 + | +LL | &pin mut (x,): &'a mut (&'a pin mut Foo,), + | ^^^^^^^^^^^^^ ----------------------------- expected due to this + | | + | expected `&mut (Pin<&mut Foo>,)`, found `Pin<&mut _>` + | + = note: expected mutable reference `&'a mut (Pin<&'a mut Foo>,)` + found struct `Pin<&mut _>` + +error[E0308]: mismatched types + --> $DIR/pin-pattern.rs:109:5 + | +LL | &pin mut (x,): &'a mut &'a pin mut (Foo,), + | ^^^^^^^^^^^^^ ----------------------------- expected due to this + | | + | expected `&mut Pin<&mut (Foo,)>`, found `Pin<&mut _>` + | + = note: expected mutable reference `&'a mut Pin<&'a mut (Foo,)>` + found struct `Pin<&mut _>` + +error[E0507]: cannot move out of `foo_mut.pointer` which is behind a mutable reference + --> $DIR/pin-pattern.rs:45:27 + | +LL | let &pin mut Foo(x) = foo_mut; + | - ^^^^^^^ + | | + | data moved here + | move occurs because `x` has type `T`, which does not implement the `Copy` trait + | +help: consider removing the pinned mutable borrow + | +LL - let &pin mut Foo(x) = foo_mut; +LL + let Foo(x) = foo_mut; + | + +error[E0507]: cannot move out of `foo_const.pointer` which is behind a shared reference + --> $DIR/pin-pattern.rs:49:29 + | +LL | let &pin const Foo(x) = foo_const; + | - ^^^^^^^^^ + | | + | data moved here + | move occurs because `x` has type `T`, which does not implement the `Copy` trait + | +help: consider removing the pinned borrow + | +LL - let &pin const Foo(x) = foo_const; +LL + let Foo(x) = foo_const; + | + +error: cannot explicitly dereference within an implicitly-borrowing pattern + --> $DIR/pin-pattern.rs:83:7 + | +LL | ((&pin mut x,),): &'a pin mut (&'a mut (&'a pin mut Foo,),), + | ^^^^^^^^ reference pattern not allowed when implicitly borrowing + | + = note: for more information, see +note: matching on a reference type with a non-reference pattern implicitly borrows the contents + --> $DIR/pin-pattern.rs:83:6 + | +LL | ((&pin mut x,),): &'a pin mut (&'a mut (&'a pin mut Foo,),), + | ^^^^^^^^^^^^^ this non-reference pattern matches on a reference type `&mut _` +help: match on the reference with a reference pattern to avoid implicitly borrowing + | +LL | (&mut (&pin mut x,),): &'a pin mut (&'a mut (&'a pin mut Foo,),), + | ++++ + +error[E0507]: cannot move out of a mutable reference + --> $DIR/pin-pattern.rs:83:5 + | +LL | ((&pin mut x,),): &'a pin mut (&'a mut (&'a pin mut Foo,),), + | ^^^^^^^^^^^-^^^^ + | | + | data moved here + | move occurs because `x` has type `Foo`, which does not implement the `Copy` trait + | +help: consider borrowing the pattern binding + | +LL | ((&pin mut ref x,),): &'a pin mut (&'a mut (&'a pin mut Foo,),), + | +++ + +error: aborting due to 10 previous errors + +Some errors have detailed explanations: E0277, E0308, E0507. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/pin-ergonomics/sugar-ambiguity.rs b/tests/ui/pin-ergonomics/sugar-ambiguity.rs index d183000931ec..fbe12e6f7790 100644 --- a/tests/ui/pin-ergonomics/sugar-ambiguity.rs +++ b/tests/ui/pin-ergonomics/sugar-ambiguity.rs @@ -8,8 +8,16 @@ struct Foo; mod pin { pub struct Foo; + #[expect(non_camel_case_types)] + pub struct pin; + + fn foo() { + let _x: &pin = &pin; + } } fn main() { - let _x: &pin ::Foo = &pin::Foo; + let _x: &pin::Foo = &pin::Foo; + let &pin: &i32 = &0; + let ref pin: i32 = 0; } diff --git a/tests/ui/pin-ergonomics/sugar-no-const.rs b/tests/ui/pin-ergonomics/sugar-no-const.rs index dd6456b60348..727036680849 100644 --- a/tests/ui/pin-ergonomics/sugar-no-const.rs +++ b/tests/ui/pin-ergonomics/sugar-no-const.rs @@ -3,6 +3,22 @@ // Makes sure we don't accidentally accept `&pin Foo` without the `const` keyword. -fn main() { +fn ty() { let _x: &pin i32 = todo!(); //~ ERROR found `i32` } + +fn expr() { + let x = 0_i32; + let _x = &pin x; //~ ERROR found `x` +} + +fn pat() { + let &pin _x: &pin i32 = todo!(); //~ ERROR found `_x` +} + +fn binding() { + let ref pin _x: i32 = todo!(); //~ ERROR found `_x` +} + +fn main() { +} diff --git a/tests/ui/pin-ergonomics/sugar-no-const.stderr b/tests/ui/pin-ergonomics/sugar-no-const.stderr index 062b6d3f4871..151bb92ed4cd 100644 --- a/tests/ui/pin-ergonomics/sugar-no-const.stderr +++ b/tests/ui/pin-ergonomics/sugar-no-const.stderr @@ -12,5 +12,41 @@ LL - let _x: &pin i32 = todo!(); LL + let _x: &in i32 = todo!(); | -error: aborting due to 1 previous error +error: expected one of `!`, `.`, `::`, `;`, `?`, `else`, `{`, or an operator, found `x` + --> $DIR/sugar-no-const.rs:12:19 + | +LL | let _x = &pin x; + | ^ expected one of 8 possible tokens + | +help: there is a keyword `in` with a similar name + | +LL - let _x = &pin x; +LL + let _x = &in x; + | + +error: expected one of `:`, `;`, `=`, `@`, or `|`, found `_x` + --> $DIR/sugar-no-const.rs:16:14 + | +LL | let &pin _x: &pin i32 = todo!(); + | ^^ expected one of `:`, `;`, `=`, `@`, or `|` + | +help: there is a keyword `in` with a similar name + | +LL - let &pin _x: &pin i32 = todo!(); +LL + let &in _x: &pin i32 = todo!(); + | + +error: expected one of `:`, `;`, `=`, `@`, or `|`, found `_x` + --> $DIR/sugar-no-const.rs:20:17 + | +LL | let ref pin _x: i32 = todo!(); + | ^^ expected one of `:`, `;`, `=`, `@`, or `|` + | +help: there is a keyword `in` with a similar name + | +LL - let ref pin _x: i32 = todo!(); +LL + let ref in _x: i32 = todo!(); + | + +error: aborting due to 4 previous errors diff --git a/tests/ui/range/range-to-iterator-suggestion-issue-147749.rs b/tests/ui/range/range-to-iterator-suggestion-issue-147749.rs new file mode 100644 index 000000000000..8bcdffc13687 --- /dev/null +++ b/tests/ui/range/range-to-iterator-suggestion-issue-147749.rs @@ -0,0 +1,38 @@ +fn main() { + for x in (..4).rev() { + //~^ ERROR `RangeTo<{integer}>` is not an iterator + //~| HELP consider using a bounded `Range` by adding a concrete starting value + let _ = x; + } + + for x in (..=4).rev() { + //~^ ERROR `std::ops::RangeToInclusive<{integer}>` is not an iterator + //~| HELP consider using a bounded `RangeInclusive` by adding a concrete starting value + let _ = x; + } + + // should not suggest for `iter` method + let _v: Vec<_> = (..5).iter().collect(); + //~^ ERROR no method named `iter` found + + for _x in (..'a').rev() {} + //~^ ERROR `RangeTo` is not an iterator + //~| HELP consider using a bounded `Range` by adding a concrete starting value + + for _x in (..='a').rev() {} + //~^ ERROR `std::ops::RangeToInclusive` is not an iterator + //~| HELP consider using a bounded `RangeInclusive` by adding a concrete starting value + + for _x in (..-10).rev() {} + //~^ ERROR `RangeTo<{integer}>` is not an iterator + //~| HELP consider using a bounded `Range` by adding a concrete starting value + + for _x in (..=-10).rev() {} + //~^ ERROR `std::ops::RangeToInclusive<{integer}>` is not an iterator + //~| HELP consider using a bounded `RangeInclusive` by adding a concrete starting value + + let end_val = 10; + for _x in (..-end_val).rev() {} + //~^ ERROR `RangeTo<{integer}>` is not an iterator + //~| HELP consider using a bounded `Range` by adding a concrete starting value +} diff --git a/tests/ui/range/range-to-iterator-suggestion-issue-147749.stderr b/tests/ui/range/range-to-iterator-suggestion-issue-147749.stderr new file mode 100644 index 000000000000..cb109de20a06 --- /dev/null +++ b/tests/ui/range/range-to-iterator-suggestion-issue-147749.stderr @@ -0,0 +1,114 @@ +error[E0599]: `RangeTo<{integer}>` is not an iterator + --> $DIR/range-to-iterator-suggestion-issue-147749.rs:2:20 + | +LL | for x in (..4).rev() { + | ^^^ `RangeTo<{integer}>` is not an iterator + | + = note: the following trait bounds were not satisfied: + `RangeTo<{integer}>: Iterator` + which is required by `&mut RangeTo<{integer}>: Iterator` + = note: you might have meant to use a bounded `Range` +help: consider using a bounded `Range` by adding a concrete starting value + | +LL | for x in (0..4).rev() { + | + + +error[E0599]: `std::ops::RangeToInclusive<{integer}>` is not an iterator + --> $DIR/range-to-iterator-suggestion-issue-147749.rs:8:21 + | +LL | for x in (..=4).rev() { + | ^^^ `std::ops::RangeToInclusive<{integer}>` is not an iterator + | + = note: the following trait bounds were not satisfied: + `std::ops::RangeToInclusive<{integer}>: Iterator` + which is required by `&mut std::ops::RangeToInclusive<{integer}>: Iterator` + = note: you might have meant to use a bounded `RangeInclusive` +help: consider using a bounded `RangeInclusive` by adding a concrete starting value + | +LL | for x in (0..=4).rev() { + | + + +error[E0599]: no method named `iter` found for struct `RangeTo` in the current scope + --> $DIR/range-to-iterator-suggestion-issue-147749.rs:15:28 + | +LL | let _v: Vec<_> = (..5).iter().collect(); + | ^^^^ method not found in `RangeTo<{integer}>` + +error[E0599]: `RangeTo` is not an iterator + --> $DIR/range-to-iterator-suggestion-issue-147749.rs:18:23 + | +LL | for _x in (..'a').rev() {} + | ^^^ `RangeTo` is not an iterator + | + = note: the following trait bounds were not satisfied: + `RangeTo: Iterator` + which is required by `&mut RangeTo: Iterator` + = note: you might have meant to use a bounded `Range` +help: consider using a bounded `Range` by adding a concrete starting value + | +LL | for _x in (/* start */..'a').rev() {} + | +++++++++++ + +error[E0599]: `std::ops::RangeToInclusive` is not an iterator + --> $DIR/range-to-iterator-suggestion-issue-147749.rs:22:24 + | +LL | for _x in (..='a').rev() {} + | ^^^ `std::ops::RangeToInclusive` is not an iterator + | + = note: the following trait bounds were not satisfied: + `std::ops::RangeToInclusive: Iterator` + which is required by `&mut std::ops::RangeToInclusive: Iterator` + = note: you might have meant to use a bounded `RangeInclusive` +help: consider using a bounded `RangeInclusive` by adding a concrete starting value + | +LL | for _x in (/* start */..='a').rev() {} + | +++++++++++ + +error[E0599]: `RangeTo<{integer}>` is not an iterator + --> $DIR/range-to-iterator-suggestion-issue-147749.rs:26:23 + | +LL | for _x in (..-10).rev() {} + | ^^^ `RangeTo<{integer}>` is not an iterator + | + = note: the following trait bounds were not satisfied: + `RangeTo<{integer}>: Iterator` + which is required by `&mut RangeTo<{integer}>: Iterator` + = note: you might have meant to use a bounded `Range` +help: consider using a bounded `Range` by adding a concrete starting value + | +LL | for _x in (/* start */..-10).rev() {} + | +++++++++++ + +error[E0599]: `std::ops::RangeToInclusive<{integer}>` is not an iterator + --> $DIR/range-to-iterator-suggestion-issue-147749.rs:30:24 + | +LL | for _x in (..=-10).rev() {} + | ^^^ `std::ops::RangeToInclusive<{integer}>` is not an iterator + | + = note: the following trait bounds were not satisfied: + `std::ops::RangeToInclusive<{integer}>: Iterator` + which is required by `&mut std::ops::RangeToInclusive<{integer}>: Iterator` + = note: you might have meant to use a bounded `RangeInclusive` +help: consider using a bounded `RangeInclusive` by adding a concrete starting value + | +LL | for _x in (/* start */..=-10).rev() {} + | +++++++++++ + +error[E0599]: `RangeTo<{integer}>` is not an iterator + --> $DIR/range-to-iterator-suggestion-issue-147749.rs:35:28 + | +LL | for _x in (..-end_val).rev() {} + | ^^^ `RangeTo<{integer}>` is not an iterator + | + = note: the following trait bounds were not satisfied: + `RangeTo<{integer}>: Iterator` + which is required by `&mut RangeTo<{integer}>: Iterator` + = note: you might have meant to use a bounded `Range` +help: consider using a bounded `Range` by adding a concrete starting value + | +LL | for _x in (/* start */..-end_val).rev() {} + | +++++++++++ + +error: aborting due to 8 previous errors + +For more information about this error, try `rustc --explain E0599`. diff --git a/tests/ui/rfcs/rfc-2005-default-binding-mode/enum.stderr b/tests/ui/rfcs/rfc-2005-default-binding-mode/enum.stderr index 21e3d3d273d7..3ba69f73783c 100644 --- a/tests/ui/rfcs/rfc-2005-default-binding-mode/enum.stderr +++ b/tests/ui/rfcs/rfc-2005-default-binding-mode/enum.stderr @@ -2,19 +2,19 @@ error[E0594]: cannot assign to `*x`, which is behind a `&` reference --> $DIR/enum.rs:9:5 | LL | *x += 1; - | ^^^^^^^ `x` is a `&` reference, so the data it refers to cannot be written + | ^^^^^^^ `x` is a `&` reference, so it cannot be written to error[E0594]: cannot assign to `*x`, which is behind a `&` reference --> $DIR/enum.rs:13:9 | LL | *x += 1; - | ^^^^^^^ `x` is a `&` reference, so the data it refers to cannot be written + | ^^^^^^^ `x` is a `&` reference, so it cannot be written to error[E0594]: cannot assign to `*x`, which is behind a `&` reference --> $DIR/enum.rs:19:9 | LL | *x += 1; - | ^^^^^^^ `x` is a `&` reference, so the data it refers to cannot be written + | ^^^^^^^ `x` is a `&` reference, so it cannot be written to error: aborting due to 3 previous errors diff --git a/tests/ui/rfcs/rfc-2005-default-binding-mode/explicit-mut.stderr b/tests/ui/rfcs/rfc-2005-default-binding-mode/explicit-mut.stderr index c3f64f65a412..2892884ebf36 100644 --- a/tests/ui/rfcs/rfc-2005-default-binding-mode/explicit-mut.stderr +++ b/tests/ui/rfcs/rfc-2005-default-binding-mode/explicit-mut.stderr @@ -2,19 +2,19 @@ error[E0594]: cannot assign to `*n`, which is behind a `&` reference --> $DIR/explicit-mut.rs:7:13 | LL | *n += 1; - | ^^^^^^^ `n` is a `&` reference, so the data it refers to cannot be written + | ^^^^^^^ `n` is a `&` reference, so it cannot be written to error[E0594]: cannot assign to `*n`, which is behind a `&` reference --> $DIR/explicit-mut.rs:15:13 | LL | *n += 1; - | ^^^^^^^ `n` is a `&` reference, so the data it refers to cannot be written + | ^^^^^^^ `n` is a `&` reference, so it cannot be written to error[E0594]: cannot assign to `*n`, which is behind a `&` reference --> $DIR/explicit-mut.rs:23:13 | LL | *n += 1; - | ^^^^^^^ `n` is a `&` reference, so the data it refers to cannot be written + | ^^^^^^^ `n` is a `&` reference, so it cannot be written to error: aborting due to 3 previous errors diff --git a/tests/ui/runtime/signal-alternate-stack-cleanup.rs b/tests/ui/runtime/signal-alternate-stack-cleanup.rs index f2af86be0a5f..8d52e9e26a29 100644 --- a/tests/ui/runtime/signal-alternate-stack-cleanup.rs +++ b/tests/ui/runtime/signal-alternate-stack-cleanup.rs @@ -9,6 +9,7 @@ //@ ignore-vxworks no SIGWINCH in user space //@ ignore-nto no SA_ONSTACK +#![allow(function_casts_as_integer)] #![feature(rustc_private)] extern crate libc; diff --git a/tests/ui/span/borrowck-borrow-overloaded-auto-deref-mut.stderr b/tests/ui/span/borrowck-borrow-overloaded-auto-deref-mut.stderr index 4aad8843759b..0cf9dd3b488c 100644 --- a/tests/ui/span/borrowck-borrow-overloaded-auto-deref-mut.stderr +++ b/tests/ui/span/borrowck-borrow-overloaded-auto-deref-mut.stderr @@ -13,7 +13,7 @@ error[E0596]: cannot borrow `*x` as mutable, as it is behind a `&` reference --> $DIR/borrowck-borrow-overloaded-auto-deref-mut.rs:65:10 | LL | &mut x.y - | ^ `x` is a `&` reference, so the data it refers to cannot be borrowed as mutable + | ^ `x` is a `&` reference, so it cannot be borrowed as mutable | help: consider changing this to be a mutable reference | @@ -45,7 +45,7 @@ error[E0596]: cannot borrow `*x` as mutable, as it is behind a `&` reference --> $DIR/borrowck-borrow-overloaded-auto-deref-mut.rs:92:5 | LL | x.y = 3; - | ^ `x` is a `&` reference, so the data it refers to cannot be borrowed as mutable + | ^ `x` is a `&` reference, so it cannot be borrowed as mutable | help: consider changing this to be a mutable reference | @@ -77,7 +77,7 @@ error[E0596]: cannot borrow `*x` as mutable, as it is behind a `&` reference --> $DIR/borrowck-borrow-overloaded-auto-deref-mut.rs:121:5 | LL | x.y_mut() - | ^ `x` is a `&` reference, so the data it refers to cannot be borrowed as mutable + | ^ `x` is a `&` reference, so it cannot be borrowed as mutable | help: consider changing this to be a mutable reference | @@ -99,7 +99,7 @@ error[E0596]: cannot borrow `*x` as mutable, as it is behind a `&` reference --> $DIR/borrowck-borrow-overloaded-auto-deref-mut.rs:133:6 | LL | *x.y_mut() = 3; - | ^ `x` is a `&` reference, so the data it refers to cannot be borrowed as mutable + | ^ `x` is a `&` reference, so it cannot be borrowed as mutable | help: consider changing this to be a mutable reference | diff --git a/tests/ui/span/borrowck-borrow-overloaded-deref-mut.stderr b/tests/ui/span/borrowck-borrow-overloaded-deref-mut.stderr index dbd52dc2d38d..101641c8b06b 100644 --- a/tests/ui/span/borrowck-borrow-overloaded-deref-mut.stderr +++ b/tests/ui/span/borrowck-borrow-overloaded-deref-mut.stderr @@ -13,7 +13,7 @@ error[E0596]: cannot borrow `*x` as mutable, as it is behind a `&` reference --> $DIR/borrowck-borrow-overloaded-deref-mut.rs:41:11 | LL | &mut **x - | ^^ `x` is a `&` reference, so the data it refers to cannot be borrowed as mutable + | ^^ `x` is a `&` reference, so it cannot be borrowed as mutable | help: consider changing this to be a mutable reference | @@ -35,7 +35,7 @@ error[E0596]: cannot borrow `*x` as mutable, as it is behind a `&` reference --> $DIR/borrowck-borrow-overloaded-deref-mut.rs:53:6 | LL | **x = 3; - | ^^ `x` is a `&` reference, so the data it refers to cannot be borrowed as mutable + | ^^ `x` is a `&` reference, so it cannot be borrowed as mutable | help: consider changing this to be a mutable reference | diff --git a/tests/ui/span/borrowck-call-is-borrow-issue-12224.stderr b/tests/ui/span/borrowck-call-is-borrow-issue-12224.stderr index f7750884b4a6..6590ba8a79e0 100644 --- a/tests/ui/span/borrowck-call-is-borrow-issue-12224.stderr +++ b/tests/ui/span/borrowck-call-is-borrow-issue-12224.stderr @@ -14,7 +14,7 @@ error[E0596]: cannot borrow `*f` as mutable, as it is behind a `&` reference --> $DIR/borrowck-call-is-borrow-issue-12224.rs:25:5 | LL | (*f)(); - | ^^^^ `f` is a `&` reference, so the data it refers to cannot be borrowed as mutable + | ^^^^ `f` is a `&` reference, so it cannot be borrowed as mutable | help: consider changing this to be a mutable reference | @@ -25,7 +25,7 @@ error[E0596]: cannot borrow `f.f` as mutable, as it is behind a `&` reference --> $DIR/borrowck-call-is-borrow-issue-12224.rs:34:5 | LL | f.f.call_mut(()) - | ^^^ `f` is a `&` reference, so the data it refers to cannot be borrowed as mutable + | ^^^ `f` is a `&` reference, so it cannot be borrowed as mutable | help: consider changing this to be a mutable reference | diff --git a/tests/ui/span/borrowck-call-method-from-mut-aliasable.stderr b/tests/ui/span/borrowck-call-method-from-mut-aliasable.stderr index 39e7279fb77d..195a052d6dcc 100644 --- a/tests/ui/span/borrowck-call-method-from-mut-aliasable.stderr +++ b/tests/ui/span/borrowck-call-method-from-mut-aliasable.stderr @@ -2,7 +2,7 @@ error[E0596]: cannot borrow `*x` as mutable, as it is behind a `&` reference --> $DIR/borrowck-call-method-from-mut-aliasable.rs:17:5 | LL | x.h(); - | ^ `x` is a `&` reference, so the data it refers to cannot be borrowed as mutable + | ^ `x` is a `&` reference, so it cannot be borrowed as mutable | help: consider changing this to be a mutable reference | diff --git a/tests/ui/span/borrowck-fn-in-const-b.stderr b/tests/ui/span/borrowck-fn-in-const-b.stderr index d4a8ba2698da..985196c0286a 100644 --- a/tests/ui/span/borrowck-fn-in-const-b.stderr +++ b/tests/ui/span/borrowck-fn-in-const-b.stderr @@ -2,7 +2,7 @@ error[E0596]: cannot borrow `*x` as mutable, as it is behind a `&` reference --> $DIR/borrowck-fn-in-const-b.rs:7:9 | LL | x.push(format!("this is broken")); - | ^ `x` is a `&` reference, so the data it refers to cannot be borrowed as mutable + | ^ `x` is a `&` reference, so it cannot be borrowed as mutable | help: consider changing this to be a mutable reference | diff --git a/tests/ui/span/borrowck-let-suggestion-suffixes.rs b/tests/ui/span/borrowck-let-suggestion-suffixes.rs index ad556f281df1..c8acbfadacd3 100644 --- a/tests/ui/span/borrowck-let-suggestion-suffixes.rs +++ b/tests/ui/span/borrowck-let-suggestion-suffixes.rs @@ -3,6 +3,7 @@ fn id(x: T) -> T { x } fn f() { let old = ['o']; // statement 0 let mut v1 = Vec::new(); // statement 1 + //~^ NOTE variable `v1` declared here let mut v2 = Vec::new(); // statement 2 @@ -13,6 +14,8 @@ fn f() { v2.push(&young[0]); // statement 4 //~^ ERROR `young[_]` does not live long enough //~| NOTE borrowed value does not live long enough + //~| NOTE `v1` is a collection that stores borrowed references, but `young[_]` does not live long enough to be stored in it + //~| HELP buffer reuse with borrowed references requires unsafe code or restructuring } //~ NOTE `young[_]` dropped here while still borrowed let mut v3 = Vec::new(); // statement 5 diff --git a/tests/ui/span/borrowck-let-suggestion-suffixes.stderr b/tests/ui/span/borrowck-let-suggestion-suffixes.stderr index 78cadc8c694e..cdffbd2145fc 100644 --- a/tests/ui/span/borrowck-let-suggestion-suffixes.stderr +++ b/tests/ui/span/borrowck-let-suggestion-suffixes.stderr @@ -1,6 +1,9 @@ error[E0597]: `young[_]` does not live long enough - --> $DIR/borrowck-let-suggestion-suffixes.rs:13:17 + --> $DIR/borrowck-let-suggestion-suffixes.rs:14:17 | +LL | let mut v1 = Vec::new(); // statement 1 + | ------ variable `v1` declared here +... LL | let young = ['y']; // statement 3 | ----- binding `young` declared here ... @@ -12,9 +15,12 @@ LL | } ... LL | (v1, v2, v3, /* v4 is above. */ v5).use_ref(); | -- borrow later used here + | + = note: `v1` is a collection that stores borrowed references, but `young[_]` does not live long enough to be stored in it + = help: buffer reuse with borrowed references requires unsafe code or restructuring error[E0716]: temporary value dropped while borrowed - --> $DIR/borrowck-let-suggestion-suffixes.rs:20:14 + --> $DIR/borrowck-let-suggestion-suffixes.rs:23:14 | LL | v3.push(&id('x')); // statement 6 | ^^^^^^^ - temporary value is freed at the end of this statement @@ -31,7 +37,7 @@ LL ~ v3.push(&binding); // statement 6 | error[E0716]: temporary value dropped while borrowed - --> $DIR/borrowck-let-suggestion-suffixes.rs:30:18 + --> $DIR/borrowck-let-suggestion-suffixes.rs:33:18 | LL | v4.push(&id('y')); | ^^^^^^^ - temporary value is freed at the end of this statement @@ -44,7 +50,7 @@ LL | v4.use_ref(); = note: consider using a `let` binding to create a longer lived value error[E0716]: temporary value dropped while borrowed - --> $DIR/borrowck-let-suggestion-suffixes.rs:41:14 + --> $DIR/borrowck-let-suggestion-suffixes.rs:44:14 | LL | v5.push(&id('z')); | ^^^^^^^ - temporary value is freed at the end of this statement diff --git a/tests/ui/span/borrowck-object-mutability.stderr b/tests/ui/span/borrowck-object-mutability.stderr index e4b5c8ce71f1..6fd4acd34793 100644 --- a/tests/ui/span/borrowck-object-mutability.stderr +++ b/tests/ui/span/borrowck-object-mutability.stderr @@ -2,7 +2,7 @@ error[E0596]: cannot borrow `*x` as mutable, as it is behind a `&` reference --> $DIR/borrowck-object-mutability.rs:8:5 | LL | x.borrowed_mut(); - | ^ `x` is a `&` reference, so the data it refers to cannot be borrowed as mutable + | ^ `x` is a `&` reference, so it cannot be borrowed as mutable | help: consider changing this to be a mutable reference | diff --git a/tests/ui/span/mut-arg-hint.stderr b/tests/ui/span/mut-arg-hint.stderr index df782280b8af..45449db4d782 100644 --- a/tests/ui/span/mut-arg-hint.stderr +++ b/tests/ui/span/mut-arg-hint.stderr @@ -2,7 +2,7 @@ error[E0596]: cannot borrow `*a` as mutable, as it is behind a `&` reference --> $DIR/mut-arg-hint.rs:3:9 | LL | a.push_str("bar"); - | ^ `a` is a `&` reference, so the data it refers to cannot be borrowed as mutable + | ^ `a` is a `&` reference, so it cannot be borrowed as mutable | help: consider changing this to be a mutable reference | @@ -13,7 +13,7 @@ error[E0596]: cannot borrow `*a` as mutable, as it is behind a `&` reference --> $DIR/mut-arg-hint.rs:8:5 | LL | a.push_str("foo"); - | ^ `a` is a `&` reference, so the data it refers to cannot be borrowed as mutable + | ^ `a` is a `&` reference, so it cannot be borrowed as mutable | help: consider changing this to be a mutable reference | @@ -24,7 +24,7 @@ error[E0596]: cannot borrow `*a` as mutable, as it is behind a `&` reference --> $DIR/mut-arg-hint.rs:15:9 | LL | a.push_str("foo"); - | ^ `a` is a `&` reference, so the data it refers to cannot be borrowed as mutable + | ^ `a` is a `&` reference, so it cannot be borrowed as mutable | help: consider changing this to be a mutable reference | diff --git a/tests/ui/span/regions-escape-loop-via-vec.stderr b/tests/ui/span/regions-escape-loop-via-vec.stderr index 18c6cd480930..46d70e7482f3 100644 --- a/tests/ui/span/regions-escape-loop-via-vec.stderr +++ b/tests/ui/span/regions-escape-loop-via-vec.stderr @@ -23,6 +23,9 @@ LL | _y.push(&mut z); error[E0597]: `z` does not live long enough --> $DIR/regions-escape-loop-via-vec.rs:7:17 | +LL | let mut _y = vec![&mut x]; + | ------ variable `_y` declared here +LL | while x < 10 { LL | let mut z = x; | ----- binding `z` declared here LL | _y.push(&mut z); @@ -32,6 +35,9 @@ LL | _y.push(&mut z); ... LL | } | - `z` dropped here while still borrowed + | + = note: `_y` is a collection that stores borrowed references, but `z` does not live long enough to be stored in it + = help: buffer reuse with borrowed references requires unsafe code or restructuring error[E0503]: cannot use `x` because it was mutably borrowed --> $DIR/regions-escape-loop-via-vec.rs:9:9 diff --git a/tests/ui/stats/macro-stats.stderr b/tests/ui/stats/macro-stats.stderr index 75b90df6466f..11a6bfdfcd29 100644 --- a/tests/ui/stats/macro-stats.stderr +++ b/tests/ui/stats/macro-stats.stderr @@ -2,7 +2,7 @@ macro-stats ==================================================================== macro-stats MACRO EXPANSION STATS: macro_stats macro-stats Macro Name Uses Lines Avg Lines Bytes Avg Bytes macro-stats ----------------------------------------------------------------------------------- -macro-stats #[derive(Clone)] 8 64 8.0 1_788 223.5 +macro-stats #[derive(Clone)] 8 67 8.4 1_879 234.9 macro-stats #[derive(PartialOrd)] 1 17 17.0 675 675.0 macro-stats #[derive(Hash)] 2 17 8.5 577 288.5 macro-stats q! 1 26 26.0 519 519.0 diff --git a/tests/ui/suggestions/dont_suggest_raw_pointer_syntax-issue-127562.stderr b/tests/ui/suggestions/dont_suggest_raw_pointer_syntax-issue-127562.stderr index 5396db7940f7..fdbdf6379c1d 100644 --- a/tests/ui/suggestions/dont_suggest_raw_pointer_syntax-issue-127562.stderr +++ b/tests/ui/suggestions/dont_suggest_raw_pointer_syntax-issue-127562.stderr @@ -2,7 +2,7 @@ error[E0594]: cannot assign to `*ptr`, which is behind a `*const` pointer --> $DIR/dont_suggest_raw_pointer_syntax-issue-127562.rs:5:9 | LL | *ptr = 3; - | ^^^^^^^^ `ptr` is a `*const` pointer, so the data it refers to cannot be written + | ^^^^^^^^ `ptr` is a `*const` pointer, so it cannot be written to error: aborting due to 1 previous error diff --git a/tests/ui/suggestions/issue-68049-1.stderr b/tests/ui/suggestions/issue-68049-1.stderr index 4e683b75c48b..11a8e9cc5275 100644 --- a/tests/ui/suggestions/issue-68049-1.stderr +++ b/tests/ui/suggestions/issue-68049-1.stderr @@ -4,7 +4,7 @@ error[E0594]: cannot assign to `self.0`, which is behind a `&` reference LL | unsafe fn alloc(&self, _layout: Layout) -> *mut u8 { | ----- this is an immutable reference LL | self.0 += 1; - | ^^^^^^^^^^^ `self` is a `&` reference, so the data it refers to cannot be written + | ^^^^^^^^^^^ `self` is a `&` reference, so it cannot be written to error: aborting due to 1 previous error diff --git a/tests/ui/suggestions/issue-68049-2.stderr b/tests/ui/suggestions/issue-68049-2.stderr index 91def27bfcd7..97240af20775 100644 --- a/tests/ui/suggestions/issue-68049-2.stderr +++ b/tests/ui/suggestions/issue-68049-2.stderr @@ -2,7 +2,7 @@ error[E0594]: cannot assign to `*input`, which is behind a `&` reference --> $DIR/issue-68049-2.rs:9:7 | LL | *input = self.0; - | ^^^^^^^^^^^^^^^ `input` is a `&` reference, so the data it refers to cannot be written + | ^^^^^^^^^^^^^^^ `input` is a `&` reference, so it cannot be written to | help: consider changing this to be a mutable reference in the `impl` method and the `trait` definition | @@ -13,7 +13,7 @@ error[E0594]: cannot assign to `self.0`, which is behind a `&` reference --> $DIR/issue-68049-2.rs:17:5 | LL | self.0 += *input; - | ^^^^^^^^^^^^^^^^ `self` is a `&` reference, so the data it refers to cannot be written + | ^^^^^^^^^^^^^^^^ `self` is a `&` reference, so it cannot be written to | help: consider changing this to be a mutable reference in the `impl` method and the `trait` definition | diff --git a/tests/ui/suggestions/lifetimes/implicit-static-lifetime-in-dyn-trait-return-type.rs b/tests/ui/suggestions/lifetimes/implicit-static-lifetime-in-dyn-trait-return-type.rs new file mode 100644 index 000000000000..428033b53065 --- /dev/null +++ b/tests/ui/suggestions/lifetimes/implicit-static-lifetime-in-dyn-trait-return-type.rs @@ -0,0 +1,35 @@ +// #41966 +trait Foo {} + +struct Bar(R); + +impl Foo for Bar { +} + +fn bb(r: R) -> Box { + Box::new(Bar(r)) //~ ERROR the parameter type `R` may not live long enough +} + +fn cc(r: R) -> Box { //~ ERROR missing lifetime specifier + Box::new(Bar(r)) +} + +// #54753 +pub struct Qux(T); + +pub struct Bazzzz(T); + +pub trait Baz {} +impl Baz for Bazzzz {} + +impl Qux { + fn baz(self) -> Box { + Box::new(Bazzzz(self.0)) //~ ERROR the parameter type `T` may not live long enough + } +} + +fn main() { + let a = 10; + let _b = bb(&a); + let _c = cc(&a); +} diff --git a/tests/ui/suggestions/lifetimes/implicit-static-lifetime-in-dyn-trait-return-type.stderr b/tests/ui/suggestions/lifetimes/implicit-static-lifetime-in-dyn-trait-return-type.stderr new file mode 100644 index 000000000000..c8122dce1954 --- /dev/null +++ b/tests/ui/suggestions/lifetimes/implicit-static-lifetime-in-dyn-trait-return-type.stderr @@ -0,0 +1,53 @@ +error[E0106]: missing lifetime specifier + --> $DIR/implicit-static-lifetime-in-dyn-trait-return-type.rs:13:33 + | +LL | fn cc(r: R) -> Box { + | ^^ expected named lifetime parameter + | + = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from +help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static`, or if you will only have owned values + | +LL - fn cc(r: R) -> Box { +LL + fn cc(r: R) -> Box { + | +help: instead, you are more likely to want to change the argument to be borrowed + | +LL | fn cc(r: &R) -> Box { + | + + +error[E0310]: the parameter type `R` may not live long enough + --> $DIR/implicit-static-lifetime-in-dyn-trait-return-type.rs:10:5 + | +LL | fn bb(r: R) -> Box { + | ------- this `dyn Trait` has an implicit `'static` lifetime bound +LL | Box::new(Bar(r)) + | ^^^^^^^^^^^^^^^^ + | | + | the parameter type `R` must be valid for the static lifetime... + | ...so that the type `R` will meet its required lifetime bounds + | +help: consider adding an explicit lifetime bound + | +LL | fn bb(r: R) -> Box { + | +++++++++ + +error[E0310]: the parameter type `T` may not live long enough + --> $DIR/implicit-static-lifetime-in-dyn-trait-return-type.rs:27:9 + | +LL | fn baz(self) -> Box { + | ------- this `dyn Trait` has an implicit `'static` lifetime bound +LL | Box::new(Bazzzz(self.0)) + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | the parameter type `T` must be valid for the static lifetime... + | ...so that the type `T` will meet its required lifetime bounds + | +help: consider adding an explicit lifetime bound + | +LL | impl Qux { + | +++++++++ + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0106, E0310. +For more information about an error, try `rustc --explain E0106`. diff --git a/tests/ui/suggestions/suggest-mut-method-for-loop-closure.stderr b/tests/ui/suggestions/suggest-mut-method-for-loop-closure.stderr index 0bd286e0a622..5c0bbe24ec92 100644 --- a/tests/ui/suggestions/suggest-mut-method-for-loop-closure.stderr +++ b/tests/ui/suggestions/suggest-mut-method-for-loop-closure.stderr @@ -8,7 +8,7 @@ LL | for mut t in buzz.values() { | this iterator yields `&` references ... LL | t.v += 1; - | ^^^^^^^^ `t` is a `&` reference, so the data it refers to cannot be written + | ^^^^^^^^ `t` is a `&` reference, so it cannot be written to error: aborting due to 1 previous error diff --git a/tests/ui/suggestions/suggest-mut-method-for-loop-hashmap.stderr b/tests/ui/suggestions/suggest-mut-method-for-loop-hashmap.stderr index 1be14aa8f55d..8e4412806387 100644 --- a/tests/ui/suggestions/suggest-mut-method-for-loop-hashmap.stderr +++ b/tests/ui/suggestions/suggest-mut-method-for-loop-hashmap.stderr @@ -8,7 +8,7 @@ LL | for (_k, v) in map.iter() { | this iterator yields `&` references ... LL | v.v += 1; - | ^^^^^^^^ `v` is a `&` reference, so the data it refers to cannot be written + | ^^^^^^^^ `v` is a `&` reference, so it cannot be written to error: aborting due to 1 previous error diff --git a/tests/ui/suggestions/suggest-mut-method-for-loop.stderr b/tests/ui/suggestions/suggest-mut-method-for-loop.stderr index 37bb25b300f3..26764ebc4a45 100644 --- a/tests/ui/suggestions/suggest-mut-method-for-loop.stderr +++ b/tests/ui/suggestions/suggest-mut-method-for-loop.stderr @@ -8,7 +8,7 @@ LL | for mut t in buzz.values() { | this iterator yields `&` references ... LL | t.v += 1; - | ^^^^^^^^ `t` is a `&` reference, so the data it refers to cannot be written + | ^^^^^^^^ `t` is a `&` reference, so it cannot be written to error: aborting due to 1 previous error diff --git a/tests/ui/suggestions/suggest-ref-mut.stderr b/tests/ui/suggestions/suggest-ref-mut.stderr index 7c0899f0fbc1..ae96f6408f08 100644 --- a/tests/ui/suggestions/suggest-ref-mut.stderr +++ b/tests/ui/suggestions/suggest-ref-mut.stderr @@ -2,7 +2,7 @@ error[E0594]: cannot assign to `self.0`, which is behind a `&` reference --> $DIR/suggest-ref-mut.rs:9:9 | LL | self.0 = 32; - | ^^^^^^^^^^^ `self` is a `&` reference, so the data it refers to cannot be written + | ^^^^^^^^^^^ `self` is a `&` reference, so it cannot be written to | help: consider changing this to be a mutable reference | @@ -13,7 +13,7 @@ error[E0594]: cannot assign to `*foo`, which is behind a `&` reference --> $DIR/suggest-ref-mut.rs:17:5 | LL | *foo = 32; - | ^^^^^^^^^ `foo` is a `&` reference, so the data it refers to cannot be written + | ^^^^^^^^^ `foo` is a `&` reference, so it cannot be written to | help: consider changing this to be a mutable reference | @@ -24,7 +24,7 @@ error[E0594]: cannot assign to `*bar`, which is behind a `&` reference --> $DIR/suggest-ref-mut.rs:21:9 | LL | *bar = 32; - | ^^^^^^^^^ `bar` is a `&` reference, so the data it refers to cannot be written + | ^^^^^^^^^ `bar` is a `&` reference, so it cannot be written to | help: consider changing this to be a mutable reference | @@ -35,7 +35,7 @@ error[E0594]: cannot assign to `*quo`, which is behind a `&` reference --> $DIR/suggest-ref-mut.rs:25:22 | LL | ref quo => { *quo = 32; }, - | ^^^^^^^^^ `quo` is a `&` reference, so the data it refers to cannot be written + | ^^^^^^^^^ `quo` is a `&` reference, so it cannot be written to | help: consider changing this to be a mutable reference | diff --git a/tests/ui/suggestions/wrap-dyn-in-suggestion-issue-120223.stderr b/tests/ui/suggestions/wrap-dyn-in-suggestion-issue-120223.stderr index 62943616e3ad..0c331355407d 100644 --- a/tests/ui/suggestions/wrap-dyn-in-suggestion-issue-120223.stderr +++ b/tests/ui/suggestions/wrap-dyn-in-suggestion-issue-120223.stderr @@ -38,6 +38,8 @@ LL | fn without_sized &'static (dyn std::fmt::Debug) + ?Sized>() {} error[E0310]: the parameter type `impl FnOnce(T) -> dyn Future` may not live long enough --> $DIR/wrap-dyn-in-suggestion-issue-120223.rs:6:5 | +LL | ) -> Box dyn Future> { + | ---------------------------------------- this `dyn Trait` has an implicit `'static` lifetime bound LL | Box::new(executor) | ^^^^^^^^^^^^^^^^^^ | | diff --git a/tests/ui/thir-print/c-variadic.rs b/tests/ui/thir-print/c-variadic.rs index e03c4b083858..a418e17e84c3 100644 --- a/tests/ui/thir-print/c-variadic.rs +++ b/tests/ui/thir-print/c-variadic.rs @@ -1,6 +1,7 @@ //@ compile-flags: -Zunpretty=thir-tree --crate-type=lib //@ check-pass #![feature(c_variadic)] +#![expect(varargs_without_pattern)] // The `...` argument uses `PatKind::Missing`. unsafe extern "C" fn foo(_: i32, ...) {} diff --git a/tests/ui/thir-print/c-variadic.stdout b/tests/ui/thir-print/c-variadic.stdout index 8363f06ebe88..adfcd976a1e2 100644 --- a/tests/ui/thir-print/c-variadic.stdout +++ b/tests/ui/thir-print/c-variadic.stdout @@ -2,13 +2,13 @@ DefId(0:3 ~ c_variadic[a5de]::foo): params: [ Param { ty: i32 - ty_span: Some($DIR/c-variadic.rs:6:29: 6:32 (#0)) + ty_span: Some($DIR/c-variadic.rs:7:29: 7:32 (#0)) self_kind: None hir_id: Some(HirId(DefId(0:3 ~ c_variadic[a5de]::foo).1)) param: Some( Pat: { ty: i32 - span: $DIR/c-variadic.rs:6:26: 6:27 (#0) + span: $DIR/c-variadic.rs:7:26: 7:27 (#0) kind: PatKind { Wild } @@ -23,7 +23,7 @@ params: [ param: Some( Pat: { ty: std::ffi::VaListImpl<'{erased}> - span: $DIR/c-variadic.rs:6:34: 6:37 (#0) + span: $DIR/c-variadic.rs:7:34: 7:37 (#0) kind: PatKind { Missing } @@ -35,7 +35,7 @@ body: Expr { ty: () temp_lifetime: TempLifetime { temp_lifetime: Some(Node(6)), backwards_incompatible: None } - span: $DIR/c-variadic.rs:6:39: 6:41 (#0) + span: $DIR/c-variadic.rs:7:39: 7:41 (#0) kind: Scope { region_scope: Node(6) @@ -44,11 +44,11 @@ body: Expr { ty: () temp_lifetime: TempLifetime { temp_lifetime: Some(Node(6)), backwards_incompatible: None } - span: $DIR/c-variadic.rs:6:39: 6:41 (#0) + span: $DIR/c-variadic.rs:7:39: 7:41 (#0) kind: Block { targeted_by_break: false - span: $DIR/c-variadic.rs:6:39: 6:41 (#0) + span: $DIR/c-variadic.rs:7:39: 7:41 (#0) region_scope: Node(5) safety_mode: Safe stmts: [] diff --git a/tests/ui/thread-local/thread-local-mutation.stderr b/tests/ui/thread-local/thread-local-mutation.stderr index 9001de34adfb..02f5472ad2df 100644 --- a/tests/ui/thread-local/thread-local-mutation.stderr +++ b/tests/ui/thread-local/thread-local-mutation.stderr @@ -1,6 +1,9 @@ error[E0594]: cannot assign to immutable static item `S` --> $DIR/thread-local-mutation.rs:11:5 | +LL | static S: &str = "before"; + | -------------- this `static` cannot be written to +... LL | S = "after"; | ^^^^^^^^^^^ cannot assign diff --git a/tests/ui/traits/bound/same-crate-name.rs b/tests/ui/traits/bound/same-crate-name.rs index 395b963031a5..acd489461287 100644 --- a/tests/ui/traits/bound/same-crate-name.rs +++ b/tests/ui/traits/bound/same-crate-name.rs @@ -32,13 +32,15 @@ fn main() { extern crate crate_a1 as a; a::try_foo(foo); //~^ ERROR E0277 - //~| HELP trait impl with same name found - //~| NOTE perhaps two different versions of crate `crate_a2` + //~| NOTE there are multiple different versions of crate `crate_a1` in the dependency graph + //~| HELP you can use `cargo tree` to explore your dependency tree // We don't want to see the "version mismatch" help message here // because `implements_no_traits` has no impl for `Foo` a::try_foo(implements_no_traits); //~^ ERROR E0277 + //~| NOTE there are multiple different versions of crate `crate_a1` in the dependency graph + //~| HELP you can use `cargo tree` to explore your dependency tree // We don't want to see the "version mismatch" help message here // because `other_variant_implements_mismatched_trait` @@ -46,6 +48,8 @@ fn main() { // only for its `` variant. a::try_foo(other_variant_implements_mismatched_trait); //~^ ERROR E0277 + //~| NOTE there are multiple different versions of crate `crate_a1` in the dependency graph + //~| HELP you can use `cargo tree` to explore your dependency tree // We don't want to see the "version mismatch" help message here // because `ImplementsTraitForUsize` only has @@ -53,5 +57,7 @@ fn main() { a::try_foo(other_variant_implements_correct_trait); //~^ ERROR E0277 //~| HELP the trait `main::a::Bar` is implemented for `ImplementsTraitForUsize` + //~| NOTE there are multiple different versions of crate `crate_a1` in the dependency graph + //~| HELP you can use `cargo tree` to explore your dependency tree } } diff --git a/tests/ui/traits/bound/same-crate-name.stderr b/tests/ui/traits/bound/same-crate-name.stderr index 5266f934f3ac..9e5e110f8624 100644 --- a/tests/ui/traits/bound/same-crate-name.stderr +++ b/tests/ui/traits/bound/same-crate-name.stderr @@ -6,12 +6,17 @@ LL | a::try_foo(foo); | | | required by a bound introduced by this call | -help: trait impl with same name found - --> $DIR/auxiliary/crate_a2.rs:5:1 +note: there are multiple different versions of crate `crate_a1` in the dependency graph + --> $DIR/auxiliary/crate_a1.rs:1:1 | -LL | impl Bar for Foo {} - | ^^^^^^^^^^^^^^^^ - = note: perhaps two different versions of crate `crate_a2` are being used? +LL | pub trait Bar {} + | ^^^^^^^^^^^^^ this is the expected trait + | + ::: $DIR/auxiliary/crate_a2.rs:3:1 + | +LL | pub trait Bar {} + | ------------- this is the found trait + = help: you can use `cargo tree` to explore your dependency tree help: the trait `main::a::Bar` is implemented for `ImplementsTraitForUsize` --> $DIR/auxiliary/crate_a1.rs:9:1 | @@ -31,6 +36,17 @@ LL | a::try_foo(implements_no_traits); | | | required by a bound introduced by this call | +note: there are multiple different versions of crate `crate_a1` in the dependency graph + --> $DIR/auxiliary/crate_a1.rs:1:1 + | +LL | pub trait Bar {} + | ^^^^^^^^^^^^^ this is the expected trait + | + ::: $DIR/auxiliary/crate_a2.rs:3:1 + | +LL | pub trait Bar {} + | ------------- this is the trait that was imported + = help: you can use `cargo tree` to explore your dependency tree help: the trait `main::a::Bar` is implemented for `ImplementsTraitForUsize` --> $DIR/auxiliary/crate_a1.rs:9:1 | @@ -43,19 +59,24 @@ LL | pub fn try_foo(x: impl Bar) {} | ^^^ required by this bound in `try_foo` error[E0277]: the trait bound `ImplementsWrongTraitConditionally: main::a::Bar` is not satisfied - --> $DIR/same-crate-name.rs:47:20 + --> $DIR/same-crate-name.rs:49:20 | LL | a::try_foo(other_variant_implements_mismatched_trait); | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `main::a::Bar` is not implemented for `ImplementsWrongTraitConditionally` | | | required by a bound introduced by this call | -help: trait impl with same name found - --> $DIR/auxiliary/crate_a2.rs:13:1 +note: there are multiple different versions of crate `crate_a1` in the dependency graph + --> $DIR/auxiliary/crate_a1.rs:1:1 | -LL | impl Bar for ImplementsWrongTraitConditionally {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: perhaps two different versions of crate `crate_a2` are being used? +LL | pub trait Bar {} + | ^^^^^^^^^^^^^ this is the expected trait + | + ::: $DIR/auxiliary/crate_a2.rs:3:1 + | +LL | pub trait Bar {} + | ------------- this is the found trait + = help: you can use `cargo tree` to explore your dependency tree help: the trait `main::a::Bar` is implemented for `ImplementsTraitForUsize` --> $DIR/auxiliary/crate_a1.rs:9:1 | @@ -68,13 +89,24 @@ LL | pub fn try_foo(x: impl Bar) {} | ^^^ required by this bound in `try_foo` error[E0277]: the trait bound `ImplementsTraitForUsize: main::a::Bar` is not satisfied - --> $DIR/same-crate-name.rs:53:20 + --> $DIR/same-crate-name.rs:57:20 | LL | a::try_foo(other_variant_implements_correct_trait); | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `main::a::Bar` is not implemented for `ImplementsTraitForUsize` | | | required by a bound introduced by this call | +note: there are multiple different versions of crate `crate_a1` in the dependency graph + --> $DIR/auxiliary/crate_a1.rs:1:1 + | +LL | pub trait Bar {} + | ^^^^^^^^^^^^^ this is the expected trait + | + ::: $DIR/auxiliary/crate_a2.rs:3:1 + | +LL | pub trait Bar {} + | ------------- this is the trait that was imported + = help: you can use `cargo tree` to explore your dependency tree help: the trait `main::a::Bar` is implemented for `ImplementsTraitForUsize` --> $DIR/auxiliary/crate_a1.rs:9:1 | diff --git a/tests/ui/traits/similarly_named_trait.rs b/tests/ui/traits/similarly_named_trait.rs new file mode 100644 index 000000000000..2545b9c7ed30 --- /dev/null +++ b/tests/ui/traits/similarly_named_trait.rs @@ -0,0 +1,28 @@ +trait Trait {} //~ HELP this trait has no implementations, consider adding one +trait TraitWithParam {} //~ HELP this trait has no implementations, consider adding one + +mod m { + pub trait Trait {} + pub trait TraitWithParam {} + pub struct St; //~ HELP the trait `Trait` is not implemented for `St` + //~| HELP the trait `TraitWithParam` is not implemented for `St` + impl Trait for St {} + impl TraitWithParam for St {} +} + +fn func(_: T) {} //~ NOTE required by a bound in `func` +//~^ NOTE required by this bound in `func` + +fn func2> (_: T) {} //~ NOTE required by a bound in `func2` +//~^ NOTE required by this bound in `func2` + +fn main() { + func(m::St); //~ ERROR the trait bound `St: Trait` is not satisfied + //~^ NOTE unsatisfied trait bound + //~| NOTE required by a bound introduced by this call + //~| NOTE `St` implements similarly named trait `m::Trait`, but not `Trait` + func2(m::St); //~ ERROR the trait bound `St: TraitWithParam` is not satisfied + //~^ NOTE unsatisfied trait bound + //~| NOTE required by a bound introduced by this call + //~| NOTE `St` implements similarly named trait `m::TraitWithParam`, but not `TraitWithParam` +} diff --git a/tests/ui/traits/similarly_named_trait.stderr b/tests/ui/traits/similarly_named_trait.stderr new file mode 100644 index 000000000000..2432e1ffbbe5 --- /dev/null +++ b/tests/ui/traits/similarly_named_trait.stderr @@ -0,0 +1,53 @@ +error[E0277]: the trait bound `St: Trait` is not satisfied + --> $DIR/similarly_named_trait.rs:20:10 + | +LL | func(m::St); + | ---- ^^^^^ unsatisfied trait bound + | | + | required by a bound introduced by this call + | +help: the trait `Trait` is not implemented for `St` + --> $DIR/similarly_named_trait.rs:7:5 + | +LL | pub struct St; + | ^^^^^^^^^^^^^ + = note: `St` implements similarly named trait `m::Trait`, but not `Trait` +help: this trait has no implementations, consider adding one + --> $DIR/similarly_named_trait.rs:1:1 + | +LL | trait Trait {} + | ^^^^^^^^^^^ +note: required by a bound in `func` + --> $DIR/similarly_named_trait.rs:13:12 + | +LL | fn func(_: T) {} + | ^^^^^ required by this bound in `func` + +error[E0277]: the trait bound `St: TraitWithParam` is not satisfied + --> $DIR/similarly_named_trait.rs:24:11 + | +LL | func2(m::St); + | ----- ^^^^^ unsatisfied trait bound + | | + | required by a bound introduced by this call + | +help: the trait `TraitWithParam` is not implemented for `St` + --> $DIR/similarly_named_trait.rs:7:5 + | +LL | pub struct St; + | ^^^^^^^^^^^^^ + = note: `St` implements similarly named trait `m::TraitWithParam`, but not `TraitWithParam` +help: this trait has no implementations, consider adding one + --> $DIR/similarly_named_trait.rs:2:1 + | +LL | trait TraitWithParam {} + | ^^^^^^^^^^^^^^^^^^^^^^^ +note: required by a bound in `func2` + --> $DIR/similarly_named_trait.rs:16:13 + | +LL | fn func2> (_: T) {} + | ^^^^^^^^^^^^^^^^^ required by this bound in `func2` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/suggest-dereferences/invalid-suggest-deref-issue-127590.rs b/tests/ui/traits/suggest-dereferences/invalid-suggest-deref-issue-127590.rs index a71657316ae6..ad1ff56190c2 100644 --- a/tests/ui/traits/suggest-dereferences/invalid-suggest-deref-issue-127590.rs +++ b/tests/ui/traits/suggest-dereferences/invalid-suggest-deref-issue-127590.rs @@ -6,6 +6,7 @@ fn main() { for (src, dest) in std::iter::zip(fields.iter(), &variant.iter()) { //~^ ERROR `&std::slice::Iter<'_, {integer}>` is not an iterator //~| ERROR `&std::slice::Iter<'_, {integer}>` is not an iterator + //~| ERROR `&std::slice::Iter<'_, {integer}>` is not an iterator eprintln!("{} {}", src, dest); } @@ -13,6 +14,7 @@ fn main() { for (src, dest) in std::iter::zip(fields.iter(), &variant.iter().clone()) { //~^ ERROR `&std::slice::Iter<'_, {integer}>` is not an iterator //~| ERROR `&std::slice::Iter<'_, {integer}>` is not an iterator + //~| ERROR `&std::slice::Iter<'_, {integer}>` is not an iterator eprintln!("{} {}", src, dest); } } diff --git a/tests/ui/traits/suggest-dereferences/invalid-suggest-deref-issue-127590.stderr b/tests/ui/traits/suggest-dereferences/invalid-suggest-deref-issue-127590.stderr index 103fb7bbfe11..07a54d574df4 100644 --- a/tests/ui/traits/suggest-dereferences/invalid-suggest-deref-issue-127590.stderr +++ b/tests/ui/traits/suggest-dereferences/invalid-suggest-deref-issue-127590.stderr @@ -30,7 +30,7 @@ help: the trait `Iterator` is implemented for `std::slice::Iter<'_, T>` = note: this error originates in the macro `iterator` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: `&std::slice::Iter<'_, {integer}>` is not an iterator - --> $DIR/invalid-suggest-deref-issue-127590.rs:13:54 + --> $DIR/invalid-suggest-deref-issue-127590.rs:14:54 | LL | for (src, dest) in std::iter::zip(fields.iter(), &variant.iter().clone()) { | -------------- ^^^^^^^^^^^^^^^^^^^^^^^ `&std::slice::Iter<'_, {integer}>` is not an iterator @@ -48,7 +48,7 @@ LL + for (src, dest) in std::iter::zip(fields.iter(), variant.iter().clone() | error[E0277]: `&std::slice::Iter<'_, {integer}>` is not an iterator - --> $DIR/invalid-suggest-deref-issue-127590.rs:13:24 + --> $DIR/invalid-suggest-deref-issue-127590.rs:14:24 | LL | for (src, dest) in std::iter::zip(fields.iter(), &variant.iter().clone()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `&std::slice::Iter<'_, {integer}>` is not an iterator @@ -60,6 +60,30 @@ help: the trait `Iterator` is implemented for `std::slice::Iter<'_, T>` = note: required for `Zip, &std::slice::Iter<'_, {integer}>>` to implement `IntoIterator` = note: this error originates in the macro `iterator` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 4 previous errors +error[E0277]: `&std::slice::Iter<'_, {integer}>` is not an iterator + --> $DIR/invalid-suggest-deref-issue-127590.rs:6:24 + | +LL | for (src, dest) in std::iter::zip(fields.iter(), &variant.iter()) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `&std::slice::Iter<'_, {integer}>` is not an iterator + | + = help: the trait `Iterator` is not implemented for `&std::slice::Iter<'_, {integer}>` +help: the trait `Iterator` is implemented for `std::slice::Iter<'_, T>` + --> $SRC_DIR/core/src/slice/iter.rs:LL:COL + = note: required for `&std::slice::Iter<'_, {integer}>` to implement `IntoIterator` + = note: this error originates in the macro `iterator` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0277]: `&std::slice::Iter<'_, {integer}>` is not an iterator + --> $DIR/invalid-suggest-deref-issue-127590.rs:14:24 + | +LL | for (src, dest) in std::iter::zip(fields.iter(), &variant.iter().clone()) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `&std::slice::Iter<'_, {integer}>` is not an iterator + | + = help: the trait `Iterator` is not implemented for `&std::slice::Iter<'_, {integer}>` +help: the trait `Iterator` is implemented for `std::slice::Iter<'_, T>` + --> $SRC_DIR/core/src/slice/iter.rs:LL:COL + = note: required for `&std::slice::Iter<'_, {integer}>` to implement `IntoIterator` + = note: this error originates in the macro `iterator` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 6 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/trait-upcasting/mono-impossible.rs b/tests/ui/traits/trait-upcasting/mono-impossible.rs index f19f0538efa7..5deec77a225b 100644 --- a/tests/ui/traits/trait-upcasting/mono-impossible.rs +++ b/tests/ui/traits/trait-upcasting/mono-impossible.rs @@ -1,5 +1,7 @@ //@ build-pass +#![allow(function_casts_as_integer)] + trait Supertrait { fn method(&self) {} } diff --git a/tests/ui/trivial-bounds/trivial-bounds-inconsistent-copy-reborrow.stderr b/tests/ui/trivial-bounds/trivial-bounds-inconsistent-copy-reborrow.stderr index c054ddb893d5..703ad36c4cdc 100644 --- a/tests/ui/trivial-bounds/trivial-bounds-inconsistent-copy-reborrow.stderr +++ b/tests/ui/trivial-bounds/trivial-bounds-inconsistent-copy-reborrow.stderr @@ -2,7 +2,7 @@ error[E0596]: cannot borrow `**t` as mutable, as it is behind a `&` reference --> $DIR/trivial-bounds-inconsistent-copy-reborrow.rs:6:5 | LL | *t - | ^^ `t` is a `&` reference, so the data it refers to cannot be borrowed as mutable + | ^^ `t` is a `&` reference, so it cannot be borrowed as mutable | help: consider changing this to be a mutable reference | @@ -13,7 +13,7 @@ error[E0596]: cannot borrow `**t` as mutable, as it is behind a `&` reference --> $DIR/trivial-bounds-inconsistent-copy-reborrow.rs:10:6 | LL | {*t} - | ^^ `t` is a `&` reference, so the data it refers to cannot be borrowed as mutable + | ^^ `t` is a `&` reference, so it cannot be borrowed as mutable | help: consider changing this to be a mutable reference | diff --git a/tests/ui/type/type-mismatch-same-crate-name.rs b/tests/ui/type/type-mismatch-same-crate-name.rs index e88960364a25..df6d7aba8fd6 100644 --- a/tests/ui/type/type-mismatch-same-crate-name.rs +++ b/tests/ui/type/type-mismatch-same-crate-name.rs @@ -11,24 +11,22 @@ fn main() { let foo2 = {extern crate crate_a2 as a; a::Foo}; - //~^ NOTE one type comes from crate `crate_a2` used here, which is renamed locally to `a` - //~| NOTE one trait comes from crate `crate_a2` used here, which is renamed locally to `a` let bar2 = {extern crate crate_a2 as a; a::bar()}; { extern crate crate_a1 as a; - //~^ NOTE one type comes from crate `crate_a1` used here, which is renamed locally to `a` - //~| NOTE one trait comes from crate `crate_a1` used here, which is renamed locally to `a` a::try_foo(foo2); //~^ ERROR mismatched types //~| NOTE expected `main::a::Foo`, found a different `main::a::Foo` //~| NOTE arguments to this function are incorrect - //~| NOTE two types coming from two different crates are different types even if they look the same + //~| NOTE there are multiple different versions of crate `crate_a1` in the dependency graph //~| NOTE function defined here + //~| HELP you can use `cargo tree` to explore your dependency tree a::try_bar(bar2); //~^ ERROR mismatched types //~| NOTE expected trait `main::a::Bar`, found a different trait `main::a::Bar` //~| NOTE arguments to this function are incorrect - //~| NOTE two types coming from two different crates are different types even if they look the same + //~| NOTE there are multiple different versions of crate `crate_a1` in the dependency graph //~| NOTE function defined here + //~| HELP you can use `cargo tree` to explore your dependency tree } } diff --git a/tests/ui/type/type-mismatch-same-crate-name.stderr b/tests/ui/type/type-mismatch-same-crate-name.stderr index 8fafbfaa9342..2913b994e952 100644 --- a/tests/ui/type/type-mismatch-same-crate-name.stderr +++ b/tests/ui/type/type-mismatch-same-crate-name.stderr @@ -1,29 +1,22 @@ error[E0308]: mismatched types - --> $DIR/type-mismatch-same-crate-name.rs:21:20 + --> $DIR/type-mismatch-same-crate-name.rs:17:20 | LL | a::try_foo(foo2); | ---------- ^^^^ expected `main::a::Foo`, found a different `main::a::Foo` | | | arguments to this function are incorrect | -note: two types coming from two different crates are different types even if they look the same - --> $DIR/auxiliary/crate_a2.rs:1:1 +note: there are multiple different versions of crate `crate_a1` in the dependency graph + --> $DIR/auxiliary/crate_a1.rs:1:1 | LL | pub struct Foo; - | ^^^^^^^^^^^^^^ this is the found type `crate_a2::Foo` + | ^^^^^^^^^^^^^^ this is the expected type | - ::: $DIR/auxiliary/crate_a1.rs:1:1 + ::: $DIR/auxiliary/crate_a2.rs:1:1 | LL | pub struct Foo; - | ^^^^^^^^^^^^^^ this is the expected type `crate_a1::Foo` - | - ::: $DIR/type-mismatch-same-crate-name.rs:13:17 - | -LL | let foo2 = {extern crate crate_a2 as a; a::Foo}; - | --------------------------- one type comes from crate `crate_a2` used here, which is renamed locally to `a` -... -LL | extern crate crate_a1 as a; - | --------------------------- one type comes from crate `crate_a1` used here, which is renamed locally to `a` + | -------------- this is the found type + = help: you can use `cargo tree` to explore your dependency tree note: function defined here --> $DIR/auxiliary/crate_a1.rs:10:8 | @@ -31,31 +24,24 @@ LL | pub fn try_foo(x: Foo){} | ^^^^^^^ error[E0308]: mismatched types - --> $DIR/type-mismatch-same-crate-name.rs:27:20 + --> $DIR/type-mismatch-same-crate-name.rs:24:20 | LL | a::try_bar(bar2); | ---------- ^^^^ expected trait `main::a::Bar`, found a different trait `main::a::Bar` | | | arguments to this function are incorrect | -note: two types coming from two different crates are different types even if they look the same - --> $DIR/auxiliary/crate_a2.rs:3:1 +note: there are multiple different versions of crate `crate_a1` in the dependency graph + --> $DIR/auxiliary/crate_a1.rs:3:1 | LL | pub trait Bar {} - | ^^^^^^^^^^^^^ this is the found trait `crate_a2::Bar` + | ^^^^^^^^^^^^^ this is the expected trait | - ::: $DIR/auxiliary/crate_a1.rs:3:1 + ::: $DIR/auxiliary/crate_a2.rs:3:1 | LL | pub trait Bar {} - | ^^^^^^^^^^^^^ this is the expected trait `crate_a1::Bar` - | - ::: $DIR/type-mismatch-same-crate-name.rs:13:17 - | -LL | let foo2 = {extern crate crate_a2 as a; a::Foo}; - | --------------------------- one trait comes from crate `crate_a2` used here, which is renamed locally to `a` -... -LL | extern crate crate_a1 as a; - | --------------------------- one trait comes from crate `crate_a1` used here, which is renamed locally to `a` + | ------------- this is the found trait + = help: you can use `cargo tree` to explore your dependency tree note: function defined here --> $DIR/auxiliary/crate_a1.rs:11:8 | diff --git a/tests/ui/union/issue-81199.stderr b/tests/ui/union/issue-81199.stderr index 7deba88fc803..46f5de8d4fd8 100644 --- a/tests/ui/union/issue-81199.stderr +++ b/tests/ui/union/issue-81199.stderr @@ -16,6 +16,7 @@ error[E0277]: the trait bound `T: Pointee` is not satisfied LL | components: PtrComponents, | ^^^^^^^^^^^^^^^^ the trait `Pointee` is not implemented for `T` | + = note: `T` implements similarly named trait `std::ptr::Pointee`, but not `Pointee` note: required by a bound in `PtrComponents` --> $DIR/issue-81199.rs:11:25 | diff --git a/triagebot.toml b/triagebot.toml index b9739149ea83..adc73c42c428 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -1663,7 +1663,7 @@ labels = ["has-merge-commits", "S-waiting-on-author"] format = "rustc" project-name = "Rust" changelog-path = "RELEASES.md" -changelog-branch = "master" +changelog-branch = "main" [shortcut]