mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-30 16:43:41 +00:00
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:
commit
453ceafce3
@ -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(),
|
||||
);
|
||||
}
|
||||
|
@ -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(",");
|
||||
}
|
||||
}
|
||||
|
149
compiler/rustc_ast_pretty/src/pprust/state/fixup.rs
Normal file
149
compiler/rustc_ast_pretty/src/pprust/state/fixup.rs
Normal 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())
|
||||
}
|
||||
}
|
@ -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;
|
||||
|
@ -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: () };
|
||||
|
@ -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) => {
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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("`"),
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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 => {
|
||||
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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
|
@ -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 {
|
||||
| ------------------
|
@ -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
|
@ -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
|
177
tests/coverage/branch/lazy-boolean.cov-map
Normal file
177
tests/coverage/branch/lazy-boolean.cov-map
Normal 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))
|
||||
|
113
tests/coverage/branch/lazy-boolean.coverage
Normal file
113
tests/coverage/branch/lazy-boolean.coverage
Normal 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| |}
|
||||
|
80
tests/coverage/branch/lazy-boolean.rs
Normal file
80
tests/coverage/branch/lazy-boolean.rs
Normal 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);
|
||||
}
|
||||
}
|
@ -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
|
@ -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
|
||||
|
||||
|
@ -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.
|
||||
|
@ -1,4 +1,4 @@
|
||||
//@ unit-test: ElaborateDrops
|
||||
//@ test-mir-pass: ElaborateDrops
|
||||
//@ needs-unwind
|
||||
// this tests move up progration, which is not yet implemented
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
//@ unit-test: ElaborateDrops
|
||||
//@ test-mir-pass: ElaborateDrops
|
||||
//@ needs-unwind
|
||||
|
||||
#![feature(rustc_attrs, stmt_expr_attributes)]
|
||||
|
@ -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])] =
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -1,4 +1,4 @@
|
||||
//@ unit-test: ConstDebugInfo
|
||||
//@ test-mir-pass: ConstDebugInfo
|
||||
//@ compile-flags: -C overflow-checks=no -Zmir-enable-passes=+GVN
|
||||
|
||||
struct Point {
|
||||
|
@ -1,4 +1,4 @@
|
||||
//@ unit-test: GVN
|
||||
//@ test-mir-pass: GVN
|
||||
|
||||
// EMIT_MIR address_of_pair.fn0.GVN.diff
|
||||
pub fn fn0() -> bool {
|
||||
|
@ -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
|
||||
|
@ -1,4 +1,4 @@
|
||||
//@ unit-test: GVN
|
||||
//@ test-mir-pass: GVN
|
||||
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
|
||||
// EMIT_MIR_FOR_EACH_BIT_WIDTH
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -1,4 +1,4 @@
|
||||
//@ unit-test: GVN
|
||||
//@ test-mir-pass: GVN
|
||||
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
|
||||
// EMIT_MIR_FOR_EACH_BIT_WIDTH
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -1,4 +1,4 @@
|
||||
//@ unit-test: GVN
|
||||
//@ test-mir-pass: GVN
|
||||
//@ compile-flags: -O
|
||||
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
//@ unit-test: GVN
|
||||
//@ test-mir-pass: GVN
|
||||
// EMIT_MIR cast.main.GVN.diff
|
||||
|
||||
fn main() {
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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`
|
||||
|
@ -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
|
||||
|
@ -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)]
|
||||
|
||||
|
@ -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`.
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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:
|
||||
|
@ -1,5 +1,5 @@
|
||||
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
|
||||
//@ unit-test: GVN
|
||||
//@ test-mir-pass: GVN
|
||||
|
||||
// This used to ICE in const-prop
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
//@ unit-test: GVN
|
||||
//@ test-mir-pass: GVN
|
||||
|
||||
// EMIT_MIR mult_by_zero.test.GVN.diff
|
||||
fn test(x: i32) -> i32 {
|
||||
|
@ -1,4 +1,4 @@
|
||||
//@ unit-test: GVN
|
||||
//@ test-mir-pass: GVN
|
||||
|
||||
// EMIT_MIR mutable_variable.main.GVN.diff
|
||||
fn main() {
|
||||
|
@ -1,4 +1,4 @@
|
||||
//@ unit-test: GVN
|
||||
//@ test-mir-pass: GVN
|
||||
|
||||
// EMIT_MIR mutable_variable_aggregate.main.GVN.diff
|
||||
fn main() {
|
||||
|
@ -1,4 +1,4 @@
|
||||
//@ unit-test: GVN
|
||||
//@ test-mir-pass: GVN
|
||||
|
||||
// EMIT_MIR mutable_variable_aggregate_mut_ref.main.GVN.diff
|
||||
fn main() {
|
||||
|
@ -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() {
|
||||
|
@ -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;
|
||||
|
@ -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() {
|
||||
|
@ -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)]
|
||||
|
@ -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
|
||||
|
@ -1,5 +1,5 @@
|
||||
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
|
||||
//@ unit-test: GVN
|
||||
//@ test-mir-pass: GVN
|
||||
|
||||
#[inline(never)]
|
||||
fn read(_: usize) { }
|
||||
|
@ -1,4 +1,4 @@
|
||||
//@ unit-test: GVN
|
||||
//@ test-mir-pass: GVN
|
||||
|
||||
static FOO: u8 = 2;
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
//@ unit-test: GVN
|
||||
//@ test-mir-pass: GVN
|
||||
|
||||
// EMIT_MIR ref_deref.main.GVN.diff
|
||||
fn main() {
|
||||
|
@ -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() {
|
||||
|
@ -1,4 +1,4 @@
|
||||
//@ unit-test: GVN
|
||||
//@ test-mir-pass: GVN
|
||||
// EMIT_MIR reify_fn_ptr.main.GVN.diff
|
||||
|
||||
fn main() {
|
||||
|
@ -1,4 +1,4 @@
|
||||
//@ unit-test: GVN
|
||||
//@ test-mir-pass: GVN
|
||||
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
|
||||
// EMIT_MIR_FOR_EACH_BIT_WIDTH
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
//@ unit-test: GVN
|
||||
//@ test-mir-pass: GVN
|
||||
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
|
||||
//@ compile-flags: -C overflow-checks=on
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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() {
|
||||
|
@ -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)]
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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)]
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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)]
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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() {
|
||||
|
@ -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) {
|
||||
|
@ -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)]
|
||||
|
@ -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
|
||||
|
@ -1,5 +1,5 @@
|
||||
// skip-filecheck
|
||||
//@ unit-test: CopyProp
|
||||
//@ test-mir-pass: CopyProp
|
||||
|
||||
#![feature(custom_mir, core_intrinsics)]
|
||||
#![allow(unused_assignments)]
|
||||
|
@ -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)]
|
||||
|
@ -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)]
|
||||
|
||||
|
@ -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
|
||||
|
@ -1,4 +1,4 @@
|
||||
//@ unit-test: DataflowConstProp
|
||||
//@ test-mir-pass: DataflowConstProp
|
||||
|
||||
// EMIT_MIR boolean_identities.test.DataflowConstProp.diff
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
//@ unit-test: DataflowConstProp
|
||||
//@ test-mir-pass: DataflowConstProp
|
||||
|
||||
// EMIT_MIR cast.main.DataflowConstProp.diff
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
//@ unit-test: DataflowConstProp
|
||||
//@ test-mir-pass: DataflowConstProp
|
||||
//@ compile-flags: -Coverflow-checks=on
|
||||
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
|
||||
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user