Auto merge of #124208 - jieyouxu:rollup-gbgpu4u, r=jieyouxu

Rollup of 10 pull requests

Successful merges:

 - #123379 (Print note with closure signature on type mismatch)
 - #123967 (static_mut_refs: use raw pointers to remove the remaining FIXME)
 - #123976 (Use fake libc in core test)
 - #123986 (lint-docs: Add redirects for renamed lints.)
 - #124053 (coverage: Branch coverage tests for lazy boolean operators)
 - #124071 (Add llvm-bitcode-linker to build manifest)
 - #124103 (Improve std::fs::Metadata Debug representation)
 - #124132 (llvm RustWrapper: explain OpBundlesIndirect argument type)
 - #124191 (Give a name to each distinct manipulation of pretty-printer FixupContext)
 - #124196 (mir-opt tests: rename unit-test -> test-mir-pass)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2024-04-20 22:35:56 +00:00
commit 453ceafce3
184 changed files with 912 additions and 421 deletions

View File

@ -3,11 +3,12 @@
//! Note that HIR pretty printing is layered on top of this crate.
mod expr;
mod fixup;
mod item;
use crate::pp::Breaks::{Consistent, Inconsistent};
use crate::pp::{self, Breaks};
use crate::pprust::state::expr::FixupContext;
use crate::pprust::state::fixup::FixupContext;
use ast::TraitBoundModifiers;
use rustc_ast::attr::AttrIdGenerator;
use rustc_ast::ptr::P;
@ -15,7 +16,6 @@ use rustc_ast::token::{self, BinOpToken, CommentKind, Delimiter, Nonterminal, To
use rustc_ast::tokenstream::{Spacing, TokenStream, TokenTree};
use rustc_ast::util::classify;
use rustc_ast::util::comments::{Comment, CommentStyle};
use rustc_ast::util::parser;
use rustc_ast::{self as ast, AttrArgs, AttrArgsEq, BlockCheckMode, PatKind};
use rustc_ast::{attr, BindingMode, ByRef, DelimArgs, RangeEnd, RangeSyntax, Term};
use rustc_ast::{GenericArg, GenericBound, SelfKind};
@ -1252,22 +1252,14 @@ impl<'a> State<'a> {
ast::StmtKind::Item(item) => self.print_item(item),
ast::StmtKind::Expr(expr) => {
self.space_if_not_bol();
self.print_expr_outer_attr_style(
expr,
false,
FixupContext { stmt: true, ..FixupContext::default() },
);
self.print_expr_outer_attr_style(expr, false, FixupContext::new_stmt());
if classify::expr_requires_semi_to_be_stmt(expr) {
self.word(";");
}
}
ast::StmtKind::Semi(expr) => {
self.space_if_not_bol();
self.print_expr_outer_attr_style(
expr,
false,
FixupContext { stmt: true, ..FixupContext::default() },
);
self.print_expr_outer_attr_style(expr, false, FixupContext::new_stmt());
self.word(";");
}
ast::StmtKind::Empty => {
@ -1319,11 +1311,7 @@ impl<'a> State<'a> {
ast::StmtKind::Expr(expr) if i == blk.stmts.len() - 1 => {
self.maybe_print_comment(st.span.lo());
self.space_if_not_bol();
self.print_expr_outer_attr_style(
expr,
false,
FixupContext { stmt: true, ..FixupContext::default() },
);
self.print_expr_outer_attr_style(expr, false, FixupContext::new_stmt());
self.maybe_print_trailing_comment(expr.span, Some(blk.span.hi()));
}
_ => self.print_stmt(st),
@ -1367,8 +1355,7 @@ impl<'a> State<'a> {
self.word_space("=");
self.print_expr_cond_paren(
expr,
fixup.parenthesize_exterior_struct_lit && parser::contains_exterior_struct_lit(expr)
|| parser::needs_par_as_let_scrutinee(expr.precedence().order()),
fixup.needs_par_as_let_scrutinee(expr),
FixupContext::default(),
);
}

View File

@ -1,10 +1,10 @@
use crate::pp::Breaks::Inconsistent;
use crate::pprust::state::fixup::FixupContext;
use crate::pprust::state::{AnnNode, PrintState, State, INDENT_UNIT};
use ast::{ForLoopKind, MatchKind};
use itertools::{Itertools, Position};
use rustc_ast::ptr::P;
use rustc_ast::token;
use rustc_ast::util::classify;
use rustc_ast::util::literal::escape_byte_str_symbol;
use rustc_ast::util::parser::{self, AssocOp, Fixity};
use rustc_ast::{self as ast, BlockCheckMode};
@ -14,78 +14,6 @@ use rustc_ast::{
};
use std::fmt::Write;
#[derive(Copy, Clone, Debug)]
pub(crate) struct FixupContext {
/// Print expression such that it can be parsed back as a statement
/// consisting of the original expression.
///
/// The effect of this is for binary operators in statement position to set
/// `leftmost_subexpression_in_stmt` when printing their left-hand operand.
///
/// ```ignore (illustrative)
/// (match x {}) - 1; // match needs parens when LHS of binary operator
///
/// match x {}; // not when its own statement
/// ```
pub stmt: bool,
/// This is the difference between:
///
/// ```ignore (illustrative)
/// (match x {}) - 1; // subexpression needs parens
///
/// let _ = match x {} - 1; // no parens
/// ```
///
/// There are 3 distinguishable contexts in which `print_expr` might be
/// called with the expression `$match` as its argument, where `$match`
/// represents an expression of kind `ExprKind::Match`:
///
/// - stmt=false leftmost_subexpression_in_stmt=false
///
/// Example: `let _ = $match - 1;`
///
/// No parentheses required.
///
/// - stmt=false leftmost_subexpression_in_stmt=true
///
/// Example: `$match - 1;`
///
/// Must parenthesize `($match)`, otherwise parsing back the output as a
/// statement would terminate the statement after the closing brace of
/// the match, parsing `-1;` as a separate statement.
///
/// - stmt=true leftmost_subexpression_in_stmt=false
///
/// Example: `$match;`
///
/// No parentheses required.
pub leftmost_subexpression_in_stmt: bool,
/// This is the difference between:
///
/// ```ignore (illustrative)
/// if let _ = (Struct {}) {} // needs parens
///
/// match () {
/// () if let _ = Struct {} => {} // no parens
/// }
/// ```
pub parenthesize_exterior_struct_lit: bool,
}
/// The default amount of fixing is minimal fixing. Fixups should be turned on
/// in a targeted fashion where needed.
impl Default for FixupContext {
fn default() -> Self {
FixupContext {
stmt: false,
leftmost_subexpression_in_stmt: false,
parenthesize_exterior_struct_lit: false,
}
}
}
impl<'a> State<'a> {
fn print_else(&mut self, els: Option<&ast::Expr>) {
if let Some(_else) = els {
@ -136,9 +64,7 @@ impl<'a> State<'a> {
/// Prints an expr using syntax that's acceptable in a condition position, such as the `cond` in
/// `if cond { ... }`.
fn print_expr_as_cond(&mut self, expr: &ast::Expr) {
let fixup =
FixupContext { parenthesize_exterior_struct_lit: true, ..FixupContext::default() };
self.print_expr_cond_paren(expr, Self::cond_needs_par(expr), fixup)
self.print_expr_cond_paren(expr, Self::cond_needs_par(expr), FixupContext::new_cond())
}
/// Does `expr` need parentheses when printed in a condition position?
@ -310,15 +236,7 @@ impl<'a> State<'a> {
// because the latter is valid syntax but with the incorrect meaning.
// It's a match-expression followed by tuple-expression, not a function
// call.
self.print_expr_maybe_paren(
func,
prec,
FixupContext {
stmt: false,
leftmost_subexpression_in_stmt: fixup.stmt || fixup.leftmost_subexpression_in_stmt,
..fixup
},
);
self.print_expr_maybe_paren(func, prec, fixup.leftmost_subexpression());
self.print_call_post(args)
}
@ -387,33 +305,17 @@ impl<'a> State<'a> {
_ => left_prec,
};
self.print_expr_maybe_paren(
lhs,
left_prec,
FixupContext {
stmt: false,
leftmost_subexpression_in_stmt: fixup.stmt || fixup.leftmost_subexpression_in_stmt,
..fixup
},
);
self.print_expr_maybe_paren(lhs, left_prec, fixup.leftmost_subexpression());
self.space();
self.word_space(op.node.as_str());
self.print_expr_maybe_paren(
rhs,
right_prec,
FixupContext { stmt: false, leftmost_subexpression_in_stmt: false, ..fixup },
);
self.print_expr_maybe_paren(rhs, right_prec, fixup.subsequent_subexpression());
}
fn print_expr_unary(&mut self, op: ast::UnOp, expr: &ast::Expr, fixup: FixupContext) {
self.word(op.as_str());
self.print_expr_maybe_paren(
expr,
parser::PREC_PREFIX,
FixupContext { stmt: false, leftmost_subexpression_in_stmt: false, ..fixup },
);
self.print_expr_maybe_paren(expr, parser::PREC_PREFIX, fixup.subsequent_subexpression());
}
fn print_expr_addr_of(
@ -431,11 +333,7 @@ impl<'a> State<'a> {
self.print_mutability(mutability, true);
}
}
self.print_expr_maybe_paren(
expr,
parser::PREC_PREFIX,
FixupContext { stmt: false, leftmost_subexpression_in_stmt: false, ..fixup },
);
self.print_expr_maybe_paren(expr, parser::PREC_PREFIX, fixup.subsequent_subexpression());
}
pub(super) fn print_expr(&mut self, expr: &ast::Expr, fixup: FixupContext) {
@ -470,8 +368,7 @@ impl<'a> State<'a> {
//
// Same applies to a small set of other expression kinds which eagerly
// terminate a statement which opens with them.
let needs_par =
fixup.leftmost_subexpression_in_stmt && !classify::expr_requires_semi_to_be_stmt(expr);
let needs_par = fixup.would_cause_statement_boundary(expr);
if needs_par {
self.popen();
fixup = FixupContext::default();
@ -519,16 +416,7 @@ impl<'a> State<'a> {
}
ast::ExprKind::Cast(expr, ty) => {
let prec = AssocOp::As.precedence() as i8;
self.print_expr_maybe_paren(
expr,
prec,
FixupContext {
stmt: false,
leftmost_subexpression_in_stmt: fixup.stmt
|| fixup.leftmost_subexpression_in_stmt,
..fixup
},
);
self.print_expr_maybe_paren(expr, prec, fixup.leftmost_subexpression());
self.space();
self.word_space("as");
self.print_type(ty);
@ -660,70 +548,34 @@ impl<'a> State<'a> {
self.print_block_with_attrs(blk, attrs);
}
ast::ExprKind::Await(expr, _) => {
// Same fixups as ExprKind::MethodCall.
self.print_expr_maybe_paren(expr, parser::PREC_POSTFIX, fixup);
self.word(".await");
}
ast::ExprKind::Assign(lhs, rhs, _) => {
// Same fixups as ExprKind::Binary.
let prec = AssocOp::Assign.precedence() as i8;
self.print_expr_maybe_paren(
lhs,
prec + 1,
FixupContext {
stmt: false,
leftmost_subexpression_in_stmt: fixup.stmt
|| fixup.leftmost_subexpression_in_stmt,
..fixup
},
);
self.print_expr_maybe_paren(lhs, prec + 1, fixup.leftmost_subexpression());
self.space();
self.word_space("=");
self.print_expr_maybe_paren(
rhs,
prec,
FixupContext { stmt: false, leftmost_subexpression_in_stmt: false, ..fixup },
);
self.print_expr_maybe_paren(rhs, prec, fixup.subsequent_subexpression());
}
ast::ExprKind::AssignOp(op, lhs, rhs) => {
// Same fixups as ExprKind::Binary.
let prec = AssocOp::Assign.precedence() as i8;
self.print_expr_maybe_paren(
lhs,
prec + 1,
FixupContext {
stmt: false,
leftmost_subexpression_in_stmt: fixup.stmt
|| fixup.leftmost_subexpression_in_stmt,
..fixup
},
);
self.print_expr_maybe_paren(lhs, prec + 1, fixup.leftmost_subexpression());
self.space();
self.word(op.node.as_str());
self.word_space("=");
self.print_expr_maybe_paren(
rhs,
prec,
FixupContext { stmt: false, leftmost_subexpression_in_stmt: false, ..fixup },
);
self.print_expr_maybe_paren(rhs, prec, fixup.subsequent_subexpression());
}
ast::ExprKind::Field(expr, ident) => {
// Same fixups as ExprKind::MethodCall.
self.print_expr_maybe_paren(expr, parser::PREC_POSTFIX, fixup);
self.word(".");
self.print_ident(*ident);
}
ast::ExprKind::Index(expr, index, _) => {
// Same fixups as ExprKind::Call.
self.print_expr_maybe_paren(
expr,
parser::PREC_POSTFIX,
FixupContext {
stmt: false,
leftmost_subexpression_in_stmt: fixup.stmt
|| fixup.leftmost_subexpression_in_stmt,
..fixup
},
fixup.leftmost_subexpression(),
);
self.word("[");
self.print_expr(index, FixupContext::default());
@ -736,31 +588,14 @@ impl<'a> State<'a> {
// a "normal" binop gets parenthesized. (`LOr` is the lowest-precedence binop.)
let fake_prec = AssocOp::LOr.precedence() as i8;
if let Some(e) = start {
self.print_expr_maybe_paren(
e,
fake_prec,
FixupContext {
stmt: false,
leftmost_subexpression_in_stmt: fixup.stmt
|| fixup.leftmost_subexpression_in_stmt,
..fixup
},
);
self.print_expr_maybe_paren(e, fake_prec, fixup.leftmost_subexpression());
}
match limits {
ast::RangeLimits::HalfOpen => self.word(".."),
ast::RangeLimits::Closed => self.word("..="),
}
if let Some(e) = end {
self.print_expr_maybe_paren(
e,
fake_prec,
FixupContext {
stmt: false,
leftmost_subexpression_in_stmt: false,
..fixup
},
);
self.print_expr_maybe_paren(e, fake_prec, fixup.subsequent_subexpression());
}
}
ast::ExprKind::Underscore => self.word("_"),
@ -777,11 +612,7 @@ impl<'a> State<'a> {
self.print_expr_maybe_paren(
expr,
parser::PREC_JUMP,
FixupContext {
stmt: false,
leftmost_subexpression_in_stmt: false,
..fixup
},
fixup.subsequent_subexpression(),
);
}
}
@ -799,11 +630,7 @@ impl<'a> State<'a> {
self.print_expr_maybe_paren(
expr,
parser::PREC_JUMP,
FixupContext {
stmt: false,
leftmost_subexpression_in_stmt: false,
..fixup
},
fixup.subsequent_subexpression(),
);
}
}
@ -816,11 +643,7 @@ impl<'a> State<'a> {
self.print_expr_maybe_paren(
expr,
parser::PREC_JUMP,
FixupContext {
stmt: false,
leftmost_subexpression_in_stmt: false,
..fixup
},
fixup.subsequent_subexpression(),
);
}
}
@ -830,7 +653,7 @@ impl<'a> State<'a> {
self.print_expr_maybe_paren(
result,
parser::PREC_JUMP,
FixupContext { stmt: false, leftmost_subexpression_in_stmt: false, ..fixup },
fixup.subsequent_subexpression(),
);
}
ast::ExprKind::InlineAsm(a) => {
@ -884,16 +707,11 @@ impl<'a> State<'a> {
self.print_expr_maybe_paren(
expr,
parser::PREC_JUMP,
FixupContext {
stmt: false,
leftmost_subexpression_in_stmt: false,
..fixup
},
fixup.subsequent_subexpression(),
);
}
}
ast::ExprKind::Try(e) => {
// Same fixups as ExprKind::MethodCall.
self.print_expr_maybe_paren(e, parser::PREC_POSTFIX, fixup);
self.word("?")
}
@ -961,7 +779,7 @@ impl<'a> State<'a> {
}
_ => {
self.end(); // Close the ibox for the pattern.
self.print_expr(body, FixupContext { stmt: true, ..FixupContext::default() });
self.print_expr(body, FixupContext::new_stmt());
self.word(",");
}
}

View File

@ -0,0 +1,149 @@
use rustc_ast::util::{classify, parser};
use rustc_ast::Expr;
#[derive(Copy, Clone, Debug)]
pub(crate) struct FixupContext {
/// Print expression such that it can be parsed back as a statement
/// consisting of the original expression.
///
/// The effect of this is for binary operators in statement position to set
/// `leftmost_subexpression_in_stmt` when printing their left-hand operand.
///
/// ```ignore (illustrative)
/// (match x {}) - 1; // match needs parens when LHS of binary operator
///
/// match x {}; // not when its own statement
/// ```
stmt: bool,
/// This is the difference between:
///
/// ```ignore (illustrative)
/// (match x {}) - 1; // subexpression needs parens
///
/// let _ = match x {} - 1; // no parens
/// ```
///
/// There are 3 distinguishable contexts in which `print_expr` might be
/// called with the expression `$match` as its argument, where `$match`
/// represents an expression of kind `ExprKind::Match`:
///
/// - stmt=false leftmost_subexpression_in_stmt=false
///
/// Example: `let _ = $match - 1;`
///
/// No parentheses required.
///
/// - stmt=false leftmost_subexpression_in_stmt=true
///
/// Example: `$match - 1;`
///
/// Must parenthesize `($match)`, otherwise parsing back the output as a
/// statement would terminate the statement after the closing brace of
/// the match, parsing `-1;` as a separate statement.
///
/// - stmt=true leftmost_subexpression_in_stmt=false
///
/// Example: `$match;`
///
/// No parentheses required.
leftmost_subexpression_in_stmt: bool,
/// This is the difference between:
///
/// ```ignore (illustrative)
/// if let _ = (Struct {}) {} // needs parens
///
/// match () {
/// () if let _ = Struct {} => {} // no parens
/// }
/// ```
parenthesize_exterior_struct_lit: bool,
}
/// The default amount of fixing is minimal fixing. Fixups should be turned on
/// in a targeted fashion where needed.
impl Default for FixupContext {
fn default() -> Self {
FixupContext {
stmt: false,
leftmost_subexpression_in_stmt: false,
parenthesize_exterior_struct_lit: false,
}
}
}
impl FixupContext {
/// Create the initial fixup for printing an expression in statement
/// position.
///
/// This is currently also used for printing an expression as a match-arm,
/// but this is incorrect and leads to over-parenthesizing.
pub fn new_stmt() -> Self {
FixupContext { stmt: true, ..FixupContext::default() }
}
/// Create the initial fixup for printing an expression as the "condition"
/// of an `if` or `while`. There are a few other positions which are
/// grammatically equivalent and also use this, such as the iterator
/// expression in `for` and the scrutinee in `match`.
pub fn new_cond() -> Self {
FixupContext { parenthesize_exterior_struct_lit: true, ..FixupContext::default() }
}
/// Transform this fixup into the one that should apply when printing the
/// leftmost subexpression of the current expression.
///
/// The leftmost subexpression is any subexpression that has the same first
/// token as the current expression, but has a different last token.
///
/// For example in `$a + $b` and `$a.method()`, the subexpression `$a` is a
/// leftmost subexpression.
///
/// Not every expression has a leftmost subexpression. For example neither
/// `-$a` nor `[$a]` have one.
pub fn leftmost_subexpression(self) -> Self {
FixupContext {
stmt: false,
leftmost_subexpression_in_stmt: self.stmt || self.leftmost_subexpression_in_stmt,
..self
}
}
/// Transform this fixup into the one that should apply when printing any
/// subexpression that is neither a leftmost subexpression nor surrounded in
/// delimiters.
///
/// This is for any subexpression that has a different first token than the
/// current expression, and is not surrounded by a paren/bracket/brace. For
/// example the `$b` in `$a + $b` and `-$b`, but not the one in `[$b]` or
/// `$a.f($b)`.
pub fn subsequent_subexpression(self) -> Self {
FixupContext { stmt: false, leftmost_subexpression_in_stmt: false, ..self }
}
/// Determine whether parentheses are needed around the given expression to
/// head off an unintended statement boundary.
///
/// The documentation on `FixupContext::leftmost_subexpression_in_stmt` has
/// examples.
pub fn would_cause_statement_boundary(self, expr: &Expr) -> bool {
self.leftmost_subexpression_in_stmt && !classify::expr_requires_semi_to_be_stmt(expr)
}
/// Determine whether parentheses are needed around the given `let`
/// scrutinee.
///
/// In `if let _ = $e {}`, some examples of `$e` that would need parentheses
/// are:
///
/// - `Struct {}.f()`, because otherwise the `{` would be misinterpreted
/// as the opening of the if's then-block.
///
/// - `true && false`, because otherwise this would be misinterpreted as a
/// "let chain".
pub fn needs_par_as_let_scrutinee(self, expr: &Expr) -> bool {
self.parenthesize_exterior_struct_lit && parser::contains_exterior_struct_lit(expr)
|| parser::needs_par_as_let_scrutinee(expr.precedence().order())
}
}

View File

@ -1,5 +1,5 @@
use crate::pp::Breaks::Inconsistent;
use crate::pprust::state::expr::FixupContext;
use crate::pprust::state::fixup::FixupContext;
use crate::pprust::state::{AnnNode, PrintState, State, INDENT_UNIT};
use ast::StaticItem;

View File

@ -1,4 +1,13 @@
#![feature(no_core, lang_items, never_type, linkage, extern_types, thread_local, repr_simd)]
#![feature(
no_core,
lang_items,
never_type,
linkage,
extern_types,
thread_local,
repr_simd,
raw_ref_op
)]
#![no_core]
#![allow(dead_code, non_camel_case_types, internal_features)]
@ -112,9 +121,7 @@ fn start<T: Termination + 'static>(
static mut NUM: u8 = 6 * 7;
// FIXME: Use `SyncUnsafeCell` instead of allowing `static_mut_refs` lint
#[allow(static_mut_refs)]
static NUM_REF: &'static u8 = unsafe { &NUM };
static NUM_REF: &'static u8 = unsafe { &*&raw const NUM };
unsafe fn zeroed<T>() -> T {
let mut uninit = MaybeUninit { uninit: () };

View File

@ -2,7 +2,7 @@
#![feature(
no_core, unboxed_closures, start, lang_items, never_type, linkage,
extern_types, thread_local
extern_types, thread_local, raw_ref_op
)]
#![no_core]
#![allow(dead_code, internal_features, non_camel_case_types)]
@ -99,9 +99,7 @@ fn start<T: Termination + 'static>(
static mut NUM: u8 = 6 * 7;
// FIXME: Use `SyncUnsafeCell` instead of allowing `static_mut_refs` lint
#[allow(static_mut_refs)]
static NUM_REF: &'static u8 = unsafe { &NUM };
static NUM_REF: &'static u8 = unsafe { &* &raw const NUM };
macro_rules! assert {
($e:expr) => {

View File

@ -730,7 +730,7 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> {
} }
#[rustc_lint_diagnostics]
fn highlighted_note(&mut self, msg: Vec<StringPart>) -> &mut Self {
pub fn highlighted_note(&mut self, msg: Vec<StringPart>) -> &mut Self {
self.sub_with_highlights(Level::Note, msg, MultiSpan::new());
self
}

View File

@ -61,7 +61,7 @@ use crate::traits::{
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
use rustc_errors::{
codes::*, pluralize, struct_span_code_err, Applicability, Diag, DiagCtxt, DiagStyledString,
ErrorGuaranteed, IntoDiagArg,
ErrorGuaranteed, IntoDiagArg, StringPart,
};
use rustc_hir as hir;
use rustc_hir::def::DefKind;
@ -1917,6 +1917,23 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
);
if !is_simple_error || terr.must_include_note() {
diag.note_expected_found(&expected_label, expected, &found_label, found);
if let Some(ty::Closure(_, args)) =
exp_found.map(|expected_type_found| expected_type_found.found.kind())
{
diag.highlighted_note(vec![
StringPart::normal("closure has signature: `"),
StringPart::highlighted(
self.tcx
.signature_unclosure(
args.as_closure().sig(),
rustc_hir::Unsafety::Normal,
)
.to_string(),
),
StringPart::normal("`"),
]);
}
}
}
}

View File

@ -1522,6 +1522,7 @@ extern "C" void LLVMRustFreeOperandBundleDef(OperandBundleDef *Bundle) {
delete Bundle;
}
// OpBundlesIndirect is an array of pointers (*not* a pointer to an array).
extern "C" LLVMValueRef LLVMRustBuildCall(LLVMBuilderRef B, LLVMTypeRef Ty, LLVMValueRef Fn,
LLVMValueRef *Args, unsigned NumArgs,
OperandBundleDef **OpBundlesIndirect,
@ -1601,6 +1602,7 @@ extern "C" LLVMValueRef LLVMRustBuildMemSet(LLVMBuilderRef B,
unwrap(Dst), unwrap(Val), unwrap(Size), MaybeAlign(DstAlign), IsVolatile));
}
// OpBundlesIndirect is an array of pointers (*not* a pointer to an array).
extern "C" LLVMValueRef
LLVMRustBuildInvoke(LLVMBuilderRef B, LLVMTypeRef Ty, LLVMValueRef Fn,
LLVMValueRef *Args, unsigned NumArgs,
@ -1623,6 +1625,7 @@ LLVMRustBuildInvoke(LLVMBuilderRef B, LLVMTypeRef Ty, LLVMValueRef Fn,
Name));
}
// OpBundlesIndirect is an array of pointers (*not* a pointer to an array).
extern "C" LLVMValueRef
LLVMRustBuildCallBr(LLVMBuilderRef B, LLVMTypeRef Ty, LLVMValueRef Fn,
LLVMBasicBlockRef DefaultDest,

View File

@ -537,7 +537,11 @@ impl () {}
/// ## 4. Get it from C.
///
/// ```
/// # #![feature(rustc_private)]
/// # mod libc {
/// # pub unsafe fn malloc(_size: usize) -> *mut core::ffi::c_void { core::ptr::NonNull::dangling().as_ptr() }
/// # pub unsafe fn free(_ptr: *mut core::ffi::c_void) {}
/// # }
/// # #[cfg(any())]
/// #[allow(unused_extern_crates)]
/// extern crate libc;
///
@ -548,7 +552,7 @@ impl () {}
/// if my_num.is_null() {
/// panic!("failed to allocate memory");
/// }
/// libc::free(my_num as *mut libc::c_void);
/// libc::free(my_num as *mut core::ffi::c_void);
/// }
/// ```
///

View File

@ -214,7 +214,7 @@ pub struct Permissions(fs_imp::FilePermissions);
/// A structure representing a type of file with accessors for each file type.
/// It is returned by [`Metadata::file_type`] method.
#[stable(feature = "file_type", since = "1.1.0")]
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
#[cfg_attr(not(test), rustc_diagnostic_item = "FileType")]
pub struct FileType(fs_imp::FileType);
@ -1410,15 +1410,20 @@ impl Metadata {
#[stable(feature = "std_debug", since = "1.16.0")]
impl fmt::Debug for Metadata {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Metadata")
.field("file_type", &self.file_type())
.field("is_dir", &self.is_dir())
.field("is_file", &self.is_file())
.field("permissions", &self.permissions())
.field("modified", &self.modified())
.field("accessed", &self.accessed())
.field("created", &self.created())
.finish_non_exhaustive()
let mut debug = f.debug_struct("Metadata");
debug.field("file_type", &self.file_type());
debug.field("permissions", &self.permissions());
debug.field("len", &self.len());
if let Ok(modified) = self.modified() {
debug.field("modified", &modified);
}
if let Ok(accessed) = self.accessed() {
debug.field("accessed", &accessed);
}
if let Ok(created) = self.created() {
debug.field("created", &created);
}
debug.finish_non_exhaustive()
}
}
@ -1684,6 +1689,17 @@ impl FileType {
}
}
#[stable(feature = "std_debug", since = "1.16.0")]
impl fmt::Debug for FileType {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("FileType")
.field("is_file", &self.is_file())
.field("is_dir", &self.is_dir())
.field("is_symlink", &self.is_symlink())
.finish_non_exhaustive()
}
}
impl AsInner<fs_imp::FileType> for FileType {
#[inline]
fn as_inner(&self) -> &fs_imp::FileType {

View File

@ -11,8 +11,6 @@ pub macro thread_local_inner {
(@key $t:ty, const $init:expr) => {{
#[inline] // see comments below
#[deny(unsafe_op_in_unsafe_fn)]
// FIXME: Use `SyncUnsafeCell` instead of allowing `static_mut_refs` lint
#[allow(static_mut_refs)]
unsafe fn __getit(
_init: $crate::option::Option<&mut $crate::option::Option<$t>>,
) -> $crate::option::Option<&'static $t> {
@ -25,7 +23,8 @@ pub macro thread_local_inner {
// FIXME(#84224) this should come after the `target_thread_local`
// block.
static mut VAL: $t = INIT_EXPR;
unsafe { $crate::option::Option::Some(&VAL) }
// SAFETY: we only ever create shared references, so there's no mutable aliasing.
unsafe { $crate::option::Option::Some(&*$crate::ptr::addr_of!(VAL)) }
}
unsafe {

View File

@ -464,7 +464,8 @@ impl Builder {
| PkgType::LlvmTools
| PkgType::RustAnalysis
| PkgType::JsonDocs
| PkgType::RustcCodegenCranelift => {
| PkgType::RustcCodegenCranelift
| PkgType::LlvmBitcodeLinker => {
extensions.push(host_component(pkg));
}
PkgType::RustcDev | PkgType::RustcDocs => {

View File

@ -58,6 +58,7 @@ pkg_type! {
Miri = "miri"; preview = true,
JsonDocs = "rust-docs-json"; preview = true,
RustcCodegenCranelift = "rustc-codegen-cranelift"; preview = true,
LlvmBitcodeLinker = "llvm-bitcode-linker"; preview = true,
}
impl PkgType {
@ -94,6 +95,7 @@ impl PkgType {
PkgType::ReproducibleArtifacts => true,
PkgType::RustMingw => true,
PkgType::RustAnalysis => true,
PkgType::LlvmBitcodeLinker => true,
}
}
@ -121,6 +123,7 @@ impl PkgType {
Rustfmt => HOSTS,
RustAnalysis => TARGETS,
LlvmTools => TARGETS,
LlvmBitcodeLinker => HOSTS,
}
}

View File

@ -244,7 +244,7 @@ mod directives {
pub const STDERR_PER_BITWIDTH: &'static str = "stderr-per-bitwidth";
pub const INCREMENTAL: &'static str = "incremental";
pub const KNOWN_BUG: &'static str = "known-bug";
pub const MIR_UNIT_TEST: &'static str = "unit-test";
pub const TEST_MIR_PASS: &'static str = "test-mir-pass";
pub const REMAP_SRC_BASE: &'static str = "remap-src-base";
pub const COMPARE_OUTPUT_LINES_BY_SUBSET: &'static str = "compare-output-lines-by-subset";
pub const LLVM_COV_FLAGS: &'static str = "llvm-cov-flags";
@ -549,7 +549,7 @@ impl TestProps {
config.set_name_value_directive(
ln,
MIR_UNIT_TEST,
TEST_MIR_PASS,
&mut self.mir_unit_test,
|s| s.trim().to_string(),
);
@ -922,7 +922,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[
"should-fail",
"should-ice",
"stderr-per-bitwidth",
"unit-test",
"test-mir-pass",
"unset-exec-env",
"unset-rustc-env",
// tidy-alphabetical-end

View File

@ -7,6 +7,43 @@ use walkdir::WalkDir;
mod groups;
/// List of lints which have been renamed.
///
/// These will get redirects in the output to the new name. The
/// format is `(level, [(old_name, new_name), ...])`.
///
/// Note: This hard-coded list is a temporary hack. The intent is in the
/// future to have `rustc` expose this information in some way (like a `-Z`
/// flag spitting out JSON). Also, this does not yet support changing the
/// level of the lint, which will be more difficult to support, since rustc
/// currently does not track that historical information.
static RENAMES: &[(Level, &[(&str, &str)])] = &[
(
Level::Allow,
&[
("single-use-lifetime", "single-use-lifetimes"),
("elided-lifetime-in-path", "elided-lifetimes-in-paths"),
("async-idents", "keyword-idents"),
("disjoint-capture-migration", "rust-2021-incompatible-closure-captures"),
("or-patterns-back-compat", "rust-2021-incompatible-or-patterns"),
],
),
(
Level::Warn,
&[
("bare-trait-object", "bare-trait-objects"),
("unstable-name-collision", "unstable-name-collisions"),
("unused-doc-comment", "unused-doc-comments"),
("redundant-semicolon", "redundant-semicolons"),
("overlapping-patterns", "overlapping-range-endpoints"),
("non-fmt-panic", "non-fmt-panics"),
("unused-tuple-struct-fields", "dead-code"),
("static-mut-ref", "static-mut-refs"),
],
),
(Level::Deny, &[("exceeding-bitshifts", "arithmetic-overflow")]),
];
pub struct LintExtractor<'a> {
/// Path to the `src` directory, where it will scan for `.rs` files to
/// find lint declarations.
@ -126,6 +163,7 @@ impl<'a> LintExtractor<'a> {
)
})?;
}
add_renamed_lints(&mut lints);
self.save_lints_markdown(&lints)?;
self.generate_group_docs(&lints)?;
Ok(())
@ -482,6 +520,7 @@ impl<'a> LintExtractor<'a> {
}
result.push('\n');
}
add_rename_redirect(level, &mut result);
let out_path = self.out_path.join("listing").join(level.doc_filename());
// Delete the output because rustbuild uses hard links in its copies.
let _ = fs::remove_file(&out_path);
@ -491,6 +530,56 @@ impl<'a> LintExtractor<'a> {
}
}
/// Adds `Lint`s that have been renamed.
fn add_renamed_lints(lints: &mut Vec<Lint>) {
for (level, names) in RENAMES {
for (from, to) in *names {
lints.push(Lint {
name: from.to_string(),
doc: vec![format!("The lint `{from}` has been renamed to [`{to}`](#{to}).")],
level: *level,
path: PathBuf::new(),
lineno: 0,
});
}
}
}
// This uses DOMContentLoaded instead of running immediately because for some
// reason on Firefox (124 of this writing) doesn't update the `target` CSS
// selector if only the hash changes.
static RENAME_START: &str = "
<script>
document.addEventListener(\"DOMContentLoaded\", (event) => {
var fragments = {
";
static RENAME_END: &str = "\
};
var target = fragments[window.location.hash];
if (target) {
var url = window.location.toString();
var base = url.substring(0, url.lastIndexOf('/'));
window.location.replace(base + \"/\" + target);
}
});
</script>
";
/// Adds the javascript redirection code to the given markdown output.
fn add_rename_redirect(level: Level, output: &mut String) {
for (rename_level, names) in RENAMES {
if *rename_level == level {
let filename = level.doc_filename().replace(".md", ".html");
output.push_str(RENAME_START);
for (from, to) in *names {
write!(output, " \"#{from}\": \"{filename}#{to}\",\n").unwrap();
}
output.push_str(RENAME_END);
}
}
}
/// Extracts the lint name (removing the visibility modifier, and checking validity).
fn lint_name(line: &str) -> Result<String, &'static str> {
// Skip over any potential `pub` visibility.

View File

@ -1,4 +1,4 @@
Function name: branch_generics::print_size::<()>
Function name: generics::print_size::<()>
Raw bytes (35): 0x[01, 01, 02, 01, 05, 05, 02, 05, 01, 06, 01, 01, 24, 20, 05, 02, 01, 08, 00, 24, 05, 00, 25, 02, 06, 02, 02, 0c, 02, 06, 07, 03, 01, 00, 02]
Number of files: 1
- file 0 => global file 1
@ -16,7 +16,7 @@ Number of file 0 mappings: 5
- Code(Expression(1, Add)) at (prev + 3, 1) to (start + 0, 2)
= (c1 + (c0 - c1))
Function name: branch_generics::print_size::<u32>
Function name: generics::print_size::<u32>
Raw bytes (35): 0x[01, 01, 02, 01, 05, 05, 02, 05, 01, 06, 01, 01, 24, 20, 05, 02, 01, 08, 00, 24, 05, 00, 25, 02, 06, 02, 02, 0c, 02, 06, 07, 03, 01, 00, 02]
Number of files: 1
- file 0 => global file 1
@ -34,7 +34,7 @@ Number of file 0 mappings: 5
- Code(Expression(1, Add)) at (prev + 3, 1) to (start + 0, 2)
= (c1 + (c0 - c1))
Function name: branch_generics::print_size::<u64>
Function name: generics::print_size::<u64>
Raw bytes (35): 0x[01, 01, 02, 01, 05, 05, 02, 05, 01, 06, 01, 01, 24, 20, 05, 02, 01, 08, 00, 24, 05, 00, 25, 02, 06, 02, 02, 0c, 02, 06, 07, 03, 01, 00, 02]
Number of files: 1
- file 0 => global file 1

View File

@ -16,7 +16,7 @@
LL| 2| }
LL| 3|}
------------------
| branch_generics::print_size::<()>:
| generics::print_size::<()>:
| LL| 1|fn print_size<T>() {
| LL| 1| if std::mem::size_of::<T>() > 4 {
| ------------------
@ -28,7 +28,7 @@
| LL| 1| }
| LL| 1|}
------------------
| branch_generics::print_size::<u32>:
| generics::print_size::<u32>:
| LL| 1|fn print_size<T>() {
| LL| 1| if std::mem::size_of::<T>() > 4 {
| ------------------
@ -40,7 +40,7 @@
| LL| 1| }
| LL| 1|}
------------------
| branch_generics::print_size::<u64>:
| generics::print_size::<u64>:
| LL| 1|fn print_size<T>() {
| LL| 1| if std::mem::size_of::<T>() > 4 {
| ------------------

View File

@ -1,4 +1,4 @@
Function name: branch_guard::branch_match_guard
Function name: guard::branch_match_guard
Raw bytes (85): 0x[01, 01, 06, 19, 0d, 05, 09, 0f, 15, 13, 11, 17, 0d, 05, 09, 0d, 01, 0c, 01, 01, 10, 1d, 03, 0b, 00, 0c, 15, 01, 14, 02, 0a, 0d, 03, 0e, 00, 0f, 19, 00, 14, 00, 19, 20, 0d, 02, 00, 14, 00, 1e, 0d, 00, 1d, 02, 0a, 11, 03, 0e, 00, 0f, 1d, 00, 14, 00, 19, 20, 11, 09, 00, 14, 00, 1e, 11, 00, 1d, 02, 0a, 17, 03, 0e, 02, 0a, 0b, 04, 01, 00, 02]
Number of files: 1
- file 0 => global file 1

View File

@ -1,4 +1,4 @@
Function name: branch_if::branch_and
Function name: if::branch_and
Raw bytes (56): 0x[01, 01, 04, 05, 09, 0d, 02, 11, 0f, 0d, 02, 08, 01, 2b, 01, 01, 10, 05, 03, 08, 00, 09, 20, 09, 02, 00, 08, 00, 09, 09, 00, 0d, 00, 0e, 20, 11, 0d, 00, 0d, 00, 0e, 11, 00, 0f, 02, 06, 0f, 02, 0c, 02, 06, 0b, 03, 01, 00, 02]
Number of files: 1
- file 0 => global file 1
@ -23,7 +23,7 @@ Number of file 0 mappings: 8
- Code(Expression(2, Add)) at (prev + 3, 1) to (start + 0, 2)
= (c4 + (c3 + (c1 - c2)))
Function name: branch_if::branch_not
Function name: if::branch_not
Raw bytes (224): 0x[01, 01, 29, 05, 09, 09, 02, a3, 01, 0d, 09, 02, a3, 01, 0d, 09, 02, 0d, 9e, 01, a3, 01, 0d, 09, 02, 9b, 01, 11, 0d, 9e, 01, a3, 01, 0d, 09, 02, 9b, 01, 11, 0d, 9e, 01, a3, 01, 0d, 09, 02, 11, 96, 01, 9b, 01, 11, 0d, 9e, 01, a3, 01, 0d, 09, 02, 93, 01, 15, 11, 96, 01, 9b, 01, 11, 0d, 9e, 01, a3, 01, 0d, 09, 02, 93, 01, 15, 11, 96, 01, 9b, 01, 11, 0d, 9e, 01, a3, 01, 0d, 09, 02, 15, 8e, 01, 93, 01, 15, 11, 96, 01, 9b, 01, 11, 0d, 9e, 01, a3, 01, 0d, 09, 02, 12, 01, 0c, 01, 01, 10, 05, 03, 08, 00, 09, 20, 09, 02, 00, 08, 00, 09, 09, 01, 09, 00, 11, 02, 01, 06, 00, 07, a3, 01, 01, 08, 00, 0a, 20, 9e, 01, 0d, 00, 08, 00, 0a, 9e, 01, 00, 0b, 02, 06, 0d, 02, 06, 00, 07, 9b, 01, 01, 08, 00, 0b, 20, 11, 96, 01, 00, 08, 00, 0b, 11, 00, 0c, 02, 06, 96, 01, 02, 06, 00, 07, 93, 01, 01, 08, 00, 0c, 20, 8e, 01, 15, 00, 08, 00, 0c, 8e, 01, 00, 0d, 02, 06, 15, 02, 06, 00, 07, 8b, 01, 01, 01, 00, 02]
Number of files: 1
- file 0 => global file 1
@ -105,7 +105,7 @@ Number of file 0 mappings: 18
- Code(Expression(34, Add)) at (prev + 1, 1) to (start + 0, 2)
= (c5 + ((c4 + ((c3 + ((c2 + (c1 - c2)) - c3)) - c4)) - c5))
Function name: branch_if::branch_not_as
Function name: if::branch_not_as
Raw bytes (124): 0x[01, 01, 16, 05, 09, 09, 02, 57, 0d, 09, 02, 57, 0d, 09, 02, 0d, 52, 57, 0d, 09, 02, 4f, 11, 0d, 52, 57, 0d, 09, 02, 4f, 11, 0d, 52, 57, 0d, 09, 02, 11, 4a, 4f, 11, 0d, 52, 57, 0d, 09, 02, 0e, 01, 1d, 01, 01, 10, 05, 03, 08, 00, 14, 20, 02, 09, 00, 08, 00, 14, 02, 00, 15, 02, 06, 09, 02, 06, 00, 07, 57, 01, 08, 00, 15, 20, 0d, 52, 00, 08, 00, 15, 0d, 00, 16, 02, 06, 52, 02, 06, 00, 07, 4f, 01, 08, 00, 16, 20, 4a, 11, 00, 08, 00, 16, 4a, 00, 17, 02, 06, 11, 02, 06, 00, 07, 47, 01, 01, 00, 02]
Number of files: 1
- file 0 => global file 1
@ -160,7 +160,7 @@ Number of file 0 mappings: 14
- Code(Expression(17, Add)) at (prev + 1, 1) to (start + 0, 2)
= (c4 + ((c3 + ((c2 + (c1 - c2)) - c3)) - c4))
Function name: branch_if::branch_or
Function name: if::branch_or
Raw bytes (56): 0x[01, 01, 04, 05, 09, 09, 0d, 0f, 11, 09, 0d, 08, 01, 35, 01, 01, 10, 05, 03, 08, 00, 09, 20, 09, 02, 00, 08, 00, 09, 02, 00, 0d, 00, 0e, 20, 0d, 11, 00, 0d, 00, 0e, 0f, 00, 0f, 02, 06, 11, 02, 0c, 02, 06, 0b, 03, 01, 00, 02]
Number of files: 1
- file 0 => global file 1

View File

@ -0,0 +1,177 @@
Function name: lazy_boolean::branch_and
Raw bytes (42): 0x[01, 01, 03, 09, 0a, 05, 09, 05, 09, 06, 01, 13, 01, 01, 10, 03, 04, 09, 00, 0a, 05, 00, 0d, 00, 0e, 20, 09, 0a, 00, 0d, 00, 0e, 09, 00, 12, 00, 13, 03, 01, 05, 01, 02]
Number of files: 1
- file 0 => global file 1
Number of expressions: 3
- expression 0 operands: lhs = Counter(2), rhs = Expression(2, Sub)
- expression 1 operands: lhs = Counter(1), rhs = Counter(2)
- expression 2 operands: lhs = Counter(1), rhs = Counter(2)
Number of file 0 mappings: 6
- Code(Counter(0)) at (prev + 19, 1) to (start + 1, 16)
- Code(Expression(0, Add)) at (prev + 4, 9) to (start + 0, 10)
= (c2 + (c1 - c2))
- Code(Counter(1)) at (prev + 0, 13) to (start + 0, 14)
- Branch { true: Counter(2), false: Expression(2, Sub) } at (prev + 0, 13) to (start + 0, 14)
true = c2
false = (c1 - c2)
- Code(Counter(2)) at (prev + 0, 18) to (start + 0, 19)
- Code(Expression(0, Add)) at (prev + 1, 5) to (start + 1, 2)
= (c2 + (c1 - c2))
Function name: lazy_boolean::branch_or
Raw bytes (44): 0x[01, 01, 04, 09, 0e, 05, 09, 05, 09, 05, 09, 06, 01, 1b, 01, 01, 10, 03, 04, 09, 00, 0a, 05, 00, 0d, 00, 0e, 20, 09, 0e, 00, 0d, 00, 0e, 0e, 00, 12, 00, 13, 03, 01, 05, 01, 02]
Number of files: 1
- file 0 => global file 1
Number of expressions: 4
- expression 0 operands: lhs = Counter(2), rhs = Expression(3, Sub)
- expression 1 operands: lhs = Counter(1), rhs = Counter(2)
- expression 2 operands: lhs = Counter(1), rhs = Counter(2)
- expression 3 operands: lhs = Counter(1), rhs = Counter(2)
Number of file 0 mappings: 6
- Code(Counter(0)) at (prev + 27, 1) to (start + 1, 16)
- Code(Expression(0, Add)) at (prev + 4, 9) to (start + 0, 10)
= (c2 + (c1 - c2))
- Code(Counter(1)) at (prev + 0, 13) to (start + 0, 14)
- Branch { true: Counter(2), false: Expression(3, Sub) } at (prev + 0, 13) to (start + 0, 14)
true = c2
false = (c1 - c2)
- Code(Expression(3, Sub)) at (prev + 0, 18) to (start + 0, 19)
= (c1 - c2)
- Code(Expression(0, Add)) at (prev + 1, 5) to (start + 1, 2)
= (c2 + (c1 - c2))
Function name: lazy_boolean::chain
Raw bytes (149): 0x[01, 01, 13, 11, 07, 0b, 16, 15, 1a, 09, 0d, 05, 09, 05, 09, 09, 0d, 47, 25, 4b, 21, 19, 1d, 03, 19, 03, 19, 3e, 1d, 03, 19, 3e, 1d, 03, 19, 47, 25, 4b, 21, 19, 1d, 13, 01, 24, 01, 01, 10, 03, 04, 09, 00, 0a, 05, 00, 0d, 00, 12, 20, 09, 16, 00, 0d, 00, 12, 09, 00, 16, 00, 1b, 20, 0d, 1a, 00, 16, 00, 1b, 0d, 00, 1f, 00, 24, 20, 11, 15, 00, 1f, 00, 24, 11, 00, 28, 00, 2d, 03, 01, 05, 00, 11, 43, 03, 09, 00, 0a, 03, 00, 0d, 00, 12, 20, 19, 3e, 00, 0d, 00, 12, 3e, 00, 16, 00, 1b, 20, 1d, 3a, 00, 16, 00, 1b, 3a, 00, 1f, 00, 24, 20, 21, 25, 00, 1f, 00, 24, 25, 00, 28, 00, 2d, 43, 01, 05, 01, 02]
Number of files: 1
- file 0 => global file 1
Number of expressions: 19
- expression 0 operands: lhs = Counter(4), rhs = Expression(1, Add)
- expression 1 operands: lhs = Expression(2, Add), rhs = Expression(5, Sub)
- expression 2 operands: lhs = Counter(5), rhs = Expression(6, Sub)
- expression 3 operands: lhs = Counter(2), rhs = Counter(3)
- expression 4 operands: lhs = Counter(1), rhs = Counter(2)
- expression 5 operands: lhs = Counter(1), rhs = Counter(2)
- expression 6 operands: lhs = Counter(2), rhs = Counter(3)
- expression 7 operands: lhs = Expression(17, Add), rhs = Counter(9)
- expression 8 operands: lhs = Expression(18, Add), rhs = Counter(8)
- expression 9 operands: lhs = Counter(6), rhs = Counter(7)
- expression 10 operands: lhs = Expression(0, Add), rhs = Counter(6)
- expression 11 operands: lhs = Expression(0, Add), rhs = Counter(6)
- expression 12 operands: lhs = Expression(15, Sub), rhs = Counter(7)
- expression 13 operands: lhs = Expression(0, Add), rhs = Counter(6)
- expression 14 operands: lhs = Expression(15, Sub), rhs = Counter(7)
- expression 15 operands: lhs = Expression(0, Add), rhs = Counter(6)
- expression 16 operands: lhs = Expression(17, Add), rhs = Counter(9)
- expression 17 operands: lhs = Expression(18, Add), rhs = Counter(8)
- expression 18 operands: lhs = Counter(6), rhs = Counter(7)
Number of file 0 mappings: 19
- Code(Counter(0)) at (prev + 36, 1) to (start + 1, 16)
- Code(Expression(0, Add)) at (prev + 4, 9) to (start + 0, 10)
= (c4 + ((c5 + (c2 - c3)) + (c1 - c2)))
- Code(Counter(1)) at (prev + 0, 13) to (start + 0, 18)
- Branch { true: Counter(2), false: Expression(5, Sub) } at (prev + 0, 13) to (start + 0, 18)
true = c2
false = (c1 - c2)
- Code(Counter(2)) at (prev + 0, 22) to (start + 0, 27)
- Branch { true: Counter(3), false: Expression(6, Sub) } at (prev + 0, 22) to (start + 0, 27)
true = c3
false = (c2 - c3)
- Code(Counter(3)) at (prev + 0, 31) to (start + 0, 36)
- Branch { true: Counter(4), false: Counter(5) } at (prev + 0, 31) to (start + 0, 36)
true = c4
false = c5
- Code(Counter(4)) at (prev + 0, 40) to (start + 0, 45)
- Code(Expression(0, Add)) at (prev + 1, 5) to (start + 0, 17)
= (c4 + ((c5 + (c2 - c3)) + (c1 - c2)))
- Code(Expression(16, Add)) at (prev + 3, 9) to (start + 0, 10)
= (((c6 + c7) + c8) + c9)
- Code(Expression(0, Add)) at (prev + 0, 13) to (start + 0, 18)
= (c4 + ((c5 + (c2 - c3)) + (c1 - c2)))
- Branch { true: Counter(6), false: Expression(15, Sub) } at (prev + 0, 13) to (start + 0, 18)
true = c6
false = ((c4 + ((c5 + (c2 - c3)) + (c1 - c2))) - c6)
- Code(Expression(15, Sub)) at (prev + 0, 22) to (start + 0, 27)
= ((c4 + ((c5 + (c2 - c3)) + (c1 - c2))) - c6)
- Branch { true: Counter(7), false: Expression(14, Sub) } at (prev + 0, 22) to (start + 0, 27)
true = c7
false = (((c4 + ((c5 + (c2 - c3)) + (c1 - c2))) - c6) - c7)
- Code(Expression(14, Sub)) at (prev + 0, 31) to (start + 0, 36)
= (((c4 + ((c5 + (c2 - c3)) + (c1 - c2))) - c6) - c7)
- Branch { true: Counter(8), false: Counter(9) } at (prev + 0, 31) to (start + 0, 36)
true = c8
false = c9
- Code(Counter(9)) at (prev + 0, 40) to (start + 0, 45)
- Code(Expression(16, Add)) at (prev + 1, 5) to (start + 1, 2)
= (((c6 + c7) + c8) + c9)
Function name: lazy_boolean::nested_mixed
Raw bytes (159): 0x[01, 01, 18, 07, 22, 11, 36, 3b, 11, 09, 0d, 26, 0d, 05, 09, 05, 09, 05, 09, 26, 0d, 05, 09, 09, 0d, 3b, 11, 09, 0d, 3b, 11, 09, 0d, 19, 5f, 1d, 21, 03, 15, 15, 19, 52, 56, 15, 19, 03, 15, 19, 5f, 1d, 21, 13, 01, 31, 01, 01, 10, 03, 04, 09, 00, 0a, 05, 00, 0e, 00, 13, 20, 09, 26, 00, 0e, 00, 13, 26, 00, 17, 00, 1d, 20, 0d, 22, 00, 17, 00, 1d, 3b, 00, 23, 00, 28, 20, 11, 36, 00, 23, 00, 28, 36, 00, 2c, 00, 33, 03, 01, 05, 00, 11, 5b, 03, 09, 00, 0a, 03, 00, 0e, 00, 13, 20, 15, 56, 00, 0e, 00, 13, 15, 00, 17, 00, 1c, 20, 19, 52, 00, 17, 00, 1c, 4f, 00, 22, 00, 28, 20, 1d, 21, 00, 22, 00, 28, 1d, 00, 2c, 00, 33, 5b, 01, 05, 01, 02]
Number of files: 1
- file 0 => global file 1
Number of expressions: 24
- expression 0 operands: lhs = Expression(1, Add), rhs = Expression(8, Sub)
- expression 1 operands: lhs = Counter(4), rhs = Expression(13, Sub)
- expression 2 operands: lhs = Expression(14, Add), rhs = Counter(4)
- expression 3 operands: lhs = Counter(2), rhs = Counter(3)
- expression 4 operands: lhs = Expression(9, Sub), rhs = Counter(3)
- expression 5 operands: lhs = Counter(1), rhs = Counter(2)
- expression 6 operands: lhs = Counter(1), rhs = Counter(2)
- expression 7 operands: lhs = Counter(1), rhs = Counter(2)
- expression 8 operands: lhs = Expression(9, Sub), rhs = Counter(3)
- expression 9 operands: lhs = Counter(1), rhs = Counter(2)
- expression 10 operands: lhs = Counter(2), rhs = Counter(3)
- expression 11 operands: lhs = Expression(14, Add), rhs = Counter(4)
- expression 12 operands: lhs = Counter(2), rhs = Counter(3)
- expression 13 operands: lhs = Expression(14, Add), rhs = Counter(4)
- expression 14 operands: lhs = Counter(2), rhs = Counter(3)
- expression 15 operands: lhs = Counter(6), rhs = Expression(23, Add)
- expression 16 operands: lhs = Counter(7), rhs = Counter(8)
- expression 17 operands: lhs = Expression(0, Add), rhs = Counter(5)
- expression 18 operands: lhs = Counter(5), rhs = Counter(6)
- expression 19 operands: lhs = Expression(20, Sub), rhs = Expression(21, Sub)
- expression 20 operands: lhs = Counter(5), rhs = Counter(6)
- expression 21 operands: lhs = Expression(0, Add), rhs = Counter(5)
- expression 22 operands: lhs = Counter(6), rhs = Expression(23, Add)
- expression 23 operands: lhs = Counter(7), rhs = Counter(8)
Number of file 0 mappings: 19
- Code(Counter(0)) at (prev + 49, 1) to (start + 1, 16)
- Code(Expression(0, Add)) at (prev + 4, 9) to (start + 0, 10)
= ((c4 + ((c2 + c3) - c4)) + ((c1 - c2) - c3))
- Code(Counter(1)) at (prev + 0, 14) to (start + 0, 19)
- Branch { true: Counter(2), false: Expression(9, Sub) } at (prev + 0, 14) to (start + 0, 19)
true = c2
false = (c1 - c2)
- Code(Expression(9, Sub)) at (prev + 0, 23) to (start + 0, 29)
= (c1 - c2)
- Branch { true: Counter(3), false: Expression(8, Sub) } at (prev + 0, 23) to (start + 0, 29)
true = c3
false = ((c1 - c2) - c3)
- Code(Expression(14, Add)) at (prev + 0, 35) to (start + 0, 40)
= (c2 + c3)
- Branch { true: Counter(4), false: Expression(13, Sub) } at (prev + 0, 35) to (start + 0, 40)
true = c4
false = ((c2 + c3) - c4)
- Code(Expression(13, Sub)) at (prev + 0, 44) to (start + 0, 51)
= ((c2 + c3) - c4)
- Code(Expression(0, Add)) at (prev + 1, 5) to (start + 0, 17)
= ((c4 + ((c2 + c3) - c4)) + ((c1 - c2) - c3))
- Code(Expression(22, Add)) at (prev + 3, 9) to (start + 0, 10)
= (c6 + (c7 + c8))
- Code(Expression(0, Add)) at (prev + 0, 14) to (start + 0, 19)
= ((c4 + ((c2 + c3) - c4)) + ((c1 - c2) - c3))
- Branch { true: Counter(5), false: Expression(21, Sub) } at (prev + 0, 14) to (start + 0, 19)
true = c5
false = (((c4 + ((c2 + c3) - c4)) + ((c1 - c2) - c3)) - c5)
- Code(Counter(5)) at (prev + 0, 23) to (start + 0, 28)
- Branch { true: Counter(6), false: Expression(20, Sub) } at (prev + 0, 23) to (start + 0, 28)
true = c6
false = (c5 - c6)
- Code(Expression(19, Add)) at (prev + 0, 34) to (start + 0, 40)
= ((c5 - c6) + (((c4 + ((c2 + c3) - c4)) + ((c1 - c2) - c3)) - c5))
- Branch { true: Counter(7), false: Counter(8) } at (prev + 0, 34) to (start + 0, 40)
true = c7
false = c8
- Code(Counter(7)) at (prev + 0, 44) to (start + 0, 51)
- Code(Expression(22, Add)) at (prev + 1, 5) to (start + 1, 2)
= (c6 + (c7 + c8))

View File

@ -0,0 +1,113 @@
LL| |#![feature(coverage_attribute)]
LL| |//@ edition: 2021
LL| |//@ compile-flags: -Zcoverage-options=branch
LL| |//@ llvm-cov-flags: --show-branches=count
LL| |
LL| |// Tests for branch coverage of the lazy boolean operators `&&` and `||`,
LL| |// as ordinary expressions that aren't part of an `if` condition or similar.
LL| |
LL| |use core::hint::black_box;
LL| |
LL| |// Helper macro to prevent start-of-function spans from being merged into
LL| |// spans on the lines we care about.
LL| |macro_rules! no_merge {
LL| | () => {
LL| | for _ in 0..1 {}
LL| | };
LL| |}
LL| |
LL| 15|fn branch_and(a: bool, b: bool) {
LL| 15| no_merge!();
LL| |
LL| | // |13 |18 (no branch)
LL| 15| let c = a && b;
^12
------------------
| Branch (LL:13): [True: 12, False: 3]
------------------
LL| 15| black_box(c);
LL| 15|}
LL| |
LL| 15|fn branch_or(a: bool, b: bool) {
LL| 15| no_merge!();
LL| |
LL| | // |13 |18 (no branch)
LL| 15| let c = a || b;
^3
------------------
| Branch (LL:13): [True: 12, False: 3]
------------------
LL| 15| black_box(c);
LL| 15|}
LL| |
LL| |// Test for chaining one operator several times.
LL| 16|fn chain(x: u32) {
LL| 16| no_merge!();
LL| |
LL| | // |13 |22 |31 |40 (no branch)
LL| 16| let c = x > 1 && x > 2 && x > 4 && x > 8;
^14 ^13 ^11
------------------
| Branch (LL:13): [True: 14, False: 2]
| Branch (LL:22): [True: 13, False: 1]
| Branch (LL:31): [True: 11, False: 2]
------------------
LL| 16| black_box(c);
LL| |
LL| | // |13 |22 |31 |40 (no branch)
LL| 16| let d = x < 1 || x < 2 || x < 4 || x < 8;
^15 ^14 ^12
------------------
| Branch (LL:13): [True: 1, False: 15]
| Branch (LL:22): [True: 1, False: 14]
| Branch (LL:31): [True: 2, False: 12]
------------------
LL| 16| black_box(d);
LL| 16|}
LL| |
LL| |// Test for nested combinations of different operators.
LL| 16|fn nested_mixed(x: u32) {
LL| 16| no_merge!();
LL| |
LL| | // |14 |23 |35 |44 (no branch)
LL| 16| let c = (x < 4 || x >= 9) && (x < 2 || x >= 10);
^12 ^11 ^9
------------------
| Branch (LL:14): [True: 4, False: 12]
| Branch (LL:23): [True: 7, False: 5]
| Branch (LL:35): [True: 2, False: 9]
------------------
LL| 16| black_box(c);
LL| |
LL| | // |14 |23 |34 |44 (no branch)
LL| 16| let d = (x < 4 && x < 1) || (x >= 8 && x >= 10);
^4 ^15 ^8
------------------
| Branch (LL:14): [True: 4, False: 12]
| Branch (LL:23): [True: 1, False: 3]
| Branch (LL:34): [True: 8, False: 7]
------------------
LL| 16| black_box(d);
LL| 16|}
LL| |
LL| |#[coverage(off)]
LL| |fn main() {
LL| | // Use each set of arguments (2^n) times, so that each combination has a
LL| | // unique sum, and we can use those sums to verify expected control flow.
LL| | // 1x (false, false)
LL| | // 2x (false, true)
LL| | // 4x (true, false)
LL| | // 8x (true, true)
LL| | for a in [false, true, true, true, true] {
LL| | for b in [false, true, true] {
LL| | branch_and(a, b);
LL| | branch_or(a, b);
LL| | }
LL| | }
LL| |
LL| | for x in 0..16 {
LL| | chain(x);
LL| | nested_mixed(x);
LL| | }
LL| |}

View File

@ -0,0 +1,80 @@
#![feature(coverage_attribute)]
//@ edition: 2021
//@ compile-flags: -Zcoverage-options=branch
//@ llvm-cov-flags: --show-branches=count
// Tests for branch coverage of the lazy boolean operators `&&` and `||`,
// as ordinary expressions that aren't part of an `if` condition or similar.
use core::hint::black_box;
// Helper macro to prevent start-of-function spans from being merged into
// spans on the lines we care about.
macro_rules! no_merge {
() => {
for _ in 0..1 {}
};
}
fn branch_and(a: bool, b: bool) {
no_merge!();
// |13 |18 (no branch)
let c = a && b;
black_box(c);
}
fn branch_or(a: bool, b: bool) {
no_merge!();
// |13 |18 (no branch)
let c = a || b;
black_box(c);
}
// Test for chaining one operator several times.
fn chain(x: u32) {
no_merge!();
// |13 |22 |31 |40 (no branch)
let c = x > 1 && x > 2 && x > 4 && x > 8;
black_box(c);
// |13 |22 |31 |40 (no branch)
let d = x < 1 || x < 2 || x < 4 || x < 8;
black_box(d);
}
// Test for nested combinations of different operators.
fn nested_mixed(x: u32) {
no_merge!();
// |14 |23 |35 |44 (no branch)
let c = (x < 4 || x >= 9) && (x < 2 || x >= 10);
black_box(c);
// |14 |23 |34 |44 (no branch)
let d = (x < 4 && x < 1) || (x >= 8 && x >= 10);
black_box(d);
}
#[coverage(off)]
fn main() {
// Use each set of arguments (2^n) times, so that each combination has a
// unique sum, and we can use those sums to verify expected control flow.
// 1x (false, false)
// 2x (false, true)
// 4x (true, false)
// 8x (true, true)
for a in [false, true, true, true, true] {
for b in [false, true, true] {
branch_and(a, b);
branch_or(a, b);
}
}
for x in 0..16 {
chain(x);
nested_mixed(x);
}
}

View File

@ -1,4 +1,4 @@
Function name: branch_while::while_cond
Function name: while::while_cond
Raw bytes (42): 0x[01, 01, 03, 05, 09, 03, 09, 03, 09, 06, 01, 0c, 01, 01, 10, 05, 03, 09, 00, 12, 03, 01, 0b, 00, 10, 20, 09, 0a, 00, 0b, 00, 10, 09, 00, 11, 02, 06, 0a, 03, 01, 00, 02]
Number of files: 1
- file 0 => global file 1
@ -18,7 +18,7 @@ Number of file 0 mappings: 6
- Code(Expression(2, Sub)) at (prev + 3, 1) to (start + 0, 2)
= ((c1 + c2) - c2)
Function name: branch_while::while_cond_not
Function name: while::while_cond_not
Raw bytes (42): 0x[01, 01, 03, 05, 09, 03, 09, 03, 09, 06, 01, 15, 01, 01, 10, 05, 03, 09, 00, 12, 03, 01, 0b, 00, 14, 20, 09, 0a, 00, 0b, 00, 14, 09, 00, 15, 02, 06, 0a, 03, 01, 00, 02]
Number of files: 1
- file 0 => global file 1
@ -38,7 +38,7 @@ Number of file 0 mappings: 6
- Code(Expression(2, Sub)) at (prev + 3, 1) to (start + 0, 2)
= ((c1 + c2) - c2)
Function name: branch_while::while_op_and
Function name: while::while_op_and
Raw bytes (56): 0x[01, 01, 04, 05, 09, 03, 0d, 03, 0d, 11, 0d, 08, 01, 1e, 01, 01, 10, 05, 03, 09, 01, 12, 03, 02, 0b, 00, 10, 20, 0a, 0d, 00, 0b, 00, 10, 0a, 00, 14, 00, 19, 20, 09, 11, 00, 14, 00, 19, 09, 00, 1a, 03, 06, 0f, 04, 01, 00, 02]
Number of files: 1
- file 0 => global file 1
@ -64,7 +64,7 @@ Number of file 0 mappings: 8
- Code(Expression(3, Add)) at (prev + 4, 1) to (start + 0, 2)
= (c4 + c3)
Function name: branch_while::while_op_or
Function name: while::while_op_or
Raw bytes (66): 0x[01, 01, 09, 05, 1b, 09, 0d, 03, 09, 03, 09, 22, 0d, 03, 09, 09, 0d, 22, 0d, 03, 09, 08, 01, 29, 01, 01, 10, 05, 03, 09, 01, 12, 03, 02, 0b, 00, 10, 20, 09, 22, 00, 0b, 00, 10, 22, 00, 14, 00, 19, 20, 0d, 1e, 00, 14, 00, 19, 1b, 00, 1a, 03, 06, 1e, 04, 01, 00, 02]
Number of files: 1
- file 0 => global file 1

View File

@ -14,17 +14,18 @@ presence of pointers in constants or other bit width dependent things. In that c
to your test, causing separate files to be generated for 32bit and 64bit systems.
## Unit testing
## Testing a particular MIR pass
If you are only testing the behavior of a particular mir-opt pass on some specific input (as is
usually the case), you should add
```
// unit-test: PassName
//@ test-mir-pass: PassName
```
to the top of the file. This makes sure that other passes don't run which means you'll get the input
you expected and your test won't break when other code changes.
you expected and your test won't break when other code changes. This also lets you test passes
that are disabled by default.
## Emit a diff of the mir for a specific optimization

View File

@ -1,4 +1,4 @@
//@ unit-test: SimplifyCfg-pre-optimizations
//@ test-mir-pass: SimplifyCfg-pre-optimizations
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
// Retagging (from Stacked Borrows) relies on the array index being a fresh
// temporary, so that side-effects cannot change it.

View File

@ -1,4 +1,4 @@
//@ unit-test: ElaborateDrops
//@ test-mir-pass: ElaborateDrops
//@ needs-unwind
// this tests move up progration, which is not yet implemented

View File

@ -1,4 +1,4 @@
//@ unit-test: ElaborateDrops
//@ test-mir-pass: ElaborateDrops
//@ needs-unwind
#![feature(rustc_attrs, stmt_expr_attributes)]

View File

@ -1,5 +1,5 @@
// skip-filecheck
//@ unit-test: GVN
//@ test-mir-pass: GVN
//@ ignore-endian-big
// EMIT_MIR_FOR_EACH_BIT_WIDTH
static FOO: &[(Option<i32>, &[&str])] =

View File

@ -1,5 +1,5 @@
// skip-filecheck
//@ unit-test: GVN
//@ test-mir-pass: GVN
//@ ignore-endian-big
// EMIT_MIR_FOR_EACH_BIT_WIDTH
// EMIT_MIR const_allocation2.main.GVN.after.mir

View File

@ -1,5 +1,5 @@
// skip-filecheck
//@ unit-test: GVN
//@ test-mir-pass: GVN
//@ ignore-endian-big
// EMIT_MIR_FOR_EACH_BIT_WIDTH
// EMIT_MIR const_allocation3.main.GVN.after.mir

View File

@ -1,4 +1,4 @@
//@ unit-test: ConstDebugInfo
//@ test-mir-pass: ConstDebugInfo
//@ compile-flags: -C overflow-checks=no -Zmir-enable-passes=+GVN
struct Point {

View File

@ -1,4 +1,4 @@
//@ unit-test: GVN
//@ test-mir-pass: GVN
// EMIT_MIR address_of_pair.fn0.GVN.diff
pub fn fn0() -> bool {

View File

@ -1,5 +1,5 @@
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
//@ unit-test: GVN
//@ test-mir-pass: GVN
//@ compile-flags: -O
// EMIT_MIR aggregate.main.GVN.diff

View File

@ -1,4 +1,4 @@
//@ unit-test: GVN
//@ test-mir-pass: GVN
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
// EMIT_MIR_FOR_EACH_BIT_WIDTH

View File

@ -1,4 +1,4 @@
//@ unit-test: GVN
//@ test-mir-pass: GVN
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
// EMIT_MIR bad_op_div_by_zero.main.GVN.diff

View File

@ -1,4 +1,4 @@
//@ unit-test: GVN
//@ test-mir-pass: GVN
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
// EMIT_MIR bad_op_mod_by_zero.main.GVN.diff

View File

@ -1,4 +1,4 @@
//@ unit-test: GVN
//@ test-mir-pass: GVN
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
// EMIT_MIR_FOR_EACH_BIT_WIDTH

View File

@ -1,4 +1,4 @@
//@ unit-test: GVN
//@ test-mir-pass: GVN
// EMIT_MIR boolean_identities.test.GVN.diff
pub fn test(x: bool, y: bool) -> bool {

View File

@ -1,4 +1,4 @@
//@ unit-test: GVN
//@ test-mir-pass: GVN
//@ compile-flags: -O
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY

View File

@ -1,4 +1,4 @@
//@ unit-test: GVN
//@ test-mir-pass: GVN
// EMIT_MIR cast.main.GVN.diff
fn main() {

View File

@ -1,5 +1,5 @@
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
//@ unit-test: GVN
//@ test-mir-pass: GVN
//@ compile-flags: -C overflow-checks=on
// EMIT_MIR checked_add.main.GVN.diff

View File

@ -1,6 +1,6 @@
// skip-filecheck
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
//@ unit-test: GVN
//@ test-mir-pass: GVN
//@ compile-flags: -Zmir-opt-level=1
trait NeedsDrop: Sized {

View File

@ -1,4 +1,4 @@
//@ unit-test: GVN
//@ test-mir-pass: GVN
// FIXME(wesleywiser): Ideally, we could const-prop away all of this and just be left with
// `let x = 42` but that doesn't work because const-prop doesn't support `Operand::Indirect`

View File

@ -1,5 +1,5 @@
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
//@ unit-test: GVN
//@ test-mir-pass: GVN
//@ compile-flags: -C overflow-checks=on
// EMIT_MIR indirect.main.GVN.diff

View File

@ -1,4 +1,4 @@
//@ unit-test: GVN
//@ test-mir-pass: GVN
// Check that we do not propagate past an indirect mutation.
#![feature(raw_ref_op)]

View File

@ -1,5 +1,5 @@
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
//@ unit-test: GVN
//@ test-mir-pass: GVN
//@ compile-flags: -Zmir-enable-passes=+Inline
// After inlining, this will contain a `CheckedBinaryOp`.

View File

@ -1,5 +1,5 @@
// skip-filecheck
//@ unit-test: GVN
//@ test-mir-pass: GVN
//@ compile-flags: -Zmir-enable-passes=+RemoveZsts
// Verify that we can pretty print invalid constants.

View File

@ -1,5 +1,5 @@
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
//@ unit-test: GVN
//@ test-mir-pass: GVN
// Due to a bug in propagating scalar pairs the assertion below used to fail. In the expected
// outputs below, after GVN this is how _2 would look like with the bug:

View File

@ -1,5 +1,5 @@
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
//@ unit-test: GVN
//@ test-mir-pass: GVN
// This used to ICE in const-prop

View File

@ -1,5 +1,5 @@
// skip-filecheck
//@ unit-test: GVN
//@ test-mir-pass: GVN
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
// EMIT_MIR_FOR_EACH_BIT_WIDTH

View File

@ -1,4 +1,4 @@
//@ unit-test: GVN
//@ test-mir-pass: GVN
// EMIT_MIR mult_by_zero.test.GVN.diff
fn test(x: i32) -> i32 {

View File

@ -1,4 +1,4 @@
//@ unit-test: GVN
//@ test-mir-pass: GVN
// EMIT_MIR mutable_variable.main.GVN.diff
fn main() {

View File

@ -1,4 +1,4 @@
//@ unit-test: GVN
//@ test-mir-pass: GVN
// EMIT_MIR mutable_variable_aggregate.main.GVN.diff
fn main() {

View File

@ -1,4 +1,4 @@
//@ unit-test: GVN
//@ test-mir-pass: GVN
// EMIT_MIR mutable_variable_aggregate_mut_ref.main.GVN.diff
fn main() {

View File

@ -1,5 +1,5 @@
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
//@ unit-test: GVN
//@ test-mir-pass: GVN
// EMIT_MIR mutable_variable_aggregate_partial_read.main.GVN.diff
fn main() {

View File

@ -1,4 +1,4 @@
//@ unit-test: GVN
//@ test-mir-pass: GVN
// Verify that we do not propagate the contents of this mutable static.
static mut STATIC: u32 = 0x42424242;

View File

@ -1,5 +1,5 @@
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
//@ unit-test: GVN
//@ test-mir-pass: GVN
// EMIT_MIR mutable_variable_unprop_assign.main.GVN.diff
fn main() {

View File

@ -1,5 +1,5 @@
// skip-filecheck
//@ unit-test: GVN
//@ test-mir-pass: GVN
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
#![feature(offset_of_enum, offset_of_nested)]

View File

@ -1,4 +1,4 @@
//@ unit-test: GVN
//@ test-mir-pass: GVN
//@ compile-flags: -O
// Regression test for https://github.com/rust-lang/rust/issues/118328

View File

@ -1,5 +1,5 @@
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
//@ unit-test: GVN
//@ test-mir-pass: GVN
#[inline(never)]
fn read(_: usize) { }

View File

@ -1,4 +1,4 @@
//@ unit-test: GVN
//@ test-mir-pass: GVN
static FOO: u8 = 2;

View File

@ -1,4 +1,4 @@
//@ unit-test: GVN
//@ test-mir-pass: GVN
// EMIT_MIR ref_deref.main.GVN.diff
fn main() {

View File

@ -1,5 +1,5 @@
// This does not currently propagate (#67862)
//@ unit-test: GVN
//@ test-mir-pass: GVN
// EMIT_MIR ref_deref_project.main.GVN.diff
fn main() {

View File

@ -1,4 +1,4 @@
//@ unit-test: GVN
//@ test-mir-pass: GVN
// EMIT_MIR reify_fn_ptr.main.GVN.diff
fn main() {

View File

@ -1,4 +1,4 @@
//@ unit-test: GVN
//@ test-mir-pass: GVN
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
// EMIT_MIR_FOR_EACH_BIT_WIDTH

View File

@ -1,4 +1,4 @@
//@ unit-test: GVN
//@ test-mir-pass: GVN
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
//@ compile-flags: -C overflow-checks=on

View File

@ -1,4 +1,4 @@
//@ unit-test: GVN
//@ test-mir-pass: GVN
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
// EMIT_MIR scalar_literal_propagation.main.GVN.diff

View File

@ -1,4 +1,4 @@
//@ unit-test: GVN
//@ test-mir-pass: GVN
//@ compile-flags: -Zmir-enable-passes=+InstSimplify
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
// EMIT_MIR_FOR_EACH_BIT_WIDTH

View File

@ -1,4 +1,4 @@
//@ unit-test: GVN
//@ test-mir-pass: GVN
//@ compile-flags: -Zmir-enable-passes=+SimplifyConstCondition-after-const-prop
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY

View File

@ -1,4 +1,4 @@
//@ unit-test: GVN
//@ test-mir-pass: GVN
//@ compile-flags: -O --crate-type=lib
//@ ignore-endian-big
// EMIT_MIR_FOR_EACH_BIT_WIDTH

View File

@ -1,4 +1,4 @@
//@ unit-test: GVN
//@ test-mir-pass: GVN
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
// EMIT_MIR tuple_literal_propagation.main.GVN.diff

View File

@ -1,4 +1,4 @@
//@ unit-test: GVN
//@ test-mir-pass: GVN
// EMIT_MIR while_let_loops.change_loop_body.GVN.diff
pub fn change_loop_body() {

View File

@ -1,6 +1,6 @@
// skip-filecheck
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
//@ unit-test: CopyProp
//@ test-mir-pass: CopyProp
#![feature(custom_mir, core_intrinsics)]
#![allow(unused_assignments)]

View File

@ -1,7 +1,7 @@
// skip-filecheck
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
//! Tests that we bail out when there are multiple assignments to the same local.
//@ unit-test: CopyProp
//@ test-mir-pass: CopyProp
fn val() -> i32 {
1
}

View File

@ -1,6 +1,6 @@
// skip-filecheck
// Check that CopyProp does propagate return values of call terminators.
//@ unit-test: CopyProp
//@ test-mir-pass: CopyProp
//@ needs-unwind
#![feature(custom_mir, core_intrinsics)]

View File

@ -2,7 +2,7 @@
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
// Check that CopyProp does not propagate an assignment to a function argument
// (doing so can break usages of the original argument value)
//@ unit-test: CopyProp
//@ test-mir-pass: CopyProp
fn dummy(x: u8) -> u8 {
x
}

View File

@ -1,6 +1,6 @@
// skip-filecheck
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
//@ unit-test: CopyProp
//@ test-mir-pass: CopyProp
#![feature(custom_mir, core_intrinsics)]
#![allow(unused_assignments)]

View File

@ -1,7 +1,7 @@
// skip-filecheck
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
//! Tests that cyclic assignments don't hang CopyProp, and result in reasonable code.
//@ unit-test: CopyProp
//@ test-mir-pass: CopyProp
fn val() -> i32 {
1
}

View File

@ -1,6 +1,6 @@
// skip-filecheck
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
//@ unit-test: CopyProp
//@ test-mir-pass: CopyProp
fn id<T>(x: T) -> T {
x

View File

@ -3,7 +3,7 @@
// This is a copy of the `dead_stores_79191` test, except that we turn on DSE. This demonstrates
// that that pass enables this one to do more optimizations.
//@ unit-test: CopyProp
//@ test-mir-pass: CopyProp
//@ compile-flags: -Zmir-enable-passes=+DeadStoreElimination
fn id<T>(x: T) -> T {

View File

@ -1,6 +1,6 @@
// skip-filecheck
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
//@ unit-test: CopyProp
//@ test-mir-pass: CopyProp
// EMIT_MIR issue_107511.main.CopyProp.diff
fn main() {

View File

@ -1,7 +1,7 @@
// skip-filecheck
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
// Test that we do not move multiple times from the same local.
//@ unit-test: CopyProp
//@ test-mir-pass: CopyProp
// EMIT_MIR move_arg.f.CopyProp.diff
pub fn f<T: Copy>(a: T) {

View File

@ -1,6 +1,6 @@
// skip-filecheck
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
//@ unit-test: CopyProp
//@ test-mir-pass: CopyProp
#![feature(custom_mir, core_intrinsics)]
#![allow(unused_assignments)]

View File

@ -1,5 +1,5 @@
// skip-filecheck
//@ unit-test: CopyProp
//@ test-mir-pass: CopyProp
//
// This attempts to mutate `a` via a pointer derived from `addr_of!(a)`. That is UB
// according to Miri. However, the decision to make this UB - and to allow

View File

@ -1,5 +1,5 @@
// skip-filecheck
//@ unit-test: CopyProp
//@ test-mir-pass: CopyProp
#![feature(custom_mir, core_intrinsics)]
#![allow(unused_assignments)]

View File

@ -1,5 +1,5 @@
// skip-filecheck
//@ unit-test: CopyProp
//@ test-mir-pass: CopyProp
// Verify that we do not ICE on partial initializations.
#![feature(custom_mir, core_intrinsics)]

View File

@ -1,7 +1,7 @@
// skip-filecheck
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
// Check that CopyProp considers reborrows as not mutating the pointer.
//@ unit-test: CopyProp
//@ test-mir-pass: CopyProp
#![feature(raw_ref_op)]

View File

@ -1,5 +1,5 @@
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
//@ unit-test: DataflowConstProp
//@ test-mir-pass: DataflowConstProp
// EMIT_MIR_FOR_EACH_BIT_WIDTH
// EMIT_MIR array_index.main.DataflowConstProp.diff

View File

@ -1,4 +1,4 @@
//@ unit-test: DataflowConstProp
//@ test-mir-pass: DataflowConstProp
// EMIT_MIR boolean_identities.test.DataflowConstProp.diff

View File

@ -1,4 +1,4 @@
//@ unit-test: DataflowConstProp
//@ test-mir-pass: DataflowConstProp
// EMIT_MIR cast.main.DataflowConstProp.diff

View File

@ -1,4 +1,4 @@
//@ unit-test: DataflowConstProp
//@ test-mir-pass: DataflowConstProp
//@ compile-flags: -Coverflow-checks=on
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY

View File

@ -1,4 +1,4 @@
//@ unit-test: DataflowConstProp
//@ test-mir-pass: DataflowConstProp
//@ compile-flags: -Zmir-enable-passes=+GVN,+Inline
// EMIT_MIR_FOR_EACH_BIT_WIDTH
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY

Some files were not shown because too many files have changed in this diff Show More