Auto merge of #3489 - rust-lang:rustup-2024-04-19, r=RalfJung
Automatic Rustup
This commit is contained in:
commit
95ae2dd7ff
342 changed files with 3253 additions and 2433 deletions
|
|
@ -6332,9 +6332,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "windows-bindgen"
|
||||
version = "0.55.0"
|
||||
version = "0.56.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "073ff8a486ebad239d557809d2cd5fe5e04ee1de29e09c6cd83fb0bae19b8a4c"
|
||||
checksum = "a28e3ea6330cf17fdcdce8bf08d0549ce93769dca9bedc6c39c36c8c0e17db46"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"rayon",
|
||||
|
|
@ -6355,9 +6355,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "windows-metadata"
|
||||
version = "0.55.0"
|
||||
version = "0.56.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b602635050172a1fc57a35040d4d225baefc6098fefd97094919921d95961a7d"
|
||||
checksum = "3993f7827fff10c454e3a24847075598c7c08108304b8b07943c2c73d78f3b34"
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
|
|
|
|||
|
|
@ -568,7 +568,7 @@ impl Pat {
|
|||
// In a type expression `_` is an inference variable.
|
||||
PatKind::Wild => TyKind::Infer,
|
||||
// An IDENT pattern with no binding mode would be valid as path to a type. E.g. `u32`.
|
||||
PatKind::Ident(BindingAnnotation::NONE, ident, None) => {
|
||||
PatKind::Ident(BindingMode::NONE, ident, None) => {
|
||||
TyKind::Path(None, Path::from_ident(*ident))
|
||||
}
|
||||
PatKind::Path(qself, path) => TyKind::Path(qself.clone(), path.clone()),
|
||||
|
|
@ -675,7 +675,7 @@ impl Pat {
|
|||
pub fn descr(&self) -> Option<String> {
|
||||
match &self.kind {
|
||||
PatKind::Wild => Some("_".to_string()),
|
||||
PatKind::Ident(BindingAnnotation::NONE, ident, None) => Some(format!("{ident}")),
|
||||
PatKind::Ident(BindingMode::NONE, ident, None) => Some(format!("{ident}")),
|
||||
PatKind::Ref(pat, mutbl) => pat.descr().map(|d| format!("&{}{d}", mutbl.prefix_str())),
|
||||
_ => None,
|
||||
}
|
||||
|
|
@ -707,14 +707,25 @@ pub enum ByRef {
|
|||
No,
|
||||
}
|
||||
|
||||
/// Explicit binding annotations given in the HIR for a binding. Note
|
||||
/// that this is not the final binding *mode* that we infer after type
|
||||
/// inference.
|
||||
impl ByRef {
|
||||
pub fn cap_ref_mutability(mut self, mutbl: Mutability) -> Self {
|
||||
if let ByRef::Yes(old_mutbl) = &mut self {
|
||||
*old_mutbl = cmp::min(*old_mutbl, mutbl);
|
||||
}
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
/// The mode of a binding (`mut`, `ref mut`, etc).
|
||||
/// Used for both the explicit binding annotations given in the HIR for a binding
|
||||
/// and the final binding mode that we infer after type inference/match ergonomics.
|
||||
/// `.0` is the by-reference mode (`ref`, `ref mut`, or by value),
|
||||
/// `.1` is the mutability of the binding.
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
#[derive(Encodable, Decodable, HashStable_Generic)]
|
||||
pub struct BindingAnnotation(pub ByRef, pub Mutability);
|
||||
pub struct BindingMode(pub ByRef, pub Mutability);
|
||||
|
||||
impl BindingAnnotation {
|
||||
impl BindingMode {
|
||||
pub const NONE: Self = Self(ByRef::No, Mutability::Not);
|
||||
pub const REF: Self = Self(ByRef::Yes(Mutability::Not), Mutability::Not);
|
||||
pub const MUT: Self = Self(ByRef::No, Mutability::Mut);
|
||||
|
|
@ -732,13 +743,6 @@ impl BindingAnnotation {
|
|||
Self::MUT_REF_MUT => "mut ref mut ",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn cap_ref_mutability(mut self, mutbl: Mutability) -> Self {
|
||||
if let ByRef::Yes(old_mutbl) = &mut self.0 {
|
||||
*old_mutbl = cmp::min(*old_mutbl, mutbl);
|
||||
}
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Encodable, Decodable, Debug)]
|
||||
|
|
@ -769,7 +773,7 @@ pub enum PatKind {
|
|||
/// or a unit struct/variant pattern, or a const pattern (in the last two cases the third
|
||||
/// field must be `None`). Disambiguation cannot be done with parser alone, so it happens
|
||||
/// during name resolution.
|
||||
Ident(BindingAnnotation, Ident, Option<P<Pat>>),
|
||||
Ident(BindingMode, Ident, Option<P<Pat>>),
|
||||
|
||||
/// A struct or struct variant pattern (e.g., `Variant {x, y, ..}`).
|
||||
Struct(Option<P<QSelf>>, Path, ThinVec<PatField>, PatFieldsRest),
|
||||
|
|
@ -2382,7 +2386,7 @@ pub type ExplicitSelf = Spanned<SelfKind>;
|
|||
impl Param {
|
||||
/// Attempts to cast parameter to `ExplicitSelf`.
|
||||
pub fn to_self(&self) -> Option<ExplicitSelf> {
|
||||
if let PatKind::Ident(BindingAnnotation(ByRef::No, mutbl), ident, _) = self.pat.kind {
|
||||
if let PatKind::Ident(BindingMode(ByRef::No, mutbl), ident, _) = self.pat.kind {
|
||||
if ident.name == kw::SelfLower {
|
||||
return match self.ty.kind {
|
||||
TyKind::ImplicitSelf => Some(respan(self.pat.span, SelfKind::Value(mutbl))),
|
||||
|
|
@ -2434,7 +2438,7 @@ impl Param {
|
|||
attrs,
|
||||
pat: P(Pat {
|
||||
id: DUMMY_NODE_ID,
|
||||
kind: PatKind::Ident(BindingAnnotation(ByRef::No, mutbl), eself_ident, None),
|
||||
kind: PatKind::Ident(BindingMode(ByRef::No, mutbl), eself_ident, None),
|
||||
span,
|
||||
tokens: None,
|
||||
}),
|
||||
|
|
@ -3363,7 +3367,7 @@ impl TryFrom<ItemKind> for ForeignItemKind {
|
|||
pub type ForeignItem = Item<ForeignItemKind>;
|
||||
|
||||
// Some nodes are used a lot. Make sure they don't unintentionally get bigger.
|
||||
#[cfg(all(any(target_arch = "x86_64", target_arch = "aarch64"), target_pointer_width = "64"))]
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
mod size_asserts {
|
||||
use super::*;
|
||||
use rustc_data_structures::static_assert_size;
|
||||
|
|
|
|||
|
|
@ -1023,7 +1023,7 @@ where
|
|||
}
|
||||
|
||||
// Some types are used a lot. Make sure they don't unintentionally get bigger.
|
||||
#[cfg(all(any(target_arch = "x86_64", target_arch = "aarch64"), target_pointer_width = "64"))]
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
mod size_asserts {
|
||||
use super::*;
|
||||
use rustc_data_structures::static_assert_size;
|
||||
|
|
|
|||
|
|
@ -768,7 +768,7 @@ impl DelimSpacing {
|
|||
}
|
||||
|
||||
// Some types are used a lot. Make sure they don't unintentionally get bigger.
|
||||
#[cfg(all(any(target_arch = "x86_64", target_arch = "aarch64"), target_pointer_width = "64"))]
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
mod size_asserts {
|
||||
use super::*;
|
||||
use rustc_data_structures::static_assert_size;
|
||||
|
|
|
|||
|
|
@ -178,7 +178,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
let pat_id = self.lower_node_id(pat_node_id);
|
||||
let pat = self.arena.alloc(hir::Pat {
|
||||
hir_id: pat_id,
|
||||
kind: hir::PatKind::Binding(hir::BindingAnnotation::NONE, pat_id, Ident::empty(), None),
|
||||
kind: hir::PatKind::Binding(hir::BindingMode::NONE, pat_id, Ident::empty(), None),
|
||||
span: ty.span,
|
||||
default_binding_modes: false,
|
||||
});
|
||||
|
|
|
|||
|
|
@ -643,7 +643,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
let (pat, task_context_hid) = self.pat_ident_binding_mode(
|
||||
span,
|
||||
Ident::with_dummy_span(sym::_task_context),
|
||||
hir::BindingAnnotation::MUT,
|
||||
hir::BindingMode::MUT,
|
||||
);
|
||||
let param = hir::Param {
|
||||
hir_id: self.next_id(),
|
||||
|
|
@ -805,11 +805,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
// debuggers and debugger extensions expect it to be called `__awaitee`. They use
|
||||
// this name to identify what is being awaited by a suspended async functions.
|
||||
let awaitee_ident = Ident::with_dummy_span(sym::__awaitee);
|
||||
let (awaitee_pat, awaitee_pat_hid) = self.pat_ident_binding_mode(
|
||||
gen_future_span,
|
||||
awaitee_ident,
|
||||
hir::BindingAnnotation::MUT,
|
||||
);
|
||||
let (awaitee_pat, awaitee_pat_hid) =
|
||||
self.pat_ident_binding_mode(gen_future_span, awaitee_ident, hir::BindingMode::MUT);
|
||||
|
||||
let task_context_ident = Ident::with_dummy_span(sym::_task_context);
|
||||
|
||||
|
|
@ -1648,7 +1645,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
// `mut iter`
|
||||
let iter = Ident::with_dummy_span(sym::iter);
|
||||
let (iter_pat, iter_pat_nid) =
|
||||
self.pat_ident_binding_mode(head_span, iter, hir::BindingAnnotation::MUT);
|
||||
self.pat_ident_binding_mode(head_span, iter, hir::BindingMode::MUT);
|
||||
|
||||
let match_expr = {
|
||||
let iter = self.expr_ident(head_span, iter, iter_pat_nid);
|
||||
|
|
|
|||
|
|
@ -1179,9 +1179,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
// Check if this is a binding pattern, if so, we can optimize and avoid adding a
|
||||
// `let <pat> = __argN;` statement. In this case, we do not rename the parameter.
|
||||
let (ident, is_simple_parameter) = match parameter.pat.kind {
|
||||
hir::PatKind::Binding(hir::BindingAnnotation(ByRef::No, _), _, ident, _) => {
|
||||
(ident, true)
|
||||
}
|
||||
hir::PatKind::Binding(hir::BindingMode(ByRef::No, _), _, ident, _) => (ident, true),
|
||||
// For `ref mut` or wildcard arguments, we can't reuse the binding, but
|
||||
// we can keep the same name for the parameter.
|
||||
// This lets rustdoc render it correctly in documentation.
|
||||
|
|
@ -1244,7 +1242,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
// because the user may have specified a `ref mut` binding in the next
|
||||
// statement.
|
||||
let (move_pat, move_id) =
|
||||
self.pat_ident_binding_mode(desugared_span, ident, hir::BindingAnnotation::MUT);
|
||||
self.pat_ident_binding_mode(desugared_span, ident, hir::BindingMode::MUT);
|
||||
let move_expr = self.expr_ident(desugared_span, ident, new_parameter_id);
|
||||
let move_stmt = self.stmt_let_pat(
|
||||
None,
|
||||
|
|
|
|||
|
|
@ -1895,7 +1895,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
implicit_self: decl.inputs.get(0).map_or(hir::ImplicitSelfKind::None, |arg| {
|
||||
let is_mutable_pat = matches!(
|
||||
arg.pat.kind,
|
||||
PatKind::Ident(hir::BindingAnnotation(_, Mutability::Mut), ..)
|
||||
PatKind::Ident(hir::BindingMode(_, Mutability::Mut), ..)
|
||||
);
|
||||
|
||||
match &arg.ty.kind {
|
||||
|
|
@ -2478,18 +2478,18 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
}
|
||||
|
||||
fn pat_ident(&mut self, span: Span, ident: Ident) -> (&'hir hir::Pat<'hir>, HirId) {
|
||||
self.pat_ident_binding_mode(span, ident, hir::BindingAnnotation::NONE)
|
||||
self.pat_ident_binding_mode(span, ident, hir::BindingMode::NONE)
|
||||
}
|
||||
|
||||
fn pat_ident_mut(&mut self, span: Span, ident: Ident) -> (hir::Pat<'hir>, HirId) {
|
||||
self.pat_ident_binding_mode_mut(span, ident, hir::BindingAnnotation::NONE)
|
||||
self.pat_ident_binding_mode_mut(span, ident, hir::BindingMode::NONE)
|
||||
}
|
||||
|
||||
fn pat_ident_binding_mode(
|
||||
&mut self,
|
||||
span: Span,
|
||||
ident: Ident,
|
||||
bm: hir::BindingAnnotation,
|
||||
bm: hir::BindingMode,
|
||||
) -> (&'hir hir::Pat<'hir>, HirId) {
|
||||
let (pat, hir_id) = self.pat_ident_binding_mode_mut(span, ident, bm);
|
||||
(self.arena.alloc(pat), hir_id)
|
||||
|
|
@ -2499,7 +2499,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
&mut self,
|
||||
span: Span,
|
||||
ident: Ident,
|
||||
bm: hir::BindingAnnotation,
|
||||
bm: hir::BindingMode,
|
||||
) -> (hir::Pat<'hir>, HirId) {
|
||||
let hir_id = self.next_id();
|
||||
|
||||
|
|
|
|||
|
|
@ -243,7 +243,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
fn lower_pat_ident(
|
||||
&mut self,
|
||||
p: &Pat,
|
||||
annotation: BindingAnnotation,
|
||||
annotation: BindingMode,
|
||||
ident: Ident,
|
||||
lower_sub: impl FnOnce(&mut Self) -> Option<&'hir hir::Pat<'hir>>,
|
||||
) -> hir::PatKind<'hir> {
|
||||
|
|
|
|||
|
|
@ -276,8 +276,8 @@ impl<'a> AstValidator<'a> {
|
|||
fn check_decl_no_pat(decl: &FnDecl, mut report_err: impl FnMut(Span, Option<Ident>, bool)) {
|
||||
for Param { pat, .. } in &decl.inputs {
|
||||
match pat.kind {
|
||||
PatKind::Ident(BindingAnnotation::NONE, _, None) | PatKind::Wild => {}
|
||||
PatKind::Ident(BindingAnnotation::MUT, ident, None) => {
|
||||
PatKind::Ident(BindingMode::NONE, _, None) | PatKind::Wild => {}
|
||||
PatKind::Ident(BindingMode::MUT, ident, None) => {
|
||||
report_err(pat.span, Some(ident), true)
|
||||
}
|
||||
_ => report_err(pat.span, None, false),
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ use rustc_ast::util::classify;
|
|||
use rustc_ast::util::comments::{Comment, CommentStyle};
|
||||
use rustc_ast::util::parser;
|
||||
use rustc_ast::{self as ast, AttrArgs, AttrArgsEq, BlockCheckMode, PatKind};
|
||||
use rustc_ast::{attr, BindingAnnotation, ByRef, DelimArgs, RangeEnd, RangeSyntax, Term};
|
||||
use rustc_ast::{attr, BindingMode, ByRef, DelimArgs, RangeEnd, RangeSyntax, Term};
|
||||
use rustc_ast::{GenericArg, GenericBound, SelfKind};
|
||||
use rustc_ast::{InlineAsmOperand, InlineAsmRegOrRegClass};
|
||||
use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
|
||||
|
|
@ -1558,7 +1558,7 @@ impl<'a> State<'a> {
|
|||
match &pat.kind {
|
||||
PatKind::Wild => self.word("_"),
|
||||
PatKind::Never => self.word("!"),
|
||||
PatKind::Ident(BindingAnnotation(by_ref, mutbl), ident, sub) => {
|
||||
PatKind::Ident(BindingMode(by_ref, mutbl), ident, sub) => {
|
||||
if mutbl.is_mut() {
|
||||
self.word_nbsp("mut");
|
||||
}
|
||||
|
|
@ -1654,7 +1654,7 @@ impl<'a> State<'a> {
|
|||
if mutbl.is_mut() {
|
||||
self.word("mut ");
|
||||
}
|
||||
if let PatKind::Ident(ast::BindingAnnotation::MUT, ..) = inner.kind {
|
||||
if let PatKind::Ident(ast::BindingMode::MUT, ..) = inner.kind {
|
||||
self.popen();
|
||||
self.print_pat(inner);
|
||||
self.pclose();
|
||||
|
|
|
|||
|
|
@ -377,7 +377,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
if p.span == self.expr_span {
|
||||
self.pat = Some(p);
|
||||
}
|
||||
if let hir::PatKind::Binding(hir::BindingAnnotation::NONE, _, i, sub) = p.kind {
|
||||
if let hir::PatKind::Binding(hir::BindingMode::NONE, _, i, sub) = p.kind {
|
||||
if i.span == self.expr_span || p.span == self.expr_span {
|
||||
self.pat = Some(p);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use core::ops::ControlFlow;
|
|||
use hir::{ExprKind, Param};
|
||||
use rustc_errors::{Applicability, Diag};
|
||||
use rustc_hir::intravisit::Visitor;
|
||||
use rustc_hir::{self as hir, BindingAnnotation, ByRef, Node};
|
||||
use rustc_hir::{self as hir, BindingMode, ByRef, Node};
|
||||
use rustc_infer::traits;
|
||||
use rustc_middle::mir::{Mutability, Place, PlaceRef, ProjectionElem};
|
||||
use rustc_middle::ty::{self, InstanceDef, ToPredicate, Ty, TyCtxt};
|
||||
|
|
@ -303,7 +303,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
|||
{
|
||||
match *decl.local_info() {
|
||||
LocalInfo::User(BindingForm::Var(mir::VarBindingForm {
|
||||
binding_mode: BindingAnnotation(ByRef::No, Mutability::Not),
|
||||
binding_mode: BindingMode(ByRef::No, Mutability::Not),
|
||||
opt_ty_info: Some(sp),
|
||||
opt_match_place: _,
|
||||
pat_span: _,
|
||||
|
|
@ -398,7 +398,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
|||
let upvar_hir_id = captured_place.get_root_variable();
|
||||
|
||||
if let Node::Pat(pat) = self.infcx.tcx.hir_node(upvar_hir_id)
|
||||
&& let hir::PatKind::Binding(hir::BindingAnnotation::NONE, _, upvar_ident, _) =
|
||||
&& let hir::PatKind::Binding(hir::BindingMode::NONE, _, upvar_ident, _) =
|
||||
pat.kind
|
||||
{
|
||||
if upvar_ident.name == kw::SelfLower {
|
||||
|
|
@ -729,7 +729,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
|||
debug!("local_decl: {:?}", local_decl);
|
||||
let pat_span = match *local_decl.local_info() {
|
||||
LocalInfo::User(BindingForm::Var(mir::VarBindingForm {
|
||||
binding_mode: BindingAnnotation(ByRef::No, Mutability::Not),
|
||||
binding_mode: BindingMode(ByRef::No, Mutability::Not),
|
||||
opt_ty_info: _,
|
||||
opt_match_place: _,
|
||||
pat_span,
|
||||
|
|
@ -1086,7 +1086,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
|||
}
|
||||
|
||||
LocalInfo::User(mir::BindingForm::Var(mir::VarBindingForm {
|
||||
binding_mode: BindingAnnotation(ByRef::No, _),
|
||||
binding_mode: BindingMode(ByRef::No, _),
|
||||
opt_ty_info,
|
||||
..
|
||||
})) => {
|
||||
|
|
@ -1154,7 +1154,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
|||
}
|
||||
|
||||
LocalInfo::User(mir::BindingForm::Var(mir::VarBindingForm {
|
||||
binding_mode: BindingAnnotation(ByRef::Yes(_), _),
|
||||
binding_mode: BindingMode(ByRef::Yes(_), _),
|
||||
..
|
||||
})) => {
|
||||
let pattern_span: Span = local_decl.source_info.span;
|
||||
|
|
@ -1356,7 +1356,7 @@ pub fn mut_borrow_of_mutable_ref(local_decl: &LocalDecl<'_>, local_name: Option<
|
|||
match *local_decl.local_info() {
|
||||
// Check if mutably borrowing a mutable reference.
|
||||
LocalInfo::User(mir::BindingForm::Var(mir::VarBindingForm {
|
||||
binding_mode: BindingAnnotation(ByRef::No, Mutability::Not),
|
||||
binding_mode: BindingMode(ByRef::No, Mutability::Not),
|
||||
..
|
||||
})) => matches!(local_decl.ty.kind(), ty::Ref(_, _, hir::Mutability::Mut)),
|
||||
LocalInfo::User(mir::BindingForm::ImplicitSelf(kind)) => {
|
||||
|
|
|
|||
|
|
@ -180,7 +180,7 @@ pub use SubstructureFields::*;
|
|||
use crate::{deriving, errors};
|
||||
use rustc_ast::ptr::P;
|
||||
use rustc_ast::{
|
||||
self as ast, BindingAnnotation, ByRef, EnumDef, Expr, GenericArg, GenericParamKind, Generics,
|
||||
self as ast, BindingMode, ByRef, EnumDef, Expr, GenericArg, GenericParamKind, Generics,
|
||||
Mutability, PatKind, TyKind, VariantData,
|
||||
};
|
||||
use rustc_attr as attr;
|
||||
|
|
@ -1479,11 +1479,7 @@ impl<'a> TraitDef<'a> {
|
|||
struct_field.ident,
|
||||
cx.pat(
|
||||
path.span,
|
||||
PatKind::Ident(
|
||||
BindingAnnotation(by_ref, Mutability::Not),
|
||||
path,
|
||||
None,
|
||||
),
|
||||
PatKind::Ident(BindingMode(by_ref, Mutability::Not), path, None),
|
||||
),
|
||||
)
|
||||
});
|
||||
|
|
|
|||
|
|
@ -415,6 +415,7 @@ impl<'a> LlvmArchiveBuilder<'a> {
|
|||
members.as_ptr() as *const &_,
|
||||
true,
|
||||
kind,
|
||||
self.sess.target.arch == "arm64ec",
|
||||
);
|
||||
let ret = if r.into_result().is_err() {
|
||||
let err = llvm::LLVMRustGetLastError();
|
||||
|
|
|
|||
|
|
@ -255,21 +255,38 @@ impl<'ll, 'tcx> ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> {
|
|||
let (prov, offset) = ptr.into_parts();
|
||||
let (base_addr, base_addr_space) = match self.tcx.global_alloc(prov.alloc_id()) {
|
||||
GlobalAlloc::Memory(alloc) => {
|
||||
let init = const_alloc_to_llvm(self, alloc);
|
||||
let alloc = alloc.inner();
|
||||
let value = match alloc.mutability {
|
||||
Mutability::Mut => self.static_addr_of_mut(init, alloc.align, None),
|
||||
_ => self.static_addr_of(init, alloc.align, None),
|
||||
};
|
||||
if !self.sess().fewer_names() && llvm::get_value_name(value).is_empty() {
|
||||
let hash = self.tcx.with_stable_hashing_context(|mut hcx| {
|
||||
let mut hasher = StableHasher::new();
|
||||
alloc.hash_stable(&mut hcx, &mut hasher);
|
||||
hasher.finish::<Hash128>()
|
||||
});
|
||||
llvm::set_value_name(value, format!("alloc_{hash:032x}").as_bytes());
|
||||
// For ZSTs directly codegen an aligned pointer.
|
||||
// This avoids generating a zero-sized constant value and actually needing a
|
||||
// real address at runtime.
|
||||
if alloc.inner().len() == 0 {
|
||||
assert_eq!(offset.bytes(), 0);
|
||||
let llval = self.const_usize(alloc.inner().align.bytes());
|
||||
return if matches!(layout.primitive(), Pointer(_)) {
|
||||
unsafe { llvm::LLVMConstIntToPtr(llval, llty) }
|
||||
} else {
|
||||
self.const_bitcast(llval, llty)
|
||||
};
|
||||
} else {
|
||||
let init = const_alloc_to_llvm(self, alloc, /*static*/ false);
|
||||
let alloc = alloc.inner();
|
||||
let value = match alloc.mutability {
|
||||
Mutability::Mut => self.static_addr_of_mut(init, alloc.align, None),
|
||||
_ => self.static_addr_of(init, alloc.align, None),
|
||||
};
|
||||
if !self.sess().fewer_names() && llvm::get_value_name(value).is_empty()
|
||||
{
|
||||
let hash = self.tcx.with_stable_hashing_context(|mut hcx| {
|
||||
let mut hasher = StableHasher::new();
|
||||
alloc.hash_stable(&mut hcx, &mut hasher);
|
||||
hasher.finish::<Hash128>()
|
||||
});
|
||||
llvm::set_value_name(
|
||||
value,
|
||||
format!("alloc_{hash:032x}").as_bytes(),
|
||||
);
|
||||
}
|
||||
(value, AddressSpace::DATA)
|
||||
}
|
||||
(value, AddressSpace::DATA)
|
||||
}
|
||||
GlobalAlloc::Function(fn_instance) => (
|
||||
self.get_fn_addr(fn_instance.polymorphize(self.tcx)),
|
||||
|
|
@ -280,7 +297,7 @@ impl<'ll, 'tcx> ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> {
|
|||
.tcx
|
||||
.global_alloc(self.tcx.vtable_allocation((ty, trait_ref)))
|
||||
.unwrap_memory();
|
||||
let init = const_alloc_to_llvm(self, alloc);
|
||||
let init = const_alloc_to_llvm(self, alloc, /*static*/ false);
|
||||
let value = self.static_addr_of(init, alloc.inner().align, None);
|
||||
(value, AddressSpace::DATA)
|
||||
}
|
||||
|
|
@ -308,7 +325,7 @@ impl<'ll, 'tcx> ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> {
|
|||
}
|
||||
|
||||
fn const_data_from_alloc(&self, alloc: ConstAllocation<'tcx>) -> Self::Value {
|
||||
const_alloc_to_llvm(self, alloc)
|
||||
const_alloc_to_llvm(self, alloc, /*static*/ false)
|
||||
}
|
||||
|
||||
fn const_bitcast(&self, val: &'ll Value, ty: &'ll Type) -> &'ll Value {
|
||||
|
|
|
|||
|
|
@ -26,8 +26,22 @@ use rustc_target::abi::{
|
|||
};
|
||||
use std::ops::Range;
|
||||
|
||||
pub fn const_alloc_to_llvm<'ll>(cx: &CodegenCx<'ll, '_>, alloc: ConstAllocation<'_>) -> &'ll Value {
|
||||
pub fn const_alloc_to_llvm<'ll>(
|
||||
cx: &CodegenCx<'ll, '_>,
|
||||
alloc: ConstAllocation<'_>,
|
||||
is_static: bool,
|
||||
) -> &'ll Value {
|
||||
let alloc = alloc.inner();
|
||||
// We expect that callers of const_alloc_to_llvm will instead directly codegen a pointer or
|
||||
// integer for any &ZST where the ZST is a constant (i.e. not a static). We should never be
|
||||
// producing empty LLVM allocations as they're just adding noise to binaries and forcing less
|
||||
// optimal codegen.
|
||||
//
|
||||
// Statics have a guaranteed meaningful address so it's less clear that we want to do
|
||||
// something like this; it's also harder.
|
||||
if !is_static {
|
||||
assert!(alloc.len() != 0);
|
||||
}
|
||||
let mut llvals = Vec::with_capacity(alloc.provenance().ptrs().len() + 1);
|
||||
let dl = cx.data_layout();
|
||||
let pointer_size = dl.pointer_size.bytes() as usize;
|
||||
|
|
@ -120,7 +134,7 @@ fn codegen_static_initializer<'ll, 'tcx>(
|
|||
def_id: DefId,
|
||||
) -> Result<(&'ll Value, ConstAllocation<'tcx>), ErrorHandled> {
|
||||
let alloc = cx.tcx.eval_static_initializer(def_id)?;
|
||||
Ok((const_alloc_to_llvm(cx, alloc), alloc))
|
||||
Ok((const_alloc_to_llvm(cx, alloc, /*static*/ true), alloc))
|
||||
}
|
||||
|
||||
fn set_global_alignment<'ll>(cx: &CodegenCx<'ll, '_>, gv: &'ll Value, mut align: Align) {
|
||||
|
|
|
|||
|
|
@ -2303,6 +2303,7 @@ extern "C" {
|
|||
Members: *const &RustArchiveMember<'_>,
|
||||
WriteSymbtab: bool,
|
||||
Kind: ArchiveKind,
|
||||
isEC: bool,
|
||||
) -> LLVMRustResult;
|
||||
pub fn LLVMRustArchiveMemberNew<'a>(
|
||||
Filename: *const c_char,
|
||||
|
|
|
|||
|
|
@ -270,9 +270,10 @@ pub fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> LLVMFeature<'a> {
|
|||
"sve2-bitperm",
|
||||
TargetFeatureFoldStrength::EnableOnly("neon"),
|
||||
),
|
||||
// The unaligned-scalar-mem feature was renamed to fast-unaligned-access.
|
||||
("riscv32" | "riscv64", "fast-unaligned-access") if get_version().0 <= 17 => {
|
||||
LLVMFeature::new("unaligned-scalar-mem")
|
||||
// In LLVM 18, `unaligned-scalar-mem` was merged with `unaligned-vector-mem` into a single feature called
|
||||
// `fast-unaligned-access`. In LLVM 19, it was split back out.
|
||||
("riscv32" | "riscv64", "unaligned-scalar-mem") if get_version().0 == 18 => {
|
||||
LLVMFeature::new("fast-unaligned-access")
|
||||
}
|
||||
// For LLVM 18, enable the evex512 target feature if a avx512 target feature is enabled.
|
||||
("x86", s) if get_version().0 >= 18 && s.starts_with("avx512") => {
|
||||
|
|
|
|||
|
|
@ -10,20 +10,21 @@ use rustc_middle::traits::Reveal;
|
|||
use rustc_middle::ty::layout::LayoutOf;
|
||||
use rustc_middle::ty::print::with_no_trimmed_paths;
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||
use rustc_session::lint;
|
||||
use rustc_span::def_id::LocalDefId;
|
||||
use rustc_span::Span;
|
||||
use rustc_target::abi::{self, Abi};
|
||||
|
||||
use super::{CanAccessMutGlobal, CompileTimeEvalContext, CompileTimeInterpreter};
|
||||
use crate::const_eval::CheckAlignment;
|
||||
use crate::errors;
|
||||
use crate::errors::ConstEvalError;
|
||||
use crate::interpret::eval_nullary_intrinsic;
|
||||
use crate::errors::{self, DanglingPtrInFinal};
|
||||
use crate::interpret::{
|
||||
create_static_alloc, intern_const_alloc_recursive, CtfeValidationMode, GlobalId, Immediate,
|
||||
InternKind, InterpCx, InterpError, InterpResult, MPlaceTy, MemoryKind, OpTy, RefTracking,
|
||||
StackPopCleanup,
|
||||
};
|
||||
use crate::interpret::{eval_nullary_intrinsic, InternResult};
|
||||
use crate::CTRL_C_RECEIVED;
|
||||
|
||||
// Returns a pointer to where the result lives
|
||||
|
|
@ -89,11 +90,35 @@ fn eval_body_using_ecx<'mir, 'tcx, R: InterpretationResult<'tcx>>(
|
|||
}
|
||||
|
||||
// Intern the result
|
||||
intern_const_alloc_recursive(ecx, intern_kind, &ret)?;
|
||||
let intern_result = intern_const_alloc_recursive(ecx, intern_kind, &ret);
|
||||
|
||||
// Since evaluation had no errors, validate the resulting constant.
|
||||
const_validate_mplace(&ecx, &ret, cid)?;
|
||||
|
||||
// Only report this after validation, as validaiton produces much better diagnostics.
|
||||
// FIXME: ensure validation always reports this and stop making interning care about it.
|
||||
|
||||
match intern_result {
|
||||
Ok(()) => {}
|
||||
Err(InternResult::FoundDanglingPointer) => {
|
||||
return Err(ecx
|
||||
.tcx
|
||||
.dcx()
|
||||
.emit_err(DanglingPtrInFinal { span: ecx.tcx.span, kind: intern_kind })
|
||||
.into());
|
||||
}
|
||||
Err(InternResult::FoundBadMutablePointer) => {
|
||||
// only report mutable pointers if there were no dangling pointers
|
||||
let err_diag = errors::MutablePtrInFinal { span: ecx.tcx.span, kind: intern_kind };
|
||||
ecx.tcx.emit_node_span_lint(
|
||||
lint::builtin::CONST_EVAL_MUTABLE_PTR_IN_FINAL_VALUE,
|
||||
ecx.best_lint_scope(),
|
||||
err_diag.span,
|
||||
err_diag,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Ok(R::make_result(ret, ecx))
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,19 +16,17 @@
|
|||
use hir::def::DefKind;
|
||||
use rustc_ast::Mutability;
|
||||
use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
|
||||
use rustc_errors::ErrorGuaranteed;
|
||||
use rustc_hir as hir;
|
||||
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs;
|
||||
use rustc_middle::mir::interpret::{ConstAllocation, CtfeProvenance, InterpResult};
|
||||
use rustc_middle::query::TyCtxtAt;
|
||||
use rustc_middle::ty::layout::TyAndLayout;
|
||||
use rustc_session::lint;
|
||||
use rustc_span::def_id::LocalDefId;
|
||||
use rustc_span::sym;
|
||||
|
||||
use super::{AllocId, Allocation, InterpCx, MPlaceTy, Machine, MemoryKind, PlaceTy};
|
||||
use crate::const_eval;
|
||||
use crate::errors::{DanglingPtrInFinal, MutablePtrInFinal, NestedStaticInThreadLocal};
|
||||
use crate::errors::NestedStaticInThreadLocal;
|
||||
|
||||
pub trait CompileTimeMachine<'mir, 'tcx: 'mir, T> = Machine<
|
||||
'mir,
|
||||
|
|
@ -134,6 +132,12 @@ pub enum InternKind {
|
|||
Promoted,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum InternResult {
|
||||
FoundBadMutablePointer,
|
||||
FoundDanglingPointer,
|
||||
}
|
||||
|
||||
/// Intern `ret` and everything it references.
|
||||
///
|
||||
/// This *cannot raise an interpreter error*. Doing so is left to validation, which
|
||||
|
|
@ -149,7 +153,7 @@ pub fn intern_const_alloc_recursive<
|
|||
ecx: &mut InterpCx<'mir, 'tcx, M>,
|
||||
intern_kind: InternKind,
|
||||
ret: &MPlaceTy<'tcx>,
|
||||
) -> Result<(), ErrorGuaranteed> {
|
||||
) -> Result<(), InternResult> {
|
||||
// We are interning recursively, and for mutability we are distinguishing the "root" allocation
|
||||
// that we are starting in, and all other allocations that we are encountering recursively.
|
||||
let (base_mutability, inner_mutability, is_static) = match intern_kind {
|
||||
|
|
@ -201,7 +205,7 @@ pub fn intern_const_alloc_recursive<
|
|||
// Whether we encountered a bad mutable pointer.
|
||||
// We want to first report "dangling" and then "mutable", so we need to delay reporting these
|
||||
// errors.
|
||||
let mut found_bad_mutable_pointer = false;
|
||||
let mut result = Ok(());
|
||||
|
||||
// Keep interning as long as there are things to intern.
|
||||
// We show errors if there are dangling pointers, or mutable pointers in immutable contexts
|
||||
|
|
@ -251,7 +255,10 @@ pub fn intern_const_alloc_recursive<
|
|||
// on the promotion analysis not screwing up to ensure that it is sound to intern
|
||||
// promoteds as immutable.
|
||||
trace!("found bad mutable pointer");
|
||||
found_bad_mutable_pointer = true;
|
||||
// Prefer dangling pointer errors over mutable pointer errors
|
||||
if result.is_ok() {
|
||||
result = Err(InternResult::FoundBadMutablePointer);
|
||||
}
|
||||
}
|
||||
if ecx.tcx.try_get_global_alloc(alloc_id).is_some() {
|
||||
// Already interned.
|
||||
|
|
@ -269,21 +276,15 @@ pub fn intern_const_alloc_recursive<
|
|||
// pointers before deciding which allocations can be made immutable; but for now we are
|
||||
// okay with losing some potential for immutability here. This can anyway only affect
|
||||
// `static mut`.
|
||||
todo.extend(intern_shallow(ecx, alloc_id, inner_mutability).map_err(|()| {
|
||||
ecx.tcx.dcx().emit_err(DanglingPtrInFinal { span: ecx.tcx.span, kind: intern_kind })
|
||||
})?);
|
||||
match intern_shallow(ecx, alloc_id, inner_mutability) {
|
||||
Ok(nested) => todo.extend(nested),
|
||||
Err(()) => {
|
||||
ecx.tcx.dcx().delayed_bug("found dangling pointer during const interning");
|
||||
result = Err(InternResult::FoundDanglingPointer);
|
||||
}
|
||||
}
|
||||
}
|
||||
if found_bad_mutable_pointer {
|
||||
let err_diag = MutablePtrInFinal { span: ecx.tcx.span, kind: intern_kind };
|
||||
ecx.tcx.emit_node_span_lint(
|
||||
lint::builtin::CONST_EVAL_MUTABLE_PTR_IN_FINAL_VALUE,
|
||||
ecx.best_lint_scope(),
|
||||
err_diag.span,
|
||||
err_diag,
|
||||
)
|
||||
}
|
||||
|
||||
Ok(())
|
||||
result
|
||||
}
|
||||
|
||||
/// Intern `ret`. This function assumes that `ret` references no other allocation.
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ pub use rustc_middle::mir::interpret::*; // have all the `interpret` symbols in
|
|||
pub use self::eval_context::{format_interp_error, Frame, FrameInfo, InterpCx, StackPopCleanup};
|
||||
pub use self::intern::{
|
||||
intern_const_alloc_for_constprop, intern_const_alloc_recursive, HasStaticRootDefId, InternKind,
|
||||
InternResult,
|
||||
};
|
||||
pub use self::machine::{compile_time_machine, AllocMap, Machine, MayLeak, StackPopJump};
|
||||
pub use self::memory::{AllocKind, AllocRef, AllocRefMut, FnVal, Memory, MemoryKind};
|
||||
|
|
|
|||
|
|
@ -792,7 +792,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
}
|
||||
|
||||
// Some nodes are used a lot. Make sure they don't unintentionally get bigger.
|
||||
#[cfg(all(any(target_arch = "x86_64", target_arch = "aarch64"), target_pointer_width = "64"))]
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
mod size_asserts {
|
||||
use super::*;
|
||||
use rustc_data_structures::static_assert_size;
|
||||
|
|
|
|||
|
|
@ -1058,7 +1058,7 @@ where
|
|||
}
|
||||
|
||||
// Some nodes are used a lot. Make sure they don't unintentionally get bigger.
|
||||
#[cfg(all(any(target_arch = "x86_64", target_arch = "aarch64"), target_pointer_width = "64"))]
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
mod size_asserts {
|
||||
use super::*;
|
||||
use rustc_data_structures::static_assert_size;
|
||||
|
|
|
|||
|
|
@ -449,67 +449,41 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
|
|||
// `!` is a ZST and we want to validate it.
|
||||
if let Ok((alloc_id, _offset, _prov)) = self.ecx.ptr_try_get_alloc_id(place.ptr()) {
|
||||
let mut skip_recursive_check = false;
|
||||
// Let's see what kind of memory this points to.
|
||||
// `unwrap` since dangling pointers have already been handled.
|
||||
let alloc_kind = self.ecx.tcx.try_get_global_alloc(alloc_id).unwrap();
|
||||
let alloc_actual_mutbl = match alloc_kind {
|
||||
GlobalAlloc::Static(did) => {
|
||||
// Special handling for pointers to statics (irrespective of their type).
|
||||
assert!(!self.ecx.tcx.is_thread_local_static(did));
|
||||
assert!(self.ecx.tcx.is_static(did));
|
||||
// Mode-specific checks
|
||||
match self.ctfe_mode {
|
||||
Some(
|
||||
CtfeValidationMode::Static { .. }
|
||||
| CtfeValidationMode::Promoted { .. },
|
||||
) => {
|
||||
// We skip recursively checking other statics. These statics must be sound by
|
||||
// themselves, and the only way to get broken statics here is by using
|
||||
// unsafe code.
|
||||
// The reasons we don't check other statics is twofold. For one, in all
|
||||
// sound cases, the static was already validated on its own, and second, we
|
||||
// trigger cycle errors if we try to compute the value of the other static
|
||||
// and that static refers back to us (potentially through a promoted).
|
||||
// This could miss some UB, but that's fine.
|
||||
skip_recursive_check = true;
|
||||
}
|
||||
Some(CtfeValidationMode::Const { .. }) => {
|
||||
// We can't recursively validate `extern static`, so we better reject them.
|
||||
if self.ecx.tcx.is_foreign_item(did) {
|
||||
throw_validation_failure!(self.path, ConstRefToExtern);
|
||||
}
|
||||
}
|
||||
None => {}
|
||||
let alloc_actual_mutbl = mutability(self.ecx, alloc_id);
|
||||
if let GlobalAlloc::Static(did) = self.ecx.tcx.global_alloc(alloc_id) {
|
||||
let DefKind::Static { nested, .. } = self.ecx.tcx.def_kind(did) else { bug!() };
|
||||
// Special handling for pointers to statics (irrespective of their type).
|
||||
assert!(!self.ecx.tcx.is_thread_local_static(did));
|
||||
assert!(self.ecx.tcx.is_static(did));
|
||||
// Mode-specific checks
|
||||
match self.ctfe_mode {
|
||||
Some(
|
||||
CtfeValidationMode::Static { .. } | CtfeValidationMode::Promoted { .. },
|
||||
) => {
|
||||
// We skip recursively checking other statics. These statics must be sound by
|
||||
// themselves, and the only way to get broken statics here is by using
|
||||
// unsafe code.
|
||||
// The reasons we don't check other statics is twofold. For one, in all
|
||||
// sound cases, the static was already validated on its own, and second, we
|
||||
// trigger cycle errors if we try to compute the value of the other static
|
||||
// and that static refers back to us (potentially through a promoted).
|
||||
// This could miss some UB, but that's fine.
|
||||
// We still walk nested allocations, as they are fundamentally part of this validation run.
|
||||
// This means we will also recurse into nested statics of *other*
|
||||
// statics, even though we do not recurse into other statics directly.
|
||||
// That's somewhat inconsistent but harmless.
|
||||
skip_recursive_check = !nested;
|
||||
}
|
||||
// Return alloc mutability. For "root" statics we look at the type to account for interior
|
||||
// mutability; for nested statics we have no type and directly use the annotated mutability.
|
||||
let DefKind::Static { mutability, nested } = self.ecx.tcx.def_kind(did)
|
||||
else {
|
||||
bug!()
|
||||
};
|
||||
match (mutability, nested) {
|
||||
(Mutability::Mut, _) => Mutability::Mut,
|
||||
(Mutability::Not, true) => Mutability::Not,
|
||||
(Mutability::Not, false)
|
||||
if !self
|
||||
.ecx
|
||||
.tcx
|
||||
.type_of(did)
|
||||
.no_bound_vars()
|
||||
.expect("statics should not have generic parameters")
|
||||
.is_freeze(*self.ecx.tcx, ty::ParamEnv::reveal_all()) =>
|
||||
{
|
||||
Mutability::Mut
|
||||
Some(CtfeValidationMode::Const { .. }) => {
|
||||
// We can't recursively validate `extern static`, so we better reject them.
|
||||
if self.ecx.tcx.is_foreign_item(did) {
|
||||
throw_validation_failure!(self.path, ConstRefToExtern);
|
||||
}
|
||||
(Mutability::Not, false) => Mutability::Not,
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
GlobalAlloc::Memory(alloc) => alloc.inner().mutability,
|
||||
GlobalAlloc::Function(..) | GlobalAlloc::VTable(..) => {
|
||||
// These are immutable, we better don't allow mutable pointers here.
|
||||
Mutability::Not
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Mutability check.
|
||||
// If this allocation has size zero, there is no actual mutability here.
|
||||
let (size, _align, _alloc_kind) = self.ecx.get_alloc_info(alloc_id);
|
||||
|
|
@ -708,20 +682,61 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
|
|||
fn in_mutable_memory(&self, op: &OpTy<'tcx, M::Provenance>) -> bool {
|
||||
if let Some(mplace) = op.as_mplace_or_imm().left() {
|
||||
if let Some(alloc_id) = mplace.ptr().provenance.and_then(|p| p.get_alloc_id()) {
|
||||
let mutability = match self.ecx.tcx.global_alloc(alloc_id) {
|
||||
GlobalAlloc::Static(_) => {
|
||||
self.ecx.memory.alloc_map.get(alloc_id).unwrap().1.mutability
|
||||
}
|
||||
GlobalAlloc::Memory(alloc) => alloc.inner().mutability,
|
||||
_ => span_bug!(self.ecx.tcx.span, "not a memory allocation"),
|
||||
};
|
||||
return mutability == Mutability::Mut;
|
||||
return mutability(self.ecx, alloc_id).is_mut();
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns whether the allocation is mutable, and whether it's actually a static.
|
||||
/// For "root" statics we look at the type to account for interior
|
||||
/// mutability; for nested statics we have no type and directly use the annotated mutability.
|
||||
fn mutability<'mir, 'tcx: 'mir>(
|
||||
ecx: &InterpCx<'mir, 'tcx, impl Machine<'mir, 'tcx>>,
|
||||
alloc_id: AllocId,
|
||||
) -> Mutability {
|
||||
// Let's see what kind of memory this points to.
|
||||
// We're not using `try_global_alloc` since dangling pointers have already been handled.
|
||||
match ecx.tcx.global_alloc(alloc_id) {
|
||||
GlobalAlloc::Static(did) => {
|
||||
let DefKind::Static { mutability, nested } = ecx.tcx.def_kind(did) else { bug!() };
|
||||
if nested {
|
||||
assert!(
|
||||
ecx.memory.alloc_map.get(alloc_id).is_none(),
|
||||
"allocations of nested statics are already interned: {alloc_id:?}, {did:?}"
|
||||
);
|
||||
// Nested statics in a `static` are never interior mutable,
|
||||
// so just use the declared mutability.
|
||||
mutability
|
||||
} else {
|
||||
let mutability = match mutability {
|
||||
Mutability::Not
|
||||
if !ecx
|
||||
.tcx
|
||||
.type_of(did)
|
||||
.no_bound_vars()
|
||||
.expect("statics should not have generic parameters")
|
||||
.is_freeze(*ecx.tcx, ty::ParamEnv::reveal_all()) =>
|
||||
{
|
||||
Mutability::Mut
|
||||
}
|
||||
_ => mutability,
|
||||
};
|
||||
if let Some((_, alloc)) = ecx.memory.alloc_map.get(alloc_id) {
|
||||
assert_eq!(alloc.mutability, mutability);
|
||||
}
|
||||
mutability
|
||||
}
|
||||
}
|
||||
GlobalAlloc::Memory(alloc) => alloc.inner().mutability,
|
||||
GlobalAlloc::Function(..) | GlobalAlloc::VTable(..) => {
|
||||
// These are immutable, we better don't allow mutable pointers here.
|
||||
Mutability::Not
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
|
||||
for ValidityVisitor<'rt, 'mir, 'tcx, M>
|
||||
{
|
||||
|
|
|
|||
|
|
@ -102,9 +102,9 @@ pub type PResult<'a, T> = Result<T, PErr<'a>>;
|
|||
rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
|
||||
|
||||
// `PResult` is used a lot. Make sure it doesn't unintentionally get bigger.
|
||||
#[cfg(all(any(target_arch = "x86_64", target_arch = "aarch64"), target_pointer_width = "64"))]
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
rustc_data_structures::static_assert_size!(PResult<'_, ()>, 16);
|
||||
#[cfg(all(any(target_arch = "x86_64", target_arch = "aarch64"), target_pointer_width = "64"))]
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
rustc_data_structures::static_assert_size!(PResult<'_, bool>, 16);
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, Encodable, Decodable)]
|
||||
|
|
|
|||
|
|
@ -202,7 +202,7 @@ impl<'a> ExtCtxt<'a> {
|
|||
ex: P<ast::Expr>,
|
||||
) -> ast::Stmt {
|
||||
let pat = if mutbl {
|
||||
self.pat_ident_binding_mode(sp, ident, ast::BindingAnnotation::MUT)
|
||||
self.pat_ident_binding_mode(sp, ident, ast::BindingMode::MUT)
|
||||
} else {
|
||||
self.pat_ident(sp, ident)
|
||||
};
|
||||
|
|
@ -490,14 +490,14 @@ impl<'a> ExtCtxt<'a> {
|
|||
self.pat(span, PatKind::Lit(expr))
|
||||
}
|
||||
pub fn pat_ident(&self, span: Span, ident: Ident) -> P<ast::Pat> {
|
||||
self.pat_ident_binding_mode(span, ident, ast::BindingAnnotation::NONE)
|
||||
self.pat_ident_binding_mode(span, ident, ast::BindingMode::NONE)
|
||||
}
|
||||
|
||||
pub fn pat_ident_binding_mode(
|
||||
&self,
|
||||
span: Span,
|
||||
ident: Ident,
|
||||
ann: ast::BindingAnnotation,
|
||||
ann: ast::BindingMode,
|
||||
) -> P<ast::Pat> {
|
||||
let pat = PatKind::Ident(ann, ident.with_span_pos(span), None);
|
||||
self.pat(span, pat)
|
||||
|
|
|
|||
|
|
@ -266,7 +266,7 @@ struct MatcherPos {
|
|||
}
|
||||
|
||||
// This type is used a lot. Make sure it doesn't unintentionally get bigger.
|
||||
#[cfg(all(any(target_arch = "x86_64", target_arch = "aarch64"), target_pointer_width = "64"))]
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
rustc_data_structures::static_assert_size!(MatcherPos, 16);
|
||||
|
||||
impl MatcherPos {
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ use crate::LangItem;
|
|||
use rustc_ast as ast;
|
||||
use rustc_ast::util::parser::ExprPrecedence;
|
||||
use rustc_ast::{Attribute, FloatTy, IntTy, Label, LitKind, TraitObjectSyntax, UintTy};
|
||||
pub use rustc_ast::{BinOp, BinOpKind, BindingAnnotation, BorrowKind, ByRef, CaptureBy};
|
||||
pub use rustc_ast::{BinOp, BinOpKind, BindingMode, BorrowKind, ByRef, CaptureBy};
|
||||
pub use rustc_ast::{ImplPolarity, IsAuto, Movability, Mutability, UnOp};
|
||||
use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
|
||||
use rustc_data_structures::fingerprint::Fingerprint;
|
||||
|
|
@ -1151,7 +1151,7 @@ pub enum PatKind<'hir> {
|
|||
/// The `HirId` is the canonical ID for the variable being bound,
|
||||
/// (e.g., in `Ok(x) | Err(x)`, both `x` use the same canonical ID),
|
||||
/// which is the pattern ID of the first `x`.
|
||||
Binding(BindingAnnotation, HirId, Ident, Option<&'hir Pat<'hir>>),
|
||||
Binding(BindingMode, HirId, Ident, Option<&'hir Pat<'hir>>),
|
||||
|
||||
/// A struct or struct variant pattern (e.g., `Variant {x, y, ..}`).
|
||||
/// The `bool` is `true` in the presence of a `..`.
|
||||
|
|
@ -3786,7 +3786,7 @@ impl<'hir> Node<'hir> {
|
|||
}
|
||||
|
||||
// Some nodes are used a lot. Make sure they don't unintentionally get bigger.
|
||||
#[cfg(all(any(target_arch = "x86_64", target_arch = "aarch64"), target_pointer_width = "64"))]
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
mod size_asserts {
|
||||
use super::*;
|
||||
// tidy-alphabetical-start
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use crate::def::{CtorOf, DefKind, Res};
|
||||
use crate::def_id::{DefId, DefIdSet};
|
||||
use crate::hir::{self, BindingAnnotation, ByRef, HirId, PatKind};
|
||||
use crate::hir::{self, BindingMode, ByRef, HirId, PatKind};
|
||||
use rustc_span::symbol::Ident;
|
||||
use rustc_span::Span;
|
||||
|
||||
|
|
@ -60,7 +60,7 @@ impl<T: ExactSizeIterator> EnumerateAndAdjustIterator for T {
|
|||
impl hir::Pat<'_> {
|
||||
/// Call `f` on every "binding" in a pattern, e.g., on `a` in
|
||||
/// `match foo() { Some(a) => (), None => () }`
|
||||
pub fn each_binding(&self, mut f: impl FnMut(hir::BindingAnnotation, HirId, Span, Ident)) {
|
||||
pub fn each_binding(&self, mut f: impl FnMut(hir::BindingMode, HirId, Span, Ident)) {
|
||||
self.walk_always(|p| {
|
||||
if let PatKind::Binding(binding_mode, _, ident, _) = p.kind {
|
||||
f(binding_mode, p.hir_id, p.span, ident);
|
||||
|
|
@ -74,10 +74,7 @@ impl hir::Pat<'_> {
|
|||
/// When encountering an or-pattern `p_0 | ... | p_n` only the first non-never pattern will be
|
||||
/// visited. If they're all never patterns we visit nothing, which is ok since a never pattern
|
||||
/// cannot have bindings.
|
||||
pub fn each_binding_or_first(
|
||||
&self,
|
||||
f: &mut impl FnMut(hir::BindingAnnotation, HirId, Span, Ident),
|
||||
) {
|
||||
pub fn each_binding_or_first(&self, f: &mut impl FnMut(hir::BindingMode, HirId, Span, Ident)) {
|
||||
self.walk(|p| match &p.kind {
|
||||
PatKind::Or(ps) => {
|
||||
for p in *ps {
|
||||
|
|
@ -98,7 +95,7 @@ impl hir::Pat<'_> {
|
|||
|
||||
pub fn simple_ident(&self) -> Option<Ident> {
|
||||
match self.kind {
|
||||
PatKind::Binding(BindingAnnotation(ByRef::No, _), _, ident, None) => Some(ident),
|
||||
PatKind::Binding(BindingMode(ByRef::No, _), _, ident, None) => Some(ident),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
|
@ -135,8 +132,8 @@ impl hir::Pat<'_> {
|
|||
pub fn contains_explicit_ref_binding(&self) -> Option<hir::Mutability> {
|
||||
let mut result = None;
|
||||
self.each_binding(|annotation, _, _, _| match annotation {
|
||||
hir::BindingAnnotation::REF if result.is_none() => result = Some(hir::Mutability::Not),
|
||||
hir::BindingAnnotation::REF_MUT => result = Some(hir::Mutability::Mut),
|
||||
hir::BindingMode::REF if result.is_none() => result = Some(hir::Mutability::Not),
|
||||
hir::BindingMode::REF_MUT => result = Some(hir::Mutability::Mut),
|
||||
_ => {}
|
||||
});
|
||||
result
|
||||
|
|
|
|||
|
|
@ -654,7 +654,7 @@ fn resolve_local<'tcx>(
|
|||
// & expression, and its lifetime would be extended to the end of the block (due
|
||||
// to a different rule, not the below code).
|
||||
match pat.kind {
|
||||
PatKind::Binding(hir::BindingAnnotation(hir::ByRef::Yes(_), _), ..) => true,
|
||||
PatKind::Binding(hir::BindingMode(hir::ByRef::Yes(_), _), ..) => true,
|
||||
|
||||
PatKind::Struct(_, field_pats, _) => field_pats.iter().any(|fp| is_binding_pat(fp.pat)),
|
||||
|
||||
|
|
@ -671,7 +671,7 @@ fn resolve_local<'tcx>(
|
|||
PatKind::Box(subpat) | PatKind::Deref(subpat) => is_binding_pat(subpat),
|
||||
|
||||
PatKind::Ref(_, _)
|
||||
| PatKind::Binding(hir::BindingAnnotation(hir::ByRef::No, _), ..)
|
||||
| PatKind::Binding(hir::BindingMode(hir::ByRef::No, _), ..)
|
||||
| PatKind::Wild
|
||||
| PatKind::Never
|
||||
| PatKind::Path(_)
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ use rustc_ast_pretty::pp::{self, Breaks};
|
|||
use rustc_ast_pretty::pprust::{Comments, PrintState};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::{
|
||||
BindingAnnotation, ByRef, GenericArg, GenericBound, GenericParam, GenericParamKind, HirId,
|
||||
BindingMode, ByRef, GenericArg, GenericBound, GenericParam, GenericParamKind, HirId,
|
||||
LifetimeParamKind, Node, PatKind, RangeEnd, Term, TraitBoundModifier,
|
||||
};
|
||||
use rustc_span::source_map::SourceMap;
|
||||
|
|
@ -1723,7 +1723,7 @@ impl<'a> State<'a> {
|
|||
match pat.kind {
|
||||
PatKind::Wild => self.word("_"),
|
||||
PatKind::Never => self.word("!"),
|
||||
PatKind::Binding(BindingAnnotation(by_ref, mutbl), _, ident, sub) => {
|
||||
PatKind::Binding(BindingMode(by_ref, mutbl), _, ident, sub) => {
|
||||
if mutbl.is_mut() {
|
||||
self.word_nbsp("mut");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ use rustc_errors::{
|
|||
};
|
||||
use rustc_hir::def::{CtorKind, DefKind, Res};
|
||||
use rustc_hir::pat_util::EnumerateAndAdjustIterator;
|
||||
use rustc_hir::{self as hir, BindingAnnotation, ByRef, HirId, Mutability, Pat, PatKind};
|
||||
use rustc_hir::{self as hir, BindingMode, ByRef, HirId, Mutability, Pat, PatKind};
|
||||
use rustc_infer::infer;
|
||||
use rustc_infer::infer::type_variable::TypeVariableOrigin;
|
||||
use rustc_lint as lint;
|
||||
|
|
@ -79,7 +79,7 @@ struct TopInfo<'tcx> {
|
|||
|
||||
#[derive(Copy, Clone)]
|
||||
struct PatInfo<'tcx, 'a> {
|
||||
binding_mode: BindingAnnotation,
|
||||
binding_mode: ByRef,
|
||||
max_ref_mutbl: Mutability,
|
||||
top_info: TopInfo<'tcx>,
|
||||
decl_origin: Option<DeclOrigin<'a>>,
|
||||
|
|
@ -125,8 +125,6 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
const INITIAL_BM: BindingAnnotation = BindingAnnotation(ByRef::No, Mutability::Not);
|
||||
|
||||
/// Mode for adjusting the expected type and binding mode.
|
||||
enum AdjustMode {
|
||||
/// Peel off all immediate reference types.
|
||||
|
|
@ -163,7 +161,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
) {
|
||||
let info = TopInfo { expected, origin_expr, span };
|
||||
let pat_info = PatInfo {
|
||||
binding_mode: INITIAL_BM,
|
||||
binding_mode: ByRef::No,
|
||||
max_ref_mutbl: Mutability::Mut,
|
||||
top_info: info,
|
||||
decl_origin,
|
||||
|
|
@ -296,43 +294,43 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
&self,
|
||||
pat: &'tcx Pat<'tcx>,
|
||||
expected: Ty<'tcx>,
|
||||
def_bm: BindingAnnotation,
|
||||
def_br: ByRef,
|
||||
adjust_mode: AdjustMode,
|
||||
max_ref_mutbl: Mutability,
|
||||
) -> (Ty<'tcx>, BindingAnnotation, Mutability, bool) {
|
||||
if let ByRef::Yes(mutbl) = def_bm.0 {
|
||||
) -> (Ty<'tcx>, ByRef, Mutability, bool) {
|
||||
if let ByRef::Yes(mutbl) = def_br {
|
||||
debug_assert!(mutbl <= max_ref_mutbl);
|
||||
}
|
||||
match adjust_mode {
|
||||
AdjustMode::Pass => (expected, def_bm, max_ref_mutbl, false),
|
||||
AdjustMode::Reset => (expected, INITIAL_BM, Mutability::Mut, false),
|
||||
AdjustMode::Pass => (expected, def_br, max_ref_mutbl, false),
|
||||
AdjustMode::Reset => (expected, ByRef::No, Mutability::Mut, false),
|
||||
AdjustMode::ResetAndConsumeRef(ref_pat_mutbl) => {
|
||||
let mutbls_match = def_bm.0 == ByRef::Yes(ref_pat_mutbl);
|
||||
let mutbls_match = def_br == ByRef::Yes(ref_pat_mutbl);
|
||||
if pat.span.at_least_rust_2024() && self.tcx.features().ref_pat_eat_one_layer_2024 {
|
||||
if mutbls_match {
|
||||
debug!("consuming inherited reference");
|
||||
(expected, INITIAL_BM, cmp::min(max_ref_mutbl, ref_pat_mutbl), true)
|
||||
(expected, ByRef::No, cmp::min(max_ref_mutbl, ref_pat_mutbl), true)
|
||||
} else {
|
||||
let (new_ty, new_bm, max_ref_mutbl) = if ref_pat_mutbl == Mutability::Mut {
|
||||
self.peel_off_references(
|
||||
pat,
|
||||
expected,
|
||||
def_bm,
|
||||
def_br,
|
||||
Mutability::Not,
|
||||
max_ref_mutbl,
|
||||
)
|
||||
} else {
|
||||
(expected, def_bm.cap_ref_mutability(Mutability::Not), Mutability::Not)
|
||||
(expected, def_br.cap_ref_mutability(Mutability::Not), Mutability::Not)
|
||||
};
|
||||
(new_ty, new_bm, max_ref_mutbl, false)
|
||||
}
|
||||
} else {
|
||||
(expected, INITIAL_BM, max_ref_mutbl, mutbls_match)
|
||||
(expected, ByRef::No, max_ref_mutbl, mutbls_match)
|
||||
}
|
||||
}
|
||||
AdjustMode::Peel => {
|
||||
let peeled =
|
||||
self.peel_off_references(pat, expected, def_bm, Mutability::Mut, max_ref_mutbl);
|
||||
self.peel_off_references(pat, expected, def_br, Mutability::Mut, max_ref_mutbl);
|
||||
(peeled.0, peeled.1, peeled.2, false)
|
||||
}
|
||||
}
|
||||
|
|
@ -413,10 +411,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
&self,
|
||||
pat: &'tcx Pat<'tcx>,
|
||||
expected: Ty<'tcx>,
|
||||
mut def_bm: BindingAnnotation,
|
||||
mut def_br: ByRef,
|
||||
max_peelable_mutability: Mutability,
|
||||
mut max_ref_mutability: Mutability,
|
||||
) -> (Ty<'tcx>, BindingAnnotation, Mutability) {
|
||||
) -> (Ty<'tcx>, ByRef, Mutability) {
|
||||
let mut expected = self.try_structurally_resolve_type(pat.span, expected);
|
||||
// Peel off as many `&` or `&mut` from the scrutinee type as possible. For example,
|
||||
// for `match &&&mut Some(5)` the loop runs three times, aborting when it reaches
|
||||
|
|
@ -437,7 +435,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
pat_adjustments.push(expected);
|
||||
|
||||
expected = self.try_structurally_resolve_type(pat.span, inner_ty);
|
||||
def_bm.0 = ByRef::Yes(match def_bm.0 {
|
||||
def_br = ByRef::Yes(match def_br {
|
||||
// If default binding mode is by value, make it `ref` or `ref mut`
|
||||
// (depending on whether we observe `&` or `&mut`).
|
||||
ByRef::No |
|
||||
|
|
@ -450,21 +448,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
}
|
||||
|
||||
if pat.span.at_least_rust_2024() && self.tcx.features().ref_pat_eat_one_layer_2024 {
|
||||
def_bm = def_bm.cap_ref_mutability(max_ref_mutability);
|
||||
if def_bm.0 == ByRef::Yes(Mutability::Not) {
|
||||
def_br = def_br.cap_ref_mutability(max_ref_mutability);
|
||||
if def_br == ByRef::Yes(Mutability::Not) {
|
||||
max_ref_mutability = Mutability::Not;
|
||||
}
|
||||
}
|
||||
|
||||
if !pat_adjustments.is_empty() {
|
||||
debug!("default binding mode is now {:?}", def_bm);
|
||||
debug!("default binding mode is now {:?}", def_br);
|
||||
self.typeck_results
|
||||
.borrow_mut()
|
||||
.pat_adjustments_mut()
|
||||
.insert(pat.hir_id, pat_adjustments);
|
||||
}
|
||||
|
||||
(expected, def_bm, max_ref_mutability)
|
||||
(expected, def_br, max_ref_mutability)
|
||||
}
|
||||
|
||||
fn check_pat_lit(
|
||||
|
|
@ -669,17 +667,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
fn check_pat_ident(
|
||||
&self,
|
||||
pat: &'tcx Pat<'tcx>,
|
||||
ba: BindingAnnotation,
|
||||
ba: BindingMode,
|
||||
var_id: HirId,
|
||||
sub: Option<&'tcx Pat<'tcx>>,
|
||||
expected: Ty<'tcx>,
|
||||
pat_info: PatInfo<'tcx, '_>,
|
||||
) -> Ty<'tcx> {
|
||||
let PatInfo { binding_mode: BindingAnnotation(def_br, _), top_info: ti, .. } = pat_info;
|
||||
let PatInfo { binding_mode: def_br, top_info: ti, .. } = pat_info;
|
||||
|
||||
// Determine the binding mode...
|
||||
let bm = match ba {
|
||||
BindingAnnotation(ByRef::No, Mutability::Mut)
|
||||
BindingMode(ByRef::No, Mutability::Mut)
|
||||
if !(pat.span.at_least_rust_2024()
|
||||
&& self.tcx.features().mut_preserve_binding_mode_2024)
|
||||
&& matches!(def_br, ByRef::Yes(_)) =>
|
||||
|
|
@ -691,10 +689,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
pat.span,
|
||||
errors::DereferencingMutBinding { span: pat.span },
|
||||
);
|
||||
BindingAnnotation(ByRef::No, Mutability::Mut)
|
||||
BindingMode(ByRef::No, Mutability::Mut)
|
||||
}
|
||||
BindingAnnotation(ByRef::No, mutbl) => BindingAnnotation(def_br, mutbl),
|
||||
BindingAnnotation(ByRef::Yes(_), _) => ba,
|
||||
BindingMode(ByRef::No, mutbl) => BindingMode(def_br, mutbl),
|
||||
BindingMode(ByRef::Yes(_), _) => ba,
|
||||
};
|
||||
// ...and store it in a side table:
|
||||
self.typeck_results.borrow_mut().pat_binding_modes_mut().insert(pat.hir_id, bm);
|
||||
|
|
@ -736,7 +734,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
/// bindings have the same type by comparing them all against the type of that first pat.
|
||||
fn check_binding_alt_eq_ty(
|
||||
&self,
|
||||
ba: BindingAnnotation,
|
||||
ba: BindingMode,
|
||||
span: Span,
|
||||
var_id: HirId,
|
||||
ty: Ty<'tcx>,
|
||||
|
|
@ -776,10 +774,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
span: Span,
|
||||
expected: Ty<'tcx>,
|
||||
actual: Ty<'tcx>,
|
||||
ba: BindingAnnotation,
|
||||
ba: BindingMode,
|
||||
) {
|
||||
match (expected.kind(), actual.kind(), ba) {
|
||||
(ty::Ref(_, inner_ty, _), _, BindingAnnotation::NONE)
|
||||
(ty::Ref(_, inner_ty, _), _, BindingMode::NONE)
|
||||
if self.can_eq(self.param_env, *inner_ty, actual) =>
|
||||
{
|
||||
err.span_suggestion_verbose(
|
||||
|
|
@ -789,7 +787,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
(_, ty::Ref(_, inner_ty, _), BindingAnnotation::REF)
|
||||
(_, ty::Ref(_, inner_ty, _), BindingMode::REF)
|
||||
if self.can_eq(self.param_env, expected, *inner_ty) =>
|
||||
{
|
||||
err.span_suggestion_verbose(
|
||||
|
|
@ -881,7 +879,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
if let PatKind::Ref(the_ref, _) = i.kind
|
||||
&& let PatKind::Binding(mt, _, ident, _) = the_ref.kind
|
||||
{
|
||||
let BindingAnnotation(_, mtblty) = mt;
|
||||
let BindingMode(_, mtblty) = mt;
|
||||
err.span_suggestion_verbose(
|
||||
i.span,
|
||||
format!("consider removing `&{mutability}` from the pattern"),
|
||||
|
|
|
|||
|
|
@ -229,8 +229,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
else {
|
||||
bug!();
|
||||
};
|
||||
let hir::PatKind::Binding(hir::BindingAnnotation(hir::ByRef::No, _), _, _, _) =
|
||||
pat.kind
|
||||
let hir::PatKind::Binding(hir::BindingMode(hir::ByRef::No, _), _, _, _) = pat.kind
|
||||
else {
|
||||
// Complex pattern, skip the non-upvar local.
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -400,7 +400,7 @@ enum Chunk {
|
|||
}
|
||||
|
||||
// This type is used a lot. Make sure it doesn't unintentionally get bigger.
|
||||
#[cfg(all(any(target_arch = "x86_64", target_arch = "aarch64"), target_pointer_width = "64"))]
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
crate::static_assert_size!(Chunk, 16);
|
||||
|
||||
impl<T> ChunkedBitSet<T> {
|
||||
|
|
|
|||
|
|
@ -477,7 +477,7 @@ pub enum SubregionOrigin<'tcx> {
|
|||
}
|
||||
|
||||
// `SubregionOrigin` is used a lot. Make sure it doesn't unintentionally get bigger.
|
||||
#[cfg(all(any(target_arch = "x86_64", target_arch = "aarch64"), target_pointer_width = "64"))]
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
static_assert_size!(SubregionOrigin<'_>, 32);
|
||||
|
||||
impl<'tcx> SubregionOrigin<'tcx> {
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@
|
|||
|
||||
#[macro_use]
|
||||
extern crate rustc_macros;
|
||||
#[cfg(all(any(target_arch = "x86_64", target_arch = "aarch64"), target_pointer_width = "64"))]
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
#[macro_use]
|
||||
extern crate rustc_data_structures;
|
||||
#[macro_use]
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ impl<'tcx> PolyTraitObligation<'tcx> {
|
|||
}
|
||||
|
||||
// `PredicateObligation` is used a lot. Make sure it doesn't unintentionally get bigger.
|
||||
#[cfg(all(any(target_arch = "x86_64", target_arch = "aarch64"), target_pointer_width = "64"))]
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
static_assert_size!(PredicateObligation<'_>, 48);
|
||||
|
||||
pub type PredicateObligations<'tcx> = Vec<PredicateObligation<'tcx>>;
|
||||
|
|
|
|||
|
|
@ -1056,7 +1056,7 @@ impl UnusedParens {
|
|||
avoid_mut: bool,
|
||||
keep_space: (bool, bool),
|
||||
) {
|
||||
use ast::{BindingAnnotation, PatKind};
|
||||
use ast::{BindingMode, PatKind};
|
||||
|
||||
if let PatKind::Paren(inner) = &value.kind {
|
||||
match inner.kind {
|
||||
|
|
@ -1068,7 +1068,7 @@ impl UnusedParens {
|
|||
// Avoid `p0 | .. | pn` if we should.
|
||||
PatKind::Or(..) if avoid_or => return,
|
||||
// Avoid `mut x` and `mut x @ p` if we should:
|
||||
PatKind::Ident(BindingAnnotation::MUT, ..) if avoid_mut => {
|
||||
PatKind::Ident(BindingMode::MUT, ..) if avoid_mut => {
|
||||
return;
|
||||
}
|
||||
// Otherwise proceed with linting.
|
||||
|
|
|
|||
|
|
@ -175,7 +175,7 @@ extern "C" void LLVMRustArchiveMemberFree(LLVMRustArchiveMemberRef Member) {
|
|||
extern "C" LLVMRustResult
|
||||
LLVMRustWriteArchive(char *Dst, size_t NumMembers,
|
||||
const LLVMRustArchiveMemberRef *NewMembers,
|
||||
bool WriteSymbtab, LLVMRustArchiveKind RustKind) {
|
||||
bool WriteSymbtab, LLVMRustArchiveKind RustKind, bool isEC) {
|
||||
|
||||
std::vector<NewArchiveMember> Members;
|
||||
auto Kind = fromRust(RustKind);
|
||||
|
|
@ -207,7 +207,7 @@ LLVMRustWriteArchive(char *Dst, size_t NumMembers,
|
|||
auto Result = writeArchive(Dst, Members, WriteSymbtab, Kind, true, false);
|
||||
#else
|
||||
auto SymtabMode = WriteSymbtab ? SymtabWritingMode::NormalSymtab : SymtabWritingMode::NoSymtab;
|
||||
auto Result = writeArchive(Dst, Members, SymtabMode, Kind, true, false);
|
||||
auto Result = writeArchive(Dst, Members, SymtabMode, Kind, true, false, nullptr, isEC);
|
||||
#endif
|
||||
if (!Result)
|
||||
return LLVMRustResult::Success;
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ pub enum ConstValue<'tcx> {
|
|||
},
|
||||
}
|
||||
|
||||
#[cfg(all(any(target_arch = "x86_64", target_arch = "aarch64"), target_pointer_width = "64"))]
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
static_assert_size!(ConstValue<'_>, 24);
|
||||
|
||||
impl<'tcx> ConstValue<'tcx> {
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ pub type EvalToConstValueResult<'tcx> = Result<ConstValue<'tcx>, ErrorHandled>;
|
|||
/// This is needed in `thir::pattern::lower_inline_const`.
|
||||
pub type EvalToValTreeResult<'tcx> = Result<Option<ValTree<'tcx>>, ErrorHandled>;
|
||||
|
||||
#[cfg(all(any(target_arch = "x86_64", target_arch = "aarch64"), target_pointer_width = "64"))]
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
static_assert_size!(InterpErrorInfo<'_>, 8);
|
||||
|
||||
/// Packages the kind of error we got from the const code interpreter
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ pub enum Scalar<Prov = CtfeProvenance> {
|
|||
Ptr(Pointer<Prov>, u8),
|
||||
}
|
||||
|
||||
#[cfg(all(any(target_arch = "x86_64", target_arch = "aarch64"), target_pointer_width = "64"))]
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
static_assert_size!(Scalar, 24);
|
||||
|
||||
// We want the `Debug` output to be readable as it is used by `derive(Debug)` for
|
||||
|
|
|
|||
|
|
@ -18,8 +18,7 @@ use rustc_errors::{DiagArgName, DiagArgValue, DiagMessage, ErrorGuaranteed, Into
|
|||
use rustc_hir::def::{CtorKind, Namespace};
|
||||
use rustc_hir::def_id::{DefId, CRATE_DEF_ID};
|
||||
use rustc_hir::{
|
||||
self as hir, BindingAnnotation, ByRef, CoroutineDesugaring, CoroutineKind, HirId,
|
||||
ImplicitSelfKind,
|
||||
self as hir, BindingMode, ByRef, CoroutineDesugaring, CoroutineKind, HirId, ImplicitSelfKind,
|
||||
};
|
||||
use rustc_session::Session;
|
||||
use rustc_span::source_map::Spanned;
|
||||
|
|
@ -930,7 +929,7 @@ pub enum LocalKind {
|
|||
#[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable)]
|
||||
pub struct VarBindingForm<'tcx> {
|
||||
/// Is variable bound via `x`, `mut x`, `ref x`, `ref mut x`, `mut ref x`, or `mut ref mut x`?
|
||||
pub binding_mode: BindingAnnotation,
|
||||
pub binding_mode: BindingMode,
|
||||
/// If an explicit type was provided for this variable binding,
|
||||
/// this holds the source Span of that type.
|
||||
///
|
||||
|
|
@ -1155,7 +1154,7 @@ impl<'tcx> LocalDecl<'tcx> {
|
|||
self.local_info(),
|
||||
LocalInfo::User(
|
||||
BindingForm::Var(VarBindingForm {
|
||||
binding_mode: BindingAnnotation(ByRef::No, _),
|
||||
binding_mode: BindingMode(ByRef::No, _),
|
||||
opt_ty_info: _,
|
||||
opt_match_place: _,
|
||||
pat_span: _,
|
||||
|
|
@ -1172,7 +1171,7 @@ impl<'tcx> LocalDecl<'tcx> {
|
|||
self.local_info(),
|
||||
LocalInfo::User(
|
||||
BindingForm::Var(VarBindingForm {
|
||||
binding_mode: BindingAnnotation(ByRef::No, _),
|
||||
binding_mode: BindingMode(ByRef::No, _),
|
||||
opt_ty_info: _,
|
||||
opt_match_place: _,
|
||||
pat_span: _,
|
||||
|
|
@ -1814,7 +1813,7 @@ impl DefLocation {
|
|||
}
|
||||
|
||||
// Some nodes are used a lot. Make sure they don't unintentionally get bigger.
|
||||
#[cfg(all(any(target_arch = "x86_64", target_arch = "aarch64"), target_pointer_width = "64"))]
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
mod size_asserts {
|
||||
use super::*;
|
||||
use rustc_data_structures::static_assert_size;
|
||||
|
|
|
|||
|
|
@ -213,7 +213,7 @@ pub struct ClosureOutlivesRequirement<'tcx> {
|
|||
}
|
||||
|
||||
// Make sure this enum doesn't unintentionally grow
|
||||
#[cfg(all(any(target_arch = "x86_64", target_arch = "aarch64"), target_pointer_width = "64"))]
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
rustc_data_structures::static_assert_size!(ConstraintCategory<'_>, 16);
|
||||
|
||||
/// Outlives-constraints can be categorized to determine whether and why they
|
||||
|
|
|
|||
|
|
@ -1453,7 +1453,7 @@ pub enum BinOp {
|
|||
}
|
||||
|
||||
// Some nodes are used a lot. Make sure they don't unintentionally get bigger.
|
||||
#[cfg(all(any(target_arch = "x86_64", target_arch = "aarch64"), target_pointer_width = "64"))]
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
mod size_asserts {
|
||||
use super::*;
|
||||
// tidy-alphabetical-start
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ pub struct PlaceTy<'tcx> {
|
|||
}
|
||||
|
||||
// At least on 64 bit systems, `PlaceTy` should not be larger than two or three pointers.
|
||||
#[cfg(all(any(target_arch = "x86_64", target_arch = "aarch64"), target_pointer_width = "64"))]
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
static_assert_size!(PlaceTy<'_>, 16);
|
||||
|
||||
impl<'tcx> PlaceTy<'tcx> {
|
||||
|
|
|
|||
|
|
@ -322,7 +322,7 @@ macro_rules! define_callbacks {
|
|||
|
||||
// Ensure that keys grow no larger than 72 bytes by accident.
|
||||
// Increase this limit if necessary, but do try to keep the size low if possible
|
||||
#[cfg(all(any(target_arch = "x86_64", target_arch="aarch64"), target_pointer_width = "64"))]
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
const _: () = {
|
||||
if mem::size_of::<Key<'static>>() > 72 {
|
||||
panic!("{}", concat!(
|
||||
|
|
@ -337,7 +337,7 @@ macro_rules! define_callbacks {
|
|||
|
||||
// Ensure that values grow no larger than 64 bytes by accident.
|
||||
// Increase this limit if necessary, but do try to keep the size low if possible
|
||||
#[cfg(all(any(target_arch = "x86_64", target_arch="aarch64"), target_pointer_width = "64"))]
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
const _: () = {
|
||||
if mem::size_of::<Value<'static>>() > 64 {
|
||||
panic!("{}", concat!(
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
|
|||
use rustc_errors::{DiagArgValue, IntoDiagArg};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_hir::{BindingAnnotation, ByRef, HirId, MatchSource, RangeEnd};
|
||||
use rustc_hir::{BindingMode, ByRef, HirId, MatchSource, RangeEnd};
|
||||
use rustc_index::newtype_index;
|
||||
use rustc_index::IndexVec;
|
||||
use rustc_middle::middle::region;
|
||||
|
|
@ -603,10 +603,7 @@ impl<'tcx> Pat<'tcx> {
|
|||
pub fn simple_ident(&self) -> Option<Symbol> {
|
||||
match self.kind {
|
||||
PatKind::Binding {
|
||||
name,
|
||||
mode: BindingAnnotation(ByRef::No, _),
|
||||
subpattern: None,
|
||||
..
|
||||
name, mode: BindingMode(ByRef::No, _), subpattern: None, ..
|
||||
} => Some(name),
|
||||
_ => None,
|
||||
}
|
||||
|
|
@ -730,7 +727,7 @@ pub enum PatKind<'tcx> {
|
|||
Binding {
|
||||
name: Symbol,
|
||||
#[type_visitable(ignore)]
|
||||
mode: BindingAnnotation,
|
||||
mode: BindingMode,
|
||||
#[type_visitable(ignore)]
|
||||
var: LocalVarId,
|
||||
ty: Ty<'tcx>,
|
||||
|
|
@ -1206,7 +1203,7 @@ impl<'tcx> fmt::Display for Pat<'tcx> {
|
|||
}
|
||||
|
||||
// Some nodes are used a lot. Make sure they don't unintentionally get bigger.
|
||||
#[cfg(all(any(target_arch = "x86_64", target_arch = "aarch64"), target_pointer_width = "64"))]
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
mod size_asserts {
|
||||
use super::*;
|
||||
// tidy-alphabetical-start
|
||||
|
|
|
|||
|
|
@ -551,7 +551,7 @@ impl<'tcx> ObligationCauseCode<'tcx> {
|
|||
}
|
||||
|
||||
// `ObligationCauseCode` is used a lot. Make sure it doesn't unintentionally get bigger.
|
||||
#[cfg(all(any(target_arch = "x86_64", target_arch = "aarch64"), target_pointer_width = "64"))]
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
static_assert_size!(ObligationCauseCode<'_>, 48);
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
|
||||
|
|
|
|||
|
|
@ -22,6 +22,9 @@ pub use valtree::*;
|
|||
|
||||
pub type ConstKind<'tcx> = IrConstKind<TyCtxt<'tcx>>;
|
||||
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
static_assert_size!(ConstKind<'_>, 32);
|
||||
|
||||
/// Use this rather than `ConstData`, whenever possible.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, HashStable)]
|
||||
#[rustc_pass_by_value]
|
||||
|
|
@ -59,7 +62,7 @@ pub struct ConstData<'tcx> {
|
|||
pub kind: ConstKind<'tcx>,
|
||||
}
|
||||
|
||||
#[cfg(all(any(target_arch = "x86_64", target_arch = "aarch64"), target_pointer_width = "64"))]
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
static_assert_size!(ConstData<'_>, 40);
|
||||
|
||||
impl<'tcx> Const<'tcx> {
|
||||
|
|
|
|||
|
|
@ -71,8 +71,5 @@ pub enum Expr<'tcx> {
|
|||
Cast(CastKind, Const<'tcx>, Ty<'tcx>),
|
||||
}
|
||||
|
||||
#[cfg(all(any(target_arch = "x86_64", target_arch = "aarch64"), target_pointer_width = "64"))]
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
static_assert_size!(Expr<'_>, 24);
|
||||
|
||||
#[cfg(all(any(target_arch = "x86_64", target_arch = "aarch64"), target_pointer_width = "64"))]
|
||||
static_assert_size!(super::ConstKind<'_>, 32);
|
||||
|
|
|
|||
|
|
@ -2183,7 +2183,7 @@ pub struct DestructuredConst<'tcx> {
|
|||
}
|
||||
|
||||
// Some types are used a lot. Make sure they don't unintentionally get bigger.
|
||||
#[cfg(all(any(target_arch = "x86_64", target_arch = "aarch64"), target_pointer_width = "64"))]
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
mod size_asserts {
|
||||
use super::*;
|
||||
use rustc_data_structures::static_assert_size;
|
||||
|
|
|
|||
|
|
@ -2697,7 +2697,7 @@ impl<'tcx> VarianceDiagInfo<'tcx> {
|
|||
}
|
||||
|
||||
// Some types are used a lot. Make sure they don't unintentionally get bigger.
|
||||
#[cfg(all(any(target_arch = "x86_64", target_arch = "aarch64"), target_pointer_width = "64"))]
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
mod size_asserts {
|
||||
use super::*;
|
||||
use rustc_data_structures::static_assert_size;
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ use rustc_hir::{
|
|||
def::{DefKind, Res},
|
||||
def_id::{DefId, LocalDefId, LocalDefIdMap},
|
||||
hir_id::OwnerId,
|
||||
BindingAnnotation, ByRef, HirId, ItemLocalId, ItemLocalMap, ItemLocalSet, Mutability,
|
||||
BindingMode, ByRef, HirId, ItemLocalId, ItemLocalMap, ItemLocalSet, Mutability,
|
||||
};
|
||||
use rustc_index::IndexVec;
|
||||
use rustc_macros::HashStable;
|
||||
|
|
@ -78,8 +78,8 @@ pub struct TypeckResults<'tcx> {
|
|||
|
||||
adjustments: ItemLocalMap<Vec<ty::adjustment::Adjustment<'tcx>>>,
|
||||
|
||||
/// Stores the actual binding mode for all instances of [`BindingAnnotation`].
|
||||
pat_binding_modes: ItemLocalMap<BindingAnnotation>,
|
||||
/// Stores the actual binding mode for all instances of [`BindingMode`].
|
||||
pat_binding_modes: ItemLocalMap<BindingMode>,
|
||||
|
||||
/// Stores the types which were implicitly dereferenced in pattern binding modes
|
||||
/// for later usage in THIR lowering. For example,
|
||||
|
|
@ -413,22 +413,17 @@ impl<'tcx> TypeckResults<'tcx> {
|
|||
matches!(self.type_dependent_defs().get(expr.hir_id), Some(Ok((DefKind::AssocFn, _))))
|
||||
}
|
||||
|
||||
pub fn extract_binding_mode(
|
||||
&self,
|
||||
s: &Session,
|
||||
id: HirId,
|
||||
sp: Span,
|
||||
) -> Option<BindingAnnotation> {
|
||||
pub fn extract_binding_mode(&self, s: &Session, id: HirId, sp: Span) -> Option<BindingMode> {
|
||||
self.pat_binding_modes().get(id).copied().or_else(|| {
|
||||
s.dcx().span_bug(sp, "missing binding mode");
|
||||
})
|
||||
}
|
||||
|
||||
pub fn pat_binding_modes(&self) -> LocalTableInContext<'_, BindingAnnotation> {
|
||||
pub fn pat_binding_modes(&self) -> LocalTableInContext<'_, BindingMode> {
|
||||
LocalTableInContext { hir_owner: self.hir_owner, data: &self.pat_binding_modes }
|
||||
}
|
||||
|
||||
pub fn pat_binding_modes_mut(&mut self) -> LocalTableInContextMut<'_, BindingAnnotation> {
|
||||
pub fn pat_binding_modes_mut(&mut self) -> LocalTableInContextMut<'_, BindingMode> {
|
||||
LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.pat_binding_modes }
|
||||
}
|
||||
|
||||
|
|
@ -460,7 +455,7 @@ impl<'tcx> TypeckResults<'tcx> {
|
|||
let mut has_ref_mut = false;
|
||||
pat.walk(|pat| {
|
||||
if let hir::PatKind::Binding(_, id, _, _) = pat.kind
|
||||
&& let Some(BindingAnnotation(ByRef::Yes(Mutability::Mut), _)) =
|
||||
&& let Some(BindingMode(ByRef::Yes(Mutability::Mut), _)) =
|
||||
self.pat_binding_modes().get(id)
|
||||
{
|
||||
has_ref_mut = true;
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ use rustc_data_structures::{
|
|||
fx::{FxHashSet, FxIndexMap, FxIndexSet},
|
||||
stack::ensure_sufficient_stack,
|
||||
};
|
||||
use rustc_hir::{BindingAnnotation, ByRef};
|
||||
use rustc_hir::{BindingMode, ByRef};
|
||||
use rustc_middle::middle::region;
|
||||
use rustc_middle::mir::{self, *};
|
||||
use rustc_middle::thir::{self, *};
|
||||
|
|
@ -385,15 +385,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
let fake_borrows = match_has_guard
|
||||
.then(|| util::FakeBorrowCollector::collect_fake_borrows(self, candidates));
|
||||
|
||||
// See the doc comment on `match_candidates` for why we have an
|
||||
// otherwise block. Match checking will ensure this is actually
|
||||
// unreachable.
|
||||
let otherwise_block = self.cfg.start_new_block();
|
||||
|
||||
// This will generate code to test scrutinee_place and
|
||||
// branch to the appropriate arm block
|
||||
self.match_candidates(match_start_span, scrutinee_span, block, otherwise_block, candidates);
|
||||
|
||||
// See the doc comment on `match_candidates` for why we may have an
|
||||
// otherwise block. Match checking will ensure this is actually
|
||||
// unreachable.
|
||||
let source_info = self.source_info(scrutinee_span);
|
||||
|
||||
// Matching on a `scrutinee_place` with an uninhabited type doesn't
|
||||
|
|
@ -621,12 +621,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
) -> BlockAnd<()> {
|
||||
match irrefutable_pat.kind {
|
||||
// Optimize the case of `let x = ...` to write directly into `x`
|
||||
PatKind::Binding {
|
||||
mode: BindingAnnotation(ByRef::No, _),
|
||||
var,
|
||||
subpattern: None,
|
||||
..
|
||||
} => {
|
||||
PatKind::Binding { mode: BindingMode(ByRef::No, _), var, subpattern: None, .. } => {
|
||||
let place =
|
||||
self.storage_live_binding(block, var, irrefutable_pat.span, OutsideGuard, true);
|
||||
unpack!(block = self.expr_into_dest(place, block, initializer_id));
|
||||
|
|
@ -652,7 +647,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
box Pat {
|
||||
kind:
|
||||
PatKind::Binding {
|
||||
mode: BindingAnnotation(ByRef::No, _),
|
||||
mode: BindingMode(ByRef::No, _),
|
||||
var,
|
||||
subpattern: None,
|
||||
..
|
||||
|
|
@ -893,7 +888,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
f: &mut impl FnMut(
|
||||
&mut Self,
|
||||
Symbol,
|
||||
BindingAnnotation,
|
||||
BindingMode,
|
||||
LocalVarId,
|
||||
Span,
|
||||
Ty<'tcx>,
|
||||
|
|
@ -1148,7 +1143,7 @@ struct Binding<'tcx> {
|
|||
span: Span,
|
||||
source: Place<'tcx>,
|
||||
var_id: LocalVarId,
|
||||
binding_mode: BindingAnnotation,
|
||||
binding_mode: BindingMode,
|
||||
}
|
||||
|
||||
/// Indicates that the type of `source` must be a subtype of the
|
||||
|
|
@ -2412,7 +2407,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
source_info: SourceInfo,
|
||||
visibility_scope: SourceScope,
|
||||
name: Symbol,
|
||||
mode: BindingAnnotation,
|
||||
mode: BindingMode,
|
||||
var_id: LocalVarId,
|
||||
var_ty: Ty<'tcx>,
|
||||
user_ty: UserTypeProjections,
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ use rustc_data_structures::sorted_map::SortedIndexMultiMap;
|
|||
use rustc_errors::ErrorGuaranteed;
|
||||
use rustc_hir::def::DefKind;
|
||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||
use rustc_hir::{self as hir, BindingAnnotation, ByRef, HirId, Node};
|
||||
use rustc_hir::{self as hir, BindingMode, ByRef, HirId, Node};
|
||||
use rustc_index::bit_set::GrowableBitSet;
|
||||
use rustc_index::{Idx, IndexSlice, IndexVec};
|
||||
use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
|
||||
|
|
@ -931,7 +931,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
// Don't introduce extra copies for simple bindings
|
||||
PatKind::Binding {
|
||||
var,
|
||||
mode: BindingAnnotation(ByRef::No, mutability),
|
||||
mode: BindingMode(ByRef::No, mutability),
|
||||
subpattern: None,
|
||||
..
|
||||
} => {
|
||||
|
|
@ -941,7 +941,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
if let Some(kind) = param.self_kind {
|
||||
LocalInfo::User(BindingForm::ImplicitSelf(kind))
|
||||
} else {
|
||||
let binding_mode = BindingAnnotation(ByRef::No, mutability);
|
||||
let binding_mode = BindingMode(ByRef::No, mutability);
|
||||
LocalInfo::User(BindingForm::Var(VarBindingForm {
|
||||
binding_mode,
|
||||
opt_ty_info: param.ty_span,
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use crate::build::ExprCategory;
|
|||
use crate::errors::*;
|
||||
|
||||
use rustc_errors::DiagArgValue;
|
||||
use rustc_hir::{self as hir, BindingAnnotation, ByRef, HirId, Mutability};
|
||||
use rustc_hir::{self as hir, BindingMode, ByRef, HirId, Mutability};
|
||||
use rustc_middle::mir::BorrowKind;
|
||||
use rustc_middle::thir::visit::Visitor;
|
||||
use rustc_middle::thir::*;
|
||||
|
|
@ -288,7 +288,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
|
|||
visit::walk_pat(self, pat);
|
||||
}
|
||||
}
|
||||
PatKind::Binding { mode: BindingAnnotation(ByRef::Yes(rm), _), ty, .. } => {
|
||||
PatKind::Binding { mode: BindingMode(ByRef::Yes(rm), _), ty, .. } => {
|
||||
if self.inside_adt {
|
||||
let ty::Ref(_, ty, _) = ty.kind() else {
|
||||
span_bug!(
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ use rustc_errors::{
|
|||
};
|
||||
use rustc_hir::def::*;
|
||||
use rustc_hir::def_id::LocalDefId;
|
||||
use rustc_hir::{self as hir, BindingAnnotation, ByRef, HirId};
|
||||
use rustc_hir::{self as hir, BindingMode, ByRef, HirId};
|
||||
use rustc_middle::middle::limits::get_limit_size;
|
||||
use rustc_middle::thir::visit::Visitor;
|
||||
use rustc_middle::thir::*;
|
||||
|
|
@ -839,7 +839,7 @@ fn check_for_bindings_named_same_as_variants(
|
|||
) {
|
||||
if let PatKind::Binding {
|
||||
name,
|
||||
mode: BindingAnnotation(ByRef::No, Mutability::Not),
|
||||
mode: BindingMode(ByRef::No, Mutability::Not),
|
||||
subpattern: None,
|
||||
ty,
|
||||
..
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ use rustc_middle::mir::visit::*;
|
|||
use rustc_middle::mir::*;
|
||||
use rustc_middle::ty::TypeVisitableExt;
|
||||
use rustc_middle::ty::{self, Instance, InstanceDef, ParamEnv, Ty, TyCtxt};
|
||||
use rustc_session::config::OptLevel;
|
||||
use rustc_session::config::{DebugInfo, OptLevel};
|
||||
use rustc_span::source_map::Spanned;
|
||||
use rustc_span::sym;
|
||||
use rustc_target::abi::FieldIdx;
|
||||
|
|
@ -699,7 +699,19 @@ impl<'tcx> Inliner<'tcx> {
|
|||
// Insert all of the (mapped) parts of the callee body into the caller.
|
||||
caller_body.local_decls.extend(callee_body.drain_vars_and_temps());
|
||||
caller_body.source_scopes.extend(&mut callee_body.source_scopes.drain(..));
|
||||
caller_body.var_debug_info.append(&mut callee_body.var_debug_info);
|
||||
if self
|
||||
.tcx
|
||||
.sess
|
||||
.opts
|
||||
.unstable_opts
|
||||
.inline_mir_preserve_debug
|
||||
.unwrap_or(self.tcx.sess.opts.debuginfo != DebugInfo::None)
|
||||
{
|
||||
// Note that we need to preserve these in the standard library so that
|
||||
// people working on rust can build with or without debuginfo while
|
||||
// still getting consistent results from the mir-opt tests.
|
||||
caller_body.var_debug_info.append(&mut callee_body.var_debug_info);
|
||||
}
|
||||
caller_body.basic_blocks_mut().extend(callee_body.basic_blocks_mut().drain(..));
|
||||
|
||||
caller_body[callsite.block].terminator = Some(Terminator {
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ use unescape_error_reporting::{emit_unescape_error, escaped_char};
|
|||
//
|
||||
// This assertion is in this crate, rather than in `rustc_lexer`, because that
|
||||
// crate cannot depend on `rustc_data_structures`.
|
||||
#[cfg(all(any(target_arch = "x86_64", target_arch = "aarch64"), target_pointer_width = "64"))]
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
rustc_data_structures::static_assert_size!(rustc_lexer::Token, 12);
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
|
|
|
|||
|
|
@ -454,7 +454,7 @@ fn make_token_stream(
|
|||
}
|
||||
|
||||
// Some types are used a lot. Make sure they don't unintentionally get bigger.
|
||||
#[cfg(all(any(target_arch = "x86_64", target_arch = "aarch64"), target_pointer_width = "64"))]
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
mod size_asserts {
|
||||
use super::*;
|
||||
use rustc_data_structures::static_assert_size;
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ use rustc_ast::token::{self, Delimiter, Lit, LitKind, Token, TokenKind};
|
|||
use rustc_ast::tokenstream::AttrTokenTree;
|
||||
use rustc_ast::util::parser::AssocOp;
|
||||
use rustc_ast::{
|
||||
AngleBracketedArg, AngleBracketedArgs, AnonConst, AttrVec, BinOpKind, BindingAnnotation, Block,
|
||||
AngleBracketedArg, AngleBracketedArgs, AnonConst, AttrVec, BinOpKind, BindingMode, Block,
|
||||
BlockCheckMode, Expr, ExprKind, GenericArg, Generics, HasTokens, Item, ItemKind, Param, Pat,
|
||||
PatKind, Path, PathSegment, QSelf, Ty, TyKind,
|
||||
};
|
||||
|
|
@ -51,7 +51,7 @@ use thin_vec::{thin_vec, ThinVec};
|
|||
pub(super) fn dummy_arg(ident: Ident, guar: ErrorGuaranteed) -> Param {
|
||||
let pat = P(Pat {
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
kind: PatKind::Ident(BindingAnnotation::NONE, ident, None),
|
||||
kind: PatKind::Ident(BindingMode::NONE, ident, None),
|
||||
span: ident.span,
|
||||
tokens: None,
|
||||
});
|
||||
|
|
@ -2787,7 +2787,7 @@ impl<'a> Parser<'a> {
|
|||
}
|
||||
_ => {}
|
||||
},
|
||||
PatKind::Ident(BindingAnnotation::NONE, ident, None) => {
|
||||
PatKind::Ident(BindingMode::NONE, ident, None) => {
|
||||
match &first_pat.kind {
|
||||
PatKind::Ident(_, old_ident, _) => {
|
||||
let path = PatKind::Path(
|
||||
|
|
|
|||
|
|
@ -2712,7 +2712,7 @@ impl<'a> Parser<'a> {
|
|||
match ty {
|
||||
Ok(ty) => {
|
||||
let ident = Ident::new(kw::Empty, this.prev_token.span);
|
||||
let bm = BindingAnnotation::NONE;
|
||||
let bm = BindingMode::NONE;
|
||||
let pat = this.mk_pat_ident(ty.span, bm, ident);
|
||||
(pat, ty)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -179,7 +179,7 @@ pub struct Parser<'a> {
|
|||
|
||||
// This type is used a lot, e.g. it's cloned when matching many declarative macro rules with nonterminals. Make sure
|
||||
// it doesn't unintentionally get bigger.
|
||||
#[cfg(all(any(target_arch = "x86_64", target_arch = "aarch64"), target_pointer_width = "64"))]
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
rustc_data_structures::static_assert_size!(Parser<'_>, 264);
|
||||
|
||||
/// Stores span information about a closure.
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@ use rustc_ast::mut_visit::{noop_visit_pat, MutVisitor};
|
|||
use rustc_ast::ptr::P;
|
||||
use rustc_ast::token::{self, BinOpToken, Delimiter, Token};
|
||||
use rustc_ast::{
|
||||
self as ast, AttrVec, BindingAnnotation, ByRef, Expr, ExprKind, MacCall, Mutability, Pat,
|
||||
PatField, PatFieldsRest, PatKind, Path, QSelf, RangeEnd, RangeSyntax,
|
||||
self as ast, AttrVec, BindingMode, ByRef, Expr, ExprKind, MacCall, Mutability, Pat, PatField,
|
||||
PatFieldsRest, PatKind, Path, QSelf, RangeEnd, RangeSyntax,
|
||||
};
|
||||
use rustc_ast_pretty::pprust;
|
||||
use rustc_errors::{Applicability, Diag, PResult};
|
||||
|
|
@ -486,7 +486,7 @@ impl<'a> Parser<'a> {
|
|||
}
|
||||
// Parse ref ident @ pat / ref mut ident @ pat
|
||||
let mutbl = self.parse_mutability();
|
||||
self.parse_pat_ident(BindingAnnotation(ByRef::Yes(mutbl), Mutability::Not), syntax_loc)?
|
||||
self.parse_pat_ident(BindingMode(ByRef::Yes(mutbl), Mutability::Not), syntax_loc)?
|
||||
} else if self.eat_keyword(kw::Box) {
|
||||
self.parse_pat_box()?
|
||||
} else if self.check_inline_const(0) {
|
||||
|
|
@ -511,7 +511,7 @@ impl<'a> Parser<'a> {
|
|||
// Parse `ident @ pat`
|
||||
// This can give false positives and parse nullary enums,
|
||||
// they are dealt with later in resolve.
|
||||
self.parse_pat_ident(BindingAnnotation::NONE, syntax_loc)?
|
||||
self.parse_pat_ident(BindingMode::NONE, syntax_loc)?
|
||||
} else if self.is_start_of_pat_with_path() {
|
||||
// Parse pattern starting with a path
|
||||
let (qself, path) = if self.eat_lt() {
|
||||
|
|
@ -766,8 +766,7 @@ impl<'a> Parser<'a> {
|
|||
let mut pat = self.parse_pat_no_top_alt(Some(Expected::Identifier), None)?;
|
||||
|
||||
// If we don't have `mut $ident (@ pat)?`, error.
|
||||
if let PatKind::Ident(BindingAnnotation(br @ ByRef::No, m @ Mutability::Not), ..) =
|
||||
&mut pat.kind
|
||||
if let PatKind::Ident(BindingMode(br @ ByRef::No, m @ Mutability::Not), ..) = &mut pat.kind
|
||||
{
|
||||
// Don't recurse into the subpattern.
|
||||
// `mut` on the outer binding doesn't affect the inner bindings.
|
||||
|
|
@ -779,8 +778,7 @@ impl<'a> Parser<'a> {
|
|||
self.ban_mut_general_pat(mut_span, &pat, changed_any_binding);
|
||||
}
|
||||
|
||||
if matches!(pat.kind, PatKind::Ident(BindingAnnotation(ByRef::Yes(_), Mutability::Mut), ..))
|
||||
{
|
||||
if matches!(pat.kind, PatKind::Ident(BindingMode(ByRef::Yes(_), Mutability::Mut), ..)) {
|
||||
self.psess.gated_spans.gate(sym::mut_ref, pat.span);
|
||||
}
|
||||
Ok(pat.into_inner().kind)
|
||||
|
|
@ -792,7 +790,7 @@ impl<'a> Parser<'a> {
|
|||
struct AddMut(bool);
|
||||
impl MutVisitor for AddMut {
|
||||
fn visit_pat(&mut self, pat: &mut P<Pat>) {
|
||||
if let PatKind::Ident(BindingAnnotation(ByRef::No, m @ Mutability::Not), ..) =
|
||||
if let PatKind::Ident(BindingMode(ByRef::No, m @ Mutability::Not), ..) =
|
||||
&mut pat.kind
|
||||
{
|
||||
self.0 = true;
|
||||
|
|
@ -1025,7 +1023,7 @@ impl<'a> Parser<'a> {
|
|||
/// error message when parsing mistakes like `ref foo(a, b)`.
|
||||
fn parse_pat_ident(
|
||||
&mut self,
|
||||
binding_annotation: BindingAnnotation,
|
||||
binding_annotation: BindingMode,
|
||||
syntax_loc: Option<PatternLocation>,
|
||||
) -> PResult<'a, PatKind> {
|
||||
let ident = self.parse_ident_common(false)?;
|
||||
|
|
@ -1163,7 +1161,7 @@ impl<'a> Parser<'a> {
|
|||
None
|
||||
};
|
||||
|
||||
Ok(PatKind::Ident(BindingAnnotation::NONE, Ident::new(kw::Box, box_span), sub))
|
||||
Ok(PatKind::Ident(BindingMode::NONE, Ident::new(kw::Box, box_span), sub))
|
||||
} else {
|
||||
let pat = self.parse_pat_with_range_pat(false, None, None)?;
|
||||
self.psess.gated_spans.gate(sym::box_patterns, box_span.to(self.prev_token.span));
|
||||
|
|
@ -1344,7 +1342,7 @@ impl<'a> Parser<'a> {
|
|||
if let Some(last) = fields.iter().last()
|
||||
&& last.is_shorthand
|
||||
&& let PatKind::Ident(binding, ident, None) = last.pat.kind
|
||||
&& binding != BindingAnnotation::NONE
|
||||
&& binding != BindingMode::NONE
|
||||
&& self.token == token::Colon
|
||||
// We found `ref mut? ident:`, try to parse a `name,` or `name }`.
|
||||
&& let Some(name_span) = self.look_ahead(1, |t| t.is_ident().then(|| t.span))
|
||||
|
|
@ -1400,7 +1398,7 @@ impl<'a> Parser<'a> {
|
|||
|
||||
let fieldname = self.parse_field_name()?;
|
||||
hi = self.prev_token.span;
|
||||
let ann = BindingAnnotation(by_ref, mutability);
|
||||
let ann = BindingMode(by_ref, mutability);
|
||||
let fieldpat = self.mk_pat_ident(boxed_span.to(hi), ann, fieldname);
|
||||
let subpat =
|
||||
if is_box { self.mk_pat(lo.to(hi), PatKind::Box(fieldpat)) } else { fieldpat };
|
||||
|
|
@ -1418,7 +1416,7 @@ impl<'a> Parser<'a> {
|
|||
})
|
||||
}
|
||||
|
||||
pub(super) fn mk_pat_ident(&self, span: Span, ann: BindingAnnotation, ident: Ident) -> P<Pat> {
|
||||
pub(super) fn mk_pat_ident(&self, span: Span, ann: BindingMode, ident: Ident) -> P<Pat> {
|
||||
self.mk_pat(span, PatKind::Ident(ann, ident, None))
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1087,7 +1087,7 @@ fn unescape_string(string: &str) -> Option<string::String> {
|
|||
}
|
||||
|
||||
// Assert a reasonable size for `Piece`
|
||||
#[cfg(all(any(target_arch = "x86_64", target_arch = "aarch64"), target_pointer_width = "64"))]
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
rustc_index::static_assert_size!(Piece<'_>, 16);
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
|
|||
|
|
@ -83,8 +83,7 @@ fn check_abi(tcx: TyCtxt<'_>, def_id: LocalDefId, abi: Abi) {
|
|||
fn check_no_patterns(tcx: TyCtxt<'_>, params: &[hir::Param<'_>]) {
|
||||
for param in params {
|
||||
match param.pat.kind {
|
||||
hir::PatKind::Wild
|
||||
| hir::PatKind::Binding(hir::BindingAnnotation::NONE, _, _, None) => {}
|
||||
hir::PatKind::Wild | hir::PatKind::Binding(hir::BindingMode::NONE, _, _, None) => {}
|
||||
_ => {
|
||||
tcx.dcx().emit_err(NoPatterns { span: param.pat.span });
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ use diagnostics::{ElisionFnParameter, LifetimeElisionCandidate, MissingLifetime}
|
|||
#[derive(Copy, Clone, Debug)]
|
||||
struct BindingInfo {
|
||||
span: Span,
|
||||
annotation: BindingAnnotation,
|
||||
annotation: BindingMode,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
||||
|
|
@ -3655,14 +3655,14 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
|
|||
fn try_resolve_as_non_binding(
|
||||
&mut self,
|
||||
pat_src: PatternSource,
|
||||
ann: BindingAnnotation,
|
||||
ann: BindingMode,
|
||||
ident: Ident,
|
||||
has_sub: bool,
|
||||
) -> Option<Res> {
|
||||
// An immutable (no `mut`) by-value (no `ref`) binding pattern without
|
||||
// a sub pattern (no `@ $pat`) is syntactically ambiguous as it could
|
||||
// also be interpreted as a path to e.g. a constant, variant, etc.
|
||||
let is_syntactic_ambiguity = !has_sub && ann == BindingAnnotation::NONE;
|
||||
let is_syntactic_ambiguity = !has_sub && ann == BindingMode::NONE;
|
||||
|
||||
let ls_binding = self.maybe_resolve_ident_in_lexical_scope(ident, ValueNS)?;
|
||||
let (res, binding) = match ls_binding {
|
||||
|
|
|
|||
|
|
@ -1717,6 +1717,9 @@ options! {
|
|||
"enable MIR inlining (default: no)"),
|
||||
inline_mir_hint_threshold: Option<usize> = (None, parse_opt_number, [TRACKED],
|
||||
"inlining threshold for functions with inline hint (default: 100)"),
|
||||
inline_mir_preserve_debug: Option<bool> = (None, parse_opt_bool, [TRACKED],
|
||||
"when MIR inlining, whether to preserve debug info for callee variables \
|
||||
(default: preserve for debuginfo != None, otherwise remove)"),
|
||||
inline_mir_threshold: Option<usize> = (None, parse_opt_number, [TRACKED],
|
||||
"a default MIR inlining threshold (default: 50)"),
|
||||
input_stats: bool = (false, parse_bool, [UNTRACKED],
|
||||
|
|
|
|||
|
|
@ -947,7 +947,7 @@ impl FromStr for Conv {
|
|||
}
|
||||
|
||||
// Some types are used a lot. Make sure they don't unintentionally get bigger.
|
||||
#[cfg(all(any(target_arch = "x86_64", target_arch = "aarch64"), target_pointer_width = "64"))]
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
mod size_asserts {
|
||||
use super::*;
|
||||
use rustc_data_structures::static_assert_size;
|
||||
|
|
|
|||
|
|
@ -279,9 +279,9 @@ const RISCV_ALLOWED_FEATURES: &[(&str, Stability)] = &[
|
|||
("d", Unstable(sym::riscv_target_feature)),
|
||||
("e", Unstable(sym::riscv_target_feature)),
|
||||
("f", Unstable(sym::riscv_target_feature)),
|
||||
("fast-unaligned-access", Unstable(sym::riscv_target_feature)),
|
||||
("m", Stable),
|
||||
("relax", Unstable(sym::riscv_target_feature)),
|
||||
("unaligned-scalar-mem", Unstable(sym::riscv_target_feature)),
|
||||
("v", Unstable(sym::riscv_target_feature)),
|
||||
("zba", Stable),
|
||||
("zbb", Stable),
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@
|
|||
|
||||
#[macro_use]
|
||||
extern crate rustc_macros;
|
||||
#[cfg(all(any(target_arch = "x86_64", target_arch = "aarch64"), target_pointer_width = "64"))]
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
#[macro_use]
|
||||
extern crate rustc_data_structures;
|
||||
#[macro_use]
|
||||
|
|
|
|||
|
|
@ -751,9 +751,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
|||
// Get the local name of this closure. This can be inaccurate because
|
||||
// of the possibility of reassignment, but this should be good enough.
|
||||
match &kind {
|
||||
hir::PatKind::Binding(hir::BindingAnnotation::NONE, _, ident, None) => {
|
||||
Some(ident.name)
|
||||
}
|
||||
hir::PatKind::Binding(hir::BindingMode::NONE, _, ident, None) => Some(ident.name),
|
||||
_ => {
|
||||
err.note(msg);
|
||||
None
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ pub struct PendingPredicateObligation<'tcx> {
|
|||
}
|
||||
|
||||
// `PendingPredicateObligation` is used a lot. Make sure it doesn't unintentionally get bigger.
|
||||
#[cfg(all(any(target_arch = "x86_64", target_arch = "aarch64"), target_pointer_width = "64"))]
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
static_assert_size!(PendingPredicateObligation<'_>, 72);
|
||||
|
||||
impl<'tcx> FulfillmentContext<'tcx> {
|
||||
|
|
|
|||
|
|
@ -237,7 +237,7 @@ pub fn spin_loop() {
|
|||
crate::arch::riscv64::pause();
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
#[cfg(any(target_arch = "aarch64", target_arch = "arm64ec"))]
|
||||
{
|
||||
// SAFETY: the `cfg` attr ensures that we only execute this on aarch64 targets.
|
||||
unsafe { crate::arch::aarch64::__isb(crate::arch::aarch64::SY) };
|
||||
|
|
|
|||
|
|
@ -239,7 +239,7 @@ pub const unsafe fn from_raw_parts<'a>(ptr: *const u8, len: usize) -> &'a str {
|
|||
#[must_use]
|
||||
#[unstable(feature = "str_from_raw_parts", issue = "119206")]
|
||||
#[rustc_const_unstable(feature = "const_str_from_raw_parts_mut", issue = "119206")]
|
||||
pub const unsafe fn from_raw_parts_mut<'a>(ptr: *mut u8, len: usize) -> &'a str {
|
||||
pub const unsafe fn from_raw_parts_mut<'a>(ptr: *mut u8, len: usize) -> &'a mut str {
|
||||
// SAFETY: the caller must uphold the safety contract for `from_raw_parts_mut`.
|
||||
unsafe { &mut *ptr::from_raw_parts_mut(ptr.cast(), len) }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#![doc(issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/")]
|
||||
#![panic_runtime]
|
||||
#![allow(unused_features)]
|
||||
#![feature(asm_experimental_arch)]
|
||||
#![feature(core_intrinsics)]
|
||||
#![feature(panic_runtime)]
|
||||
#![feature(std_internals)]
|
||||
|
|
@ -78,7 +79,7 @@ pub unsafe fn __rust_start_panic(_payload: &mut dyn PanicPayload) -> u32 {
|
|||
core::arch::asm!("int $$0x29", in("ecx") FAST_FAIL_FATAL_APP_EXIT, options(noreturn, nostack));
|
||||
} else if #[cfg(all(target_arch = "arm", target_feature = "thumb-mode"))] {
|
||||
core::arch::asm!(".inst 0xDEFB", in("r0") FAST_FAIL_FATAL_APP_EXIT, options(noreturn, nostack));
|
||||
} else if #[cfg(target_arch = "aarch64")] {
|
||||
} else if #[cfg(any(target_arch = "aarch64", target_arch = "arm64ec"))] {
|
||||
core::arch::asm!("brk 0xF003", in("x0") FAST_FAIL_FATAL_APP_EXIT, options(noreturn, nostack));
|
||||
} else {
|
||||
core::intrinsics::abort();
|
||||
|
|
|
|||
|
|
@ -277,6 +277,7 @@
|
|||
#![feature(allocator_internals)]
|
||||
#![feature(allow_internal_unsafe)]
|
||||
#![feature(allow_internal_unstable)]
|
||||
#![feature(asm_experimental_arch)]
|
||||
#![feature(c_unwind)]
|
||||
#![feature(cfg_sanitizer_cfi)]
|
||||
#![feature(cfg_target_thread_local)]
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ pub const MIN_ALIGN: usize = 8;
|
|||
#[cfg(any(
|
||||
target_arch = "x86_64",
|
||||
target_arch = "aarch64",
|
||||
target_arch = "arm64ec",
|
||||
target_arch = "loongarch64",
|
||||
target_arch = "mips64",
|
||||
target_arch = "mips64r6",
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Bindings generated by `windows-bindgen` 0.55.0
|
||||
// Bindings generated by `windows-bindgen` 0.56.0
|
||||
|
||||
#![allow(non_snake_case, non_upper_case_globals, non_camel_case_types, dead_code, clippy::all)]
|
||||
#[link(name = "advapi32")]
|
||||
|
|
@ -345,7 +345,7 @@ extern "system" {
|
|||
}
|
||||
#[link(name = "kernel32")]
|
||||
extern "system" {
|
||||
pub fn GetSystemTimePreciseAsFileTime(lpsystemtimeasfiletime: *mut FILETIME) -> ();
|
||||
pub fn GetSystemTimePreciseAsFileTime(lpsystemtimeasfiletime: *mut FILETIME);
|
||||
}
|
||||
#[link(name = "kernel32")]
|
||||
extern "system" {
|
||||
|
|
@ -1018,7 +1018,7 @@ impl Clone for CONTEXT_0_0 {
|
|||
}
|
||||
}
|
||||
#[repr(C)]
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
#[cfg(any(target_arch = "arm64ec", target_arch = "x86_64"))]
|
||||
pub struct CONTEXT {
|
||||
pub P1Home: u64,
|
||||
pub P2Home: u64,
|
||||
|
|
@ -1067,30 +1067,30 @@ pub struct CONTEXT {
|
|||
pub LastExceptionToRip: u64,
|
||||
pub LastExceptionFromRip: u64,
|
||||
}
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
#[cfg(any(target_arch = "arm64ec", target_arch = "x86_64"))]
|
||||
impl Copy for CONTEXT {}
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
#[cfg(any(target_arch = "arm64ec", target_arch = "x86_64"))]
|
||||
impl Clone for CONTEXT {
|
||||
fn clone(&self) -> Self {
|
||||
*self
|
||||
}
|
||||
}
|
||||
#[repr(C)]
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
#[cfg(any(target_arch = "arm64ec", target_arch = "x86_64"))]
|
||||
pub union CONTEXT_0 {
|
||||
pub FltSave: XSAVE_FORMAT,
|
||||
pub Anonymous: CONTEXT_0_0,
|
||||
}
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
#[cfg(any(target_arch = "arm64ec", target_arch = "x86_64"))]
|
||||
impl Copy for CONTEXT_0 {}
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
#[cfg(any(target_arch = "arm64ec", target_arch = "x86_64"))]
|
||||
impl Clone for CONTEXT_0 {
|
||||
fn clone(&self) -> Self {
|
||||
*self
|
||||
}
|
||||
}
|
||||
#[repr(C)]
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
#[cfg(any(target_arch = "arm64ec", target_arch = "x86_64"))]
|
||||
pub struct CONTEXT_0_0 {
|
||||
pub Header: [M128A; 2],
|
||||
pub Legacy: [M128A; 8],
|
||||
|
|
@ -1111,9 +1111,9 @@ pub struct CONTEXT_0_0 {
|
|||
pub Xmm14: M128A,
|
||||
pub Xmm15: M128A,
|
||||
}
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
#[cfg(any(target_arch = "arm64ec", target_arch = "x86_64"))]
|
||||
impl Copy for CONTEXT_0_0 {}
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
#[cfg(any(target_arch = "arm64ec", target_arch = "x86_64"))]
|
||||
impl Clone for CONTEXT_0_0 {
|
||||
fn clone(&self) -> Self {
|
||||
*self
|
||||
|
|
@ -3339,7 +3339,7 @@ pub const FILE_WRITE_EA: FILE_ACCESS_RIGHTS = 16u32;
|
|||
pub const FILE_WRITE_THROUGH: NTCREATEFILE_CREATE_OPTIONS = 2u32;
|
||||
pub const FIONBIO: i32 = -2147195266i32;
|
||||
#[repr(C)]
|
||||
#[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))]
|
||||
#[cfg(any(target_arch = "aarch64", target_arch = "arm64ec", target_arch = "x86_64"))]
|
||||
pub struct FLOATING_SAVE_AREA {
|
||||
pub ControlWord: u32,
|
||||
pub StatusWord: u32,
|
||||
|
|
@ -3351,9 +3351,9 @@ pub struct FLOATING_SAVE_AREA {
|
|||
pub RegisterArea: [u8; 80],
|
||||
pub Cr0NpxState: u32,
|
||||
}
|
||||
#[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))]
|
||||
#[cfg(any(target_arch = "aarch64", target_arch = "arm64ec", target_arch = "x86_64"))]
|
||||
impl Copy for FLOATING_SAVE_AREA {}
|
||||
#[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))]
|
||||
#[cfg(any(target_arch = "aarch64", target_arch = "arm64ec", target_arch = "x86_64"))]
|
||||
impl Clone for FLOATING_SAVE_AREA {
|
||||
fn clone(&self) -> Self {
|
||||
*self
|
||||
|
|
@ -4106,7 +4106,7 @@ impl Clone for WSABUF {
|
|||
}
|
||||
}
|
||||
#[repr(C)]
|
||||
#[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))]
|
||||
#[cfg(any(target_arch = "aarch64", target_arch = "arm64ec", target_arch = "x86_64"))]
|
||||
pub struct WSADATA {
|
||||
pub wVersion: u16,
|
||||
pub wHighVersion: u16,
|
||||
|
|
@ -4116,9 +4116,9 @@ pub struct WSADATA {
|
|||
pub szDescription: [i8; 257],
|
||||
pub szSystemStatus: [i8; 129],
|
||||
}
|
||||
#[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))]
|
||||
#[cfg(any(target_arch = "aarch64", target_arch = "arm64ec", target_arch = "x86_64"))]
|
||||
impl Copy for WSADATA {}
|
||||
#[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))]
|
||||
#[cfg(any(target_arch = "aarch64", target_arch = "arm64ec", target_arch = "x86_64"))]
|
||||
impl Clone for WSADATA {
|
||||
fn clone(&self) -> Self {
|
||||
*self
|
||||
|
|
@ -4286,7 +4286,7 @@ pub const WSA_SECURE_HOST_NOT_FOUND: WSA_ERROR = 11032i32;
|
|||
pub const WSA_WAIT_EVENT_0: WSA_ERROR = 0i32;
|
||||
pub const WSA_WAIT_IO_COMPLETION: WSA_ERROR = 192i32;
|
||||
#[repr(C)]
|
||||
#[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))]
|
||||
#[cfg(any(target_arch = "aarch64", target_arch = "arm64ec", target_arch = "x86_64"))]
|
||||
pub struct XSAVE_FORMAT {
|
||||
pub ControlWord: u16,
|
||||
pub StatusWord: u16,
|
||||
|
|
@ -4305,9 +4305,9 @@ pub struct XSAVE_FORMAT {
|
|||
pub XmmRegisters: [M128A; 16],
|
||||
pub Reserved4: [u8; 96],
|
||||
}
|
||||
#[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))]
|
||||
#[cfg(any(target_arch = "aarch64", target_arch = "arm64ec", target_arch = "x86_64"))]
|
||||
impl Copy for XSAVE_FORMAT {}
|
||||
#[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))]
|
||||
#[cfg(any(target_arch = "aarch64", target_arch = "arm64ec", target_arch = "x86_64"))]
|
||||
impl Clone for XSAVE_FORMAT {
|
||||
fn clone(&self) -> Self {
|
||||
*self
|
||||
|
|
|
|||
|
|
@ -332,7 +332,7 @@ pub fn abort_internal() -> ! {
|
|||
core::arch::asm!("int $$0x29", in("ecx") c::FAST_FAIL_FATAL_APP_EXIT, options(noreturn, nostack));
|
||||
} else if #[cfg(all(target_arch = "arm", target_feature = "thumb-mode"))] {
|
||||
core::arch::asm!(".inst 0xDEFB", in("r0") c::FAST_FAIL_FATAL_APP_EXIT, options(noreturn, nostack));
|
||||
} else if #[cfg(target_arch = "aarch64")] {
|
||||
} else if #[cfg(any(target_arch = "aarch64", target_arch = "arm64ec"))] {
|
||||
core::arch::asm!("brk 0xF003", in("x0") c::FAST_FAIL_FATAL_APP_EXIT, options(noreturn, nostack));
|
||||
} else {
|
||||
core::intrinsics::abort();
|
||||
|
|
|
|||
|
|
@ -394,16 +394,13 @@ fn copy_self_contained_objects(
|
|||
target_deps.push((libunwind_path, DependencyType::TargetSelfContained));
|
||||
}
|
||||
} else if target.contains("-wasi") {
|
||||
let srcdir = builder
|
||||
.wasi_root(target)
|
||||
.unwrap_or_else(|| {
|
||||
panic!(
|
||||
"Target {:?} does not have a \"wasi-root\" key in Config.toml",
|
||||
target.triple
|
||||
)
|
||||
})
|
||||
.join("lib")
|
||||
.join(target.to_string().replace("-preview1", "").replace("p2", "").replace("p1", ""));
|
||||
let srcdir = builder.wasi_libdir(target).unwrap_or_else(|| {
|
||||
panic!(
|
||||
"Target {:?} does not have a \"wasi-root\" key in Config.toml \
|
||||
or `$WASI_SDK_PATH` set",
|
||||
target.triple
|
||||
)
|
||||
});
|
||||
for &obj in &["libc.a", "crt1-command.o", "crt1-reactor.o"] {
|
||||
copy_and_stamp(
|
||||
builder,
|
||||
|
|
@ -514,12 +511,8 @@ pub fn std_cargo(builder: &Builder<'_>, target: TargetSelection, stage: u32, car
|
|||
}
|
||||
|
||||
if target.contains("-wasi") {
|
||||
if let Some(p) = builder.wasi_root(target) {
|
||||
let root = format!(
|
||||
"native={}/lib/{}",
|
||||
p.to_str().unwrap(),
|
||||
target.to_string().replace("-preview1", "")
|
||||
);
|
||||
if let Some(dir) = builder.wasi_libdir(target) {
|
||||
let root = format!("native={}", dir.to_str().unwrap());
|
||||
cargo.rustflag("-L").rustflag(&root);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2102,6 +2102,14 @@ impl<'a> Builder<'a> {
|
|||
// break when incremental compilation is enabled. So this overrides the "no inlining
|
||||
// during incremental builds" heuristic for the standard library.
|
||||
rustflags.arg("-Zinline-mir");
|
||||
|
||||
// FIXME: always pass this after the next `#[cfg(bootstrap)]` update.
|
||||
if compiler.stage != 0 {
|
||||
// Similarly, we need to keep debug info for functions inlined into other std functions,
|
||||
// even if we're not going to output debuginfo for the crate we're currently building,
|
||||
// so that it'll be available when downstream consumers of std try to use it.
|
||||
rustflags.arg("-Zinline-mir-preserve-debug");
|
||||
}
|
||||
}
|
||||
|
||||
if self.config.rustc_parallel
|
||||
|
|
|
|||
|
|
@ -1373,9 +1373,24 @@ impl Build {
|
|||
self.musl_root(target).map(|root| root.join("lib"))
|
||||
}
|
||||
|
||||
/// Returns the sysroot for the wasi target, if defined
|
||||
fn wasi_root(&self, target: TargetSelection) -> Option<&Path> {
|
||||
self.config.target_config.get(&target).and_then(|t| t.wasi_root.as_ref()).map(|p| &**p)
|
||||
/// Returns the `lib` directory for the WASI target specified, if
|
||||
/// configured.
|
||||
///
|
||||
/// This first consults `wasi-root` as configured in per-target
|
||||
/// configuration, and failing that it assumes that `$WASI_SDK_PATH` is
|
||||
/// set in the environment, and failing that `None` is returned.
|
||||
fn wasi_libdir(&self, target: TargetSelection) -> Option<PathBuf> {
|
||||
let configured =
|
||||
self.config.target_config.get(&target).and_then(|t| t.wasi_root.as_ref()).map(|p| &**p);
|
||||
if let Some(path) = configured {
|
||||
return Some(path.join("lib").join(target.to_string()));
|
||||
}
|
||||
let mut env_root = PathBuf::from(std::env::var_os("WASI_SDK_PATH")?);
|
||||
env_root.push("share");
|
||||
env_root.push("wasi-sysroot");
|
||||
env_root.push("lib");
|
||||
env_root.push(target.to_string());
|
||||
Some(env_root)
|
||||
}
|
||||
|
||||
/// Returns `true` if this is a no-std `target`, if defined
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ fn cc2ar(cc: &Path, target: TargetSelection) -> Option<PathBuf> {
|
|||
Some(PathBuf::from("ar"))
|
||||
} else if target.contains("vxworks") {
|
||||
Some(PathBuf::from("wr-ar"))
|
||||
} else if target.contains("android") {
|
||||
} else if target.contains("android") || target.contains("-wasi") {
|
||||
Some(cc.parent().unwrap().join(PathBuf::from("llvm-ar")))
|
||||
} else {
|
||||
let parent = cc.parent().unwrap();
|
||||
|
|
@ -223,6 +223,16 @@ fn default_compiler(
|
|||
}
|
||||
}
|
||||
|
||||
t if t.contains("-wasi") => {
|
||||
let root = PathBuf::from(std::env::var_os("WASI_SDK_PATH")?);
|
||||
let compiler = match compiler {
|
||||
Language::C => format!("{t}-clang"),
|
||||
Language::CPlusPlus => format!("{t}-clang++"),
|
||||
};
|
||||
let compiler = root.join("bin").join(compiler);
|
||||
Some(compiler)
|
||||
}
|
||||
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -85,11 +85,9 @@ RUN /tmp/build-solaris-toolchain.sh sparcv9 sparcv9 solaris-sparc sun
|
|||
COPY host-x86_64/dist-various-2/build-x86_64-fortanix-unknown-sgx-toolchain.sh /tmp/
|
||||
RUN /tmp/build-x86_64-fortanix-unknown-sgx-toolchain.sh
|
||||
|
||||
COPY host-x86_64/dist-various-2/build-wasi-toolchain.sh /tmp/
|
||||
RUN /tmp/build-wasi-toolchain.sh
|
||||
|
||||
COPY host-x86_64/dist-various-2/build-wasi-threads-toolchain.sh /tmp/
|
||||
RUN /tmp/build-wasi-threads-toolchain.sh
|
||||
RUN curl -L https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-22/wasi-sdk-22.0-linux.tar.gz | \
|
||||
tar -xz
|
||||
ENV WASI_SDK_PATH=/tmp/wasi-sdk-22.0
|
||||
|
||||
COPY scripts/freebsd-toolchain.sh /tmp/
|
||||
RUN /tmp/freebsd-toolchain.sh i686
|
||||
|
|
@ -136,9 +134,6 @@ ENV TARGETS=$TARGETS,x86_64-unknown-uefi
|
|||
RUN ln -s /usr/include/x86_64-linux-gnu/asm /usr/local/include/asm
|
||||
|
||||
ENV RUST_CONFIGURE_ARGS --enable-extended --enable-lld --enable-llvm-bitcode-linker --disable-docs \
|
||||
--set target.wasm32-wasi.wasi-root=/wasm32-wasip1 \
|
||||
--set target.wasm32-wasip1.wasi-root=/wasm32-wasip1 \
|
||||
--set target.wasm32-wasip1-threads.wasi-root=/wasm32-wasip1-threads \
|
||||
--musl-root-armv7=/musl-armv7
|
||||
|
||||
ENV SCRIPT python3 ../x.py dist --host='' --target $TARGETS
|
||||
|
|
|
|||
|
|
@ -1,24 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
set -ex
|
||||
|
||||
# Originally from https://github.com/llvm/llvm-project/releases/download/llvmorg-16.0.4/clang+llvm-16.0.4-x86_64-linux-gnu-ubuntu-22.04.tar.xz
|
||||
curl https://ci-mirrors.rust-lang.org/rustc/2023-05-17-clang%2Bllvm-16.0.4-x86_64-linux-gnu-ubuntu-22.04.tar.xz | \
|
||||
tar xJf -
|
||||
bin="$PWD/clang+llvm-16.0.4-x86_64-linux-gnu-ubuntu-22.04/bin"
|
||||
|
||||
git clone https://github.com/WebAssembly/wasi-libc
|
||||
|
||||
cd wasi-libc
|
||||
git reset --hard ec4566beae84e54952637f0bf61bee4b4cacc087
|
||||
make -j$(nproc) \
|
||||
CC="$bin/clang" \
|
||||
NM="$bin/llvm-nm" \
|
||||
AR="$bin/llvm-ar" \
|
||||
THREAD_MODEL=posix \
|
||||
INSTALL_DIR=/wasm32-wasip1-threads \
|
||||
install
|
||||
|
||||
cd ..
|
||||
rm -rf wasi-libc
|
||||
rm -rf clang+llvm*
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
set -ex
|
||||
|
||||
# Originally from https://github.com/llvm/llvm-project/releases/download/llvmorg-16.0.4/clang+llvm-16.0.4-x86_64-linux-gnu-ubuntu-22.04.tar.xz
|
||||
curl https://ci-mirrors.rust-lang.org/rustc/2023-05-17-clang%2Bllvm-16.0.4-x86_64-linux-gnu-ubuntu-22.04.tar.xz | \
|
||||
tar xJf -
|
||||
bin="$PWD/clang+llvm-16.0.4-x86_64-linux-gnu-ubuntu-22.04/bin"
|
||||
|
||||
git clone https://github.com/WebAssembly/wasi-libc
|
||||
|
||||
cd wasi-libc
|
||||
git reset --hard ec4566beae84e54952637f0bf61bee4b4cacc087
|
||||
make -j$(nproc) \
|
||||
CC="$bin/clang" \
|
||||
NM="$bin/llvm-nm" \
|
||||
AR="$bin/llvm-ar" \
|
||||
INSTALL_DIR=/wasm32-wasip1 \
|
||||
install
|
||||
|
||||
cd ..
|
||||
rm -rf wasi-libc
|
||||
rm -rf clang+llvm*
|
||||
|
|
@ -39,14 +39,14 @@ WORKDIR /
|
|||
COPY scripts/sccache.sh /scripts/
|
||||
RUN sh /scripts/sccache.sh
|
||||
|
||||
COPY host-x86_64/dist-various-2/build-wasi-toolchain.sh /tmp/
|
||||
RUN /tmp/build-wasi-toolchain.sh
|
||||
RUN curl -L https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-22/wasi-sdk-22.0-linux.tar.gz | \
|
||||
tar -xz
|
||||
ENV WASI_SDK_PATH=/wasi-sdk-22.0
|
||||
|
||||
ENV RUST_CONFIGURE_ARGS \
|
||||
--musl-root-x86_64=/usr/local/x86_64-linux-musl \
|
||||
--set build.nodejs=/node-v18.12.0-linux-x64/bin/node \
|
||||
--set rust.lld \
|
||||
--set target.wasm32-wasip1.wasi-root=/wasm32-wasip1
|
||||
--set rust.lld
|
||||
|
||||
# Some run-make tests have assertions about code size, and enabling debug
|
||||
# assertions in libstd causes the binary to be much bigger than it would
|
||||
|
|
@ -68,9 +68,6 @@ ENV WASM_SCRIPT python3 /checkout/x.py --stage 2 test --host='' --target $WASM_T
|
|||
tests/codegen \
|
||||
tests/assembly \
|
||||
library/core
|
||||
ENV CC_wasm32_wasip1=clang-11 \
|
||||
CFLAGS_wasm32_wasip1="--sysroot /wasm32-wasip1" \
|
||||
AR_wasm32_wasip1=llvm-ar-11
|
||||
|
||||
ENV NVPTX_TARGETS=nvptx64-nvidia-cuda
|
||||
ENV NVPTX_SCRIPT python3 /checkout/x.py --stage 2 test --host='' --target $NVPTX_TARGETS \
|
||||
|
|
|
|||
|
|
@ -11,48 +11,69 @@ applications on AArch64 Windows 11. See <https://learn.microsoft.com/en-us/windo
|
|||
|
||||
## Requirements
|
||||
|
||||
Target only supports cross-compilation, `core` and `alloc` are supported but
|
||||
`std` is not.
|
||||
|
||||
Builds Arm64EC static and dynamic libraries and executables which can be run on
|
||||
AArch64 Windows 11 devices. Arm64EC static libraries can also be linked into
|
||||
Arm64X dynamic libraries and executables.
|
||||
|
||||
Uses `arm64ec` as its `target_arch` - code built for Arm64EC must be compatible
|
||||
with x86_64 code (e.g., same structure layouts, function signatures, etc.) but
|
||||
use AArch64 intrinsics.
|
||||
Only supported backend is LLVM 18 or above:
|
||||
* 18.1.0 added initial support for Arm64EC.
|
||||
* 18.1.2 fixed import library generation (required for `raw-dylib` support).
|
||||
* 18.1.4 fixed linking issue for some intrinsics implemented in
|
||||
`compiler_builtins`.
|
||||
|
||||
Only supported backend is LLVM 18 (or above).
|
||||
### Reusing code from other architectures - x86_64 or AArch64?
|
||||
|
||||
Arm64EC uses `arm64ec` as its `target_arch`, but it is possible to reuse
|
||||
existing architecture-specific code in most cases. The best mental model for
|
||||
deciding which architecture to reuse is to is to think of Arm64EC as an x86_64
|
||||
process that happens to use the AArch64 instruction set (with some caveats) and
|
||||
has a completely custom ABI.
|
||||
|
||||
To put this in practice:
|
||||
* Arm64EC interacts with the operating system, other processes and other DLLs as
|
||||
x86_64.
|
||||
- For example, [in `backtrace`](https://github.com/rust-lang/backtrace-rs/commit/ef39a7d7da58b4cae8c8f3fc67a8300fd8d2d0d9)
|
||||
we use the x86_64 versions of `CONTEXT` and `RtlVirtualUnwind`.
|
||||
- If you are configuring a search path to find DLLs (e.g., to load plugins or
|
||||
addons into your application), you should use the same path as the x86_64
|
||||
version of your application, not the AArch64 path (since Arm64EC (i.e.,
|
||||
x86_64) processes cannot load native AArch64 DLLs).
|
||||
* Arm64EC uses AArch64 intrinsics.
|
||||
- For example, <https://github.com/rust-lang/portable-simd/commit/ca4033f49b1f6019561b8b161b4097b4a07f2e1b>
|
||||
and <https://github.com/rust-lang/stdarch/commit/166ef7ba22b6a1d908d4b29a36e68ceca324808a>.
|
||||
* Assembly for AArch64 might be reusable for Arm64EC, but there are many
|
||||
caveats. For full details see [Microsoft's documentation on the Arm64EC ABI](https://learn.microsoft.com/en-us/windows/arm/arm64ec-abi)
|
||||
but in brief:
|
||||
- Arm64EC uses a subset of AArch64 registers.
|
||||
- Arm64EC uses a different name mangling scheme than AArch64.
|
||||
- Arm64EC requires entry and exit thunks be generated for some functions.
|
||||
- Indirect calls must be done via a call checker.
|
||||
- Control Flow Guard and stack checks use different functions than AArch64.
|
||||
|
||||
## Building the target
|
||||
|
||||
You can build Rust with support for the targets by adding it to the `target`
|
||||
list in `config.toml` and disabling `std`:
|
||||
list in `config.toml`:
|
||||
|
||||
```toml
|
||||
[build]
|
||||
target = [ "arm64ec-pc-windows-msvc" ]
|
||||
|
||||
[target.arm64ec-pc-windows-msvc]
|
||||
no-std = true
|
||||
```
|
||||
|
||||
## Building Rust programs
|
||||
|
||||
Rust does not yet ship pre-compiled artifacts for this target. To compile for
|
||||
this target, you will either need to build Rust with the target enabled (see
|
||||
"Building the target" above), or build your own copy of `core` by using
|
||||
`build-std` or similar.
|
||||
"Building the target" above), or build your own copy using `build-std` or
|
||||
similar.
|
||||
|
||||
## Testing
|
||||
|
||||
Tests can be run on AArch64 Windows 11 devices.
|
||||
|
||||
Since this is a `no_std` target, the Rust test suite is not supported.
|
||||
|
||||
## Cross-compilation toolchains and C code
|
||||
|
||||
C code can be built using the Arm64-targetting MSVC toolchain.
|
||||
C code can be built using the Arm64-targetting MSVC or Clang toolchain.
|
||||
|
||||
To compile:
|
||||
|
||||
|
|
|
|||
|
|
@ -73,19 +73,21 @@ be used instead.
|
|||
|
||||
## Building the target
|
||||
|
||||
To build this target a compiled version of [`wasi-libc`] is required to be
|
||||
present at build time. This can be installed through
|
||||
[`wasi-sdk`](https://github.com/WebAssembly/wasi-sdk) as well. This is the
|
||||
configured with:
|
||||
To build this target first acquire a copy of
|
||||
[`wasi-sdk`](https://github.com/WebAssembly/wasi-sdk/). At this time version 22
|
||||
is the minimum needed.
|
||||
|
||||
```toml
|
||||
[target.wasm32-wasip1]
|
||||
wasi-root = ".../wasi-libc/sysroot"
|
||||
Next configure the `WASI_SDK_PATH` environment variable to point to where this
|
||||
is installed. For example:
|
||||
|
||||
```text
|
||||
export WASI_SDK_PATH=/path/to/wasi-sdk-22.0
|
||||
```
|
||||
|
||||
Additionally users will need to enable LLD when building Rust from source as
|
||||
LLVM's `wasm-ld` driver for LLD is required when linking WebAssembly code
|
||||
together.
|
||||
Next be sure to enable LLD when building Rust from source as LLVM's `wasm-ld`
|
||||
driver for LLD is required when linking WebAssembly code together. Rust's build
|
||||
system will automatically pick up any necessary binaries and programs from
|
||||
`WASI_SDK_PATH`.
|
||||
|
||||
## Building Rust programs
|
||||
|
||||
|
|
@ -112,8 +114,10 @@ This target can be cross-compiled from any hosts.
|
|||
|
||||
## Testing
|
||||
|
||||
Currently the WASI target is not tested in rust-lang/rust CI. This means that
|
||||
tests in the repository are not guaranteed to pass. This is theoretically
|
||||
possibly by installing a standalone WebAssembly runtime and using it as a
|
||||
"runner" for all tests, but there are various failures that will need to be
|
||||
waded through to adjust tests to work on the WASI target.
|
||||
This target is tested in rust-lang/rust CI on all merges. A subset of tests are
|
||||
run in the `test-various` builder such as the UI tests and libcore tests. This
|
||||
can be tested locally, for example, with:
|
||||
|
||||
```text
|
||||
./x.py test --target wasm32-wasip1 tests/ui
|
||||
```
|
||||
|
|
|
|||
|
|
@ -22,9 +22,34 @@ This target is cross-compiled. The target supports `std` fully.
|
|||
|
||||
## Platform requirements
|
||||
|
||||
The WebAssembly runtime should support the wasi preview 2 API set.
|
||||
The WebAssembly runtime should support the wasi preview 2 API set. Runtimes also
|
||||
are required to support components since this target outputs a component as
|
||||
opposed to a core wasm module. As of the time of this writing Wasmtime 17 and
|
||||
above is able to run this target natively with no extra flags.
|
||||
|
||||
This target is not a stable target. This means that there are only a few engines
|
||||
which implement wasi preview 2, for example:
|
||||
## Building the target
|
||||
|
||||
* Wasmtime - `-W component-model`
|
||||
To build this target first acquire a copy of
|
||||
[`wasi-sdk`](https://github.com/WebAssembly/wasi-sdk/). At this time version 22
|
||||
is the minimum needed.
|
||||
|
||||
Next configure the `WASI_SDK_PATH` environment variable to point to where this
|
||||
is installed. For example:
|
||||
|
||||
```text
|
||||
export WASI_SDK_PATH=/path/to/wasi-sdk-22.0
|
||||
```
|
||||
|
||||
Next be sure to enable LLD when building Rust from source as LLVM's `wasm-ld`
|
||||
driver for LLD is required when linking WebAssembly code together. Rust's build
|
||||
system will automatically pick up any necessary binaries and programs from
|
||||
`WASI_SDK_PATH`.
|
||||
|
||||
## Testing
|
||||
|
||||
This target is not tested in CI at this time. Locally it can be tested with a
|
||||
`wasmtime` binary in `PATH` like so:
|
||||
|
||||
```text
|
||||
./x.py test --target wasm32-wasip2 tests/ui
|
||||
```
|
||||
|
|
|
|||
|
|
@ -2567,7 +2567,7 @@ pub(crate) enum TypeBindingKind {
|
|||
}
|
||||
|
||||
// Some nodes are used a lot. Make sure they don't unintentionally get bigger.
|
||||
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
mod size_asserts {
|
||||
use super::*;
|
||||
use rustc_data_structures::static_assert_size;
|
||||
|
|
|
|||
|
|
@ -346,16 +346,28 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> {
|
|||
{
|
||||
let desc =
|
||||
short_markdown_summary(&item.doc_value(), &item.link_names(self.cache));
|
||||
// For searching purposes, a re-export is a duplicate if:
|
||||
//
|
||||
// - It's either an inline, or a true re-export
|
||||
// - It's got the same name
|
||||
// - Both of them have the same exact path
|
||||
let defid = (match &*item.kind {
|
||||
&clean::ItemKind::ImportItem(ref import) => import.source.did,
|
||||
_ => None,
|
||||
})
|
||||
.or_else(|| item.item_id.as_def_id());
|
||||
// In case this is a field from a tuple struct, we don't add it into
|
||||
// the search index because its name is something like "0", which is
|
||||
// not useful for rustdoc search.
|
||||
self.cache.search_index.push(IndexItem {
|
||||
ty,
|
||||
defid,
|
||||
name: s,
|
||||
path: join_with_double_colon(path),
|
||||
desc,
|
||||
parent,
|
||||
parent_idx: None,
|
||||
exact_path: None,
|
||||
impl_id: if let Some(ParentStackItem::Impl { item_id, .. }) =
|
||||
self.cache.parent_stack.last()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -78,8 +78,10 @@ pub(crate) struct Context<'tcx> {
|
|||
}
|
||||
|
||||
// `Context` is cloned a lot, so we don't want the size to grow unexpectedly.
|
||||
#[cfg(all(not(windows), target_arch = "x86_64", target_pointer_width = "64"))]
|
||||
#[cfg(all(not(windows), target_pointer_width = "64"))]
|
||||
rustc_data_structures::static_assert_size!(Context<'_>, 160);
|
||||
#[cfg(all(windows, target_pointer_width = "64"))]
|
||||
rustc_data_structures::static_assert_size!(Context<'_>, 168);
|
||||
|
||||
/// Shared mutable state used in [`Context`] and elsewhere.
|
||||
pub(crate) struct SharedContext<'tcx> {
|
||||
|
|
|
|||
|
|
@ -111,11 +111,13 @@ pub(crate) enum RenderMode {
|
|||
#[derive(Debug)]
|
||||
pub(crate) struct IndexItem {
|
||||
pub(crate) ty: ItemType,
|
||||
pub(crate) defid: Option<DefId>,
|
||||
pub(crate) name: Symbol,
|
||||
pub(crate) path: String,
|
||||
pub(crate) desc: String,
|
||||
pub(crate) parent: Option<DefId>,
|
||||
pub(crate) parent_idx: Option<isize>,
|
||||
pub(crate) exact_path: Option<String>,
|
||||
pub(crate) impl_id: Option<DefId>,
|
||||
pub(crate) search_type: Option<IndexItemFunctionType>,
|
||||
pub(crate) aliases: Box<[Symbol]>,
|
||||
|
|
|
|||
|
|
@ -59,10 +59,13 @@ pub(crate) fn build_index<'tcx>(
|
|||
cache: &mut Cache,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
) -> SerializedSearchIndex {
|
||||
// Maps from ID to position in the `crate_paths` array.
|
||||
let mut itemid_to_pathid = FxHashMap::default();
|
||||
let mut primitives = FxHashMap::default();
|
||||
let mut associated_types = FxHashMap::default();
|
||||
let mut crate_paths = vec![];
|
||||
|
||||
// item type, display path, re-exported internal path
|
||||
let mut crate_paths: Vec<(ItemType, Vec<Symbol>, Option<Vec<Symbol>>)> = vec![];
|
||||
|
||||
// Attach all orphan items to the type's definition if the type
|
||||
// has since been learned.
|
||||
|
|
@ -72,11 +75,13 @@ pub(crate) fn build_index<'tcx>(
|
|||
let desc = short_markdown_summary(&item.doc_value(), &item.link_names(cache));
|
||||
cache.search_index.push(IndexItem {
|
||||
ty: item.type_(),
|
||||
defid: item.item_id.as_def_id(),
|
||||
name: item.name.unwrap(),
|
||||
path: join_with_double_colon(&fqp[..fqp.len() - 1]),
|
||||
desc,
|
||||
parent: Some(parent),
|
||||
parent_idx: None,
|
||||
exact_path: None,
|
||||
impl_id,
|
||||
search_type: get_function_type_for_search(
|
||||
item,
|
||||
|
|
@ -126,9 +131,10 @@ pub(crate) fn build_index<'tcx>(
|
|||
map: &mut FxHashMap<F, isize>,
|
||||
itemid: F,
|
||||
lastpathid: &mut isize,
|
||||
crate_paths: &mut Vec<(ItemType, Vec<Symbol>)>,
|
||||
crate_paths: &mut Vec<(ItemType, Vec<Symbol>, Option<Vec<Symbol>>)>,
|
||||
item_type: ItemType,
|
||||
path: &[Symbol],
|
||||
exact_path: Option<&[Symbol]>,
|
||||
) -> RenderTypeId {
|
||||
match map.entry(itemid) {
|
||||
Entry::Occupied(entry) => RenderTypeId::Index(*entry.get()),
|
||||
|
|
@ -136,7 +142,11 @@ pub(crate) fn build_index<'tcx>(
|
|||
let pathid = *lastpathid;
|
||||
entry.insert(pathid);
|
||||
*lastpathid += 1;
|
||||
crate_paths.push((item_type, path.to_vec()));
|
||||
crate_paths.push((
|
||||
item_type,
|
||||
path.to_vec(),
|
||||
exact_path.map(|path| path.to_vec()),
|
||||
));
|
||||
RenderTypeId::Index(pathid)
|
||||
}
|
||||
}
|
||||
|
|
@ -149,14 +159,24 @@ pub(crate) fn build_index<'tcx>(
|
|||
primitives: &mut FxHashMap<Symbol, isize>,
|
||||
associated_types: &mut FxHashMap<Symbol, isize>,
|
||||
lastpathid: &mut isize,
|
||||
crate_paths: &mut Vec<(ItemType, Vec<Symbol>)>,
|
||||
crate_paths: &mut Vec<(ItemType, Vec<Symbol>, Option<Vec<Symbol>>)>,
|
||||
) -> Option<RenderTypeId> {
|
||||
let Cache { ref paths, ref external_paths, .. } = *cache;
|
||||
let Cache { ref paths, ref external_paths, ref exact_paths, .. } = *cache;
|
||||
match id {
|
||||
RenderTypeId::DefId(defid) => {
|
||||
if let Some(&(ref fqp, item_type)) =
|
||||
paths.get(&defid).or_else(|| external_paths.get(&defid))
|
||||
{
|
||||
let exact_fqp = exact_paths
|
||||
.get(&defid)
|
||||
.or_else(|| external_paths.get(&defid).map(|&(ref fqp, _)| fqp))
|
||||
// Re-exports only count if the name is exactly the same.
|
||||
// This is a size optimization, since it means we only need
|
||||
// to store the name once (and the path is re-used for everything
|
||||
// exported from this same module). It's also likely to Do
|
||||
// What I Mean, since if a re-export changes the name, it might
|
||||
// also be a change in semantic meaning.
|
||||
.filter(|fqp| fqp.last() == fqp.last());
|
||||
Some(insert_into_map(
|
||||
itemid_to_pathid,
|
||||
ItemId::DefId(defid),
|
||||
|
|
@ -164,6 +184,7 @@ pub(crate) fn build_index<'tcx>(
|
|||
crate_paths,
|
||||
item_type,
|
||||
fqp,
|
||||
exact_fqp.map(|x| &x[..]).filter(|exact_fqp| exact_fqp != fqp),
|
||||
))
|
||||
} else {
|
||||
None
|
||||
|
|
@ -178,6 +199,7 @@ pub(crate) fn build_index<'tcx>(
|
|||
crate_paths,
|
||||
ItemType::Primitive,
|
||||
&[sym],
|
||||
None,
|
||||
))
|
||||
}
|
||||
RenderTypeId::Index(_) => Some(id),
|
||||
|
|
@ -188,6 +210,7 @@ pub(crate) fn build_index<'tcx>(
|
|||
crate_paths,
|
||||
ItemType::AssocType,
|
||||
&[sym],
|
||||
None,
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
|
@ -199,7 +222,7 @@ pub(crate) fn build_index<'tcx>(
|
|||
primitives: &mut FxHashMap<Symbol, isize>,
|
||||
associated_types: &mut FxHashMap<Symbol, isize>,
|
||||
lastpathid: &mut isize,
|
||||
crate_paths: &mut Vec<(ItemType, Vec<Symbol>)>,
|
||||
crate_paths: &mut Vec<(ItemType, Vec<Symbol>, Option<Vec<Symbol>>)>,
|
||||
) {
|
||||
if let Some(generics) = &mut ty.generics {
|
||||
for item in generics {
|
||||
|
|
@ -296,7 +319,7 @@ pub(crate) fn build_index<'tcx>(
|
|||
}
|
||||
}
|
||||
|
||||
let Cache { ref paths, .. } = *cache;
|
||||
let Cache { ref paths, ref exact_paths, ref external_paths, .. } = *cache;
|
||||
|
||||
// Then, on parent modules
|
||||
let crate_items: Vec<&IndexItem> = search_index
|
||||
|
|
@ -311,7 +334,13 @@ pub(crate) fn build_index<'tcx>(
|
|||
lastpathid += 1;
|
||||
|
||||
if let Some(&(ref fqp, short)) = paths.get(&defid) {
|
||||
crate_paths.push((short, fqp.clone()));
|
||||
let exact_fqp = exact_paths
|
||||
.get(&defid)
|
||||
.or_else(|| external_paths.get(&defid).map(|&(ref fqp, _)| fqp))
|
||||
.filter(|exact_fqp| {
|
||||
exact_fqp.last() == Some(&item.name) && *exact_fqp != fqp
|
||||
});
|
||||
crate_paths.push((short, fqp.clone(), exact_fqp.cloned()));
|
||||
Some(pathid)
|
||||
} else {
|
||||
None
|
||||
|
|
@ -319,6 +348,42 @@ pub(crate) fn build_index<'tcx>(
|
|||
}
|
||||
});
|
||||
|
||||
if let Some(defid) = item.defid
|
||||
&& item.parent_idx.is_none()
|
||||
{
|
||||
// If this is a re-export, retain the original path.
|
||||
// Associated items don't use this.
|
||||
// Their parent carries the exact fqp instead.
|
||||
let exact_fqp = exact_paths
|
||||
.get(&defid)
|
||||
.or_else(|| external_paths.get(&defid).map(|&(ref fqp, _)| fqp));
|
||||
item.exact_path = exact_fqp.and_then(|fqp| {
|
||||
// Re-exports only count if the name is exactly the same.
|
||||
// This is a size optimization, since it means we only need
|
||||
// to store the name once (and the path is re-used for everything
|
||||
// exported from this same module). It's also likely to Do
|
||||
// What I Mean, since if a re-export changes the name, it might
|
||||
// also be a change in semantic meaning.
|
||||
if fqp.last() != Some(&item.name) {
|
||||
return None;
|
||||
}
|
||||
let path =
|
||||
if item.ty == ItemType::Macro && tcx.has_attr(defid, sym::macro_export) {
|
||||
// `#[macro_export]` always exports to the crate root.
|
||||
tcx.crate_name(defid.krate).to_string()
|
||||
} else {
|
||||
if fqp.len() < 2 {
|
||||
return None;
|
||||
}
|
||||
join_with_double_colon(&fqp[..fqp.len() - 1])
|
||||
};
|
||||
if path == item.path {
|
||||
return None;
|
||||
}
|
||||
Some(path)
|
||||
});
|
||||
}
|
||||
|
||||
// Omit the parent path if it is same to that of the prior item.
|
||||
if lastpath == &item.path {
|
||||
item.path.clear();
|
||||
|
|
@ -356,7 +421,7 @@ pub(crate) fn build_index<'tcx>(
|
|||
|
||||
struct CrateData<'a> {
|
||||
items: Vec<&'a IndexItem>,
|
||||
paths: Vec<(ItemType, Vec<Symbol>)>,
|
||||
paths: Vec<(ItemType, Vec<Symbol>, Option<Vec<Symbol>>)>,
|
||||
// The String is alias name and the vec is the list of the elements with this alias.
|
||||
//
|
||||
// To be noted: the `usize` elements are indexes to `items`.
|
||||
|
|
@ -374,6 +439,7 @@ pub(crate) fn build_index<'tcx>(
|
|||
ty: ItemType,
|
||||
name: Symbol,
|
||||
path: Option<usize>,
|
||||
exact_path: Option<usize>,
|
||||
}
|
||||
|
||||
impl Serialize for Paths {
|
||||
|
|
@ -387,6 +453,10 @@ pub(crate) fn build_index<'tcx>(
|
|||
if let Some(ref path) = self.path {
|
||||
seq.serialize_element(path)?;
|
||||
}
|
||||
if let Some(ref path) = self.exact_path {
|
||||
assert!(self.path.is_some());
|
||||
seq.serialize_element(path)?;
|
||||
}
|
||||
seq.end()
|
||||
}
|
||||
}
|
||||
|
|
@ -409,14 +479,39 @@ pub(crate) fn build_index<'tcx>(
|
|||
mod_paths.insert(&item.path, index);
|
||||
}
|
||||
let mut paths = Vec::with_capacity(self.paths.len());
|
||||
for (ty, path) in &self.paths {
|
||||
for (ty, path, exact) in &self.paths {
|
||||
if path.len() < 2 {
|
||||
paths.push(Paths { ty: *ty, name: path[0], path: None });
|
||||
paths.push(Paths { ty: *ty, name: path[0], path: None, exact_path: None });
|
||||
continue;
|
||||
}
|
||||
let full_path = join_with_double_colon(&path[..path.len() - 1]);
|
||||
let full_exact_path = exact
|
||||
.as_ref()
|
||||
.filter(|exact| exact.last() == path.last() && exact.len() >= 2)
|
||||
.map(|exact| join_with_double_colon(&exact[..exact.len() - 1]));
|
||||
let exact_path = extra_paths.len() + self.items.len();
|
||||
let exact_path = full_exact_path.as_ref().map(|full_exact_path| match extra_paths
|
||||
.entry(full_exact_path.clone())
|
||||
{
|
||||
Entry::Occupied(entry) => *entry.get(),
|
||||
Entry::Vacant(entry) => {
|
||||
if let Some(index) = mod_paths.get(&full_exact_path) {
|
||||
return *index;
|
||||
}
|
||||
entry.insert(exact_path);
|
||||
if !revert_extra_paths.contains_key(&exact_path) {
|
||||
revert_extra_paths.insert(exact_path, full_exact_path.clone());
|
||||
}
|
||||
exact_path
|
||||
}
|
||||
});
|
||||
if let Some(index) = mod_paths.get(&full_path) {
|
||||
paths.push(Paths { ty: *ty, name: *path.last().unwrap(), path: Some(*index) });
|
||||
paths.push(Paths {
|
||||
ty: *ty,
|
||||
name: *path.last().unwrap(),
|
||||
path: Some(*index),
|
||||
exact_path,
|
||||
});
|
||||
continue;
|
||||
}
|
||||
// It means it comes from an external crate so the item and its path will be
|
||||
|
|
@ -424,28 +519,54 @@ pub(crate) fn build_index<'tcx>(
|
|||
//
|
||||
// `index` is put after the last `mod_paths`
|
||||
let index = extra_paths.len() + self.items.len();
|
||||
if !revert_extra_paths.contains_key(&index) {
|
||||
revert_extra_paths.insert(index, full_path.clone());
|
||||
}
|
||||
match extra_paths.entry(full_path) {
|
||||
match extra_paths.entry(full_path.clone()) {
|
||||
Entry::Occupied(entry) => {
|
||||
paths.push(Paths {
|
||||
ty: *ty,
|
||||
name: *path.last().unwrap(),
|
||||
path: Some(*entry.get()),
|
||||
exact_path,
|
||||
});
|
||||
}
|
||||
Entry::Vacant(entry) => {
|
||||
entry.insert(index);
|
||||
if !revert_extra_paths.contains_key(&index) {
|
||||
revert_extra_paths.insert(index, full_path);
|
||||
}
|
||||
paths.push(Paths {
|
||||
ty: *ty,
|
||||
name: *path.last().unwrap(),
|
||||
path: Some(index),
|
||||
exact_path,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Direct exports use adjacent arrays for the current crate's items,
|
||||
// but re-exported exact paths don't.
|
||||
let mut re_exports = Vec::new();
|
||||
for (item_index, item) in self.items.iter().enumerate() {
|
||||
if let Some(exact_path) = item.exact_path.as_ref() {
|
||||
if let Some(path_index) = mod_paths.get(&exact_path) {
|
||||
re_exports.push((item_index, *path_index));
|
||||
} else {
|
||||
let path_index = extra_paths.len() + self.items.len();
|
||||
let path_index = match extra_paths.entry(exact_path.clone()) {
|
||||
Entry::Occupied(entry) => *entry.get(),
|
||||
Entry::Vacant(entry) => {
|
||||
entry.insert(path_index);
|
||||
if !revert_extra_paths.contains_key(&path_index) {
|
||||
revert_extra_paths.insert(path_index, exact_path.clone());
|
||||
}
|
||||
path_index
|
||||
}
|
||||
};
|
||||
re_exports.push((item_index, path_index));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut names = Vec::with_capacity(self.items.len());
|
||||
let mut types = String::with_capacity(self.items.len());
|
||||
let mut full_paths = Vec::with_capacity(self.items.len());
|
||||
|
|
@ -501,6 +622,7 @@ pub(crate) fn build_index<'tcx>(
|
|||
crate_data.serialize_field("f", &functions)?;
|
||||
crate_data.serialize_field("D", &self.desc_index)?;
|
||||
crate_data.serialize_field("p", &paths)?;
|
||||
crate_data.serialize_field("r", &re_exports)?;
|
||||
crate_data.serialize_field("b", &self.associated_item_disambiguators)?;
|
||||
crate_data.serialize_field("c", &bitmap_to_string(&deprecated))?;
|
||||
crate_data.serialize_field("e", &bitmap_to_string(&self.empty_desc))?;
|
||||
|
|
|
|||
|
|
@ -1627,24 +1627,27 @@ a.tooltip:hover::after {
|
|||
color: var(--copy-path-button-color);
|
||||
background: var(--main-background-color);
|
||||
height: 34px;
|
||||
width: 33px;
|
||||
margin-left: 10px;
|
||||
padding: 0;
|
||||
padding-left: 2px;
|
||||
border: 0;
|
||||
width: 33px;
|
||||
line-height: 0;
|
||||
font-size: 0;
|
||||
}
|
||||
|
||||
#copy-path:before {
|
||||
#copy-path::before {
|
||||
filter: var(--copy-path-img-filter);
|
||||
content: url('clipboard-24048e6d87f63d07.svg');
|
||||
width: 19px;
|
||||
height: 18px;
|
||||
}
|
||||
#copy-path:hover:before {
|
||||
#copy-path:hover::before {
|
||||
filter: var(--copy-path-img-hover-filter);
|
||||
}
|
||||
#copy-path.clicked::before {
|
||||
/* Checkmark <https://www.svgrepo.com/svg/335033/checkmark> */
|
||||
content: url('data:image/svg+xml,<svg viewBox="-1 -1 23 23" xmlns="http://www.w3.org/2000/svg" \
|
||||
fill="black" height="18px">\
|
||||
<g><path d="M9 19.414l-6.707-6.707 1.414-1.414L9 16.586 20.293 5.293l1.414 1.414"></path>\
|
||||
</g></svg>');
|
||||
}
|
||||
|
||||
@keyframes rotating {
|
||||
from {
|
||||
|
|
|
|||
|
|
@ -239,20 +239,27 @@ let FunctionType;
|
|||
* `doc` contains the description of the crate.
|
||||
*
|
||||
* `p` is a list of path/type pairs. It is used for parents and function parameters.
|
||||
* The first item is the type, the second is the name, the third is the visible path (if any) and
|
||||
* the fourth is the canonical path used for deduplication (if any).
|
||||
*
|
||||
* `r` is the canonical path used for deduplication of re-exported items.
|
||||
* It is not used for associated items like methods (that's the fourth element
|
||||
* of `p`) but is used for modules items like free functions.
|
||||
*
|
||||
* `c` is an array of item indices that are deprecated.
|
||||
* @typedef {{
|
||||
* doc: string,
|
||||
* a: Object,
|
||||
* n: Array<string>,
|
||||
* t: String,
|
||||
* t: string,
|
||||
* d: Array<string>,
|
||||
* q: Array<[Number, string]>,
|
||||
* i: Array<Number>,
|
||||
* q: Array<[number, string]>,
|
||||
* i: Array<number>,
|
||||
* f: string,
|
||||
* p: Array<Object>,
|
||||
* b: Array<[Number, String]>,
|
||||
* c: Array<Number>
|
||||
* p: Array<[number, string] | [number, string, number] | [number, string, number, number]>,
|
||||
* b: Array<[number, String]>,
|
||||
* c: Array<number>,
|
||||
* r: Array<[number, number]>,
|
||||
* }}
|
||||
*/
|
||||
let RawSearchIndexCrate;
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue