Skip to content

Rollup of 9 pull requests #105218

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 51 commits into from
Dec 4, 2022
Merged
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
b6ae82b
replace 'locally built rustc' instructions by 'Miri in rustc'
RalfJung Nov 27, 2022
a0d104d
refactor scheduling of TLS dtors
RalfJung Nov 27, 2022
0849084
cleanup global imports a bit
RalfJung Nov 27, 2022
ec003fd
yield the main thread a number of times after its TLS dtors are done
RalfJung Nov 27, 2022
c9b9c17
add scoped thread test
RalfJung Nov 27, 2022
5238d17
fix TLS on partially supported OSes
RalfJung Nov 27, 2022
af92b04
move interpreter loop into thread manager; they are pretty tightly co…
RalfJung Nov 27, 2022
ad9784e
make ./miri run a bit more silent; add option to control seeds tested…
RalfJung Nov 28, 2022
63eae2b
add many-seeds capabilities to CI
RalfJung Nov 28, 2022
8f705e2
Keep track of the start of the argument block of a closure
SarthakSingh31 Nov 9, 2022
5c2592c
Auto merge of #2698 - RalfJung:miri-in-rustc, r=oli-obk
bors Nov 28, 2022
ef5d5e7
decreasw yield count a bit and explain reasoning a bit more
RalfJung Nov 28, 2022
623b4ab
Auto merge of #2699 - RalfJung:schedule-refactor, r=RalfJung
bors Dec 1, 2022
e8ff9b1
Bump ui_test crate
oli-obk Dec 1, 2022
4a12a13
Auto merge of #2707 - oli-obk:ui_test_bump, r=RalfJung
bors Dec 1, 2022
f2b97a8
Remove useless borrows and derefs
WaffleLapkin Nov 29, 2022
083ef45
`rustc_data_structures` deref in a more humane way
WaffleLapkin Nov 29, 2022
e590258
Create a hacky fail-fast mode that stops tests at the first failure
oli-obk Dec 1, 2022
dc45eb9
Revert 88f2140
compiler-errors Dec 2, 2022
2d42d26
extract common borrow tracking logic
Vanille-N Dec 2, 2022
2528f4e
move stacked_borrows to borrow_tracker/stacked_borrows
Vanille-N Dec 2, 2022
3a01493
SbTag -> BorTag everywhere
Vanille-N Dec 2, 2022
8bb3d9e
other renames, introduction of BorrowTrackerMethod and AllocExtra
Vanille-N Dec 2, 2022
ab08f2a
fix imports
Vanille-N Dec 2, 2022
90118a1
Auto merge of #2697 - Vanille-N:borrow-tracking, r=RalfJung
bors Dec 2, 2022
5fd4b84
forward verbosity to cargo setup
RalfJung Dec 2, 2022
89dd322
Auto merge of #2708 - RalfJung:verbose-setup, r=RalfJung
bors Dec 2, 2022
595490e
slight simplifications for borrow tracking
RalfJung Dec 2, 2022
b12ce55
rename some more types for consistency
RalfJung Dec 2, 2022
0d1e365
fix ICE in pointer tracking
RalfJung Dec 2, 2022
4a64902
Auto merge of #2711 - RalfJung:btrack, r=RalfJung
bors Dec 2, 2022
7d75cc4
Auto merge of #2710 - RalfJung:ptr-tracking-ice, r=oli-obk
bors Dec 2, 2022
80ab672
Preparing for merge from rustc
RalfJung Dec 2, 2022
b64d867
Merge from rustc
RalfJung Dec 2, 2022
c955add
Disable coverage instrumentation for naked functions
tmiasko Dec 2, 2022
b740cdc
Mark naked functions as never inline in codegen_fn_attrs
tmiasko Dec 2, 2022
59cc6cd
Remove useless filter in unused extern crate check.
cjgillot Dec 3, 2022
e973240
Do not call fn_sig on non-functions.
cjgillot Dec 3, 2022
29814f2
clippy
RalfJung Dec 3, 2022
840f227
Auto merge of #2712 - RalfJung:rustup, r=RalfJung
bors Dec 3, 2022
795b2af
fix #105069, Add AmbiguityError for inconsistent resolution for an im…
chenyukang Dec 3, 2022
229e65a
update lockfile
RalfJung Dec 3, 2022
c89bff2
Rollup merge of #104199 - SarthakSingh31:issue-97417-1, r=cjgillot
matthiaskrgr Dec 3, 2022
1a2f79b
Rollup merge of #105050 - WaffleLapkin:uselessrefign, r=jyn514
matthiaskrgr Dec 3, 2022
6f0a2ad
Rollup merge of #105153 - oli-obk:fail_faster, r=compiler-errors
matthiaskrgr Dec 3, 2022
a739fc8
Rollup merge of #105164 - compiler-errors:revert-import-filter, r=est…
matthiaskrgr Dec 3, 2022
ed9a21e
Rollup merge of #105193 - tmiasko:naked-nocoverage, r=wesleywiser
matthiaskrgr Dec 3, 2022
b1e6806
Rollup merge of #105200 - cjgillot:issue-104562, r=compiler-errors
matthiaskrgr Dec 3, 2022
f91fa51
Rollup merge of #105201 - cjgillot:issue-105040, r=compiler-errors
matthiaskrgr Dec 3, 2022
af8f722
Rollup merge of #105208 - chenyukang:yukang/fix-105069, r=cjgillot
matthiaskrgr Dec 3, 2022
8be329d
Rollup merge of #105214 - RalfJung:miri, r=RalfJung
matthiaskrgr Dec 3, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Cargo.lock
Original file line number Diff line number Diff line change
@@ -5346,9 +5346,9 @@ checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c"

[[package]]
name = "ui_test"
version = "0.4.0"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf4559da3fe6b481f8674a29379677cb9606cd6f75fc254a2c9834c55638503d"
checksum = "54ddb6f31025943e2f9d59237f433711c461a43d9415974c3eb3a4902edc1c1f"
dependencies = [
"bstr 1.0.1",
"cargo_metadata 0.15.0",
10 changes: 5 additions & 5 deletions compiler/rustc_abi/src/layout.rs
Original file line number Diff line number Diff line change
@@ -354,7 +354,7 @@ pub trait LayoutCalculator {
if !always_sized { StructKind::MaybeUnsized } else { StructKind::AlwaysSized }
};

let mut st = self.univariant(dl, &variants[v], &repr, kind)?;
let mut st = self.univariant(dl, &variants[v], repr, kind)?;
st.variants = Variants::Single { index: v };

if is_unsafe_cell {
@@ -457,7 +457,7 @@ pub trait LayoutCalculator {
let mut variant_layouts = variants
.iter_enumerated()
.map(|(j, v)| {
let mut st = self.univariant(dl, v, &repr, StructKind::AlwaysSized)?;
let mut st = self.univariant(dl, v, repr, StructKind::AlwaysSized)?;
st.variants = Variants::Single { index: j };

align = align.max(st.align);
@@ -647,8 +647,8 @@ pub trait LayoutCalculator {
.map(|(i, field_layouts)| {
let mut st = self.univariant(
dl,
&field_layouts,
&repr,
field_layouts,
repr,
StructKind::Prefixed(min_ity.size(), prefix_align),
)?;
st.variants = Variants::Single { index: i };
@@ -755,7 +755,7 @@ pub trait LayoutCalculator {
// Try to use a ScalarPair for all tagged enums.
let mut common_prim = None;
let mut common_prim_initialized_in_all_variants = true;
for (field_layouts, layout_variant) in iter::zip(&*variants, &layout_variants) {
for (field_layouts, layout_variant) in iter::zip(variants, &layout_variants) {
let FieldsShape::Arbitrary { ref offsets, .. } = layout_variant.fields else {
panic!();
};
8 changes: 5 additions & 3 deletions compiler/rustc_ast/src/ast.rs
Original file line number Diff line number Diff line change
@@ -1179,7 +1179,7 @@ impl Expr {
pub fn peel_parens(&self) -> &Expr {
let mut expr = self;
while let ExprKind::Paren(inner) = &expr.kind {
expr = &inner;
expr = inner;
}
expr
}
@@ -1312,8 +1312,10 @@ pub struct Closure {
pub movability: Movability,
pub fn_decl: P<FnDecl>,
pub body: P<Expr>,
/// The span of the argument block `|...|`.
/// The span of the declaration block: 'move |...| -> ...'
pub fn_decl_span: Span,
/// The span of the argument block `|...|`
pub fn_arg_span: Span,
}

/// Limit types of a range (inclusive or exclusive)
@@ -2027,7 +2029,7 @@ impl Ty {
pub fn peel_refs(&self) -> &Self {
let mut final_ty = self;
while let TyKind::Rptr(_, MutTy { ty, .. }) = &final_ty.kind {
final_ty = &ty;
final_ty = ty;
}
final_ty
}
4 changes: 2 additions & 2 deletions compiler/rustc_ast/src/mut_visit.rs
Original file line number Diff line number Diff line change
@@ -736,8 +736,7 @@ pub fn visit_token<T: MutVisitor>(t: &mut Token, vis: &mut T) {
return; // Avoid visiting the span for the second time.
}
token::Interpolated(nt) => {
let mut nt = Lrc::make_mut(nt);
visit_nonterminal(&mut nt, vis);
visit_nonterminal(Lrc::make_mut(nt), vis);
}
_ => {}
}
@@ -1368,6 +1367,7 @@ pub fn noop_visit_expr<T: MutVisitor>(
fn_decl,
body,
fn_decl_span,
fn_arg_span: _,
}) => {
vis.visit_closure_binder(binder);
vis.visit_asyncness(asyncness);
8 changes: 4 additions & 4 deletions compiler/rustc_ast/src/tokenstream.rs
Original file line number Diff line number Diff line change
@@ -64,7 +64,7 @@ impl TokenTree {
match (self, other) {
(TokenTree::Token(token, _), TokenTree::Token(token2, _)) => token.kind == token2.kind,
(TokenTree::Delimited(_, delim, tts), TokenTree::Delimited(_, delim2, tts2)) => {
delim == delim2 && tts.eq_unspanned(&tts2)
delim == delim2 && tts.eq_unspanned(tts2)
}
_ => false,
}
@@ -402,7 +402,7 @@ impl TokenStream {
let mut t1 = self.trees();
let mut t2 = other.trees();
for (t1, t2) in iter::zip(&mut t1, &mut t2) {
if !t1.eq_unspanned(&t2) {
if !t1.eq_unspanned(t2) {
return false;
}
}
@@ -475,7 +475,7 @@ impl TokenStream {
token::Interpolated(nt) => TokenTree::Delimited(
DelimSpan::from_single(token.span),
Delimiter::Invisible,
TokenStream::from_nonterminal_ast(&nt).flattened(),
TokenStream::from_nonterminal_ast(nt).flattened(),
),
_ => TokenTree::Token(token.clone(), spacing),
}
@@ -511,7 +511,7 @@ impl TokenStream {
fn try_glue_to_last(vec: &mut Vec<TokenTree>, tt: &TokenTree) -> bool {
if let Some(TokenTree::Token(last_tok, Spacing::Joint)) = vec.last()
&& let TokenTree::Token(tok, spacing) = tt
&& let Some(glued_tok) = last_tok.glue(&tok)
&& let Some(glued_tok) = last_tok.glue(tok)
{
// ...then overwrite the last token tree in `vec` with the
// glued token, and skip the first token tree from `stream`.
4 changes: 2 additions & 2 deletions compiler/rustc_ast/src/util/comments.rs
Original file line number Diff line number Diff line change
@@ -110,7 +110,7 @@ pub fn beautify_doc_string(data: Symbol, kind: CommentKind) -> Symbol {
} else {
&mut lines
};
if let Some(horizontal) = get_horizontal_trim(&lines, kind) {
if let Some(horizontal) = get_horizontal_trim(lines, kind) {
changes = true;
// remove a "[ \t]*\*" block from each line, if possible
for line in lines.iter_mut() {
@@ -147,7 +147,7 @@ fn all_whitespace(s: &str, col: CharPos) -> Option<usize> {

fn trim_whitespace_prefix(s: &str, col: CharPos) -> &str {
let len = s.len();
match all_whitespace(&s, col) {
match all_whitespace(s, col) {
Some(col) => {
if col < len {
&s[col..]
10 changes: 5 additions & 5 deletions compiler/rustc_ast/src/util/literal.rs
Original file line number Diff line number Diff line change
@@ -52,14 +52,14 @@ impl LitKind {
// new symbol because the string in the LitKind is different to the
// string in the token.
let s = symbol.as_str();
let symbol = if s.contains(&['\\', '\r']) {
let symbol = if s.contains(['\\', '\r']) {
let mut buf = String::with_capacity(s.len());
let mut error = Ok(());
// Force-inlining here is aggressive but the closure is
// called on every char in the string, so it can be
// hot in programs with many long strings.
unescape_literal(
&s,
s,
Mode::Str,
&mut #[inline(always)]
|_, unescaped_char| match unescaped_char {
@@ -85,7 +85,7 @@ impl LitKind {
if s.contains('\r') {
let mut buf = String::with_capacity(s.len());
let mut error = Ok(());
unescape_literal(&s, Mode::RawStr, &mut |_, unescaped_char| {
unescape_literal(s, Mode::RawStr, &mut |_, unescaped_char| {
match unescaped_char {
Ok(c) => buf.push(c),
Err(err) => {
@@ -106,7 +106,7 @@ impl LitKind {
let s = symbol.as_str();
let mut buf = Vec::with_capacity(s.len());
let mut error = Ok(());
unescape_literal(&s, Mode::ByteStr, &mut |_, c| match c {
unescape_literal(s, Mode::ByteStr, &mut |_, c| match c {
Ok(c) => buf.push(byte_from_char(c)),
Err(err) => {
if err.is_fatal() {
@@ -122,7 +122,7 @@ impl LitKind {
let bytes = if s.contains('\r') {
let mut buf = Vec::with_capacity(s.len());
let mut error = Ok(());
unescape_literal(&s, Mode::RawByteStr, &mut |_, c| match c {
unescape_literal(s, Mode::RawByteStr, &mut |_, c| match c {
Ok(c) => buf.push(byte_from_char(c)),
Err(err) => {
if err.is_fatal() {
6 changes: 3 additions & 3 deletions compiler/rustc_ast/src/util/parser.rs
Original file line number Diff line number Diff line change
@@ -384,7 +384,7 @@ pub fn contains_exterior_struct_lit(value: &ast::Expr) -> bool {
| ast::ExprKind::AssignOp(_, lhs, rhs)
| ast::ExprKind::Binary(_, lhs, rhs) => {
// X { y: 1 } + X { y: 2 }
contains_exterior_struct_lit(&lhs) || contains_exterior_struct_lit(&rhs)
contains_exterior_struct_lit(lhs) || contains_exterior_struct_lit(rhs)
}
ast::ExprKind::Await(x)
| ast::ExprKind::Unary(_, x)
@@ -393,12 +393,12 @@ pub fn contains_exterior_struct_lit(value: &ast::Expr) -> bool {
| ast::ExprKind::Field(x, _)
| ast::ExprKind::Index(x, _) => {
// &X { y: 1 }, X { y: 1 }.y
contains_exterior_struct_lit(&x)
contains_exterior_struct_lit(x)
}

ast::ExprKind::MethodCall(box ast::MethodCall { receiver, .. }) => {
// X { y: 1 }.bar(...)
contains_exterior_struct_lit(&receiver)
contains_exterior_struct_lit(receiver)
}

_ => false,
2 changes: 1 addition & 1 deletion compiler/rustc_ast/src/util/unicode.rs
Original file line number Diff line number Diff line change
@@ -17,7 +17,7 @@ pub fn contains_text_flow_control_chars(s: &str) -> bool {
// U+2069 - E2 81 A9
let mut bytes = s.as_bytes();
loop {
match core::slice::memchr::memchr(0xE2, &bytes) {
match core::slice::memchr::memchr(0xE2, bytes) {
Some(idx) => {
// bytes are valid UTF-8 -> E2 must be followed by two bytes
let ch = &bytes[idx..idx + 3];
1 change: 1 addition & 0 deletions compiler/rustc_ast/src/visit.rs
Original file line number Diff line number Diff line change
@@ -840,6 +840,7 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) {
fn_decl,
body,
fn_decl_span: _,
fn_arg_span: _,
}) => {
visitor.visit_fn(FnKind::Closure(binder, fn_decl, body), expression.span, expression.id)
}
8 changes: 8 additions & 0 deletions compiler/rustc_ast_lowering/src/expr.rs
Original file line number Diff line number Diff line change
@@ -176,6 +176,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
fn_decl,
body,
fn_decl_span,
fn_arg_span,
}) => {
if let Async::Yes { closure_id, .. } = asyncness {
self.lower_expr_async_closure(
@@ -186,6 +187,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
fn_decl,
body,
*fn_decl_span,
*fn_arg_span,
)
} else {
self.lower_expr_closure(
@@ -196,6 +198,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
fn_decl,
body,
*fn_decl_span,
*fn_arg_span,
)
}
}
@@ -642,6 +645,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
fn_decl,
body,
fn_decl_span: self.lower_span(span),
fn_arg_span: None,
movability: Some(hir::Movability::Static),
});

@@ -898,6 +902,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
decl: &FnDecl,
body: &Expr,
fn_decl_span: Span,
fn_arg_span: Span,
) -> hir::ExprKind<'hir> {
let (binder_clause, generic_params) = self.lower_closure_binder(binder);

@@ -928,6 +933,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
fn_decl,
body: body_id,
fn_decl_span: self.lower_span(fn_decl_span),
fn_arg_span: Some(self.lower_span(fn_arg_span)),
movability: generator_option,
});

@@ -984,6 +990,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
decl: &FnDecl,
body: &Expr,
fn_decl_span: Span,
fn_arg_span: Span,
) -> hir::ExprKind<'hir> {
if let &ClosureBinder::For { span, .. } = binder {
self.tcx.sess.emit_err(NotSupportedForLifetimeBinderAsyncClosure { span });
@@ -1038,6 +1045,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
fn_decl,
body,
fn_decl_span: self.lower_span(fn_decl_span),
fn_arg_span: Some(self.lower_span(fn_arg_span)),
movability: None,
});
hir::ExprKind::Closure(c)
24 changes: 12 additions & 12 deletions compiler/rustc_ast_pretty/src/pprust/state.rs
Original file line number Diff line number Diff line change
@@ -519,7 +519,7 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
ast::MetaItemKind::List(items) => {
self.print_path(&item.path, false, 0);
self.popen();
self.commasep(Consistent, &items, |s, i| s.print_meta_list_item(i));
self.commasep(Consistent, items, |s, i| s.print_meta_list_item(i));
self.pclose();
}
}
@@ -536,7 +536,7 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
fn print_tt(&mut self, tt: &TokenTree, convert_dollar_crate: bool) {
match tt {
TokenTree::Token(token, _) => {
let token_str = self.token_to_string_ext(&token, convert_dollar_crate);
let token_str = self.token_to_string_ext(token, convert_dollar_crate);
self.word(token_str);
if let token::DocComment(..) = token.kind {
self.hardbreak()
@@ -998,7 +998,7 @@ impl<'a> State<'a> {
ast::AssocConstraintKind::Bound { bounds } => {
if !bounds.is_empty() {
self.word_nbsp(":");
self.print_type_bounds(&bounds);
self.print_type_bounds(bounds);
}
}
}
@@ -1035,7 +1035,7 @@ impl<'a> State<'a> {
}
ast::TyKind::Tup(elts) => {
self.popen();
self.commasep(Inconsistent, &elts, |s, ty| s.print_type(ty));
self.commasep(Inconsistent, elts, |s, ty| s.print_type(ty));
if elts.len() == 1 {
self.word(",");
}
@@ -1254,7 +1254,7 @@ impl<'a> State<'a> {

self.popen();
self.commasep(Consistent, &args, |s, arg| match arg {
AsmArg::Template(template) => s.print_string(&template, ast::StrStyle::Cooked),
AsmArg::Template(template) => s.print_string(template, ast::StrStyle::Cooked),
AsmArg::Operand(op) => {
let print_reg_or_class = |s: &mut Self, r: &InlineAsmRegOrRegClass| match r {
InlineAsmRegOrRegClass::Reg(r) => s.print_symbol(*r, ast::StrStyle::Cooked),
@@ -1424,11 +1424,11 @@ impl<'a> State<'a> {
self.print_path(path, true, 0);
}
self.popen();
self.commasep(Inconsistent, &elts, |s, p| s.print_pat(p));
self.commasep(Inconsistent, elts, |s, p| s.print_pat(p));
self.pclose();
}
PatKind::Or(pats) => {
self.strsep("|", true, Inconsistent, &pats, |s, p| s.print_pat(p));
self.strsep("|", true, Inconsistent, pats, |s, p| s.print_pat(p));
}
PatKind::Path(None, path) => {
self.print_path(path, true, 0);
@@ -1450,7 +1450,7 @@ impl<'a> State<'a> {
}
self.commasep_cmnt(
Consistent,
&fields,
fields,
|s, f| {
s.cbox(INDENT_UNIT);
if !f.is_shorthand {
@@ -1475,7 +1475,7 @@ impl<'a> State<'a> {
}
PatKind::Tuple(elts) => {
self.popen();
self.commasep(Inconsistent, &elts, |s, p| s.print_pat(p));
self.commasep(Inconsistent, elts, |s, p| s.print_pat(p));
if elts.len() == 1 {
self.word(",");
}
@@ -1498,7 +1498,7 @@ impl<'a> State<'a> {
self.print_pat(inner);
}
}
PatKind::Lit(e) => self.print_expr(&**e),
PatKind::Lit(e) => self.print_expr(e),
PatKind::Range(begin, end, Spanned { node: end_kind, .. }) => {
if let Some(e) = begin {
self.print_expr(e);
@@ -1514,7 +1514,7 @@ impl<'a> State<'a> {
}
PatKind::Slice(elts) => {
self.word("[");
self.commasep(Inconsistent, &elts, |s, p| s.print_pat(p));
self.commasep(Inconsistent, elts, |s, p| s.print_pat(p));
self.word("]");
}
PatKind::Rest => self.word(".."),
@@ -1600,7 +1600,7 @@ impl<'a> State<'a> {

self.word("<");

self.commasep(Inconsistent, &generic_params, |s, param| {
self.commasep(Inconsistent, generic_params, |s, param| {
s.print_outer_attributes_inline(&param.attrs);

match &param.kind {
7 changes: 4 additions & 3 deletions compiler/rustc_ast_pretty/src/pprust/state/expr.rs
Original file line number Diff line number Diff line change
@@ -305,10 +305,10 @@ impl<'a> State<'a> {
self.print_expr_tup(exprs);
}
ast::ExprKind::Call(func, args) => {
self.print_expr_call(func, &args);
self.print_expr_call(func, args);
}
ast::ExprKind::MethodCall(box ast::MethodCall { seg, receiver, args, .. }) => {
self.print_expr_method_call(seg, &receiver, &args);
self.print_expr_method_call(seg, receiver, args);
}
ast::ExprKind::Binary(op, lhs, rhs) => {
self.print_expr_binary(*op, lhs, rhs);
@@ -402,6 +402,7 @@ impl<'a> State<'a> {
fn_decl,
body,
fn_decl_span: _,
fn_arg_span: _,
}) => {
self.print_closure_binder(binder);
self.print_movability(*movability);
@@ -605,7 +606,7 @@ impl<'a> State<'a> {
match binder {
ast::ClosureBinder::NotPresent => {}
ast::ClosureBinder::For { generic_params, .. } => {
self.print_formal_generic_params(&generic_params)
self.print_formal_generic_params(generic_params)
}
}
}
13 changes: 6 additions & 7 deletions compiler/rustc_codegen_llvm/src/attributes.rs
Original file line number Diff line number Diff line change
@@ -258,13 +258,12 @@ pub fn from_fn_attrs<'ll, 'tcx>(
OptimizeAttr::Speed => {}
}

let inline = if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::NAKED) {
InlineAttr::Never
} else if codegen_fn_attrs.inline == InlineAttr::None && instance.def.requires_inline(cx.tcx) {
InlineAttr::Hint
} else {
codegen_fn_attrs.inline
};
let inline =
if codegen_fn_attrs.inline == InlineAttr::None && instance.def.requires_inline(cx.tcx) {
InlineAttr::Hint
} else {
codegen_fn_attrs.inline
};
to_add.extend(inline_attr(cx, inline));

// The `uwtable` attribute according to LLVM is:
4 changes: 2 additions & 2 deletions compiler/rustc_data_structures/src/intern.rs
Original file line number Diff line number Diff line change
@@ -72,7 +72,7 @@ impl<'a, T: PartialOrd> PartialOrd for Interned<'a, T> {
if ptr::eq(self.0, other.0) {
Some(Ordering::Equal)
} else {
let res = self.0.partial_cmp(&other.0);
let res = self.0.partial_cmp(other.0);
debug_assert_ne!(res, Some(Ordering::Equal));
res
}
@@ -86,7 +86,7 @@ impl<'a, T: Ord> Ord for Interned<'a, T> {
if ptr::eq(self.0, other.0) {
Ordering::Equal
} else {
let res = self.0.cmp(&other.0);
let res = self.0.cmp(other.0);
debug_assert_ne!(res, Ordering::Equal);
res
}
6 changes: 3 additions & 3 deletions compiler/rustc_data_structures/src/memmap.rs
Original file line number Diff line number Diff line change
@@ -36,7 +36,7 @@ impl Deref for Mmap {

#[inline]
fn deref(&self) -> &[u8] {
&*self.0
&self.0
}
}

@@ -96,13 +96,13 @@ impl Deref for MmapMut {

#[inline]
fn deref(&self) -> &[u8] {
&*self.0
&self.0
}
}

impl DerefMut for MmapMut {
#[inline]
fn deref_mut(&mut self) -> &mut [u8] {
&mut *self.0
&mut self.0
}
}
24 changes: 12 additions & 12 deletions compiler/rustc_data_structures/src/owning_ref/mod.rs
Original file line number Diff line number Diff line change
@@ -899,25 +899,25 @@ unsafe impl<O, T: ?Sized> StableAddress for OwningRef<O, T> {}

impl<O, T: ?Sized> AsRef<T> for OwningRef<O, T> {
fn as_ref(&self) -> &T {
&*self
self
}
}

impl<O, T: ?Sized> AsRef<T> for OwningRefMut<O, T> {
fn as_ref(&self) -> &T {
&*self
self
}
}

impl<O, T: ?Sized> AsMut<T> for OwningRefMut<O, T> {
fn as_mut(&mut self) -> &mut T {
&mut *self
self
}
}

impl<O, T: ?Sized> Borrow<T> for OwningRef<O, T> {
fn borrow(&self) -> &T {
&*self
self
}
}

@@ -1021,7 +1021,7 @@ where
T: PartialEq,
{
fn eq(&self, other: &Self) -> bool {
(&*self as &T).eq(&*other as &T)
self.deref().eq(other.deref())
}
}

@@ -1032,7 +1032,7 @@ where
T: PartialOrd,
{
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
(&*self as &T).partial_cmp(&*other as &T)
self.deref().partial_cmp(other.deref())
}
}

@@ -1041,7 +1041,7 @@ where
T: Ord,
{
fn cmp(&self, other: &Self) -> Ordering {
(&*self as &T).cmp(&*other as &T)
self.deref().cmp(other.deref())
}
}

@@ -1050,7 +1050,7 @@ where
T: Hash,
{
fn hash<H: Hasher>(&self, state: &mut H) {
(&*self as &T).hash(state);
self.deref().hash(state);
}
}

@@ -1059,7 +1059,7 @@ where
T: PartialEq,
{
fn eq(&self, other: &Self) -> bool {
(&*self as &T).eq(&*other as &T)
self.deref().eq(other.deref())
}
}

@@ -1070,7 +1070,7 @@ where
T: PartialOrd,
{
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
(&*self as &T).partial_cmp(&*other as &T)
self.deref().partial_cmp(other.deref())
}
}

@@ -1079,7 +1079,7 @@ where
T: Ord,
{
fn cmp(&self, other: &Self) -> Ordering {
(&*self as &T).cmp(&*other as &T)
self.deref().cmp(other.deref())
}
}

@@ -1088,7 +1088,7 @@ where
T: Hash,
{
fn hash<H: Hasher>(&self, state: &mut H) {
(&*self as &T).hash(state);
self.deref().hash(state);
}
}

6 changes: 3 additions & 3 deletions compiler/rustc_data_structures/src/profiling.rs
Original file line number Diff line number Diff line change
@@ -192,7 +192,7 @@ impl SelfProfilerRef {
F: for<'a> FnOnce(&'a SelfProfiler) -> TimingGuard<'a>,
{
let profiler = profiler_ref.profiler.as_ref().unwrap();
f(&**profiler)
f(profiler)
}

if self.event_filter_mask.contains(event_filter) {
@@ -466,7 +466,7 @@ impl SelfProfilerRef {

pub fn with_profiler(&self, f: impl FnOnce(&SelfProfiler)) {
if let Some(profiler) = &self.profiler {
f(&profiler)
f(profiler)
}
}

@@ -733,7 +733,7 @@ impl Drop for VerboseTimingGuard<'_> {
if let Some((start_time, start_rss, ref message)) = self.start_and_message {
let end_rss = get_resident_set_size();
let dur = start_time.elapsed();
print_time_passes_entry(&message, dur, start_rss, end_rss);
print_time_passes_entry(message, dur, start_rss, end_rss);
}
}
}
6 changes: 3 additions & 3 deletions compiler/rustc_data_structures/src/stable_hasher.rs
Original file line number Diff line number Diff line change
@@ -366,7 +366,7 @@ impl<CTX> HashStable<CTX> for [u8] {
impl<T: HashStable<CTX>, CTX> HashStable<CTX> for Vec<T> {
#[inline]
fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
(&self[..]).hash_stable(ctx, hasher);
self[..].hash_stable(ctx, hasher);
}
}

@@ -405,7 +405,7 @@ where
{
#[inline]
fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
(&self[..]).hash_stable(ctx, hasher);
self[..].hash_stable(ctx, hasher);
}
}

@@ -440,7 +440,7 @@ impl<CTX> HashStable<CTX> for str {
impl<CTX> HashStable<CTX> for String {
#[inline]
fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
(&self[..]).hash_stable(hcx, hasher);
self[..].hash_stable(hcx, hasher);
}
}

2 changes: 1 addition & 1 deletion compiler/rustc_data_structures/src/sync.rs
Original file line number Diff line number Diff line change
@@ -201,7 +201,7 @@ cfg_if! {

#[inline(always)]
fn deref(&self) -> &T {
&*self.0
&self.0
}
}

6 changes: 3 additions & 3 deletions compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs
Original file line number Diff line number Diff line change
@@ -39,7 +39,7 @@ impl Translate for AnnotateSnippetEmitterWriter {
}

fn fallback_fluent_bundle(&self) -> &FluentBundle {
&**self.fallback_bundle
&self.fallback_bundle
}
}

@@ -49,7 +49,7 @@ impl Emitter for AnnotateSnippetEmitterWriter {
let fluent_args = to_fluent_args(diag.args());

let mut children = diag.children.clone();
let (mut primary_span, suggestions) = self.primary_span_formatted(&diag, &fluent_args);
let (mut primary_span, suggestions) = self.primary_span_formatted(diag, &fluent_args);

self.fix_multispans_in_extern_macros_and_render_macro_backtrace(
&mut primary_span,
@@ -65,7 +65,7 @@ impl Emitter for AnnotateSnippetEmitterWriter {
&diag.code,
&primary_span,
&children,
&suggestions,
suggestions,
);
}

2 changes: 1 addition & 1 deletion compiler/rustc_errors/src/diagnostic.rs
Original file line number Diff line number Diff line change
@@ -292,7 +292,7 @@ impl Diagnostic {
let lint_index = expectation_id.get_lint_index();
expectation_id.set_lint_index(None);
let mut stable_id = unstable_to_stable
.get(&expectation_id)
.get(expectation_id)
.expect("each unstable `LintExpectationId` must have a matching stable id")
.normalize();

26 changes: 13 additions & 13 deletions compiler/rustc_errors/src/emitter.rs
Original file line number Diff line number Diff line change
@@ -283,7 +283,7 @@ pub trait Emitter: Translate {
if self
.source_map()
.map(|sm| is_case_difference(
&**sm,
sm,
substitution,
sugg.substitutions[0].parts[0].span,
))
@@ -525,7 +525,7 @@ impl Translate for EmitterWriter {
}

fn fallback_fluent_bundle(&self) -> &FluentBundle {
&**self.fallback_bundle
&self.fallback_bundle
}
}

@@ -538,7 +538,7 @@ impl Emitter for EmitterWriter {
let fluent_args = to_fluent_args(diag.args());

let mut children = diag.children.clone();
let (mut primary_span, suggestions) = self.primary_span_formatted(&diag, &fluent_args);
let (mut primary_span, suggestions) = self.primary_span_formatted(diag, &fluent_args);
debug!("emit_diagnostic: suggestions={:?}", suggestions);

self.fix_multispans_in_extern_macros_and_render_macro_backtrace(
@@ -555,7 +555,7 @@ impl Emitter for EmitterWriter {
&diag.code,
&primary_span,
&children,
&suggestions,
suggestions,
self.track_diagnostics.then_some(&diag.emitted_at),
);
}
@@ -801,7 +801,7 @@ impl EmitterWriter {
}

let source_string = match file.get_line(line.line_index - 1) {
Some(s) => normalize_whitespace(&*s),
Some(s) => normalize_whitespace(&s),
None => return Vec::new(),
};

@@ -1148,7 +1148,7 @@ impl EmitterWriter {
(pos + 2, annotation.start_col.saturating_sub(left))
};
if let Some(ref label) = annotation.label {
buffer.puts(line_offset + pos, code_offset + col, &label, style);
buffer.puts(line_offset + pos, code_offset + col, label, style);
}
}

@@ -1358,7 +1358,7 @@ impl EmitterWriter {
// only render error codes, not lint codes
if let Some(DiagnosticId::Error(ref code)) = *code {
buffer.append(0, "[", Style::Level(*level));
buffer.append(0, &code, Style::Level(*level));
buffer.append(0, code, Style::Level(*level));
buffer.append(0, "]", Style::Level(*level));
label_width += 2 + code.len();
}
@@ -1683,7 +1683,7 @@ impl EmitterWriter {
};

// Render the replacements for each suggestion
let suggestions = suggestion.splice_lines(&**sm);
let suggestions = suggestion.splice_lines(sm);
debug!("emit_suggestion_default: suggestions={:?}", suggestions);

if suggestions.is_empty() {
@@ -1784,7 +1784,7 @@ impl EmitterWriter {
buffer.puts(
row_num - 1 + line - line_start,
max_line_num_len + 3,
&normalize_whitespace(&*file_lines.file.get_line(line - 1).unwrap()),
&normalize_whitespace(&file_lines.file.get_line(line - 1).unwrap()),
Style::Removal,
);
}
@@ -1926,7 +1926,7 @@ impl EmitterWriter {
buffer.putc(
row_num,
(padding as isize + p) as usize,
if part.is_addition(&sm) { '+' } else { '~' },
if part.is_addition(sm) { '+' } else { '~' },
Style::Addition,
);
}
@@ -1973,7 +1973,7 @@ impl EmitterWriter {
buffer.puts(row_num, max_line_num_len + 3, &msg, Style::NoStyle);
} else if notice_capitalization {
let msg = "notice the capitalization difference";
buffer.puts(row_num, max_line_num_len + 3, &msg, Style::NoStyle);
buffer.puts(row_num, max_line_num_len + 3, msg, Style::NoStyle);
}
emit_to_destination(&buffer.render(), level, &mut self.dst, self.short_message)?;
Ok(())
@@ -2028,7 +2028,7 @@ impl EmitterWriter {
for child in children {
let span = child.render_span.as_ref().unwrap_or(&child.span);
if let Err(err) = self.emit_message_default(
&span,
span,
&child.message,
args,
&None,
@@ -2113,7 +2113,7 @@ impl EmitterWriter {
*row_num - 1,
max_line_num_len + 3,
&normalize_whitespace(
&*file_lines.file.get_line(file_lines.lines[line_pos].line_index).unwrap(),
&file_lines.file.get_line(file_lines.lines[line_pos].line_index).unwrap(),
),
Style::NoStyle,
);
2 changes: 1 addition & 1 deletion compiler/rustc_errors/src/json.rs
Original file line number Diff line number Diff line change
@@ -136,7 +136,7 @@ impl Translate for JsonEmitter {
}

fn fallback_fluent_bundle(&self) -> &FluentBundle {
&**self.fallback_bundle
&self.fallback_bundle
}
}

2 changes: 1 addition & 1 deletion compiler/rustc_errors/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1328,7 +1328,7 @@ impl HandlerInner {

diagnostic.children.drain_filter(already_emitted_sub).for_each(|_| {});

self.emitter.emit_diagnostic(&diagnostic);
self.emitter.emit_diagnostic(diagnostic);
if diagnostic.is_error() {
self.deduplicated_err_count += 1;
} else if let Warning(_) = diagnostic.level {
6 changes: 3 additions & 3 deletions compiler/rustc_errors/src/translation.rs
Original file line number Diff line number Diff line change
@@ -59,21 +59,21 @@ pub trait Translate {
trace!(?message, ?args);
let (identifier, attr) = match message {
DiagnosticMessage::Str(msg) | DiagnosticMessage::Eager(msg) => {
return Cow::Borrowed(&msg);
return Cow::Borrowed(msg);
}
DiagnosticMessage::FluentIdentifier(identifier, attr) => (identifier, attr),
};

let translate_with_bundle = |bundle: &'a FluentBundle| -> Option<(Cow<'_, str>, Vec<_>)> {
let message = bundle.get_message(&identifier)?;
let message = bundle.get_message(identifier)?;
let value = match attr {
Some(attr) => message.get_attribute(attr)?.value(),
None => message.value()?,
};
debug!(?message, ?value);

let mut errs = vec![];
let translated = bundle.format_pattern(value, Some(&args), &mut errs);
let translated = bundle.format_pattern(value, Some(args), &mut errs);
debug!(?translated, ?errs);
Some((translated, errs))
};
3 changes: 3 additions & 0 deletions compiler/rustc_expand/src/build.rs
Original file line number Diff line number Diff line change
@@ -539,6 +539,9 @@ impl<'a> ExtCtxt<'a> {
fn_decl,
body,
fn_decl_span: span,
// FIXME(SarthakSingh31): This points to the start of the declaration block and
// not the span of the argument block.
fn_arg_span: span,
})),
)
}
2 changes: 1 addition & 1 deletion compiler/rustc_fs_util/src/lib.rs
Original file line number Diff line number Diff line change
@@ -65,7 +65,7 @@ pub enum LinkOrCopy {
pub fn link_or_copy<P: AsRef<Path>, Q: AsRef<Path>>(p: P, q: Q) -> io::Result<LinkOrCopy> {
let p = p.as_ref();
let q = q.as_ref();
match fs::remove_file(&q) {
match fs::remove_file(q) {
Ok(()) => (),
Err(err) if err.kind() == io::ErrorKind::NotFound => (),
Err(err) => return Err(err),
6 changes: 3 additions & 3 deletions compiler/rustc_graphviz/src/lib.rs
Original file line number Diff line number Diff line change
@@ -410,7 +410,7 @@ impl<'a> Id<'a> {
}

pub fn as_slice(&'a self) -> &'a str {
&*self.name
&self.name
}
}

@@ -515,7 +515,7 @@ impl<'a> LabelText<'a> {
pub fn to_dot_string(&self) -> String {
match *self {
LabelStr(ref s) => format!("\"{}\"", s.escape_default()),
EscStr(ref s) => format!("\"{}\"", LabelText::escape_str(&s)),
EscStr(ref s) => format!("\"{}\"", LabelText::escape_str(s)),
HtmlStr(ref s) => format!("<{}>", s),
}
}
@@ -529,7 +529,7 @@ impl<'a> LabelText<'a> {
EscStr(s) => s,
LabelStr(s) => {
if s.contains('\\') {
(&*s).escape_default().to_string().into()
s.escape_default().to_string().into()
} else {
s
}
5 changes: 4 additions & 1 deletion compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
@@ -943,7 +943,10 @@ pub struct Closure<'hir> {
pub bound_generic_params: &'hir [GenericParam<'hir>],
pub fn_decl: &'hir FnDecl<'hir>,
pub body: BodyId,
/// The span of the declaration block: 'move |...| -> ...'
pub fn_decl_span: Span,
/// The span of the argument block `|...|`
pub fn_arg_span: Option<Span>,
pub movability: Option<Movability>,
}

@@ -2434,7 +2437,7 @@ impl<'hir> Ty<'hir> {
pub fn peel_refs(&self) -> &Self {
let mut final_ty = self;
while let TyKind::Rptr(_, MutTy { ty, .. }) = &final_ty.kind {
final_ty = &ty;
final_ty = ty;
}
final_ty
}
2 changes: 1 addition & 1 deletion compiler/rustc_hir/src/hir_id.rs
Original file line number Diff line number Diff line change
@@ -116,7 +116,7 @@ impl Ord for HirId {

impl PartialOrd for HirId {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
Some(self.cmp(&other))
Some(self.cmp(other))
}
}

37 changes: 19 additions & 18 deletions compiler/rustc_hir/src/intravisit.rs
Original file line number Diff line number Diff line change
@@ -448,7 +448,7 @@ pub trait Visitor<'v>: Sized {

pub fn walk_param<'v, V: Visitor<'v>>(visitor: &mut V, param: &'v Param<'v>) {
visitor.visit_id(param.hir_id);
visitor.visit_pat(&param.pat);
visitor.visit_pat(param.pat);
}

pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) {
@@ -470,7 +470,7 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) {
}
ItemKind::Fn(ref sig, ref generics, body_id) => visitor.visit_fn(
FnKind::ItemFn(item.ident, generics, sig.header),
&sig.decl,
sig.decl,
body_id,
item.span,
item.hir_id(),
@@ -544,7 +544,7 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) {

pub fn walk_body<'v, V: Visitor<'v>>(visitor: &mut V, body: &'v Body<'v>) {
walk_list!(visitor, visit_param, body.params);
visitor.visit_expr(&body.value);
visitor.visit_expr(body.value);
}

pub fn walk_ident<'v, V: Visitor<'v>>(visitor: &mut V, ident: Ident) {
@@ -580,7 +580,7 @@ pub fn walk_local<'v, V: Visitor<'v>>(visitor: &mut V, local: &'v Local<'v>) {
// dominates the local's definition.
walk_list!(visitor, visit_expr, &local.init);
visitor.visit_id(local.hir_id);
visitor.visit_pat(&local.pat);
visitor.visit_pat(local.pat);
if let Some(els) = local.els {
visitor.visit_block(els);
}
@@ -606,7 +606,7 @@ pub fn walk_stmt<'v, V: Visitor<'v>>(visitor: &mut V, statement: &'v Stmt<'v>) {

pub fn walk_arm<'v, V: Visitor<'v>>(visitor: &mut V, arm: &'v Arm<'v>) {
visitor.visit_id(arm.hir_id);
visitor.visit_pat(&arm.pat);
visitor.visit_pat(arm.pat);
if let Some(ref g) = arm.guard {
match g {
Guard::If(ref e) => visitor.visit_expr(e),
@@ -615,7 +615,7 @@ pub fn walk_arm<'v, V: Visitor<'v>>(visitor: &mut V, arm: &'v Arm<'v>) {
}
}
}
visitor.visit_expr(&arm.body);
visitor.visit_expr(arm.body);
}

pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat<'v>) {
@@ -660,7 +660,7 @@ pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat<'v>) {
pub fn walk_pat_field<'v, V: Visitor<'v>>(visitor: &mut V, field: &'v PatField<'v>) {
visitor.visit_id(field.hir_id);
visitor.visit_ident(field.ident);
visitor.visit_pat(&field.pat)
visitor.visit_pat(field.pat)
}

pub fn walk_array_len<'v, V: Visitor<'v>>(visitor: &mut V, len: &'v ArrayLen) {
@@ -740,6 +740,7 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>)
body,
capture_clause: _,
fn_decl_span: _,
fn_arg_span: _,
movability: _,
}) => {
walk_list!(visitor, visit_generic_param, bound_generic_params);
@@ -799,26 +800,26 @@ pub fn walk_let_expr<'v, V: Visitor<'v>>(visitor: &mut V, let_expr: &'v Let<'v>)
pub fn walk_expr_field<'v, V: Visitor<'v>>(visitor: &mut V, field: &'v ExprField<'v>) {
visitor.visit_id(field.hir_id);
visitor.visit_ident(field.ident);
visitor.visit_expr(&field.expr)
visitor.visit_expr(field.expr)
}

pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty<'v>) {
visitor.visit_id(typ.hir_id);

match typ.kind {
TyKind::Slice(ref ty) => visitor.visit_ty(ty),
TyKind::Ptr(ref mutable_type) => visitor.visit_ty(&mutable_type.ty),
TyKind::Ptr(ref mutable_type) => visitor.visit_ty(mutable_type.ty),
TyKind::Rptr(ref lifetime, ref mutable_type) => {
visitor.visit_lifetime(lifetime);
visitor.visit_ty(&mutable_type.ty)
visitor.visit_ty(mutable_type.ty)
}
TyKind::Never => {}
TyKind::Tup(tuple_element_types) => {
walk_list!(visitor, visit_ty, tuple_element_types);
}
TyKind::BareFn(ref function_declaration) => {
walk_list!(visitor, visit_generic_param, function_declaration.generic_params);
visitor.visit_fn_decl(&function_declaration.decl);
visitor.visit_fn_decl(function_declaration.decl);
}
TyKind::Path(ref qpath) => {
visitor.visit_qpath(qpath, typ.hir_id, typ.span);
@@ -951,8 +952,8 @@ pub fn walk_trait_item<'v, V: Visitor<'v>>(visitor: &mut V, trait_item: &'v Trai
let TraitItem { ident, generics, ref defaultness, ref kind, span, owner_id: _ } = *trait_item;
let hir_id = trait_item.hir_id();
visitor.visit_ident(ident);
visitor.visit_generics(&generics);
visitor.visit_defaultness(&defaultness);
visitor.visit_generics(generics);
visitor.visit_defaultness(defaultness);
match *kind {
TraitItemKind::Const(ref ty, default) => {
visitor.visit_id(hir_id);
@@ -961,13 +962,13 @@ pub fn walk_trait_item<'v, V: Visitor<'v>>(visitor: &mut V, trait_item: &'v Trai
}
TraitItemKind::Fn(ref sig, TraitFn::Required(param_names)) => {
visitor.visit_id(hir_id);
visitor.visit_fn_decl(&sig.decl);
visitor.visit_fn_decl(sig.decl);
for &param_name in param_names {
visitor.visit_ident(param_name);
}
}
TraitItemKind::Fn(ref sig, TraitFn::Provided(body_id)) => {
visitor.visit_fn(FnKind::Method(ident, sig), &sig.decl, body_id, span, hir_id);
visitor.visit_fn(FnKind::Method(ident, sig), sig.decl, body_id, span, hir_id);
}
TraitItemKind::Type(bounds, ref default) => {
visitor.visit_id(hir_id);
@@ -1009,7 +1010,7 @@ pub fn walk_impl_item<'v, V: Visitor<'v>>(visitor: &mut V, impl_item: &'v ImplIt
ImplItemKind::Fn(ref sig, body_id) => {
visitor.visit_fn(
FnKind::Method(impl_item.ident, sig),
&sig.decl,
sig.decl,
body_id,
impl_item.span,
impl_item.hir_id(),
@@ -1042,7 +1043,7 @@ pub fn walk_impl_item_ref<'v, V: Visitor<'v>>(visitor: &mut V, impl_item_ref: &'

pub fn walk_trait_ref<'v, V: Visitor<'v>>(visitor: &mut V, trait_ref: &'v TraitRef<'v>) {
visitor.visit_id(trait_ref.hir_ref_id);
visitor.visit_path(&trait_ref.path, trait_ref.hir_ref_id)
visitor.visit_path(trait_ref.path, trait_ref.hir_ref_id)
}

pub fn walk_param_bound<'v, V: Visitor<'v>>(visitor: &mut V, bound: &'v GenericBound<'v>) {
@@ -1074,7 +1075,7 @@ pub fn walk_struct_def<'v, V: Visitor<'v>>(
pub fn walk_field_def<'v, V: Visitor<'v>>(visitor: &mut V, field: &'v FieldDef<'v>) {
visitor.visit_id(field.hir_id);
visitor.visit_ident(field.ident);
visitor.visit_ty(&field.ty);
visitor.visit_ty(field.ty);
}

pub fn walk_enum_def<'v, V: Visitor<'v>>(
19 changes: 0 additions & 19 deletions compiler/rustc_hir_analysis/src/check_unused.rs
Original file line number Diff line number Diff line change
@@ -56,25 +56,6 @@ fn unused_crates_lint(tcx: TyCtxt<'_>) {
let unused_extern_crates: FxHashMap<LocalDefId, Span> = tcx
.maybe_unused_extern_crates(())
.iter()
.filter(|&&(def_id, _)| {
// The `def_id` here actually was calculated during resolution (at least
// at the time of this writing) and is being shipped to us via a side
// channel of the tcx. There may have been extra expansion phases,
// however, which ended up removing the `def_id` *after* expansion.
//
// As a result we need to verify that `def_id` is indeed still valid for
// our AST and actually present in the HIR map. If it's not there then
// there's safely nothing to warn about, and otherwise we carry on with
// our execution.
//
// Note that if we carry through to the `extern_mod_stmt_cnum` query
// below it'll cause a panic because `def_id` is actually bogus at this
// point in time otherwise.
if tcx.hir().find(tcx.hir().local_def_id_to_hir_id(def_id)).is_none() {
return false;
}
true
})
.filter(|&&(def_id, _)| {
tcx.extern_mod_stmt_cnum(def_id).map_or(true, |cnum| {
!tcx.is_compiler_builtins(cnum)
5 changes: 5 additions & 0 deletions compiler/rustc_hir_analysis/src/collect.rs
Original file line number Diff line number Diff line change
@@ -2073,6 +2073,11 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: DefId) -> CodegenFnAttrs {
}
}

if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::NAKED) {
codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_COVERAGE;
codegen_fn_attrs.inline = InlineAttr::Never;
}

// Weak lang items have the same semantics as "std internal" symbols in the
// sense that they're preserved through all our LTO passes and only
// strippable by the linker.
1 change: 1 addition & 0 deletions compiler/rustc_hir_pretty/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1480,6 +1480,7 @@ impl<'a> State<'a> {
fn_decl,
body,
fn_decl_span: _,
fn_arg_span: _,
movability: _,
def_id: _,
}) => {
10 changes: 6 additions & 4 deletions compiler/rustc_hir_typeck/src/closure.rs
Original file line number Diff line number Diff line change
@@ -456,10 +456,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
.iter()
.map(|ty| ArgKind::from_expected_ty(*ty, None))
.collect();
let (closure_span, found_args) = match self.get_fn_like_arguments(expr_map_node) {
Some((sp, args)) => (Some(sp), args),
None => (None, Vec::new()),
};
let (closure_span, closure_arg_span, found_args) =
match self.get_fn_like_arguments(expr_map_node) {
Some((sp, arg_sp, args)) => (Some(sp), arg_sp, args),
None => (None, None, Vec::new()),
};
let expected_span =
expected_sig.cause_span.unwrap_or_else(|| self.tcx.def_span(expr_def_id));
self.report_arg_count_mismatch(
@@ -468,6 +469,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
expected_args,
found_args,
true,
closure_arg_span,
)
.emit();

8 changes: 8 additions & 0 deletions compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
Original file line number Diff line number Diff line change
@@ -1918,6 +1918,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
receiver: Option<&'tcx hir::Expr<'tcx>>,
args: &'tcx [hir::Expr<'tcx>],
) -> bool {
// Do not call `fn_sig` on non-functions.
if !matches!(
self.tcx.def_kind(def_id),
DefKind::Fn | DefKind::AssocFn | DefKind::Variant | DefKind::Ctor(..)
) {
return false;
}

let sig = self.tcx.fn_sig(def_id).skip_binder();
let args_referencing_param: Vec<_> = sig
.inputs()
5 changes: 2 additions & 3 deletions compiler/rustc_hir_typeck/src/method/mod.rs
Original file line number Diff line number Diff line change
@@ -20,7 +20,7 @@ use rustc_hir::def_id::DefId;
use rustc_infer::infer::{self, InferOk};
use rustc_middle::traits::ObligationCause;
use rustc_middle::ty::subst::{InternalSubsts, SubstsRef};
use rustc_middle::ty::{self, DefIdTree, GenericParamDefKind, Ty, TypeVisitable};
use rustc_middle::ty::{self, GenericParamDefKind, Ty, TypeVisitable};
use rustc_span::symbol::Ident;
use rustc_span::Span;
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
@@ -217,7 +217,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}

// We probe again, taking all traits into account (not only those in scope).
let mut candidates =
let candidates =
match self.lookup_probe(segment.ident, self_ty, call_expr, ProbeScope::AllTraits) {
// If we find a different result the caller probably forgot to import a trait.
Ok(ref new_pick) if pick.differs_from(new_pick) => {
@@ -236,7 +236,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
.collect(),
_ => Vec::new(),
};
candidates.retain(|candidate| *candidate != self.tcx.parent(result.callee.def_id));

return Err(IllegalSizedBound(candidates, needs_mut, span));
}
26 changes: 13 additions & 13 deletions compiler/rustc_macros/src/diagnostics/diagnostic.rs
Original file line number Diff line number Diff line change
@@ -29,8 +29,8 @@ impl<'a> DiagnosticDerive<'a> {
let DiagnosticDerive { mut structure, mut builder } = self;

let implementation = builder.each_variant(&mut structure, |mut builder, variant| {
let preamble = builder.preamble(&variant);
let body = builder.body(&variant);
let preamble = builder.preamble(variant);
let body = builder.body(variant);

let diag = &builder.parent.diag;
let DiagnosticDeriveKind::Diagnostic { handler } = &builder.parent.kind else {
@@ -39,7 +39,7 @@ impl<'a> DiagnosticDerive<'a> {
let init = match builder.slug.value_ref() {
None => {
span_err(builder.span, "diagnostic slug not specified")
.help(&format!(
.help(format!(
"specify the slug as the first argument to the `#[diag(...)]` \
attribute, such as `#[diag(hir_analysis_example_error)]`",
))
@@ -48,10 +48,10 @@ impl<'a> DiagnosticDerive<'a> {
}
Some(slug) if let Some( Mismatch { slug_name, crate_name, slug_prefix }) = Mismatch::check(slug) => {
span_err(slug.span().unwrap(), "diagnostic slug and crate name do not match")
.note(&format!(
.note(format!(
"slug is `{slug_name}` but the crate name is `{crate_name}`"
))
.help(&format!(
.help(format!(
"expected a slug starting with `{slug_prefix}_...`"
))
.emit();
@@ -113,8 +113,8 @@ impl<'a> LintDiagnosticDerive<'a> {
let LintDiagnosticDerive { mut structure, mut builder } = self;

let implementation = builder.each_variant(&mut structure, |mut builder, variant| {
let preamble = builder.preamble(&variant);
let body = builder.body(&variant);
let preamble = builder.preamble(variant);
let body = builder.body(variant);

let diag = &builder.parent.diag;
let formatting_init = &builder.formatting_init;
@@ -128,28 +128,28 @@ impl<'a> LintDiagnosticDerive<'a> {

let msg = builder.each_variant(&mut structure, |mut builder, variant| {
// Collect the slug by generating the preamble.
let _ = builder.preamble(&variant);
let _ = builder.preamble(variant);

match builder.slug.value_ref() {
None => {
span_err(builder.span, "diagnostic slug not specified")
.help(&format!(
.help(format!(
"specify the slug as the first argument to the attribute, such as \
`#[diag(compiletest_example)]`",
))
.emit();
return DiagnosticDeriveError::ErrorHandled.to_compile_error();
DiagnosticDeriveError::ErrorHandled.to_compile_error()
}
Some(slug) if let Some( Mismatch { slug_name, crate_name, slug_prefix }) = Mismatch::check(slug) => {
span_err(slug.span().unwrap(), "diagnostic slug and crate name do not match")
.note(&format!(
.note(format!(
"slug is `{slug_name}` but the crate name is `{crate_name}`"
))
.help(&format!(
.help(format!(
"expected a slug starting with `{slug_prefix}_...`"
))
.emit();
return DiagnosticDeriveError::ErrorHandled.to_compile_error();
DiagnosticDeriveError::ErrorHandled.to_compile_error()
}
Some(slug) => {
quote! {
14 changes: 7 additions & 7 deletions compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs
Original file line number Diff line number Diff line change
@@ -100,7 +100,7 @@ impl DiagnosticDeriveBuilder {
_ => variant.ast().ident.span().unwrap(),
};
let builder = DiagnosticDeriveVariantBuilder {
parent: &self,
parent: self,
span,
field_map: build_field_mapping(variant),
formatting_init: TokenStream::new(),
@@ -211,7 +211,7 @@ impl<'a> DiagnosticDeriveVariantBuilder<'a> {
nested_iter.next();
}
Some(NestedMeta::Meta(Meta::NameValue { .. })) => {}
Some(nested_attr) => throw_invalid_nested_attr!(attr, &nested_attr, |diag| diag
Some(nested_attr) => throw_invalid_nested_attr!(attr, nested_attr, |diag| diag
.help("a diagnostic slug is required as the first argument")),
None => throw_invalid_attr!(attr, &meta, |diag| diag
.help("a diagnostic slug is required as the first argument")),
@@ -227,13 +227,13 @@ impl<'a> DiagnosticDeriveVariantBuilder<'a> {
..
})) => (value, path),
NestedMeta::Meta(Meta::Path(_)) => {
invalid_nested_attr(attr, &nested_attr)
invalid_nested_attr(attr, nested_attr)
.help("diagnostic slug must be the first argument")
.emit();
continue;
}
_ => {
invalid_nested_attr(attr, &nested_attr).emit();
invalid_nested_attr(attr, nested_attr).emit();
continue;
}
};
@@ -251,7 +251,7 @@ impl<'a> DiagnosticDeriveVariantBuilder<'a> {
#diag.code(rustc_errors::DiagnosticId::Error(#code.to_string()));
});
}
_ => invalid_nested_attr(attr, &nested_attr)
_ => invalid_nested_attr(attr, nested_attr)
.help("only `code` is a valid nested attributes following the slug")
.emit(),
}
@@ -427,9 +427,9 @@ impl<'a> DiagnosticDeriveVariantBuilder<'a> {
Ok(self.add_spanned_subdiagnostic(binding, &fn_ident, slug))
}
SubdiagnosticKind::Note | SubdiagnosticKind::Help | SubdiagnosticKind::Warn => {
if type_matches_path(&info.ty, &["rustc_span", "Span"]) {
if type_matches_path(info.ty, &["rustc_span", "Span"]) {
Ok(self.add_spanned_subdiagnostic(binding, &fn_ident, slug))
} else if type_is_unit(&info.ty) {
} else if type_is_unit(info.ty) {
Ok(self.add_subdiagnostic(&fn_ident, slug))
} else {
report_type_error(attr, "`Span` or `()`")?
4 changes: 2 additions & 2 deletions compiler/rustc_macros/src/diagnostics/subdiagnostic.rs
Original file line number Diff line number Diff line change
@@ -409,7 +409,7 @@ impl<'parent, 'a> SubdiagnosticDeriveVariantBuilder<'parent, 'a> {
let mut code = None;
for nested_attr in list.nested.iter() {
let NestedMeta::Meta(ref meta) = nested_attr else {
throw_invalid_nested_attr!(attr, &nested_attr);
throw_invalid_nested_attr!(attr, nested_attr);
};

let span = meta.span().unwrap();
@@ -427,7 +427,7 @@ impl<'parent, 'a> SubdiagnosticDeriveVariantBuilder<'parent, 'a> {
);
code.set_once((code_field, formatting_init), span);
}
_ => throw_invalid_nested_attr!(attr, &nested_attr, |diag| {
_ => throw_invalid_nested_attr!(attr, nested_attr, |diag| {
diag.help("`code` is the only valid nested attribute")
}),
}
20 changes: 10 additions & 10 deletions compiler/rustc_macros/src/diagnostics/utils.rs
Original file line number Diff line number Diff line change
@@ -80,7 +80,7 @@ fn report_error_if_not_applied_to_ty(
path: &[&str],
ty_name: &str,
) -> Result<(), DiagnosticDeriveError> {
if !type_matches_path(&info.ty, path) {
if !type_matches_path(info.ty, path) {
report_type_error(attr, ty_name)?;
}

@@ -105,8 +105,8 @@ pub(crate) fn report_error_if_not_applied_to_span(
attr: &Attribute,
info: &FieldInfo<'_>,
) -> Result<(), DiagnosticDeriveError> {
if !type_matches_path(&info.ty, &["rustc_span", "Span"])
&& !type_matches_path(&info.ty, &["rustc_errors", "MultiSpan"])
if !type_matches_path(info.ty, &["rustc_span", "Span"])
&& !type_matches_path(info.ty, &["rustc_errors", "MultiSpan"])
{
report_type_error(attr, "`Span` or `MultiSpan`")?;
}
@@ -686,7 +686,7 @@ impl SubdiagnosticKind {
let meta = match nested_attr {
NestedMeta::Meta(ref meta) => meta,
NestedMeta::Lit(_) => {
invalid_nested_attr(attr, &nested_attr).emit();
invalid_nested_attr(attr, nested_attr).emit();
continue;
}
};
@@ -698,7 +698,7 @@ impl SubdiagnosticKind {
let string_value = match meta {
Meta::NameValue(MetaNameValue { lit: syn::Lit::Str(value), .. }) => Some(value),

Meta::Path(_) => throw_invalid_nested_attr!(attr, &nested_attr, |diag| {
Meta::Path(_) => throw_invalid_nested_attr!(attr, nested_attr, |diag| {
diag.help("a diagnostic slug must be the first argument to the attribute")
}),
_ => None,
@@ -720,7 +720,7 @@ impl SubdiagnosticKind {
| SubdiagnosticKind::MultipartSuggestion { ref mut applicability, .. },
) => {
let Some(value) = string_value else {
invalid_nested_attr(attr, &nested_attr).emit();
invalid_nested_attr(attr, nested_attr).emit();
continue;
};

@@ -736,7 +736,7 @@ impl SubdiagnosticKind {
| SubdiagnosticKind::MultipartSuggestion { .. },
) => {
let Some(value) = string_value else {
invalid_nested_attr(attr, &nested_attr).emit();
invalid_nested_attr(attr, nested_attr).emit();
continue;
};

@@ -752,19 +752,19 @@ impl SubdiagnosticKind {

// Invalid nested attribute
(_, SubdiagnosticKind::Suggestion { .. }) => {
invalid_nested_attr(attr, &nested_attr)
invalid_nested_attr(attr, nested_attr)
.help(
"only `style`, `code` and `applicability` are valid nested attributes",
)
.emit();
}
(_, SubdiagnosticKind::MultipartSuggestion { .. }) => {
invalid_nested_attr(attr, &nested_attr)
invalid_nested_attr(attr, nested_attr)
.help("only `style` and `applicability` are valid nested attributes")
.emit()
}
_ => {
invalid_nested_attr(attr, &nested_attr).emit();
invalid_nested_attr(attr, nested_attr).emit();
}
}
}
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/hir/map/mod.rs
Original file line number Diff line number Diff line change
@@ -1022,7 +1022,7 @@ impl<'hir> Map<'hir> {
..
}) => {
// Ensure that the returned span has the item's SyntaxContext.
fn_decl_span.find_ancestor_in_same_ctxt(*span).unwrap_or(*span)
fn_decl_span.find_ancestor_inside(*span).unwrap_or(*span)
}
_ => self.span_with_body(hir_id),
};
4 changes: 0 additions & 4 deletions compiler/rustc_mir_transform/src/inline.rs
Original file line number Diff line number Diff line change
@@ -363,10 +363,6 @@ impl<'tcx> Inliner<'tcx> {
return Err("C variadic");
}

if callee_attrs.flags.contains(CodegenFnAttrFlags::NAKED) {
return Err("naked");
}

if callee_attrs.flags.contains(CodegenFnAttrFlags::COLD) {
return Err("cold");
}
10 changes: 7 additions & 3 deletions compiler/rustc_parse/src/parser/expr.rs
Original file line number Diff line number Diff line change
@@ -2060,7 +2060,7 @@ impl<'a> Parser<'a> {
};

let capture_clause = self.parse_capture_clause()?;
let fn_decl = self.parse_fn_block_decl()?;
let (fn_decl, fn_arg_span) = self.parse_fn_block_decl()?;
let decl_hi = self.prev_token.span;
let mut body = match fn_decl.output {
FnRetTy::Default(_) => {
@@ -2101,6 +2101,7 @@ impl<'a> Parser<'a> {
fn_decl,
body,
fn_decl_span: lo.to(decl_hi),
fn_arg_span,
})),
);

@@ -2129,7 +2130,9 @@ impl<'a> Parser<'a> {
}

/// Parses the `|arg, arg|` header of a closure.
fn parse_fn_block_decl(&mut self) -> PResult<'a, P<FnDecl>> {
fn parse_fn_block_decl(&mut self) -> PResult<'a, (P<FnDecl>, Span)> {
let arg_start = self.token.span.lo();

let inputs = if self.eat(&token::OrOr) {
Vec::new()
} else {
@@ -2145,10 +2148,11 @@ impl<'a> Parser<'a> {
self.expect_or()?;
args
};
let arg_span = self.prev_token.span.with_lo(arg_start);
let output =
self.parse_ret_ty(AllowPlus::Yes, RecoverQPath::Yes, RecoverReturnSign::Yes)?;

Ok(P(FnDecl { inputs, output }))
Ok((P(FnDecl { inputs, output }), arg_span))
}

/// Parses a parameter in a closure header (e.g., `|arg, arg|`).
21 changes: 16 additions & 5 deletions compiler/rustc_resolve/src/imports.rs
Original file line number Diff line number Diff line change
@@ -4,7 +4,10 @@ use crate::diagnostics::{import_candidates, Suggestion};
use crate::Determinacy::{self, *};
use crate::Namespace::*;
use crate::{module_to_string, names_to_string, ImportSuggestion};
use crate::{AmbiguityKind, BindingKey, ModuleKind, ResolutionError, Resolver, Segment};
use crate::{
AmbiguityError, AmbiguityErrorMisc, AmbiguityKind, BindingKey, ModuleKind, ResolutionError,
Resolver, Segment,
};
use crate::{Finalize, Module, ModuleOrUniformRoot, ParentScope, PerNS, ScopeSet};
use crate::{NameBinding, NameBindingKind, PathResult};

@@ -791,7 +794,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
match binding {
Ok(binding) => {
// Consistency checks, analogous to `finalize_macro_resolutions`.
let initial_res = source_bindings[ns].get().map(|initial_binding| {
let initial_binding = source_bindings[ns].get().map(|initial_binding| {
all_ns_err = false;
if let Some(target_binding) = target_bindings[ns].get() {
if target.name == kw::Underscore
@@ -805,12 +808,20 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
);
}
}
initial_binding.res()
initial_binding
});
let res = binding.res();
if let Ok(initial_res) = initial_res {
if let Ok(initial_binding) = initial_binding {
let initial_res = initial_binding.res();
if res != initial_res && this.ambiguity_errors.is_empty() {
span_bug!(import.span, "inconsistent resolution for an import");
this.ambiguity_errors.push(AmbiguityError {
kind: AmbiguityKind::Import,
ident,
b1: initial_binding,
b2: binding,
misc1: AmbiguityErrorMisc::None,
misc2: AmbiguityErrorMisc::None,
});
}
} else if res != Res::Err
&& this.ambiguity_errors.is_empty()
2 changes: 1 addition & 1 deletion compiler/rustc_session/src/cgu_reuse_tracker.rs
Original file line number Diff line number Diff line change
@@ -121,7 +121,7 @@ impl CguReuseTracker {
let at_least = if at_least { 1 } else { 0 };
IncorrectCguReuseType {
span: error_span.0,
cgu_user_name: &cgu_user_name,
cgu_user_name,
actual_reuse,
expected_reuse,
at_least,
12 changes: 6 additions & 6 deletions compiler/rustc_session/src/config.rs
Original file line number Diff line number Diff line change
@@ -622,7 +622,7 @@ impl OutputFilenames {
/// should be placed on disk.
pub fn output_path(&self, flavor: OutputType) -> PathBuf {
let extension = flavor.extension();
self.with_directory_and_extension(&self.out_directory, &extension)
self.with_directory_and_extension(&self.out_directory, extension)
}

/// Gets the path where a compilation artifact of the given type for the
@@ -659,7 +659,7 @@ impl OutputFilenames {

let temps_directory = self.temps_directory.as_ref().unwrap_or(&self.out_directory);

self.with_directory_and_extension(&temps_directory, &extension)
self.with_directory_and_extension(temps_directory, &extension)
}

pub fn with_extension(&self, extension: &str) -> PathBuf {
@@ -1159,7 +1159,7 @@ impl CrateCheckConfig {
values_target_family
.extend(target.options.families.iter().map(|family| Symbol::intern(family)));
values_target_arch.insert(Symbol::intern(&target.arch));
values_target_endian.insert(Symbol::intern(&target.options.endian.as_str()));
values_target_endian.insert(Symbol::intern(target.options.endian.as_str()));
values_target_env.insert(Symbol::intern(&target.options.env));
values_target_abi.insert(Symbol::intern(&target.options.abi));
values_target_vendor.insert(Symbol::intern(&target.options.vendor));
@@ -1846,7 +1846,7 @@ pub fn parse_target_triple(
match matches.opt_str("target") {
Some(target) if target.ends_with(".json") => {
let path = Path::new(&target);
TargetTriple::from_path(&path).unwrap_or_else(|_| {
TargetTriple::from_path(path).unwrap_or_else(|_| {
early_error(error_format, &format!("target file {path:?} does not exist"))
})
}
@@ -1992,7 +1992,7 @@ fn parse_native_lib_modifiers(
) -> (NativeLibKind, Option<bool>) {
let mut verbatim = None;
for modifier in modifiers.split(',') {
let (modifier, value) = match modifier.strip_prefix(&['+', '-']) {
let (modifier, value) = match modifier.strip_prefix(['+', '-']) {
Some(m) => (m, modifier.starts_with('+')),
None => early_error(
error_format,
@@ -2421,7 +2421,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {

let mut search_paths = vec![];
for s in &matches.opt_strs("L") {
search_paths.push(SearchPath::from_cli_opt(&s, error_format));
search_paths.push(SearchPath::from_cli_opt(s, error_format));
}

let libs = parse_libs(matches, error_format);
2 changes: 1 addition & 1 deletion compiler/rustc_session/src/errors.rs
Original file line number Diff line number Diff line change
@@ -317,7 +317,7 @@ pub fn report_lit_error(sess: &ParseSess, err: LitError, lit: token::Lit, span:
LitError::InvalidIntSuffix => {
let suf = suffix.expect("suffix error with no suffix");
let suf = suf.as_str();
if looks_like_width_suffix(&['i', 'u'], &suf) {
if looks_like_width_suffix(&['i', 'u'], suf) {
// If it looks like a width, try to be helpful.
sess.emit_err(InvalidIntLiteralWidth { span, width: suf[1..].into() });
} else if let Some(fixed) = fix_base_capitalisation(suf) {
2 changes: 1 addition & 1 deletion compiler/rustc_span/src/analyze_source_file.rs
Original file line number Diff line number Diff line change
@@ -247,7 +247,7 @@ fn analyze_source_file_generic(
// The slow path:
// This is either ASCII control character "DEL" or the beginning of
// a multibyte char. Just decode to `char`.
let c = (&src[i..]).chars().next().unwrap();
let c = src[i..].chars().next().unwrap();
char_len = c.len_utf8();

let pos = BytePos::from_usize(i) + output_offset;
2 changes: 1 addition & 1 deletion compiler/rustc_span/src/caching_source_map_view.rs
Original file line number Diff line number Diff line change
@@ -165,7 +165,7 @@ impl<'sm> CachingSourceMapView<'sm> {
Some(new_file_and_idx)
} else {
let file = &self.line_cache[oldest].file;
if !file_contains(&file, span_data.hi) {
if !file_contains(file, span_data.hi) {
return None;
}

2 changes: 1 addition & 1 deletion compiler/rustc_span/src/hygiene.rs
Original file line number Diff line number Diff line change
@@ -381,7 +381,7 @@ impl HygieneData {
}

pub fn with<T, F: FnOnce(&mut HygieneData) -> T>(f: F) -> T {
with_session_globals(|session_globals| f(&mut *session_globals.hygiene_data.borrow_mut()))
with_session_globals(|session_globals| f(&mut session_globals.hygiene_data.borrow_mut()))
}

#[inline]
2 changes: 1 addition & 1 deletion compiler/rustc_span/src/lib.rs
Original file line number Diff line number Diff line change
@@ -238,7 +238,7 @@ impl RealFileName {
pub fn remapped_path_if_available(&self) -> &Path {
match self {
RealFileName::LocalPath(p)
| RealFileName::Remapped { local_path: _, virtual_name: p } => &p,
| RealFileName::Remapped { local_path: _, virtual_name: p } => p,
}
}

2 changes: 1 addition & 1 deletion compiler/rustc_span/src/span_encoding.rs
Original file line number Diff line number Diff line change
@@ -166,5 +166,5 @@ impl SpanInterner {
// If an interner exists, return it. Otherwise, prepare a fresh one.
#[inline]
fn with_span_interner<T, F: FnOnce(&mut SpanInterner) -> T>(f: F) -> T {
crate::with_session_globals(|session_globals| f(&mut *session_globals.span_interner.lock()))
crate::with_session_globals(|session_globals| f(&mut session_globals.span_interner.lock()))
}
2 changes: 1 addition & 1 deletion compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
@@ -1877,7 +1877,7 @@ impl<S: Encoder> Encodable<S> for Symbol {
impl<D: Decoder> Decodable<D> for Symbol {
#[inline]
default fn decode(d: &mut D) -> Symbol {
Symbol::intern(&d.read_str())
Symbol::intern(d.read_str())
}
}

4 changes: 2 additions & 2 deletions compiler/rustc_target/src/abi/call/sparc64.rs
Original file line number Diff line number Diff line change
@@ -78,7 +78,7 @@ fn arg_scalar_pair<C>(
where
C: HasDataLayout,
{
data = arg_scalar(cx, &scalar1, offset, data);
data = arg_scalar(cx, scalar1, offset, data);
match (scalar1.primitive(), scalar2.primitive()) {
(abi::F32, _) => offset += Reg::f32().size,
(_, abi::F64) => offset += Reg::f64().size,
@@ -90,7 +90,7 @@ where
if (offset.bytes() % 4) != 0 && scalar2.primitive().is_float() {
offset += Size::from_bytes(4 - (offset.bytes() % 4));
}
data = arg_scalar(cx, &scalar2, offset, data);
data = arg_scalar(cx, scalar2, offset, data);
return data;
}

2 changes: 1 addition & 1 deletion compiler/rustc_target/src/spec/mod.rs
Original file line number Diff line number Diff line change
@@ -2658,7 +2658,7 @@ impl Target {

// Additionally look in the sysroot under `lib/rustlib/<triple>/target.json`
// as a fallback.
let rustlib_path = crate::target_rustlib_path(&sysroot, &target_triple);
let rustlib_path = crate::target_rustlib_path(sysroot, target_triple);
let p = PathBuf::from_iter([
Path::new(sysroot),
Path::new(&rustlib_path),
35 changes: 15 additions & 20 deletions compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
Original file line number Diff line number Diff line change
@@ -71,7 +71,7 @@ pub trait InferCtxtExt<'tcx> {
/// returns a span and `ArgKind` information that describes the
/// arguments it expects. This can be supplied to
/// `report_arg_count_mismatch`.
fn get_fn_like_arguments(&self, node: Node<'_>) -> Option<(Span, Vec<ArgKind>)>;
fn get_fn_like_arguments(&self, node: Node<'_>) -> Option<(Span, Option<Span>, Vec<ArgKind>)>;

/// Reports an error when the number of arguments needed by a
/// trait match doesn't match the number that the expression
@@ -83,6 +83,7 @@ pub trait InferCtxtExt<'tcx> {
expected_args: Vec<ArgKind>,
found_args: Vec<ArgKind>,
is_closure: bool,
closure_pipe_span: Option<Span>,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed>;

/// Checks if the type implements one of `Fn`, `FnMut`, or `FnOnce`
@@ -135,15 +136,16 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
/// returns a span and `ArgKind` information that describes the
/// arguments it expects. This can be supplied to
/// `report_arg_count_mismatch`.
fn get_fn_like_arguments(&self, node: Node<'_>) -> Option<(Span, Vec<ArgKind>)> {
fn get_fn_like_arguments(&self, node: Node<'_>) -> Option<(Span, Option<Span>, Vec<ArgKind>)> {
let sm = self.tcx.sess.source_map();
let hir = self.tcx.hir();
Some(match node {
Node::Expr(&hir::Expr {
kind: hir::ExprKind::Closure(&hir::Closure { body, fn_decl_span, .. }),
kind: hir::ExprKind::Closure(&hir::Closure { body, fn_decl_span, fn_arg_span, .. }),
..
}) => (
fn_decl_span,
fn_arg_span,
hir.body(body)
.params
.iter()
@@ -174,6 +176,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
kind: hir::TraitItemKind::Fn(ref sig, _), ..
}) => (
sig.span,
None,
sig.decl
.inputs
.iter()
@@ -188,7 +191,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
),
Node::Ctor(ref variant_data) => {
let span = variant_data.ctor_hir_id().map_or(DUMMY_SP, |id| hir.span(id));
(span, vec![ArgKind::empty(); variant_data.fields().len()])
(span, None, vec![ArgKind::empty(); variant_data.fields().len()])
}
_ => panic!("non-FnLike node found: {:?}", node),
})
@@ -204,6 +207,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
expected_args: Vec<ArgKind>,
found_args: Vec<ArgKind>,
is_closure: bool,
closure_arg_span: Option<Span>,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
let kind = if is_closure { "closure" } else { "function" };

@@ -241,24 +245,13 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
if let Some(found_span) = found_span {
err.span_label(found_span, format!("takes {}", found_str));

// move |_| { ... }
// ^^^^^^^^-- def_span
//
// move |_| { ... }
// ^^^^^-- prefix
let prefix_span = self.tcx.sess.source_map().span_until_non_whitespace(found_span);
// move |_| { ... }
// ^^^-- pipe_span
let pipe_span =
if let Some(span) = found_span.trim_start(prefix_span) { span } else { found_span };

// Suggest to take and ignore the arguments with expected_args_length `_`s if
// found arguments is empty (assume the user just wants to ignore args in this case).
// For example, if `expected_args_length` is 2, suggest `|_, _|`.
if found_args.is_empty() && is_closure {
let underscores = vec!["_"; expected_args.len()].join(", ");
err.span_suggestion_verbose(
pipe_span,
closure_arg_span.unwrap_or(found_span),
&format!(
"consider changing the closure to take and ignore the expected argument{}",
pluralize!(expected_args.len())
@@ -1252,20 +1245,22 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
obligation.cause.code(),
)
} else {
let (closure_span, found) = found_did
let (closure_span, closure_arg_span, found) = found_did
.and_then(|did| {
let node = self.tcx.hir().get_if_local(did)?;
let (found_span, found) = self.get_fn_like_arguments(node)?;
Some((Some(found_span), found))
let (found_span, closure_arg_span, found) =
self.get_fn_like_arguments(node)?;
Some((Some(found_span), closure_arg_span, found))
})
.unwrap_or((found_span, found));
.unwrap_or((found_span, None, found));

self.report_arg_count_mismatch(
span,
closure_span,
expected,
found,
found_trait_ty.is_closure(),
closure_arg_span,
)
}
}
5 changes: 5 additions & 0 deletions library/test/src/cli.rs
Original file line number Diff line number Diff line change
@@ -26,6 +26,10 @@ pub struct TestOpts {
pub test_threads: Option<usize>,
pub skip: Vec<String>,
pub time_options: Option<TestTimeOptions>,
/// Stop at first failing test.
/// May run a few more tests due to threading, but will
/// abort as soon as possible.
pub fail_fast: bool,
pub options: Options,
}

@@ -296,6 +300,7 @@ fn parse_opts_impl(matches: getopts::Matches) -> OptRes {
skip,
time_options,
options,
fail_fast: false,
};

Ok(test_opts)
2 changes: 1 addition & 1 deletion library/test/src/console.rs
Original file line number Diff line number Diff line change
@@ -293,7 +293,7 @@ pub fn run_tests_console(opts: &TestOpts, tests: Vec<TestDescAndFn>) -> io::Resu
run_tests(opts, tests, |x| on_test_event(&x, &mut st, &mut *out))?;
st.exec_time = start_time.map(|t| TestSuiteExecTime(t.elapsed()));

assert!(st.current_test_count() == st.total);
assert!(opts.fail_fast || st.current_test_count() == st.total);

out.write_run_finish(&st)
}
20 changes: 20 additions & 0 deletions library/test/src/lib.rs
Original file line number Diff line number Diff line change
@@ -384,8 +384,17 @@ where
let mut completed_test = rx.recv().unwrap();
RunningTest { join_handle }.join(&mut completed_test);

let fail_fast = match completed_test.result {
TrIgnored | TrOk | TrBench(_) => false,
TrFailed | TrFailedMsg(_) | TrTimedFail => opts.fail_fast,
};

let event = TestEvent::TeResult(completed_test);
notify_about_test_event(event)?;

if fail_fast {
return Ok(());
}
}
} else {
while pending > 0 || !remaining.is_empty() {
@@ -431,9 +440,20 @@ where
let running_test = running_tests.remove(&completed_test.id).unwrap();
running_test.join(&mut completed_test);

let fail_fast = match completed_test.result {
TrIgnored | TrOk | TrBench(_) => false,
TrFailed | TrFailedMsg(_) | TrTimedFail => opts.fail_fast,
};

let event = TestEvent::TeResult(completed_test);
notify_about_test_event(event)?;
pending -= 1;

if fail_fast {
// Prevent remaining test threads from panicking
std::mem::forget(rx);
return Ok(());
}
}
}

1 change: 1 addition & 0 deletions library/test/src/tests.rs
Original file line number Diff line number Diff line change
@@ -51,6 +51,7 @@ impl TestOpts {
skip: vec![],
time_options: None,
options: Options::new(),
fail_fast: false,
}
}
}
19 changes: 19 additions & 0 deletions src/test/codegen/naked-nocoverage.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Checks that naked functions are not instrumented by -Cinstrument-coverage.
// Regression test for issue #105170.
//
// needs-asm-support
// needs-profiler-support
// compile-flags: -Cinstrument-coverage
#![crate_type = "lib"]
#![feature(naked_functions)]
use std::arch::asm;

#[naked]
#[no_mangle]
pub unsafe extern "C" fn f() {
// CHECK: define void @f()
// CHECK-NEXT: start:
// CHECK-NEXT: call void asm
// CHECK-NEXT: unreachable
asm!("", options(noreturn));
}
1 change: 1 addition & 0 deletions src/test/ui-fulldeps/pprust-expr-roundtrip.rs
Original file line number Diff line number Diff line change
@@ -126,6 +126,7 @@ fn iter_exprs(depth: usize, f: &mut dyn FnMut(P<Expr>)) {
fn_decl: decl.clone(),
body: e,
fn_decl_span: DUMMY_SP,
fn_arg_span: DUMMY_SP,
})))
});
}
6 changes: 6 additions & 0 deletions src/test/ui/attributes/unused-item-in-attr.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#[w = { extern crate alloc; }]
//~^ ERROR unexpected expression: `{
//~| ERROR cannot find attribute `w` in this scope
fn f() {}

fn main() {}
16 changes: 16 additions & 0 deletions src/test/ui/attributes/unused-item-in-attr.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
error: unexpected expression: `{
extern crate alloc;
}`
--> $DIR/unused-item-in-attr.rs:1:7
|
LL | #[w = { extern crate alloc; }]
| ^^^^^^^^^^^^^^^^^^^^^^^

error: cannot find attribute `w` in this scope
--> $DIR/unused-item-in-attr.rs:1:3
|
LL | #[w = { extern crate alloc; }]
| ^

error: aborting due to 2 previous errors

14 changes: 9 additions & 5 deletions src/test/ui/issues/issue-35976.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
// revisions: imported unimported
//[imported] check-pass

mod private {
pub trait Future {
//[unimported]~^^ HELP perhaps add a `use` for it
fn wait(&self) where Self: Sized;
}

@@ -8,13 +12,13 @@ mod private {
}
}

//use private::Future;
#[cfg(imported)]
use private::Future;

fn bar(arg: Box<dyn private::Future>) {
// Importing the trait means that we don't autoderef `Box<dyn Future>`
arg.wait();
//~^ ERROR the `wait` method cannot be invoked on a trait object
//[unimported]~^ ERROR the `wait` method cannot be invoked on a trait object
}

fn main() {

}
fn main() {}
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
error: the `wait` method cannot be invoked on a trait object
--> $DIR/issue-35976.rs:14:9
--> $DIR/issue-35976.rs:20:9
|
LL | fn wait(&self) where Self: Sized;
| ----- this has a `Sized` requirement
...
LL | arg.wait();
| ^^^^
|
help: another candidate was found in the following trait, perhaps add a `use` for it:
|
LL | use private::Future;
|

error: aborting due to previous error

11 changes: 11 additions & 0 deletions src/test/ui/resolve/issue-105069.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
use self::A::*;
use V; //~ ERROR `V` is ambiguous
use self::B::*;
enum A {
V
}
enum B {
V
}

fn main() {}
21 changes: 21 additions & 0 deletions src/test/ui/resolve/issue-105069.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
error[E0659]: `V` is ambiguous
--> $DIR/issue-105069.rs:2:5
|
LL | use V;
| ^ ambiguous name
|
= note: ambiguous because of multiple potential import sources
note: `V` could refer to the variant imported here
--> $DIR/issue-105069.rs:1:5
|
LL | use self::A::*;
| ^^^^^^^^^^
note: `V` could also refer to the variant imported here
--> $DIR/issue-105069.rs:3:5
|
LL | use self::B::*;
| ^^^^^^^^^^

error: aborting due to previous error

For more information about this error, try `rustc --explain E0659`.
18 changes: 18 additions & 0 deletions src/test/ui/suggestions/assoc-const-as-fn.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
unsafe fn pointer(v: usize, w: u32) {}

pub trait UniformScalar {}
impl UniformScalar for u32 {}

pub trait GlUniformScalar: UniformScalar {
const FACTORY: unsafe fn(usize, Self) -> ();
}
impl GlUniformScalar for u32 {
const FACTORY: unsafe fn(usize, Self) -> () = pointer;
}

pub fn foo<T: UniformScalar>(value: T) {
<T as GlUniformScalar>::FACTORY(1, value);
//~^ ERROR the trait bound `T: GlUniformScalar` is not satisfied
}

fn main() {}
14 changes: 14 additions & 0 deletions src/test/ui/suggestions/assoc-const-as-fn.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
error[E0277]: the trait bound `T: GlUniformScalar` is not satisfied
--> $DIR/assoc-const-as-fn.rs:14:5
|
LL | <T as GlUniformScalar>::FACTORY(1, value);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `GlUniformScalar` is not implemented for `T`
|
help: consider further restricting this bound
|
LL | pub fn foo<T: UniformScalar + GlUniformScalar>(value: T) {
| +++++++++++++++++

error: aborting due to previous error

For more information about this error, try `rustc --explain E0277`.
1 change: 1 addition & 0 deletions src/tools/compiletest/src/main.rs
Original file line number Diff line number Diff line change
@@ -514,6 +514,7 @@ pub fn test_opts(config: &Config) -> test::TestOpts {
options: test::Options::new(),
time_options: None,
force_run_in_process: false,
fail_fast: std::env::var_os("RUSTC_TEST_FAIL_FAST").is_some(),
}
}

61 changes: 14 additions & 47 deletions src/tools/miri/CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -203,65 +203,32 @@ for more information about configuring VS Code and `rust-analyzer`.

[rdg-r-a]: https://rustc-dev-guide.rust-lang.org/building/suggested.html#configuring-rust-analyzer-for-rustc

## Advanced topic: other build environments
## Advanced topic: Working on Miri in the rustc tree

We described above the simplest way to get a working build environment for Miri,
which is to use the version of rustc indicated by `rustc-version`. But
sometimes, that is not enough.

### Building Miri with a locally built rustc
A big part of the Miri driver is shared with rustc, so working on Miri will
sometimes require also working on rustc itself. In this case, you should *not*
work in a clone of the Miri repository, but in a clone of the
[main Rust repository](https://github.com/rust-lang/rust/). There is a copy of
Miri located at `src/tools/miri` that you can work on directly. A maintainer
will eventually sync those changes back into this repository.

[building Miri with a locally built rustc]: #building-miri-with-a-locally-built-rustc
When working on Miri in the rustc tree, here's how you can run tests:

A big part of the Miri driver lives in rustc, so working on Miri will sometimes
require using a locally built rustc. The bug you want to fix may actually be on
the rustc side, or you just need to get more detailed trace of the execution
than what is possible with release builds -- in both cases, you should develop
Miri against a rustc you compiled yourself, with debug assertions (and hence
tracing) enabled.

The setup for a local rustc works as follows:
```sh
# Clone the rust-lang/rust repo.
git clone https://github.com/rust-lang/rust rustc
cd rustc
# Create a config.toml with defaults for working on Miri.
./x.py setup compiler
# Now edit `config.toml` and under `[rust]` set `debug-assertions = true`.

# Build a stage 2 rustc, and build the rustc libraries with that rustc.
# This step can take 30 minutes or more.
./x.py build --stage 2 compiler/rustc
# If you change something, you can get a faster rebuild by doing
./x.py build --keep-stage 0 --stage 2 compiler/rustc
# You may have to change the architecture in the next command
rustup toolchain link stage2 build/x86_64-unknown-linux-gnu/stage2
# Now cd to your Miri directory, then configure rustup
rustup override set stage2
```

Note: When you are working with a locally built rustc or any other toolchain that
is not the same as the one in `rust-version`, you should not have `.auto-everything` or
`.auto-toolchain` as that will keep resetting your toolchain.

```sh
rm -f .auto-everything .auto-toolchain
./x.py test miri --stage 0
```

Important: You need to delete the Miri cache when you change the stdlib; otherwise the
old, chached version will be used. On Linux, the cache is located at `~/.cache/miri`,
and on Windows, it is located at `%LOCALAPPDATA%\rust-lang\miri\cache`; the exact
location is printed after the library build: "A libstd for Miri is now available in ...".

Note: `./x.py --stage 2 compiler/rustc` currently errors with `thread 'main'
panicked at 'fs::read(stamp) failed with No such file or directory (os error 2)`,
you can simply ignore that error; Miri will build anyway.
`--bless` will work, too.

For more information about building and configuring a local compiler,
see <https://rustc-dev-guide.rust-lang.org/building/how-to-build-and-run.html>.
You can also directly run Miri on a Rust source file:

With this, you should now have a working development setup! See
[above](#building-and-testing-miri) for how to proceed working on Miri.
```
./x.py run miri --stage 0 --args src/tools/miri/tests/pass/hello.rs
```

## Advanced topic: Syncing with the rustc repo

4 changes: 2 additions & 2 deletions src/tools/miri/Cargo.lock
2 changes: 1 addition & 1 deletion src/tools/miri/Cargo.toml
Original file line number Diff line number Diff line change
@@ -39,7 +39,7 @@ libloading = "0.7"

[dev-dependencies]
colored = "2"
ui_test = "0.4"
ui_test = "0.5"
rustc_version = "0.4"
# Features chosen to match those required by env_logger, to avoid rebuilds
regex = { version = "1.5.5", default-features = false, features = ["perf", "std"] }
5 changes: 2 additions & 3 deletions src/tools/miri/cargo-miri/src/phases.rs
Original file line number Diff line number Diff line change
@@ -94,7 +94,7 @@ pub fn phase_cargo_miri(mut args: impl Iterator<Item = String>) {
let target = target.as_ref().unwrap_or(host);

// We always setup.
setup(&subcommand, target, &rustc_version);
setup(&subcommand, target, &rustc_version, verbose);

// Invoke actual cargo for the job, but with different flags.
// We re-use `cargo test` and `cargo run`, which makes target and binary handling very easy but
@@ -486,8 +486,7 @@ pub fn phase_runner(mut binary_args: impl Iterator<Item = String>, phase: Runner
continue;
} else if verbose > 0 {
eprintln!(
"[cargo-miri runner] Overwriting run-time env var {:?}={:?} with build-time value {:?}",
name, old_val, val
"[cargo-miri runner] Overwriting run-time env var {name:?}={old_val:?} with build-time value {val:?}"
);
}
}
19 changes: 12 additions & 7 deletions src/tools/miri/cargo-miri/src/setup.rs
Original file line number Diff line number Diff line change
@@ -13,7 +13,7 @@ use crate::util::*;
/// Performs the setup required to make `cargo miri` work: Getting a custom-built libstd. Then sets
/// `MIRI_SYSROOT`. Skipped if `MIRI_SYSROOT` is already set, in which case we expect the user has
/// done all this already.
pub fn setup(subcommand: &MiriCommand, target: &str, rustc_version: &VersionMeta) {
pub fn setup(subcommand: &MiriCommand, target: &str, rustc_version: &VersionMeta, verbose: usize) {
let only_setup = matches!(subcommand, MiriCommand::Setup);
let ask_user = !only_setup;
let print_sysroot = only_setup && has_arg_flag("--print-sysroot"); // whether we just print the sysroot path
@@ -99,12 +99,13 @@ pub fn setup(subcommand: &MiriCommand, target: &str, rustc_version: &VersionMeta
// `config.toml`.
command.env("RUSTC_WRAPPER", "");

if only_setup {
if print_sysroot {
// Be extra sure there is no noise on stdout.
command.stdout(process::Stdio::null());
if only_setup && !print_sysroot {
// Forward output. Even make it verbose, if requested.
for _ in 0..verbose {
command.arg("-v");
}
} else {
// Supress output.
command.stdout(process::Stdio::null());
command.stderr(process::Stdio::null());
}
@@ -120,7 +121,9 @@ pub fn setup(subcommand: &MiriCommand, target: &str, rustc_version: &VersionMeta
std::env::set_var("MIRI_SYSROOT", &sysroot_dir);

// Do the build.
if only_setup {
if print_sysroot {
// Be silent.
} else if only_setup {
// We want to be explicit.
eprintln!("Preparing a sysroot for Miri (target: {target})...");
} else {
@@ -143,7 +146,9 @@ pub fn setup(subcommand: &MiriCommand, target: &str, rustc_version: &VersionMeta
)
}
});
if only_setup {
if print_sysroot {
// Be silent.
} else if only_setup {
eprintln!("A sysroot for Miri is now available in `{}`.", sysroot_dir.display());
} else {
eprintln!("done");
11 changes: 8 additions & 3 deletions src/tools/miri/ci.sh
Original file line number Diff line number Diff line change
@@ -40,10 +40,15 @@ function run_tests {
./miri test
if [ -z "${MIRI_TEST_TARGET+exists}" ]; then
# Only for host architecture: tests with optimizations (`-O` is what cargo passes, but crank MIR
# optimizations up all the way).
# Optimizations change diagnostics (mostly backtraces), so we don't check them
#FIXME(#2155): we want to only run the pass and panic tests here, not the fail tests.
# optimizations up all the way, too).
# Optimizations change diagnostics (mostly backtraces), so we don't check
# them. Also error locations change so we don't run the failing tests.
MIRIFLAGS="${MIRIFLAGS:-} -O -Zmir-opt-level=4" MIRI_SKIP_UI_CHECKS=1 ./miri test -- tests/{pass,panic}

# Also run some many-seeds tests. 64 seeds means this takes around a minute per test.
for FILE in tests/many-seeds/*.rs; do
MIRI_SEEDS=64 CARGO_EXTRA_FLAGS="$CARGO_EXTRA_FLAGS -q" ./miri many-seeds ./miri run "$FILE"
done
fi

## test-cargo-miri
9 changes: 7 additions & 2 deletions src/tools/miri/miri
Original file line number Diff line number Diff line change
@@ -36,7 +36,8 @@ Mainly meant to be invoked by rust-analyzer.
./miri many-seeds <command>:
Runs <command> over and over again with different seeds for Miri. The MIRIFLAGS
variable is set to its original value appended with ` -Zmiri-seed=$SEED` for
many different seeds.
many different seeds. The MIRI_SEEDS variable controls how many seeds are being
tried; MIRI_SEED_START controls the first seed to try.
./miri bench <benches>:
Runs the benchmarks from bench-cargo-miri in hyperfine. hyperfine needs to be installed.
@@ -174,7 +175,9 @@ rustc-push)
fi
;;
many-seeds)
for SEED in $(seq 0 255); do
MIRI_SEED_START=${MIRI_SEED_START:-0} # default to 0
MIRI_SEEDS=${MIRI_SEEDS:-256} # default to 256
for SEED in $(seq $MIRI_SEED_START $(( $MIRI_SEED_START + $MIRI_SEEDS - 1 )) ); do
echo "Trying seed: $SEED"
MIRIFLAGS="$MIRIFLAGS -Zlayout-seed=$SEED -Zmiri-seed=$SEED" $@ || { echo "Failing seed: $SEED"; break; }
done
@@ -249,6 +252,8 @@ export RUSTFLAGS="-C link-args=-Wl,-rpath,$LIBDIR $RUSTFLAGS"
# Build a sysroot and set MIRI_SYSROOT to use it. Arguments are passed to `cargo miri setup`.
build_sysroot() {
if ! MIRI_SYSROOT="$($CARGO run $CARGO_EXTRA_FLAGS --manifest-path "$MIRIDIR"/cargo-miri/Cargo.toml -- miri setup --print-sysroot "$@")"; then
# Run it again so the user can see the error.
$CARGO run $CARGO_EXTRA_FLAGS --manifest-path "$MIRIDIR"/cargo-miri/Cargo.toml -- miri setup "$@"
echo "'cargo miri setup' failed"
exit 1
fi
2 changes: 1 addition & 1 deletion src/tools/miri/rust-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
454784afba5bf35b5ff14ada0e31265ad1d75e73
cef44f53034eac46be3a0e3eec7b2b3d4ef5140b
9 changes: 3 additions & 6 deletions src/tools/miri/src/bin/miri.rs
Original file line number Diff line number Diff line change
@@ -192,10 +192,7 @@ fn init_late_loggers(tcx: TyCtxt<'_>) {
if log::Level::from_str(&var).is_ok() {
env::set_var(
"RUSTC_LOG",
format!(
"rustc_middle::mir::interpret={0},rustc_const_eval::interpret={0}",
var
),
format!("rustc_middle::mir::interpret={var},rustc_const_eval::interpret={var}"),
);
} else {
env::set_var("RUSTC_LOG", &var);
@@ -317,7 +314,7 @@ fn main() {
} else if arg == "-Zmiri-disable-validation" {
miri_config.validate = false;
} else if arg == "-Zmiri-disable-stacked-borrows" {
miri_config.stacked_borrows = false;
miri_config.borrow_tracker = None;
} else if arg == "-Zmiri-disable-data-race-detector" {
miri_config.data_race_detector = false;
miri_config.weak_memory_emulation = false;
@@ -413,7 +410,7 @@ fn main() {
err
),
};
for id in ids.into_iter().map(miri::SbTag::new) {
for id in ids.into_iter().map(miri::BorTag::new) {
if let Some(id) = id {
miri_config.tracked_pointer_tags.insert(id);
} else {
371 changes: 371 additions & 0 deletions src/tools/miri/src/borrow_tracker/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,371 @@
use std::cell::RefCell;
use std::fmt;
use std::num::NonZeroU64;

use log::trace;
use smallvec::SmallVec;

use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_middle::mir::RetagKind;
use rustc_target::abi::Size;

use crate::*;
pub mod stacked_borrows;
use stacked_borrows::diagnostics::RetagCause;

pub type CallId = NonZeroU64;

/// Tracking pointer provenance
#[derive(Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub struct BorTag(NonZeroU64);

impl BorTag {
pub fn new(i: u64) -> Option<Self> {
NonZeroU64::new(i).map(BorTag)
}

pub fn get(&self) -> u64 {
self.0.get()
}

pub fn inner(&self) -> NonZeroU64 {
self.0
}

pub fn succ(self) -> Option<Self> {
self.0.checked_add(1).map(Self)
}

/// The minimum representable tag
pub fn one() -> Self {
Self::new(1).unwrap()
}
}

impl std::default::Default for BorTag {
/// The default to be used when borrow tracking is disabled
fn default() -> Self {
Self::one()
}
}

impl fmt::Debug for BorTag {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "<{}>", self.0)
}
}

/// Per-call-stack-frame data for borrow tracking
#[derive(Debug)]
pub struct FrameState {
/// The ID of the call this frame corresponds to.
pub call_id: CallId,

/// If this frame is protecting any tags, they are listed here. We use this list to do
/// incremental updates of the global list of protected tags stored in the
/// `stacked_borrows::GlobalState` upon function return, and if we attempt to pop a protected
/// tag, to identify which call is responsible for protecting the tag.
/// See `Stack::item_popped` for more explanation.
///
/// This will contain one tag per reference passed to the function, so
/// a size of 2 is enough for the vast majority of functions.
pub protected_tags: SmallVec<[BorTag; 2]>,
}

impl VisitTags for FrameState {
fn visit_tags(&self, _visit: &mut dyn FnMut(BorTag)) {
// `protected_tags` are fine to GC.
}
}

/// Extra global state, available to the memory access hooks.
#[derive(Debug)]
pub struct GlobalStateInner {
/// Borrow tracker method currently in use.
pub borrow_tracker_method: BorrowTrackerMethod,
/// Next unused pointer ID (tag).
pub next_ptr_tag: BorTag,
/// Table storing the "base" tag for each allocation.
/// The base tag is the one used for the initial pointer.
/// We need this in a separate table to handle cyclic statics.
pub base_ptr_tags: FxHashMap<AllocId, BorTag>,
/// Next unused call ID (for protectors).
pub next_call_id: CallId,
/// All currently protected tags.
/// An item is protected if its tag is in this set, *and* it has the "protected" bit set.
/// We add tags to this when they are created with a protector in `reborrow`, and
/// we remove tags from this when the call which is protecting them returns, in
/// `GlobalStateInner::end_call`. See `Stack::item_popped` for more details.
pub protected_tags: FxHashMap<BorTag, ProtectorKind>,
/// The pointer ids to trace
pub tracked_pointer_tags: FxHashSet<BorTag>,
/// The call ids to trace
pub tracked_call_ids: FxHashSet<CallId>,
/// Whether to recurse into datatypes when searching for pointers to retag.
pub retag_fields: RetagFields,
}

impl VisitTags for GlobalStateInner {
fn visit_tags(&self, _visit: &mut dyn FnMut(BorTag)) {
// The only candidate is base_ptr_tags, and that does not need visiting since we don't ever
// GC the bottommost tag.
}
}

/// We need interior mutable access to the global state.
pub type GlobalState = RefCell<GlobalStateInner>;

/// Indicates which kind of access is being performed.
#[derive(Copy, Clone, Hash, PartialEq, Eq, Debug)]
pub enum AccessKind {
Read,
Write,
}

impl fmt::Display for AccessKind {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
AccessKind::Read => write!(f, "read access"),
AccessKind::Write => write!(f, "write access"),
}
}
}

/// Policy on whether to recurse into fields to retag
#[derive(Copy, Clone, Debug)]
pub enum RetagFields {
/// Don't retag any fields.
No,
/// Retag all fields.
Yes,
/// Only retag fields of types with Scalar and ScalarPair layout,
/// to match the LLVM `noalias` we generate.
OnlyScalar,
}

/// The flavor of the protector.
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum ProtectorKind {
/// Protected against aliasing violations from other pointers.
///
/// Items protected like this cause UB when they are invalidated, *but* the pointer itself may
/// still be used to issue a deallocation.
///
/// This is required for LLVM IR pointers that are `noalias` but *not* `dereferenceable`.
WeakProtector,

/// Protected against any kind of invalidation.
///
/// Items protected like this cause UB when they are invalidated or the memory is deallocated.
/// This is strictly stronger protection than `WeakProtector`.
///
/// This is required for LLVM IR pointers that are `dereferenceable` (and also allows `noalias`).
StrongProtector,
}

/// Utilities for initialization and ID generation
impl GlobalStateInner {
pub fn new(
borrow_tracker_method: BorrowTrackerMethod,
tracked_pointer_tags: FxHashSet<BorTag>,
tracked_call_ids: FxHashSet<CallId>,
retag_fields: RetagFields,
) -> Self {
GlobalStateInner {
borrow_tracker_method,
next_ptr_tag: BorTag::one(),
base_ptr_tags: FxHashMap::default(),
next_call_id: NonZeroU64::new(1).unwrap(),
protected_tags: FxHashMap::default(),
tracked_pointer_tags,
tracked_call_ids,
retag_fields,
}
}

/// Generates a new pointer tag. Remember to also check track_pointer_tags and log its creation!
pub fn new_ptr(&mut self) -> BorTag {
let id = self.next_ptr_tag;
self.next_ptr_tag = id.succ().unwrap();
id
}

pub fn new_frame(&mut self, machine: &MiriMachine<'_, '_>) -> FrameState {
let call_id = self.next_call_id;
trace!("new_frame: Assigning call ID {}", call_id);
if self.tracked_call_ids.contains(&call_id) {
machine.emit_diagnostic(NonHaltingDiagnostic::CreatedCallId(call_id));
}
self.next_call_id = NonZeroU64::new(call_id.get() + 1).unwrap();
FrameState { call_id, protected_tags: SmallVec::new() }
}

pub fn end_call(&mut self, frame: &machine::FrameExtra<'_>) {
for tag in &frame
.borrow_tracker
.as_ref()
.expect("we should have borrow tracking data")
.protected_tags
{
self.protected_tags.remove(tag);
}
}

pub fn base_ptr_tag(&mut self, id: AllocId, machine: &MiriMachine<'_, '_>) -> BorTag {
self.base_ptr_tags.get(&id).copied().unwrap_or_else(|| {
let tag = self.new_ptr();
if self.tracked_pointer_tags.contains(&tag) {
machine.emit_diagnostic(NonHaltingDiagnostic::CreatedPointerTag(
tag.inner(),
None,
None,
));
}
trace!("New allocation {:?} has base tag {:?}", id, tag);
self.base_ptr_tags.try_insert(id, tag).unwrap();
tag
})
}
}

/// Which borrow tracking method to use
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum BorrowTrackerMethod {
/// Stacked Borrows, as implemented in borrow_tracker/stacked
StackedBorrows,
}

impl BorrowTrackerMethod {
pub fn instanciate_global_state(self, config: &MiriConfig) -> GlobalState {
RefCell::new(GlobalStateInner::new(
self,
config.tracked_pointer_tags.clone(),
config.tracked_call_ids.clone(),
config.retag_fields,
))
}
}

impl GlobalStateInner {
pub fn new_allocation(
&mut self,
id: AllocId,
alloc_size: Size,
kind: MemoryKind<machine::MiriMemoryKind>,
machine: &MiriMachine<'_, '_>,
) -> AllocState {
match self.borrow_tracker_method {
BorrowTrackerMethod::StackedBorrows =>
AllocState::StackedBorrows(Box::new(RefCell::new(Stacks::new_allocation(
id, alloc_size, self, kind, machine,
)))),
}
}
}

impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {}
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
fn retag(&mut self, kind: RetagKind, place: &PlaceTy<'tcx, Provenance>) -> InterpResult<'tcx> {
let this = self.eval_context_mut();
let method = this.machine.borrow_tracker.as_ref().unwrap().borrow().borrow_tracker_method;
match method {
BorrowTrackerMethod::StackedBorrows => this.sb_retag(kind, place),
}
}

fn retag_return_place(&mut self) -> InterpResult<'tcx> {
let this = self.eval_context_mut();
let method = this.machine.borrow_tracker.as_ref().unwrap().borrow().borrow_tracker_method;
match method {
BorrowTrackerMethod::StackedBorrows => this.sb_retag_return_place(),
}
}

fn expose_tag(&mut self, alloc_id: AllocId, tag: BorTag) -> InterpResult<'tcx> {
let this = self.eval_context_mut();
let method = this.machine.borrow_tracker.as_ref().unwrap().borrow().borrow_tracker_method;
match method {
BorrowTrackerMethod::StackedBorrows => this.sb_expose_tag(alloc_id, tag),
}
}
}

/// Extra per-allocation data for borrow tracking
#[derive(Debug, Clone)]
pub enum AllocState {
/// Data corresponding to Stacked Borrows
StackedBorrows(Box<RefCell<stacked_borrows::AllocState>>),
}

impl machine::AllocExtra {
#[track_caller]
pub fn borrow_tracker_sb(&self) -> &RefCell<stacked_borrows::AllocState> {
match self.borrow_tracker {
Some(AllocState::StackedBorrows(ref sb)) => sb,
_ => panic!("expected Stacked Borrows borrow tracking, got something else"),
}
}

#[track_caller]
pub fn borrow_tracker_sb_mut(&mut self) -> &mut RefCell<stacked_borrows::AllocState> {
match self.borrow_tracker {
Some(AllocState::StackedBorrows(ref mut sb)) => sb,
_ => panic!("expected Stacked Borrows borrow tracking, got something else"),
}
}
}

impl AllocState {
pub fn before_memory_read<'tcx>(
&self,
alloc_id: AllocId,
prov_extra: ProvenanceExtra,
range: AllocRange,
machine: &MiriMachine<'_, 'tcx>,
) -> InterpResult<'tcx> {
match self {
AllocState::StackedBorrows(sb) =>
sb.borrow_mut().before_memory_read(alloc_id, prov_extra, range, machine),
}
}

pub fn before_memory_write<'tcx>(
&mut self,
alloc_id: AllocId,
prov_extra: ProvenanceExtra,
range: AllocRange,
machine: &mut MiriMachine<'_, 'tcx>,
) -> InterpResult<'tcx> {
match self {
AllocState::StackedBorrows(sb) =>
sb.get_mut().before_memory_write(alloc_id, prov_extra, range, machine),
}
}

pub fn before_memory_deallocation<'tcx>(
&mut self,
alloc_id: AllocId,
prov_extra: ProvenanceExtra,
range: AllocRange,
machine: &mut MiriMachine<'_, 'tcx>,
) -> InterpResult<'tcx> {
match self {
AllocState::StackedBorrows(sb) =>
sb.get_mut().before_memory_deallocation(alloc_id, prov_extra, range, machine),
}
}

pub fn remove_unreachable_tags(&self, tags: &FxHashSet<BorTag>) {
match self {
AllocState::StackedBorrows(sb) => sb.borrow_mut().remove_unreachable_tags(tags),
}
}
}

impl VisitTags for AllocState {
fn visit_tags(&self, visit: &mut dyn FnMut(BorTag)) {
match self {
AllocState::StackedBorrows(sb) => sb.visit_tags(visit),
}
}
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
use smallvec::SmallVec;
use std::fmt;

use rustc_middle::mir::interpret::{alloc_range, AllocId, AllocRange};
use rustc_middle::mir::interpret::{alloc_range, AllocId, AllocRange, InterpError};
use rustc_span::{Span, SpanData};
use rustc_target::abi::Size;

use crate::stacked_borrows::{err_sb_ub, AccessKind, GlobalStateInner, Permission, ProtectorKind};
use crate::borrow_tracker::{
stacked_borrows::{err_sb_ub, Permission},
AccessKind, GlobalStateInner, ProtectorKind,
};
use crate::*;

use rustc_middle::mir::interpret::InterpError;

#[derive(Clone, Debug)]
pub struct AllocHistory {
id: AllocId,
@@ -51,7 +52,7 @@ impl Creation {

#[derive(Clone, Debug)]
struct Invalidation {
tag: SbTag,
tag: BorTag,
range: AllocRange,
span: Span,
cause: InvalidationCause,
@@ -98,7 +99,7 @@ impl fmt::Display for InvalidationCause {

#[derive(Clone, Debug)]
struct Protection {
tag: SbTag,
tag: BorTag,
span: Span,
}

@@ -133,7 +134,7 @@ impl<'ecx, 'mir, 'tcx> DiagnosticCxBuilder<'ecx, 'mir, 'tcx> {
pub fn retag(
machine: &'ecx MiriMachine<'mir, 'tcx>,
cause: RetagCause,
new_tag: SbTag,
new_tag: BorTag,
orig_tag: ProvenanceExtra,
range: AllocRange,
) -> Self {
@@ -183,7 +184,7 @@ enum Operation {
#[derive(Debug, Clone)]
struct RetagOp {
cause: RetagCause,
new_tag: SbTag,
new_tag: BorTag,
orig_tag: ProvenanceExtra,
range: AllocRange,
permission: Option<Permission>,
@@ -255,7 +256,7 @@ impl<'history, 'ecx, 'mir, 'tcx> DiagnosticCx<'history, 'ecx, 'mir, 'tcx> {
.push(Creation { retag: op.clone(), span: self.machine.current_span() });
}

pub fn log_invalidation(&mut self, tag: SbTag) {
pub fn log_invalidation(&mut self, tag: BorTag) {
let mut span = self.machine.current_span();
let (range, cause) = match &self.operation {
Operation::Retag(RetagOp { cause, range, permission, .. }) => {
@@ -286,8 +287,8 @@ impl<'history, 'ecx, 'mir, 'tcx> DiagnosticCx<'history, 'ecx, 'mir, 'tcx> {

pub fn get_logs_relevant_to(
&self,
tag: SbTag,
protector_tag: Option<SbTag>,
tag: BorTag,
protector_tag: Option<BorTag>,
) -> Option<TagHistory> {
let Some(created) = self.history
.creations
@@ -408,7 +409,7 @@ impl<'history, 'ecx, 'mir, 'tcx> DiagnosticCx<'history, 'ecx, 'mir, 'tcx> {
.all_stacks()
.flatten()
.map(|frame| {
frame.extra.stacked_borrows.as_ref().expect("we should have Stacked Borrows data")
frame.extra.borrow_tracker.as_ref().expect("we should have borrow tracking data")
})
.find(|frame| frame.protected_tags.contains(&item.tag()))
.map(|frame| frame.call_id)
@@ -454,23 +455,18 @@ impl<'history, 'ecx, 'mir, 'tcx> DiagnosticCx<'history, 'ecx, 'mir, 'tcx> {
if !global.tracked_pointer_tags.contains(&item.tag()) {
return;
}
let summary = match self.operation {
Operation::Dealloc(_) => None,
Operation::Access(AccessOp { kind, tag, .. }) => Some((tag, kind)),
let cause = match self.operation {
Operation::Dealloc(_) => format!(" due to deallocation"),
Operation::Access(AccessOp { kind, tag, .. }) =>
format!(" due to {kind:?} access for {tag:?}"),
Operation::Retag(RetagOp { orig_tag, permission, .. }) => {
let kind = match permission
.expect("start_grant should set the current permission before popping a tag")
{
Permission::SharedReadOnly => AccessKind::Read,
Permission::Unique => AccessKind::Write,
Permission::SharedReadWrite | Permission::Disabled => {
panic!("Only SharedReadOnly and Unique retags can pop tags");
}
};
Some((orig_tag, kind))
let permission = permission
.expect("start_grant should set the current permission before popping a tag");
format!(" due to {permission:?} retag from {orig_tag:?}")
}
};
self.machine.emit_diagnostic(NonHaltingDiagnostic::PoppedPointerTag(*item, summary));

self.machine.emit_diagnostic(NonHaltingDiagnostic::PoppedPointerTag(*item, cause));
}
}

Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
use crate::stacked_borrows::SbTag;
use std::fmt;
use std::num::NonZeroU64;

use crate::borrow_tracker::BorTag;

/// An item in the per-location borrow stack.
#[derive(Copy, Clone, Hash, PartialEq, Eq)]
pub struct Item(u64);

// An Item contains 3 bitfields:
// * Bits 0-61 store an SbTag
// * Bits 0-61 store a BorTag
// * Bits 61-63 store a Permission
// * Bit 64 stores a flag which indicates if we have a protector
const TAG_MASK: u64 = u64::MAX >> 3;
@@ -18,9 +18,9 @@ const PERM_SHIFT: u64 = 61;
const PROTECTED_SHIFT: u64 = 63;

impl Item {
pub fn new(tag: SbTag, perm: Permission, protected: bool) -> Self {
assert!(tag.0.get() <= TAG_MASK);
let packed_tag = tag.0.get();
pub fn new(tag: BorTag, perm: Permission, protected: bool) -> Self {
assert!(tag.get() <= TAG_MASK);
let packed_tag = tag.get();
let packed_perm = perm.to_bits() << PERM_SHIFT;
let packed_protected = u64::from(protected) << PROTECTED_SHIFT;

@@ -34,8 +34,8 @@ impl Item {
}

/// The pointers the permission is granted to.
pub fn tag(self) -> SbTag {
SbTag(NonZeroU64::new(self.0 & TAG_MASK).unwrap())
pub fn tag(self) -> BorTag {
BorTag::new(self.0 & TAG_MASK).unwrap()
}

/// The permission this item grants.
Loading