mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-28 02:57:37 +00:00
Auto merge of #83247 - Dylan-DPC:rollup-bdwmvjg, r=Dylan-DPC
Rollup of 11 pull requests Successful merges: - #82191 (Vec::dedup_by optimization) - #82270 (Emit error when trying to use assembler syntax directives in `asm!`) - #82434 (Add more links between hash and btree collections) - #83080 (Make source-based code coverage compatible with MIR inlining) - #83168 (Extend `proc_macro_back_compat` lint to `procedural-masquerade`) - #83192 (ci/docker: Add SDK/NDK level 21 to android docker for 32bit platforms) - #83204 (Simplify C compilation for Fortanix-SGX target) - #83216 (Allow registering tool lints with `register_tool`) - #83223 (Display error details when a `mmap` call fails) - #83228 (Don't show HTML diff if tidy isn't installed for rustdoc tests) - #83231 (Switch riscvgc-unknown-none-elf use lp64d ABI) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
146f574560
@ -33,10 +33,6 @@ impl MarkedAttrs {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_known_lint_tool(m_item: Ident) -> bool {
|
||||
[sym::clippy, sym::rustc, sym::rustdoc].contains(&m_item.name)
|
||||
}
|
||||
|
||||
impl NestedMetaItem {
|
||||
/// Returns the `MetaItem` if `self` is a `NestedMetaItem::MetaItem`.
|
||||
pub fn meta_item(&self) -> Option<&MetaItem> {
|
||||
|
@ -784,33 +784,6 @@ impl Nonterminal {
|
||||
NtTT(tt) => tt.span(),
|
||||
}
|
||||
}
|
||||
|
||||
/// This nonterminal looks like some specific enums from
|
||||
/// `proc-macro-hack` and `procedural-masquerade` crates.
|
||||
/// We need to maintain some special pretty-printing behavior for them due to incorrect
|
||||
/// asserts in old versions of those crates and their wide use in the ecosystem.
|
||||
/// See issue #73345 for more details.
|
||||
/// FIXME(#73933): Remove this eventually.
|
||||
pub fn pretty_printing_compatibility_hack(&self) -> bool {
|
||||
let item = match self {
|
||||
NtItem(item) => item,
|
||||
NtStmt(stmt) => match &stmt.kind {
|
||||
ast::StmtKind::Item(item) => item,
|
||||
_ => return false,
|
||||
},
|
||||
_ => return false,
|
||||
};
|
||||
|
||||
let name = item.ident.name;
|
||||
if name == sym::ProceduralMasqueradeDummyType || name == sym::ProcMacroHack {
|
||||
if let ast::ItemKind::Enum(enum_def, _) = &item.kind {
|
||||
if let [variant] = &*enum_def.variants {
|
||||
return variant.ident.name == sym::Input;
|
||||
}
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for Nonterminal {
|
||||
|
@ -7,7 +7,10 @@ use rustc_errors::{Applicability, DiagnosticBuilder};
|
||||
use rustc_expand::base::{self, *};
|
||||
use rustc_parse::parser::Parser;
|
||||
use rustc_parse_format as parse;
|
||||
use rustc_span::symbol::{kw, sym, Symbol};
|
||||
use rustc_span::{
|
||||
symbol::{kw, sym, Symbol},
|
||||
BytePos,
|
||||
};
|
||||
use rustc_span::{InnerSpan, Span};
|
||||
|
||||
struct AsmArgs {
|
||||
@ -399,6 +402,8 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, sp: Span, args: AsmArgs) -> P<ast
|
||||
let mut line_spans = Vec::with_capacity(args.templates.len());
|
||||
let mut curarg = 0;
|
||||
|
||||
let default_dialect = ecx.sess.inline_asm_dialect();
|
||||
|
||||
for template_expr in args.templates.into_iter() {
|
||||
if !template.is_empty() {
|
||||
template.push(ast::InlineAsmTemplatePiece::String("\n".to_string()));
|
||||
@ -424,6 +429,60 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, sp: Span, args: AsmArgs) -> P<ast
|
||||
|
||||
let template_str = &template_str.as_str();
|
||||
let template_snippet = ecx.source_map().span_to_snippet(template_sp).ok();
|
||||
|
||||
if let Some(snippet) = &template_snippet {
|
||||
let snippet = snippet.trim_matches('"');
|
||||
match default_dialect {
|
||||
ast::LlvmAsmDialect::Intel => {
|
||||
if let Some(span) = check_syntax_directive(snippet, ".intel_syntax") {
|
||||
let span = template_span.from_inner(span);
|
||||
let mut err = ecx.struct_span_err(span, "intel syntax is the default syntax on this target, and trying to use this directive may cause issues");
|
||||
err.span_suggestion(
|
||||
span,
|
||||
"remove this assembler directive",
|
||||
"".to_string(),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
err.emit();
|
||||
}
|
||||
|
||||
if let Some(span) = check_syntax_directive(snippet, ".att_syntax") {
|
||||
let span = template_span.from_inner(span);
|
||||
let mut err = ecx.struct_span_err(span, "using the .att_syntax directive may cause issues, use the att_syntax option instead");
|
||||
let asm_end = sp.hi() - BytePos(2);
|
||||
let suggestions = vec![
|
||||
(span, "".to_string()),
|
||||
(
|
||||
Span::new(asm_end, asm_end, sp.ctxt()),
|
||||
", options(att_syntax)".to_string(),
|
||||
),
|
||||
];
|
||||
err.multipart_suggestion(
|
||||
"remove the assembler directive and replace it with options(att_syntax)",
|
||||
suggestions,
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
err.emit();
|
||||
}
|
||||
}
|
||||
ast::LlvmAsmDialect::Att => {
|
||||
if let Some(span) = check_syntax_directive(snippet, ".att_syntax") {
|
||||
let span = template_span.from_inner(span);
|
||||
let mut err = ecx.struct_span_err(span, "att syntax is the default syntax on this target, and trying to use this directive may cause issues");
|
||||
err.span_suggestion(
|
||||
span,
|
||||
"remove this assembler directive",
|
||||
"".to_string(),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
err.emit();
|
||||
}
|
||||
|
||||
// Use of .intel_syntax is ignored
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut parser = parse::Parser::new(
|
||||
template_str,
|
||||
str_style,
|
||||
@ -631,3 +690,15 @@ pub fn expand_asm<'cx>(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn check_syntax_directive<S: AsRef<str>>(piece: S, syntax: &str) -> Option<InnerSpan> {
|
||||
let piece = piece.as_ref();
|
||||
if let Some(idx) = piece.find(syntax) {
|
||||
let end =
|
||||
idx + &piece[idx..].find(|c| matches!(c, '\n' | ';')).unwrap_or(piece[idx..].len());
|
||||
// Offset by one because these represent the span with the " removed
|
||||
Some(InnerSpan::new(idx + 1, end + 1))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
@ -254,7 +254,7 @@ fn save_function_record(
|
||||
///
|
||||
/// 1. The file name of an "Unreachable" function must match the file name of the existing
|
||||
/// codegenned (covered) function to which the unreachable code regions will be added.
|
||||
/// 2. The function to which the unreachable code regions will be added must not be a genaric
|
||||
/// 2. The function to which the unreachable code regions will be added must not be a generic
|
||||
/// function (must not have type parameters) because the coverage tools will get confused
|
||||
/// if the codegenned function has more than one instantiation and additional `CodeRegion`s
|
||||
/// attached to only one of those instantiations.
|
||||
@ -284,7 +284,7 @@ fn add_unreachable_coverage<'tcx>(
|
||||
let all_def_ids: DefIdSet =
|
||||
tcx.mir_keys(LOCAL_CRATE).iter().map(|local_def_id| local_def_id.to_def_id()).collect();
|
||||
|
||||
let (codegenned_def_ids, _) = tcx.collect_and_partition_mono_items(LOCAL_CRATE);
|
||||
let codegenned_def_ids = tcx.codegened_and_inlined_items(LOCAL_CRATE);
|
||||
|
||||
let mut unreachable_def_ids_by_file: FxHashMap<Symbol, Vec<DefId>> = FxHashMap::default();
|
||||
for &non_codegenned_def_id in all_def_ids.difference(codegenned_def_ids) {
|
||||
|
@ -8,7 +8,7 @@ use rustc_middle::mir::coverage::{
|
||||
use rustc_middle::ty::Instance;
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct Expression {
|
||||
lhs: ExpressionOperandId,
|
||||
op: Op,
|
||||
@ -64,7 +64,9 @@ impl<'tcx> FunctionCoverage<'tcx> {
|
||||
|
||||
/// Adds a code region to be counted by an injected counter intrinsic.
|
||||
pub fn add_counter(&mut self, id: CounterValueReference, region: CodeRegion) {
|
||||
self.counters[id].replace(region).expect_none("add_counter called with duplicate `id`");
|
||||
if let Some(previous_region) = self.counters[id].replace(region.clone()) {
|
||||
assert_eq!(previous_region, region, "add_counter: code region for id changed");
|
||||
}
|
||||
}
|
||||
|
||||
/// Both counters and "counter expressions" (or simply, "expressions") can be operands in other
|
||||
@ -94,9 +96,18 @@ impl<'tcx> FunctionCoverage<'tcx> {
|
||||
expression_id, lhs, op, rhs, region
|
||||
);
|
||||
let expression_index = self.expression_index(u32::from(expression_id));
|
||||
self.expressions[expression_index]
|
||||
.replace(Expression { lhs, op, rhs, region })
|
||||
.expect_none("add_counter_expression called with duplicate `id_descending_from_max`");
|
||||
if let Some(previous_expression) = self.expressions[expression_index].replace(Expression {
|
||||
lhs,
|
||||
op,
|
||||
rhs,
|
||||
region: region.clone(),
|
||||
}) {
|
||||
assert_eq!(
|
||||
previous_expression,
|
||||
Expression { lhs, op, rhs, region },
|
||||
"add_counter_expression: expression for id changed"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Add a region that will be marked as "unreachable", with a constant "zero counter".
|
||||
|
@ -2,27 +2,38 @@ use crate::traits::*;
|
||||
|
||||
use rustc_middle::mir::coverage::*;
|
||||
use rustc_middle::mir::Coverage;
|
||||
use rustc_middle::mir::SourceScope;
|
||||
|
||||
use super::FunctionCx;
|
||||
|
||||
impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
pub fn codegen_coverage(&self, bx: &mut Bx, coverage: Coverage) {
|
||||
pub fn codegen_coverage(&self, bx: &mut Bx, coverage: Coverage, scope: SourceScope) {
|
||||
// Determine the instance that coverage data was originally generated for.
|
||||
let scope_data = &self.mir.source_scopes[scope];
|
||||
let instance = if let Some((inlined_instance, _)) = scope_data.inlined {
|
||||
self.monomorphize(inlined_instance)
|
||||
} else if let Some(inlined_scope) = scope_data.inlined_parent_scope {
|
||||
self.monomorphize(self.mir.source_scopes[inlined_scope].inlined.unwrap().0)
|
||||
} else {
|
||||
self.instance
|
||||
};
|
||||
|
||||
let Coverage { kind, code_region } = coverage;
|
||||
match kind {
|
||||
CoverageKind::Counter { function_source_hash, id } => {
|
||||
if bx.set_function_source_hash(self.instance, function_source_hash) {
|
||||
if bx.set_function_source_hash(instance, function_source_hash) {
|
||||
// If `set_function_source_hash()` returned true, the coverage map is enabled,
|
||||
// so continue adding the counter.
|
||||
if let Some(code_region) = code_region {
|
||||
// Note: Some counters do not have code regions, but may still be referenced
|
||||
// from expressions. In that case, don't add the counter to the coverage map,
|
||||
// but do inject the counter intrinsic.
|
||||
bx.add_coverage_counter(self.instance, id, code_region);
|
||||
bx.add_coverage_counter(instance, id, code_region);
|
||||
}
|
||||
|
||||
let coverageinfo = bx.tcx().coverageinfo(self.instance.def_id());
|
||||
let coverageinfo = bx.tcx().coverageinfo(instance.def_id());
|
||||
|
||||
let fn_name = bx.create_pgo_func_name_var(self.instance);
|
||||
let fn_name = bx.create_pgo_func_name_var(instance);
|
||||
let hash = bx.const_u64(function_source_hash);
|
||||
let num_counters = bx.const_u32(coverageinfo.num_counters);
|
||||
let index = bx.const_u32(u32::from(id));
|
||||
@ -34,11 +45,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
}
|
||||
}
|
||||
CoverageKind::Expression { id, lhs, op, rhs } => {
|
||||
bx.add_coverage_counter_expression(self.instance, id, lhs, op, rhs, code_region);
|
||||
bx.add_coverage_counter_expression(instance, id, lhs, op, rhs, code_region);
|
||||
}
|
||||
CoverageKind::Unreachable => {
|
||||
bx.add_coverage_unreachable(
|
||||
self.instance,
|
||||
instance,
|
||||
code_region.expect("unreachable regions always have code regions"),
|
||||
);
|
||||
}
|
||||
|
@ -112,7 +112,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
bx
|
||||
}
|
||||
mir::StatementKind::Coverage(box ref coverage) => {
|
||||
self.codegen_coverage(&mut bx, coverage.clone());
|
||||
self.codegen_coverage(&mut bx, coverage.clone(), statement.source_info.scope);
|
||||
bx
|
||||
}
|
||||
mir::StatementKind::CopyNonOverlapping(box mir::CopyNonOverlapping {
|
||||
|
@ -10,6 +10,8 @@ use rustc_attr::{self as attr, Deprecation, Stability};
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_data_structures::sync::{self, Lrc};
|
||||
use rustc_errors::{DiagnosticBuilder, ErrorReported};
|
||||
use rustc_lint_defs::builtin::PROC_MACRO_BACK_COMPAT;
|
||||
use rustc_lint_defs::BuiltinLintDiagnostics;
|
||||
use rustc_parse::{self, nt_to_tokenstream, parser, MACRO_ARGUMENTS};
|
||||
use rustc_session::{parse::ParseSess, Limit, Session};
|
||||
use rustc_span::def_id::DefId;
|
||||
@ -1241,3 +1243,41 @@ pub fn get_exprs_from_tts(
|
||||
}
|
||||
Some(es)
|
||||
}
|
||||
|
||||
/// This nonterminal looks like some specific enums from
|
||||
/// `proc-macro-hack` and `procedural-masquerade` crates.
|
||||
/// We need to maintain some special pretty-printing behavior for them due to incorrect
|
||||
/// asserts in old versions of those crates and their wide use in the ecosystem.
|
||||
/// See issue #73345 for more details.
|
||||
/// FIXME(#73933): Remove this eventually.
|
||||
pub(crate) fn pretty_printing_compatibility_hack(nt: &Nonterminal, sess: &ParseSess) -> bool {
|
||||
let item = match nt {
|
||||
Nonterminal::NtItem(item) => item,
|
||||
Nonterminal::NtStmt(stmt) => match &stmt.kind {
|
||||
ast::StmtKind::Item(item) => item,
|
||||
_ => return false,
|
||||
},
|
||||
_ => return false,
|
||||
};
|
||||
|
||||
let name = item.ident.name;
|
||||
if name == sym::ProceduralMasqueradeDummyType {
|
||||
if let ast::ItemKind::Enum(enum_def, _) = &item.kind {
|
||||
if let [variant] = &*enum_def.variants {
|
||||
if variant.ident.name == sym::Input {
|
||||
sess.buffer_lint_with_diagnostic(
|
||||
&PROC_MACRO_BACK_COMPAT,
|
||||
item.ident.span,
|
||||
ast::CRATE_NODE_ID,
|
||||
"using `procedural-masquerade` crate",
|
||||
BuiltinLintDiagnostics::ProcMacroBackCompat(
|
||||
"The `procedural-masquerade` crate has been unnecessary since Rust 1.30.0. \
|
||||
Versions of this crate below 0.1.7 will eventually stop compiling.".to_string())
|
||||
);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
@ -90,7 +90,8 @@ impl MultiItemModifier for ProcMacroDerive {
|
||||
}
|
||||
_ => unreachable!(),
|
||||
};
|
||||
let input = if item.pretty_printing_compatibility_hack() {
|
||||
let input = if crate::base::pretty_printing_compatibility_hack(&item, &ecx.sess.parse_sess)
|
||||
{
|
||||
TokenTree::token(token::Interpolated(Lrc::new(item)), DUMMY_SP).into()
|
||||
} else {
|
||||
nt_to_tokenstream(&item, &ecx.sess.parse_sess, CanSynthesizeMissingTokens::Yes)
|
||||
|
@ -187,7 +187,7 @@ impl FromInternal<(TreeAndSpacing, &'_ ParseSess, &'_ mut Vec<Self>)>
|
||||
delimiter: Delimiter::None,
|
||||
stream,
|
||||
span: DelimSpan::from_single(span),
|
||||
flatten: nt.pretty_printing_compatibility_hack(),
|
||||
flatten: crate::base::pretty_printing_compatibility_hack(&nt, sess),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -748,7 +748,7 @@ impl<'a> EarlyContext<'a> {
|
||||
sess,
|
||||
krate,
|
||||
lint_store,
|
||||
builder: LintLevelsBuilder::new(sess, warn_about_weird_lints, lint_store),
|
||||
builder: LintLevelsBuilder::new(sess, warn_about_weird_lints, lint_store, &krate.attrs),
|
||||
buffered,
|
||||
}
|
||||
}
|
||||
|
@ -1,13 +1,12 @@
|
||||
use crate::context::{CheckLintNameResult, LintStore};
|
||||
use crate::late::unerased_lint_store;
|
||||
use rustc_ast as ast;
|
||||
use rustc_ast::attr;
|
||||
use rustc_ast::unwrap_or;
|
||||
use rustc_ast_pretty::pprust;
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
|
||||
use rustc_hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
|
||||
use rustc_hir::{intravisit, HirId};
|
||||
use rustc_middle::hir::map::Map;
|
||||
use rustc_middle::lint::LevelAndSource;
|
||||
@ -32,7 +31,8 @@ use std::cmp;
|
||||
fn lint_levels(tcx: TyCtxt<'_>, cnum: CrateNum) -> LintLevelMap {
|
||||
assert_eq!(cnum, LOCAL_CRATE);
|
||||
let store = unerased_lint_store(tcx);
|
||||
let levels = LintLevelsBuilder::new(tcx.sess, false, &store);
|
||||
let crate_attrs = tcx.get_attrs(DefId { krate: cnum, index: CRATE_DEF_INDEX });
|
||||
let levels = LintLevelsBuilder::new(tcx.sess, false, &store, crate_attrs);
|
||||
let mut builder = LintLevelMapBuilder { levels, tcx, store };
|
||||
let krate = tcx.hir().krate();
|
||||
|
||||
@ -56,6 +56,7 @@ pub struct LintLevelsBuilder<'s> {
|
||||
cur: u32,
|
||||
warn_about_weird_lints: bool,
|
||||
store: &'s LintStore,
|
||||
crate_attrs: &'s [ast::Attribute],
|
||||
}
|
||||
|
||||
pub struct BuilderPush {
|
||||
@ -64,7 +65,12 @@ pub struct BuilderPush {
|
||||
}
|
||||
|
||||
impl<'s> LintLevelsBuilder<'s> {
|
||||
pub fn new(sess: &'s Session, warn_about_weird_lints: bool, store: &'s LintStore) -> Self {
|
||||
pub fn new(
|
||||
sess: &'s Session,
|
||||
warn_about_weird_lints: bool,
|
||||
store: &'s LintStore,
|
||||
crate_attrs: &'s [ast::Attribute],
|
||||
) -> Self {
|
||||
let mut builder = LintLevelsBuilder {
|
||||
sess,
|
||||
sets: LintLevelSets::new(),
|
||||
@ -72,6 +78,7 @@ impl<'s> LintLevelsBuilder<'s> {
|
||||
id_to_set: Default::default(),
|
||||
warn_about_weird_lints,
|
||||
store,
|
||||
crate_attrs,
|
||||
};
|
||||
builder.process_command_line(sess, store);
|
||||
assert_eq!(builder.sets.list.len(), 1);
|
||||
@ -304,15 +311,22 @@ impl<'s> LintLevelsBuilder<'s> {
|
||||
};
|
||||
let tool_name = if meta_item.path.segments.len() > 1 {
|
||||
let tool_ident = meta_item.path.segments[0].ident;
|
||||
if !attr::is_known_lint_tool(tool_ident) {
|
||||
struct_span_err!(
|
||||
if !is_known_lint_tool(tool_ident.name, sess, &self.crate_attrs) {
|
||||
let mut err = struct_span_err!(
|
||||
sess,
|
||||
tool_ident.span,
|
||||
E0710,
|
||||
"an unknown tool name found in scoped lint: `{}`",
|
||||
"unknown tool name `{}` found in scoped lint: `{}`",
|
||||
tool_ident.name,
|
||||
pprust::path_to_string(&meta_item.path),
|
||||
)
|
||||
.emit();
|
||||
);
|
||||
if sess.is_nightly_build() {
|
||||
err.help(&format!(
|
||||
"add `#![register_tool({})]` to the crate root",
|
||||
tool_ident.name
|
||||
));
|
||||
}
|
||||
err.emit();
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -559,6 +573,20 @@ impl<'s> LintLevelsBuilder<'s> {
|
||||
}
|
||||
}
|
||||
|
||||
fn is_known_lint_tool(m_item: Symbol, sess: &Session, attrs: &[ast::Attribute]) -> bool {
|
||||
if [sym::clippy, sym::rustc, sym::rustdoc].contains(&m_item) {
|
||||
return true;
|
||||
}
|
||||
// Look for registered tools
|
||||
// NOTE: does no error handling; error handling is done by rustc_resolve.
|
||||
sess.filter_by_name(attrs, sym::register_tool)
|
||||
.filter_map(|attr| attr.meta_item_list())
|
||||
.flat_map(std::convert::identity)
|
||||
.filter_map(|nested_meta| nested_meta.ident())
|
||||
.map(|ident| ident.name)
|
||||
.any(|name| name == m_item)
|
||||
}
|
||||
|
||||
struct LintLevelMapBuilder<'a, 'tcx> {
|
||||
levels: LintLevelsBuilder<'tcx>,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
|
@ -1407,6 +1407,14 @@ rustc_queries! {
|
||||
query is_codegened_item(def_id: DefId) -> bool {
|
||||
desc { |tcx| "determining whether `{}` needs codegen", tcx.def_path_str(def_id) }
|
||||
}
|
||||
|
||||
/// All items participating in code generation together with items inlined into them.
|
||||
query codegened_and_inlined_items(_: CrateNum)
|
||||
-> &'tcx DefIdSet {
|
||||
eval_always
|
||||
desc { "codegened_and_inlined_items" }
|
||||
}
|
||||
|
||||
query codegen_unit(_: Symbol) -> &'tcx CodegenUnit<'tcx> {
|
||||
desc { "codegen_unit" }
|
||||
}
|
||||
|
@ -424,8 +424,33 @@ fn collect_and_partition_mono_items<'tcx>(
|
||||
(tcx.arena.alloc(mono_items), codegen_units)
|
||||
}
|
||||
|
||||
fn codegened_and_inlined_items<'tcx>(tcx: TyCtxt<'tcx>, cnum: CrateNum) -> &'tcx DefIdSet {
|
||||
let (items, cgus) = tcx.collect_and_partition_mono_items(cnum);
|
||||
let mut visited = DefIdSet::default();
|
||||
let mut result = items.clone();
|
||||
|
||||
for cgu in cgus {
|
||||
for (item, _) in cgu.items() {
|
||||
if let MonoItem::Fn(ref instance) = item {
|
||||
let did = instance.def_id();
|
||||
if !visited.insert(did) {
|
||||
continue;
|
||||
}
|
||||
for scope in &tcx.instance_mir(instance.def).source_scopes {
|
||||
if let Some((ref inlined, _)) = scope.inlined {
|
||||
result.insert(inlined.def_id());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tcx.arena.alloc(result)
|
||||
}
|
||||
|
||||
pub fn provide(providers: &mut Providers) {
|
||||
providers.collect_and_partition_mono_items = collect_and_partition_mono_items;
|
||||
providers.codegened_and_inlined_items = codegened_and_inlined_items;
|
||||
|
||||
providers.is_codegened_item = |tcx, def_id| {
|
||||
let (all_mono_items, _) = tcx.collect_and_partition_mono_items(LOCAL_CRATE);
|
||||
|
@ -1,8 +1,7 @@
|
||||
use super::*;
|
||||
|
||||
use rustc_middle::mir::coverage::*;
|
||||
use rustc_middle::mir::visit::Visitor;
|
||||
use rustc_middle::mir::{self, Coverage, CoverageInfo, Location};
|
||||
use rustc_middle::mir::{self, Body, Coverage, CoverageInfo};
|
||||
use rustc_middle::ty::query::Providers;
|
||||
use rustc_middle::ty::{self, TyCtxt};
|
||||
use rustc_span::def_id::DefId;
|
||||
@ -85,10 +84,21 @@ impl CoverageVisitor {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Visitor<'_> for CoverageVisitor {
|
||||
fn visit_coverage(&mut self, coverage: &Coverage, _location: Location) {
|
||||
fn visit_body(&mut self, body: &Body<'_>) {
|
||||
for bb_data in body.basic_blocks().iter() {
|
||||
for statement in bb_data.statements.iter() {
|
||||
if let StatementKind::Coverage(box ref coverage) = statement.kind {
|
||||
if is_inlined(body, statement) {
|
||||
continue;
|
||||
}
|
||||
self.visit_coverage(coverage);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_coverage(&mut self, coverage: &Coverage) {
|
||||
if self.add_missing_operands {
|
||||
match coverage.kind {
|
||||
CoverageKind::Expression { lhs, rhs, .. } => {
|
||||
@ -129,10 +139,14 @@ fn coverageinfo_from_mir<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> CoverageInfo
|
||||
}
|
||||
|
||||
fn covered_file_name<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Option<Symbol> {
|
||||
for bb_data in mir_body(tcx, def_id).basic_blocks().iter() {
|
||||
let body = mir_body(tcx, def_id);
|
||||
for bb_data in body.basic_blocks().iter() {
|
||||
for statement in bb_data.statements.iter() {
|
||||
if let StatementKind::Coverage(box ref coverage) = statement.kind {
|
||||
if let Some(code_region) = coverage.code_region.as_ref() {
|
||||
if is_inlined(body, statement) {
|
||||
continue;
|
||||
}
|
||||
return Some(code_region.file_name);
|
||||
}
|
||||
}
|
||||
@ -151,13 +165,17 @@ fn mir_body<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx mir::Body<'tcx> {
|
||||
}
|
||||
|
||||
fn covered_code_regions<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Vec<&'tcx CodeRegion> {
|
||||
mir_body(tcx, def_id)
|
||||
.basic_blocks()
|
||||
let body = mir_body(tcx, def_id);
|
||||
body.basic_blocks()
|
||||
.iter()
|
||||
.map(|data| {
|
||||
data.statements.iter().filter_map(|statement| match statement.kind {
|
||||
StatementKind::Coverage(box ref coverage) => {
|
||||
coverage.code_region.as_ref() // may be None
|
||||
if is_inlined(body, statement) {
|
||||
None
|
||||
} else {
|
||||
coverage.code_region.as_ref() // may be None
|
||||
}
|
||||
}
|
||||
_ => None,
|
||||
})
|
||||
@ -165,3 +183,8 @@ fn covered_code_regions<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Vec<&'tcx Cod
|
||||
.flatten()
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn is_inlined(body: &Body<'_>, statement: &Statement<'_>) -> bool {
|
||||
let scope_data = &body.source_scopes[statement.source_info.scope];
|
||||
scope_data.inlined.is_some() || scope_data.inlined_parent_scope.is_some()
|
||||
}
|
||||
|
@ -39,15 +39,6 @@ struct CallSite<'tcx> {
|
||||
|
||||
/// Returns true if MIR inlining is enabled in the current compilation session.
|
||||
crate fn is_enabled(tcx: TyCtxt<'_>) -> bool {
|
||||
if tcx.sess.opts.debugging_opts.instrument_coverage {
|
||||
// Since `Inline` happens after `InstrumentCoverage`, the function-specific coverage
|
||||
// counters can be invalidated, such as by merging coverage counter statements from
|
||||
// a pre-inlined function into a different function. This kind of change is invalid,
|
||||
// so inlining must be skipped. Note: This check is performed here so inlining can
|
||||
// be disabled without preventing other optimizations (regardless of `mir_opt_level`).
|
||||
return false;
|
||||
}
|
||||
|
||||
if let Some(enabled) = tcx.sess.opts.debugging_opts.inline_mir {
|
||||
return enabled;
|
||||
}
|
||||
|
@ -1937,25 +1937,6 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
|
||||
}
|
||||
Some(SymbolManglingVersion::V0) => {}
|
||||
}
|
||||
|
||||
if let Some(mir_opt_level) = debugging_opts.mir_opt_level {
|
||||
if mir_opt_level > 1 {
|
||||
// Functions inlined during MIR transform can, at best, make it impossible to
|
||||
// effectively cover inlined functions, and, at worst, break coverage map generation
|
||||
// during LLVM codegen. For example, function counter IDs are only unique within a
|
||||
// function. Inlining after these counters are injected can produce duplicate counters,
|
||||
// resulting in an invalid coverage map (and ICE); so this option combination is not
|
||||
// allowed.
|
||||
early_warn(
|
||||
error_format,
|
||||
&format!(
|
||||
"`-Z mir-opt-level={}` (or any level > 1) enables function inlining, which \
|
||||
is incompatible with `-Z instrument-coverage`. Inlining will be disabled.",
|
||||
mir_opt_level,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Ok(graphviz_font) = std::env::var("RUSTC_GRAPHVIZ_FONT") {
|
||||
|
@ -793,6 +793,13 @@ impl Session {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn inline_asm_dialect(&self) -> rustc_ast::LlvmAsmDialect {
|
||||
match self.asm_arch {
|
||||
Some(InlineAsmArch::X86 | InlineAsmArch::X86_64) => rustc_ast::LlvmAsmDialect::Intel,
|
||||
_ => rustc_ast::LlvmAsmDialect::Att,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn relocation_model(&self) -> RelocModel {
|
||||
self.opts.cg.relocation_model.unwrap_or(self.target.relocation_model)
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ pub fn target() -> Target {
|
||||
options: TargetOptions {
|
||||
linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld),
|
||||
linker: Some("rust-lld".to_string()),
|
||||
llvm_abiname: "lp64d".to_string(),
|
||||
cpu: "generic-rv64".to_string(),
|
||||
max_atomic_width: Some(64),
|
||||
atomic_cas: true,
|
||||
|
@ -4,6 +4,7 @@
|
||||
#![feature(btree_drain_filter)]
|
||||
#![feature(map_first_last)]
|
||||
#![feature(repr_simd)]
|
||||
#![feature(slice_partition_dedup)]
|
||||
#![feature(test)]
|
||||
|
||||
extern crate test;
|
||||
|
@ -671,3 +671,92 @@ fn bench_map_fast(b: &mut Bencher) {
|
||||
let data = black_box([(0, 0); LEN]);
|
||||
b.iter(|| map_fast(&data));
|
||||
}
|
||||
|
||||
fn random_sorted_fill(mut seed: u32, buf: &mut [u32]) {
|
||||
let mask = if buf.len() < 8192 {
|
||||
0xFF
|
||||
} else if buf.len() < 200_000 {
|
||||
0xFFFF
|
||||
} else {
|
||||
0xFFFF_FFFF
|
||||
};
|
||||
|
||||
for item in buf.iter_mut() {
|
||||
seed ^= seed << 13;
|
||||
seed ^= seed >> 17;
|
||||
seed ^= seed << 5;
|
||||
|
||||
*item = seed & mask;
|
||||
}
|
||||
|
||||
buf.sort();
|
||||
}
|
||||
|
||||
fn bench_vec_dedup_old(b: &mut Bencher, sz: usize) {
|
||||
let mut template = vec![0u32; sz];
|
||||
b.bytes = std::mem::size_of_val(template.as_slice()) as u64;
|
||||
random_sorted_fill(0x43, &mut template);
|
||||
|
||||
let mut vec = template.clone();
|
||||
b.iter(|| {
|
||||
let len = {
|
||||
let (dedup, _) = vec.partition_dedup();
|
||||
dedup.len()
|
||||
};
|
||||
vec.truncate(len);
|
||||
|
||||
black_box(vec.first());
|
||||
vec.clear();
|
||||
vec.extend_from_slice(&template);
|
||||
});
|
||||
}
|
||||
|
||||
fn bench_vec_dedup_new(b: &mut Bencher, sz: usize) {
|
||||
let mut template = vec![0u32; sz];
|
||||
b.bytes = std::mem::size_of_val(template.as_slice()) as u64;
|
||||
random_sorted_fill(0x43, &mut template);
|
||||
|
||||
let mut vec = template.clone();
|
||||
b.iter(|| {
|
||||
vec.dedup();
|
||||
black_box(vec.first());
|
||||
vec.clear();
|
||||
vec.extend_from_slice(&template);
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_dedup_old_100(b: &mut Bencher) {
|
||||
bench_vec_dedup_old(b, 100);
|
||||
}
|
||||
#[bench]
|
||||
fn bench_dedup_new_100(b: &mut Bencher) {
|
||||
bench_vec_dedup_new(b, 100);
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_dedup_old_1000(b: &mut Bencher) {
|
||||
bench_vec_dedup_old(b, 1000);
|
||||
}
|
||||
#[bench]
|
||||
fn bench_dedup_new_1000(b: &mut Bencher) {
|
||||
bench_vec_dedup_new(b, 1000);
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_dedup_old_10000(b: &mut Bencher) {
|
||||
bench_vec_dedup_old(b, 10000);
|
||||
}
|
||||
#[bench]
|
||||
fn bench_dedup_new_10000(b: &mut Bencher) {
|
||||
bench_vec_dedup_new(b, 10000);
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_dedup_old_100000(b: &mut Bencher) {
|
||||
bench_vec_dedup_old(b, 100000);
|
||||
}
|
||||
#[bench]
|
||||
fn bench_dedup_new_100000(b: &mut Bencher) {
|
||||
bench_vec_dedup_new(b, 100000);
|
||||
}
|
||||
|
@ -21,15 +21,15 @@ use Entry::*;
|
||||
/// We might temporarily have fewer elements during methods.
|
||||
pub(super) const MIN_LEN: usize = node::MIN_LEN_AFTER_SPLIT;
|
||||
|
||||
// A tree in a `BTreeMap` is a tree in the `node` module with addtional invariants:
|
||||
// A tree in a `BTreeMap` is a tree in the `node` module with additional invariants:
|
||||
// - Keys must appear in ascending order (according to the key's type).
|
||||
// - If the root node is internal, it must contain at least 1 element.
|
||||
// - Every non-root node contains at least MIN_LEN elements.
|
||||
//
|
||||
// An empty map may be represented both by the absense of a root node or by a
|
||||
// An empty map may be represented both by the absence of a root node or by a
|
||||
// root node that is an empty leaf.
|
||||
|
||||
/// A map based on a B-Tree.
|
||||
/// A map based on a [B-Tree].
|
||||
///
|
||||
/// B-Trees represent a fundamental compromise between cache-efficiency and actually minimizing
|
||||
/// the amount of work performed in a search. In theory, a binary search tree (BST) is the optimal
|
||||
@ -63,6 +63,7 @@ pub(super) const MIN_LEN: usize = node::MIN_LEN_AFTER_SPLIT;
|
||||
/// undefined behavior. This could include panics, incorrect results, aborts, memory leaks, and
|
||||
/// non-termination.
|
||||
///
|
||||
/// [B-Tree]: https://en.wikipedia.org/wiki/B-tree
|
||||
/// [`Cell`]: core::cell::Cell
|
||||
/// [`RefCell`]: core::cell::RefCell
|
||||
///
|
||||
|
@ -1512,15 +1512,98 @@ impl<T, A: Allocator> Vec<T, A> {
|
||||
/// assert_eq!(vec, ["foo", "bar", "baz", "bar"]);
|
||||
/// ```
|
||||
#[stable(feature = "dedup_by", since = "1.16.0")]
|
||||
pub fn dedup_by<F>(&mut self, same_bucket: F)
|
||||
pub fn dedup_by<F>(&mut self, mut same_bucket: F)
|
||||
where
|
||||
F: FnMut(&mut T, &mut T) -> bool,
|
||||
{
|
||||
let len = {
|
||||
let (dedup, _) = self.as_mut_slice().partition_dedup_by(same_bucket);
|
||||
dedup.len()
|
||||
};
|
||||
self.truncate(len);
|
||||
let len = self.len();
|
||||
if len <= 1 {
|
||||
return;
|
||||
}
|
||||
|
||||
/* INVARIANT: vec.len() > read >= write > write-1 >= 0 */
|
||||
struct FillGapOnDrop<'a, T, A: core::alloc::Allocator> {
|
||||
/* Offset of the element we want to check if it is duplicate */
|
||||
read: usize,
|
||||
|
||||
/* Offset of the place where we want to place the non-duplicate
|
||||
* when we find it. */
|
||||
write: usize,
|
||||
|
||||
/* The Vec that would need correction if `same_bucket` panicked */
|
||||
vec: &'a mut Vec<T, A>,
|
||||
}
|
||||
|
||||
impl<'a, T, A: core::alloc::Allocator> Drop for FillGapOnDrop<'a, T, A> {
|
||||
fn drop(&mut self) {
|
||||
/* This code gets executed when `same_bucket` panics */
|
||||
|
||||
/* SAFETY: invariant guarantees that `read - write`
|
||||
* and `len - read` never overflow and that the copy is always
|
||||
* in-bounds. */
|
||||
unsafe {
|
||||
let ptr = self.vec.as_mut_ptr();
|
||||
let len = self.vec.len();
|
||||
|
||||
/* How many items were left when `same_bucket` paniced.
|
||||
* Basically vec[read..].len() */
|
||||
let items_left = len.wrapping_sub(self.read);
|
||||
|
||||
/* Pointer to first item in vec[write..write+items_left] slice */
|
||||
let dropped_ptr = ptr.add(self.write);
|
||||
/* Pointer to first item in vec[read..] slice */
|
||||
let valid_ptr = ptr.add(self.read);
|
||||
|
||||
/* Copy `vec[read..]` to `vec[write..write+items_left]`.
|
||||
* The slices can overlap, so `copy_nonoverlapping` cannot be used */
|
||||
ptr::copy(valid_ptr, dropped_ptr, items_left);
|
||||
|
||||
/* How many items have been already dropped
|
||||
* Basically vec[read..write].len() */
|
||||
let dropped = self.read.wrapping_sub(self.write);
|
||||
|
||||
self.vec.set_len(len - dropped);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut gap = FillGapOnDrop { read: 1, write: 1, vec: self };
|
||||
let ptr = gap.vec.as_mut_ptr();
|
||||
|
||||
/* Drop items while going through Vec, it should be more efficient than
|
||||
* doing slice partition_dedup + truncate */
|
||||
|
||||
/* SAFETY: Because of the invariant, read_ptr, prev_ptr and write_ptr
|
||||
* are always in-bounds and read_ptr never aliases prev_ptr */
|
||||
unsafe {
|
||||
while gap.read < len {
|
||||
let read_ptr = ptr.add(gap.read);
|
||||
let prev_ptr = ptr.add(gap.write.wrapping_sub(1));
|
||||
|
||||
if same_bucket(&mut *read_ptr, &mut *prev_ptr) {
|
||||
/* We have found duplicate, drop it in-place */
|
||||
ptr::drop_in_place(read_ptr);
|
||||
} else {
|
||||
let write_ptr = ptr.add(gap.write);
|
||||
|
||||
/* Because `read_ptr` can be equal to `write_ptr`, we either
|
||||
* have to use `copy` or conditional `copy_nonoverlapping`.
|
||||
* Looks like the first option is faster. */
|
||||
ptr::copy(read_ptr, write_ptr, 1);
|
||||
|
||||
/* We have filled that place, so go further */
|
||||
gap.write += 1;
|
||||
}
|
||||
|
||||
gap.read += 1;
|
||||
}
|
||||
|
||||
/* Technically we could let `gap` clean up with its Drop, but
|
||||
* when `same_bucket` is guaranteed to not panic, this bloats a little
|
||||
* the codegen, so we just do it manually */
|
||||
gap.vec.set_len(gap.write);
|
||||
mem::forget(gap);
|
||||
}
|
||||
}
|
||||
|
||||
/// Appends an element to the back of a collection.
|
||||
|
@ -19,6 +19,7 @@
|
||||
#![feature(int_bits_const)]
|
||||
#![feature(vecdeque_binary_search)]
|
||||
#![feature(slice_group_by)]
|
||||
#![feature(slice_partition_dedup)]
|
||||
#![feature(vec_extend_from_within)]
|
||||
#![feature(vec_spare_capacity)]
|
||||
|
||||
|
@ -2102,6 +2102,132 @@ fn test_extend_from_within() {
|
||||
assert_eq!(v, ["a", "b", "c", "b", "c", "a", "b"]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_vec_dedup_by() {
|
||||
let mut vec: Vec<i32> = vec![1, -1, 2, 3, 1, -5, 5, -2, 2];
|
||||
|
||||
vec.dedup_by(|a, b| a.abs() == b.abs());
|
||||
|
||||
assert_eq!(vec, [1, 2, 3, 1, -5, -2]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_vec_dedup_empty() {
|
||||
let mut vec: Vec<i32> = Vec::new();
|
||||
|
||||
vec.dedup();
|
||||
|
||||
assert_eq!(vec, []);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_vec_dedup_one() {
|
||||
let mut vec = vec![12i32];
|
||||
|
||||
vec.dedup();
|
||||
|
||||
assert_eq!(vec, [12]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_vec_dedup_multiple_ident() {
|
||||
let mut vec = vec![12, 12, 12, 12, 12, 11, 11, 11, 11, 11, 11];
|
||||
|
||||
vec.dedup();
|
||||
|
||||
assert_eq!(vec, [12, 11]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_vec_dedup_partialeq() {
|
||||
#[derive(Debug)]
|
||||
struct Foo(i32, i32);
|
||||
|
||||
impl PartialEq for Foo {
|
||||
fn eq(&self, other: &Foo) -> bool {
|
||||
self.0 == other.0
|
||||
}
|
||||
}
|
||||
|
||||
let mut vec = vec![Foo(0, 1), Foo(0, 5), Foo(1, 7), Foo(1, 9)];
|
||||
|
||||
vec.dedup();
|
||||
assert_eq!(vec, [Foo(0, 1), Foo(1, 7)]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_vec_dedup() {
|
||||
let mut vec: Vec<bool> = Vec::with_capacity(8);
|
||||
let mut template = vec.clone();
|
||||
|
||||
for x in 0u8..255u8 {
|
||||
vec.clear();
|
||||
template.clear();
|
||||
|
||||
let iter = (0..8).map(move |bit| (x >> bit) & 1 == 1);
|
||||
vec.extend(iter);
|
||||
template.extend_from_slice(&vec);
|
||||
|
||||
let (dedup, _) = template.partition_dedup();
|
||||
vec.dedup();
|
||||
|
||||
assert_eq!(vec, dedup);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_vec_dedup_panicking() {
|
||||
#[derive(Debug)]
|
||||
struct Panic {
|
||||
drop_counter: &'static AtomicU32,
|
||||
value: bool,
|
||||
index: usize,
|
||||
}
|
||||
|
||||
impl PartialEq for Panic {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.value == other.value
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Panic {
|
||||
fn drop(&mut self) {
|
||||
let x = self.drop_counter.fetch_add(1, Ordering::SeqCst);
|
||||
assert!(x != 4);
|
||||
}
|
||||
}
|
||||
|
||||
static DROP_COUNTER: AtomicU32 = AtomicU32::new(0);
|
||||
let expected = [
|
||||
Panic { drop_counter: &DROP_COUNTER, value: false, index: 0 },
|
||||
Panic { drop_counter: &DROP_COUNTER, value: false, index: 5 },
|
||||
Panic { drop_counter: &DROP_COUNTER, value: true, index: 6 },
|
||||
Panic { drop_counter: &DROP_COUNTER, value: true, index: 7 },
|
||||
];
|
||||
let mut vec = vec![
|
||||
Panic { drop_counter: &DROP_COUNTER, value: false, index: 0 },
|
||||
// these elements get deduplicated
|
||||
Panic { drop_counter: &DROP_COUNTER, value: false, index: 1 },
|
||||
Panic { drop_counter: &DROP_COUNTER, value: false, index: 2 },
|
||||
Panic { drop_counter: &DROP_COUNTER, value: false, index: 3 },
|
||||
Panic { drop_counter: &DROP_COUNTER, value: false, index: 4 },
|
||||
// here it panics
|
||||
Panic { drop_counter: &DROP_COUNTER, value: false, index: 5 },
|
||||
Panic { drop_counter: &DROP_COUNTER, value: true, index: 6 },
|
||||
Panic { drop_counter: &DROP_COUNTER, value: true, index: 7 },
|
||||
];
|
||||
|
||||
let _ = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
|
||||
vec.dedup();
|
||||
}));
|
||||
|
||||
let ok = vec.iter().zip(expected.iter()).all(|(x, y)| x.index == y.index);
|
||||
|
||||
if !ok {
|
||||
panic!("expected: {:?}\ngot: {:?}\n", expected, vec);
|
||||
}
|
||||
}
|
||||
|
||||
// Regression test for issue #82533
|
||||
#[test]
|
||||
fn test_extend_from_within_panicing_clone() {
|
||||
|
@ -1,7 +1,13 @@
|
||||
//! Generic hashing support.
|
||||
//!
|
||||
//! This module provides a generic way to compute the hash of a value. The
|
||||
//! simplest way to make a type hashable is to use `#[derive(Hash)]`:
|
||||
//! This module provides a generic way to compute the [hash] of a value.
|
||||
//! Hashes are most commonly used with [`HashMap`] and [`HashSet`].
|
||||
//!
|
||||
//! [hash]: https://en.wikipedia.org/wiki/Hash_function
|
||||
//! [`HashMap`]: ../../std/collections/struct.HashMap.html
|
||||
//! [`HashSet`]: ../../std/collections/struct.HashSet.html
|
||||
//!
|
||||
//! The simplest way to make a type hashable is to use `#[derive(Hash)]`:
|
||||
//!
|
||||
//! # Examples
|
||||
//!
|
||||
|
@ -17,7 +17,7 @@ use crate::iter::{FromIterator, FusedIterator};
|
||||
use crate::ops::Index;
|
||||
use crate::sys;
|
||||
|
||||
/// A hash map implemented with quadratic probing and SIMD lookup.
|
||||
/// A [hash map] implemented with quadratic probing and SIMD lookup.
|
||||
///
|
||||
/// By default, `HashMap` uses a hashing algorithm selected to provide
|
||||
/// resistance against HashDoS attacks. The algorithm is randomly seeded, and a
|
||||
@ -62,6 +62,7 @@ use crate::sys;
|
||||
/// The original C++ version of SwissTable can be found [here], and this
|
||||
/// [CppCon talk] gives an overview of how the algorithm works.
|
||||
///
|
||||
/// [hash map]: crate::collections#use-a-hashmap-when
|
||||
/// [hashing algorithms available on crates.io]: https://crates.io/keywords/hasher
|
||||
/// [SwissTable]: https://abseil.io/blog/20180927-swisstables
|
||||
/// [here]: https://github.com/abseil/abseil-cpp/blob/master/absl/container/internal/raw_hash_set.h
|
||||
|
@ -19,7 +19,7 @@ use super::map::{map_try_reserve_error, RandomState};
|
||||
// for `bucket.val` in the case of HashSet. I suppose we would need HKT
|
||||
// to get rid of it properly.
|
||||
|
||||
/// A hash set implemented as a `HashMap` where the value is `()`.
|
||||
/// A [hash set] implemented as a `HashMap` where the value is `()`.
|
||||
///
|
||||
/// As with the [`HashMap`] type, a `HashSet` requires that the elements
|
||||
/// implement the [`Eq`] and [`Hash`] traits. This can frequently be achieved by
|
||||
@ -105,6 +105,7 @@ use super::map::{map_try_reserve_error, RandomState};
|
||||
/// // use the values stored in the set
|
||||
/// ```
|
||||
///
|
||||
/// [hash set]: crate::collections#use-the-set-variant-of-any-of-these-maps-when
|
||||
/// [`HashMap`]: crate::collections::HashMap
|
||||
/// [`RefCell`]: crate::cell::RefCell
|
||||
/// [`Cell`]: crate::cell::Cell
|
||||
|
@ -39,6 +39,7 @@ impl Drop for Handler {
|
||||
))]
|
||||
mod imp {
|
||||
use super::Handler;
|
||||
use crate::io;
|
||||
use crate::mem;
|
||||
use crate::ptr;
|
||||
|
||||
@ -149,11 +150,11 @@ mod imp {
|
||||
0,
|
||||
);
|
||||
if stackp == MAP_FAILED {
|
||||
panic!("failed to allocate an alternative stack");
|
||||
panic!("failed to allocate an alternative stack: {}", io::Error::last_os_error());
|
||||
}
|
||||
let guard_result = libc::mprotect(stackp, page_size(), PROT_NONE);
|
||||
if guard_result != 0 {
|
||||
panic!("failed to set up alternative stack guard page");
|
||||
panic!("failed to set up alternative stack guard page: {}", io::Error::last_os_error());
|
||||
}
|
||||
stackp.add(page_size())
|
||||
}
|
||||
|
@ -231,6 +231,7 @@ pub mod guard {
|
||||
use libc::{mmap, mprotect};
|
||||
use libc::{MAP_ANON, MAP_FAILED, MAP_FIXED, MAP_PRIVATE, PROT_NONE, PROT_READ, PROT_WRITE};
|
||||
|
||||
use crate::io;
|
||||
use crate::ops::Range;
|
||||
use crate::sync::atomic::{AtomicUsize, Ordering};
|
||||
use crate::sys::os;
|
||||
@ -361,12 +362,12 @@ pub mod guard {
|
||||
0,
|
||||
);
|
||||
if result != stackaddr || result == MAP_FAILED {
|
||||
panic!("failed to allocate a guard page");
|
||||
panic!("failed to allocate a guard page: {}", io::Error::last_os_error());
|
||||
}
|
||||
|
||||
let result = mprotect(stackaddr, page_size, PROT_NONE);
|
||||
if result != 0 {
|
||||
panic!("failed to protect the guard page");
|
||||
panic!("failed to protect the guard page: {}", io::Error::last_os_error());
|
||||
}
|
||||
|
||||
let guardaddr = stackaddr as usize;
|
||||
|
@ -9,6 +9,8 @@ RUN . /scripts/android-ndk.sh && \
|
||||
download_ndk android-ndk-r15c-linux-x86_64.zip && \
|
||||
make_standalone_toolchain arm 14 && \
|
||||
make_standalone_toolchain x86 14 && \
|
||||
make_standalone_toolchain arm 21 && \
|
||||
make_standalone_toolchain x86 21 && \
|
||||
make_standalone_toolchain arm64 21 && \
|
||||
make_standalone_toolchain x86_64 21 && \
|
||||
remove_ndk
|
||||
|
@ -45,10 +45,10 @@ ENV \
|
||||
CC_armv7_unknown_linux_gnueabi=arm-linux-gnueabi-gcc-8 \
|
||||
CXX_armv7_unknown_linux_gnueabi=arm-linux-gnueabi-g++-8 \
|
||||
AR_x86_64_fortanix_unknown_sgx=ar \
|
||||
CC_x86_64_fortanix_unknown_sgx=x86_64-fortanix-unknown-sgx-clang-11 \
|
||||
CFLAGS_x86_64_fortanix_unknown_sgx="-mlvi-hardening -mllvm -x86-experimental-lvi-inline-asm-hardening" \
|
||||
CXX_x86_64_fortanix_unknown_sgx=x86_64-fortanix-unknown-sgx-clang++-11 \
|
||||
CXXFLAGS_x86_64_fortanix_unknown_sgx="-mlvi-hardening -mllvm -x86-experimental-lvi-inline-asm-hardening" \
|
||||
CC_x86_64_fortanix_unknown_sgx=clang-11 \
|
||||
CFLAGS_x86_64_fortanix_unknown_sgx="-D__ELF__ -isystem/usr/include/x86_64-linux-gnu -mlvi-hardening -mllvm -x86-experimental-lvi-inline-asm-hardening" \
|
||||
CXX_x86_64_fortanix_unknown_sgx=clang++-11 \
|
||||
CXXFLAGS_x86_64_fortanix_unknown_sgx="-D__ELF__ -isystem/usr/include/x86_64-linux-gnu -mlvi-hardening -mllvm -x86-experimental-lvi-inline-asm-hardening" \
|
||||
AR_i686_unknown_freebsd=i686-unknown-freebsd11-ar \
|
||||
CC_i686_unknown_freebsd=i686-unknown-freebsd11-clang \
|
||||
CXX_i686_unknown_freebsd=i686-unknown-freebsd11-clang++ \
|
||||
@ -71,8 +71,6 @@ COPY host-x86_64/dist-various-2/build-solaris-toolchain.sh /tmp/
|
||||
RUN /tmp/build-solaris-toolchain.sh x86_64 amd64 solaris-i386
|
||||
RUN /tmp/build-solaris-toolchain.sh sparcv9 sparcv9 solaris-sparc
|
||||
COPY host-x86_64/dist-various-2/build-x86_64-fortanix-unknown-sgx-toolchain.sh /tmp/
|
||||
COPY host-x86_64/dist-various-2/x86_64-fortanix-unknown-sgx-clang-wrap.sh /usr/bin/x86_64-fortanix-unknown-sgx-clang-11
|
||||
RUN ln -s /usr/bin/x86_64-fortanix-unknown-sgx-clang-11 /usr/bin/x86_64-fortanix-unknown-sgx-clang++-11
|
||||
RUN /tmp/build-x86_64-fortanix-unknown-sgx-toolchain.sh
|
||||
|
||||
COPY host-x86_64/dist-various-2/build-wasi-toolchain.sh /tmp/
|
||||
|
@ -1,14 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
args=("$@")
|
||||
|
||||
for i in "${!args[@]}"; do
|
||||
# x86_64-fortanix-unknown-sgx doesn't have a C sysroot for things like
|
||||
# stdint.h and the C++ STL. Unlike GCC, clang will not use the host's
|
||||
# sysroot instead. Force it.
|
||||
if [ "${args[$i]}" = "--target=x86_64-fortanix-unknown-sgx" ]; then
|
||||
args[$i]="--target=x86_64-unknown-linux-gnu"
|
||||
fi
|
||||
done
|
||||
|
||||
exec "${0/x86_64-fortanix-unknown-sgx-clang/clang}" "${args[@]}"
|
@ -82,13 +82,13 @@ endif
|
||||
%: $(SOURCEDIR)/lib/%.rs
|
||||
# Compile the test library with coverage instrumentation
|
||||
$(RUSTC) $(SOURCEDIR)/lib/$@.rs \
|
||||
$$( grep -q '^\/\/ require-rust-edition-2018' $(SOURCEDIR)/lib/$@.rs && echo "--edition=2018" ) \
|
||||
$$( sed -nE 's#^// compile-flags:(.*)#\1# p' $(SOURCEDIR)/lib/$@.rs) \
|
||||
--crate-type rlib -Zinstrument-coverage
|
||||
|
||||
%: $(SOURCEDIR)/%.rs
|
||||
# Compile the test program with coverage instrumentation
|
||||
$(RUSTC) $(SOURCEDIR)/$@.rs \
|
||||
$$( grep -q '^\/\/ require-rust-edition-2018' $(SOURCEDIR)/$@.rs && echo "--edition=2018" ) \
|
||||
$$( sed -nE 's#^// compile-flags:(.*)#\1# p' $(SOURCEDIR)/$@.rs) \
|
||||
-L "$(TMPDIR)" -Zinstrument-coverage
|
||||
|
||||
# Run it in order to generate some profiling data,
|
||||
@ -107,7 +107,7 @@ endif
|
||||
# Run it through rustdoc as well to cover doctests
|
||||
LLVM_PROFILE_FILE="$(TMPDIR)"/$@-%p.profraw \
|
||||
$(RUSTDOC) --crate-name workaround_for_79771 --test $(SOURCEDIR)/$@.rs \
|
||||
$$( grep -q '^\/\/ require-rust-edition-2018' $(SOURCEDIR)/$@.rs && echo "--edition=2018" ) \
|
||||
$$( sed -nE 's#^// compile-flags:(.*)#\1# p' $(SOURCEDIR)/$@.rs) \
|
||||
-L "$(TMPDIR)" -Zinstrument-coverage \
|
||||
-Z unstable-options --persist-doctests=$(TMPDIR)/rustdoc-$@
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
1| |#![allow(unused_assignments, dead_code)]
|
||||
2| |
|
||||
3| |// require-rust-edition-2018
|
||||
3| |// compile-flags: --edition=2018
|
||||
4| |
|
||||
5| 1|async fn c(x: u8) -> u8 {
|
||||
6| 1| if x == 8 {
|
||||
|
@ -0,0 +1,53 @@
|
||||
1| |// compile-flags: -Zinline-mir
|
||||
2| |
|
||||
3| |use std::fmt::Display;
|
||||
4| |
|
||||
5| 1|fn main() {
|
||||
6| 1| permutations(&['a', 'b', 'c']);
|
||||
7| 1|}
|
||||
8| |
|
||||
9| |#[inline(always)]
|
||||
10| 1|fn permutations<T: Copy + Display>(xs: &[T]) {
|
||||
11| 1| let mut ys = xs.to_owned();
|
||||
12| 1| permutate(&mut ys, 0);
|
||||
13| 1|}
|
||||
14| |
|
||||
15| 16|fn permutate<T: Copy + Display>(xs: &mut [T], k: usize) {
|
||||
16| 16| let n = length(xs);
|
||||
17| 16| if k == n {
|
||||
18| 6| display(xs);
|
||||
19| 10| } else if k < n {
|
||||
20| 15| for i in k..n {
|
||||
^10
|
||||
21| 15| swap(xs, i, k);
|
||||
22| 15| permutate(xs, k + 1);
|
||||
23| 15| swap(xs, i, k);
|
||||
24| 15| }
|
||||
25| 0| } else {
|
||||
26| 0| error();
|
||||
27| 0| }
|
||||
28| 16|}
|
||||
29| |
|
||||
30| 16|fn length<T>(xs: &[T]) -> usize {
|
||||
31| 16| xs.len()
|
||||
32| 16|}
|
||||
33| |
|
||||
34| |#[inline]
|
||||
35| 30|fn swap<T: Copy>(xs: &mut [T], i: usize, j: usize) {
|
||||
36| 30| let t = xs[i];
|
||||
37| 30| xs[i] = xs[j];
|
||||
38| 30| xs[j] = t;
|
||||
39| 30|}
|
||||
40| |
|
||||
41| 6|fn display<T: Display>(xs: &[T]) {
|
||||
42| 18| for x in xs {
|
||||
43| 18| print!("{}", x);
|
||||
44| 18| }
|
||||
45| 6| println!();
|
||||
46| 6|}
|
||||
47| |
|
||||
48| |#[inline(always)]
|
||||
49| |fn error() {
|
||||
50| | panic!("error");
|
||||
51| |}
|
||||
|
@ -19,12 +19,12 @@
|
||||
18| 2| println!("used_only_from_bin_crate_generic_function with {:?}", arg);
|
||||
19| 2|}
|
||||
------------------
|
||||
| used_crate::used_only_from_bin_crate_generic_function::<&str>:
|
||||
| used_crate::used_only_from_bin_crate_generic_function::<&alloc::vec::Vec<i32>>:
|
||||
| 17| 1|pub fn used_only_from_bin_crate_generic_function<T: Debug>(arg: T) {
|
||||
| 18| 1| println!("used_only_from_bin_crate_generic_function with {:?}", arg);
|
||||
| 19| 1|}
|
||||
------------------
|
||||
| used_crate::used_only_from_bin_crate_generic_function::<&alloc::vec::Vec<i32>>:
|
||||
| used_crate::used_only_from_bin_crate_generic_function::<&str>:
|
||||
| 17| 1|pub fn used_only_from_bin_crate_generic_function<T: Debug>(arg: T) {
|
||||
| 18| 1| println!("used_only_from_bin_crate_generic_function with {:?}", arg);
|
||||
| 19| 1|}
|
||||
|
@ -38,9 +38,7 @@ endif
|
||||
%: $(SOURCEDIR)/lib/%.rs
|
||||
# Compile the test library with coverage instrumentation
|
||||
$(RUSTC) $(SOURCEDIR)/lib/$@.rs \
|
||||
$$( grep -q '^\/\/ require-rust-edition-2018' $(SOURCEDIR)/lib/$@.rs && \
|
||||
echo "--edition=2018" \
|
||||
) \
|
||||
$$( sed -nE 's#^// compile-flags:(.*)#\1# p' $(SOURCEDIR)/lib/$@.rs) \
|
||||
--crate-type rlib \
|
||||
-Ztrim-diagnostic-paths=no \
|
||||
-Zinstrument-coverage \
|
||||
@ -70,9 +68,7 @@ endif
|
||||
%: $(SOURCEDIR)/%.rs
|
||||
# Compile the test program with coverage instrumentation
|
||||
$(RUSTC) $(SOURCEDIR)/$@.rs \
|
||||
$$( grep -q '^\/\/ require-rust-edition-2018' $(SOURCEDIR)/$@.rs && \
|
||||
echo "--edition=2018" \
|
||||
) \
|
||||
$$( sed -nE 's#^// compile-flags:(.*)#\1# p' $(SOURCEDIR)/$@.rs) \
|
||||
-L "$(TMPDIR)" \
|
||||
-Ztrim-diagnostic-paths=no \
|
||||
-Zinstrument-coverage \
|
||||
|
@ -0,0 +1,161 @@
|
||||
<!DOCTYPE html>
|
||||
<!--
|
||||
|
||||
Preview this file as rendered HTML from the github source at:
|
||||
https://htmlpreview.github.io/?https://github.com/rust-lang/rust/blob/master/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.inline/inline.display.-------.InstrumentCoverage.0.html
|
||||
|
||||
For revisions in Pull Requests (PR):
|
||||
* Replace "rust-lang" with the github PR author
|
||||
* Replace "master" with the PR branch name
|
||||
|
||||
-->
|
||||
<html>
|
||||
<head>
|
||||
<title>inline.display - Coverage Spans</title>
|
||||
<style>
|
||||
.line {
|
||||
counter-increment: line;
|
||||
}
|
||||
.line:before {
|
||||
content: counter(line) ": ";
|
||||
font-family: Menlo, Monaco, monospace;
|
||||
font-style: italic;
|
||||
width: 3.8em;
|
||||
display: inline-block;
|
||||
text-align: right;
|
||||
filter: opacity(50%);
|
||||
-webkit-user-select: none;
|
||||
}
|
||||
.code {
|
||||
color: #dddddd;
|
||||
background-color: #222222;
|
||||
font-family: Menlo, Monaco, monospace;
|
||||
line-height: 1.4em;
|
||||
border-bottom: 2px solid #222222;
|
||||
white-space: pre;
|
||||
display: inline-block;
|
||||
}
|
||||
.odd {
|
||||
background-color: #55bbff;
|
||||
color: #223311;
|
||||
}
|
||||
.even {
|
||||
background-color: #ee7756;
|
||||
color: #551133;
|
||||
}
|
||||
.code {
|
||||
--index: calc(var(--layer) - 1);
|
||||
padding-top: calc(var(--index) * 0.15em);
|
||||
filter:
|
||||
hue-rotate(calc(var(--index) * 25deg))
|
||||
saturate(calc(100% - (var(--index) * 2%)))
|
||||
brightness(calc(100% - (var(--index) * 1.5%)));
|
||||
}
|
||||
.annotation {
|
||||
color: #4444ff;
|
||||
font-family: monospace;
|
||||
font-style: italic;
|
||||
display: none;
|
||||
-webkit-user-select: none;
|
||||
}
|
||||
body:active .annotation {
|
||||
/* requires holding mouse down anywhere on the page */
|
||||
display: inline-block;
|
||||
}
|
||||
span:hover .annotation {
|
||||
/* requires hover over a span ONLY on its first line */
|
||||
display: inline-block;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="code" style="counter-reset: line 40"><span class="line"><span><span class="code even" style="--layer: 1"><span class="annotation">@0,1⦊</span>fn display<T: Display>(xs: &[T]) <span class="annotation">⦉@0,1</span></span></span><span class="code" style="--layer: 0">{</span></span>
|
||||
<span class="line"><span class="code" style="--layer: 0"> for </span><span><span class="code odd" style="--layer: 1" title="42:9-42:10: @8[1]: _13 = ((_9 as Some).0: &T)
|
||||
42:9-42:10: @8[3]: _14 = _13
|
||||
42:9-42:10: @8[4]: _7 = move _14
|
||||
42:9-42:10: @8[5]: _8 = const ()
|
||||
42:9-42:10: @8[13]: FakeRead(ForLet, _16)"><span class="annotation">@6,8,9,10,11⦊</span>x<span class="annotation">⦉@6,8,9,10,11</span></span></span><span class="code" style="--layer: 0"> in </span><span><span class="code odd" style="--layer: 1" title="42:14-42:16: @8[12]: _16 = _7
|
||||
43:16-43:20: @8[20]: _47 = const display::<T>::promoted[2]
|
||||
43:16-43:20: @8[21]: _22 = &(*_47)
|
||||
43:16-43:20: @8[22]: _21 = &(*_22)
|
||||
43:16-43:20: @8[23]: _20 = move _21 as &[&str] (Pointer(Unsize))
|
||||
43:22-43:23: @8[31]: _29 = &_16
|
||||
43:9-43:25: @8[32]: _28 = (move _29,)
|
||||
43:9-43:25: @8[34]: FakeRead(ForMatchedPlace, _28)
|
||||
43:9-43:25: @8[36]: _30 = (_28.0: &&T)
|
||||
43:9-43:25: @8[39]: _32 = &(*_30)
|
||||
43:9-43:25: @8[41]: _33 = <&T as std::fmt::Display>::fmt as for<'r, 's, 't0> fn(&'r &T, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error> (Pointer(ReifyFnPointer))
|
||||
43:9-43:25: @8.Call: _31 = std::fmt::ArgumentV1::new::<&T>(move _32, move _33) -> [return: bb9, unwind: bb14]
|
||||
43:9-43:25: @9[2]: _27 = [move _31]
|
||||
43:9-43:25: @9[5]: _26 = &_27
|
||||
43:9-43:25: @9[6]: _25 = &(*_26)
|
||||
43:9-43:25: @9[7]: _24 = move _25 as &[std::fmt::ArgumentV1] (Pointer(Unsize))
|
||||
43:9-43:25: @9.Call: _19 = std::fmt::Arguments::new_v1(move _20, move _24) -> [return: bb10, unwind: bb14]
|
||||
43:9-43:25: @10.Call: _18 = std::io::_print(move _19) -> [return: bb11, unwind: bb14]
|
||||
42:17-44:6: @11[6]: _17 = const ()"><span class="annotation">@6,8,9,10,11⦊</span>xs {</span></span>
|
||||
<span class="line"><span class="code odd" style="--layer: 1" title="42:14-42:16: @8[12]: _16 = _7
|
||||
43:16-43:20: @8[20]: _47 = const display::<T>::promoted[2]
|
||||
43:16-43:20: @8[21]: _22 = &(*_47)
|
||||
43:16-43:20: @8[22]: _21 = &(*_22)
|
||||
43:16-43:20: @8[23]: _20 = move _21 as &[&str] (Pointer(Unsize))
|
||||
43:22-43:23: @8[31]: _29 = &_16
|
||||
43:9-43:25: @8[32]: _28 = (move _29,)
|
||||
43:9-43:25: @8[34]: FakeRead(ForMatchedPlace, _28)
|
||||
43:9-43:25: @8[36]: _30 = (_28.0: &&T)
|
||||
43:9-43:25: @8[39]: _32 = &(*_30)
|
||||
43:9-43:25: @8[41]: _33 = <&T as std::fmt::Display>::fmt as for<'r, 's, 't0> fn(&'r &T, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error> (Pointer(ReifyFnPointer))
|
||||
43:9-43:25: @8.Call: _31 = std::fmt::ArgumentV1::new::<&T>(move _32, move _33) -> [return: bb9, unwind: bb14]
|
||||
43:9-43:25: @9[2]: _27 = [move _31]
|
||||
43:9-43:25: @9[5]: _26 = &_27
|
||||
43:9-43:25: @9[6]: _25 = &(*_26)
|
||||
43:9-43:25: @9[7]: _24 = move _25 as &[std::fmt::ArgumentV1] (Pointer(Unsize))
|
||||
43:9-43:25: @9.Call: _19 = std::fmt::Arguments::new_v1(move _20, move _24) -> [return: bb10, unwind: bb14]
|
||||
43:9-43:25: @10.Call: _18 = std::io::_print(move _19) -> [return: bb11, unwind: bb14]
|
||||
42:17-44:6: @11[6]: _17 = const ()"> print!("{}", x);</span></span>
|
||||
<span class="line"><span class="code odd" style="--layer: 1" title="42:14-42:16: @8[12]: _16 = _7
|
||||
43:16-43:20: @8[20]: _47 = const display::<T>::promoted[2]
|
||||
43:16-43:20: @8[21]: _22 = &(*_47)
|
||||
43:16-43:20: @8[22]: _21 = &(*_22)
|
||||
43:16-43:20: @8[23]: _20 = move _21 as &[&str] (Pointer(Unsize))
|
||||
43:22-43:23: @8[31]: _29 = &_16
|
||||
43:9-43:25: @8[32]: _28 = (move _29,)
|
||||
43:9-43:25: @8[34]: FakeRead(ForMatchedPlace, _28)
|
||||
43:9-43:25: @8[36]: _30 = (_28.0: &&T)
|
||||
43:9-43:25: @8[39]: _32 = &(*_30)
|
||||
43:9-43:25: @8[41]: _33 = <&T as std::fmt::Display>::fmt as for<'r, 's, 't0> fn(&'r &T, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error> (Pointer(ReifyFnPointer))
|
||||
43:9-43:25: @8.Call: _31 = std::fmt::ArgumentV1::new::<&T>(move _32, move _33) -> [return: bb9, unwind: bb14]
|
||||
43:9-43:25: @9[2]: _27 = [move _31]
|
||||
43:9-43:25: @9[5]: _26 = &_27
|
||||
43:9-43:25: @9[6]: _25 = &(*_26)
|
||||
43:9-43:25: @9[7]: _24 = move _25 as &[std::fmt::ArgumentV1] (Pointer(Unsize))
|
||||
43:9-43:25: @9.Call: _19 = std::fmt::Arguments::new_v1(move _20, move _24) -> [return: bb10, unwind: bb14]
|
||||
43:9-43:25: @10.Call: _18 = std::io::_print(move _19) -> [return: bb11, unwind: bb14]
|
||||
42:17-44:6: @11[6]: _17 = const ()"> }<span class="annotation">⦉@6,8,9,10,11</span></span></span><span class="code" style="--layer: 0"></span></span>
|
||||
<span class="line"><span class="code" style="--layer: 0"> </span><span><span class="code even" style="--layer: 1" title="45:5-45:16: @5[13]: _46 = const display::<T>::promoted[1]
|
||||
45:5-45:16: @5[14]: _38 = &(*_46)
|
||||
45:5-45:16: @5[15]: _37 = &(*_38)
|
||||
45:5-45:16: @5[16]: _36 = move _37 as &[&str] (Pointer(Unsize))
|
||||
45:5-45:16: @5[22]: _44 = ()
|
||||
45:5-45:16: @5[23]: FakeRead(ForMatchedPlace, _44)
|
||||
45:5-45:16: @5[24]: _45 = const display::<T>::promoted[0]
|
||||
45:5-45:16: @5[25]: _42 = &(*_45)
|
||||
45:5-45:16: @5[26]: _41 = &(*_42)
|
||||
45:5-45:16: @5[27]: _40 = move _41 as &[std::fmt::ArgumentV1] (Pointer(Unsize))
|
||||
45:5-45:16: @5.Call: _35 = std::fmt::Arguments::new_v1(move _36, move _40) -> [return: bb12, unwind: bb14]
|
||||
45:5-45:16: @12.Call: _34 = std::io::_print(move _35) -> [return: bb13, unwind: bb14]
|
||||
46:2-46:2: @13.Return: return"><span class="annotation">@5,12,13⦊</span>println!();</span></span>
|
||||
<span class="line"><span class="code even" style="--layer: 1" title="45:5-45:16: @5[13]: _46 = const display::<T>::promoted[1]
|
||||
45:5-45:16: @5[14]: _38 = &(*_46)
|
||||
45:5-45:16: @5[15]: _37 = &(*_38)
|
||||
45:5-45:16: @5[16]: _36 = move _37 as &[&str] (Pointer(Unsize))
|
||||
45:5-45:16: @5[22]: _44 = ()
|
||||
45:5-45:16: @5[23]: FakeRead(ForMatchedPlace, _44)
|
||||
45:5-45:16: @5[24]: _45 = const display::<T>::promoted[0]
|
||||
45:5-45:16: @5[25]: _42 = &(*_45)
|
||||
45:5-45:16: @5[26]: _41 = &(*_42)
|
||||
45:5-45:16: @5[27]: _40 = move _41 as &[std::fmt::ArgumentV1] (Pointer(Unsize))
|
||||
45:5-45:16: @5.Call: _35 = std::fmt::Arguments::new_v1(move _36, move _40) -> [return: bb12, unwind: bb14]
|
||||
45:5-45:16: @12.Call: _34 = std::io::_print(move _35) -> [return: bb13, unwind: bb14]
|
||||
46:2-46:2: @13.Return: return">}<span class="annotation">⦉@5,12,13</span></span></span></span></div>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,79 @@
|
||||
<!DOCTYPE html>
|
||||
<!--
|
||||
|
||||
Preview this file as rendered HTML from the github source at:
|
||||
https://htmlpreview.github.io/?https://github.com/rust-lang/rust/blob/master/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.inline/inline.error.-------.InstrumentCoverage.0.html
|
||||
|
||||
For revisions in Pull Requests (PR):
|
||||
* Replace "rust-lang" with the github PR author
|
||||
* Replace "master" with the PR branch name
|
||||
|
||||
-->
|
||||
<html>
|
||||
<head>
|
||||
<title>inline.error - Coverage Spans</title>
|
||||
<style>
|
||||
.line {
|
||||
counter-increment: line;
|
||||
}
|
||||
.line:before {
|
||||
content: counter(line) ": ";
|
||||
font-family: Menlo, Monaco, monospace;
|
||||
font-style: italic;
|
||||
width: 3.8em;
|
||||
display: inline-block;
|
||||
text-align: right;
|
||||
filter: opacity(50%);
|
||||
-webkit-user-select: none;
|
||||
}
|
||||
.code {
|
||||
color: #dddddd;
|
||||
background-color: #222222;
|
||||
font-family: Menlo, Monaco, monospace;
|
||||
line-height: 1.4em;
|
||||
border-bottom: 2px solid #222222;
|
||||
white-space: pre;
|
||||
display: inline-block;
|
||||
}
|
||||
.odd {
|
||||
background-color: #55bbff;
|
||||
color: #223311;
|
||||
}
|
||||
.even {
|
||||
background-color: #ee7756;
|
||||
color: #551133;
|
||||
}
|
||||
.code {
|
||||
--index: calc(var(--layer) - 1);
|
||||
padding-top: calc(var(--index) * 0.15em);
|
||||
filter:
|
||||
hue-rotate(calc(var(--index) * 25deg))
|
||||
saturate(calc(100% - (var(--index) * 2%)))
|
||||
brightness(calc(100% - (var(--index) * 1.5%)));
|
||||
}
|
||||
.annotation {
|
||||
color: #4444ff;
|
||||
font-family: monospace;
|
||||
font-style: italic;
|
||||
display: none;
|
||||
-webkit-user-select: none;
|
||||
}
|
||||
body:active .annotation {
|
||||
/* requires holding mouse down anywhere on the page */
|
||||
display: inline-block;
|
||||
}
|
||||
span:hover .annotation {
|
||||
/* requires hover over a span ONLY on its first line */
|
||||
display: inline-block;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="code" style="counter-reset: line 48"><span class="line"><span><span class="code even" style="--layer: 1" title="50:5-50:21: @0.Call: std::rt::begin_panic::<&str>(const "error") -> bb1
|
||||
49:12-51:2: @1.Resume: resume"><span class="annotation">@0,1⦊</span>fn error() {</span></span>
|
||||
<span class="line"><span class="code even" style="--layer: 1" title="50:5-50:21: @0.Call: std::rt::begin_panic::<&str>(const "error") -> bb1
|
||||
49:12-51:2: @1.Resume: resume"> panic!("error");</span></span>
|
||||
<span class="line"><span class="code even" style="--layer: 1" title="50:5-50:21: @0.Call: std::rt::begin_panic::<&str>(const "error") -> bb1
|
||||
49:12-51:2: @1.Resume: resume">}<span class="annotation">⦉@0,1</span></span></span></span></div>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,82 @@
|
||||
<!DOCTYPE html>
|
||||
<!--
|
||||
|
||||
Preview this file as rendered HTML from the github source at:
|
||||
https://htmlpreview.github.io/?https://github.com/rust-lang/rust/blob/master/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.inline/inline.length.-------.InstrumentCoverage.0.html
|
||||
|
||||
For revisions in Pull Requests (PR):
|
||||
* Replace "rust-lang" with the github PR author
|
||||
* Replace "master" with the PR branch name
|
||||
|
||||
-->
|
||||
<html>
|
||||
<head>
|
||||
<title>inline.length - Coverage Spans</title>
|
||||
<style>
|
||||
.line {
|
||||
counter-increment: line;
|
||||
}
|
||||
.line:before {
|
||||
content: counter(line) ": ";
|
||||
font-family: Menlo, Monaco, monospace;
|
||||
font-style: italic;
|
||||
width: 3.8em;
|
||||
display: inline-block;
|
||||
text-align: right;
|
||||
filter: opacity(50%);
|
||||
-webkit-user-select: none;
|
||||
}
|
||||
.code {
|
||||
color: #dddddd;
|
||||
background-color: #222222;
|
||||
font-family: Menlo, Monaco, monospace;
|
||||
line-height: 1.4em;
|
||||
border-bottom: 2px solid #222222;
|
||||
white-space: pre;
|
||||
display: inline-block;
|
||||
}
|
||||
.odd {
|
||||
background-color: #55bbff;
|
||||
color: #223311;
|
||||
}
|
||||
.even {
|
||||
background-color: #ee7756;
|
||||
color: #551133;
|
||||
}
|
||||
.code {
|
||||
--index: calc(var(--layer) - 1);
|
||||
padding-top: calc(var(--index) * 0.15em);
|
||||
filter:
|
||||
hue-rotate(calc(var(--index) * 25deg))
|
||||
saturate(calc(100% - (var(--index) * 2%)))
|
||||
brightness(calc(100% - (var(--index) * 1.5%)));
|
||||
}
|
||||
.annotation {
|
||||
color: #4444ff;
|
||||
font-family: monospace;
|
||||
font-style: italic;
|
||||
display: none;
|
||||
-webkit-user-select: none;
|
||||
}
|
||||
body:active .annotation {
|
||||
/* requires holding mouse down anywhere on the page */
|
||||
display: inline-block;
|
||||
}
|
||||
span:hover .annotation {
|
||||
/* requires hover over a span ONLY on its first line */
|
||||
display: inline-block;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="code" style="counter-reset: line 29"><span class="line"><span><span class="code even" style="--layer: 1" title="31:5-31:7: @0[1]: _2 = &(*_1)
|
||||
31:5-31:13: @0.Call: _0 = core::slice::<impl [T]>::len(move _2) -> [return: bb1, unwind: bb2]
|
||||
32:2-32:2: @1.Return: return"><span class="annotation">@0,1⦊</span>fn length<T>(xs: &[T]) -> usize {</span></span>
|
||||
<span class="line"><span class="code even" style="--layer: 1" title="31:5-31:7: @0[1]: _2 = &(*_1)
|
||||
31:5-31:13: @0.Call: _0 = core::slice::<impl [T]>::len(move _2) -> [return: bb1, unwind: bb2]
|
||||
32:2-32:2: @1.Return: return"> xs.len()</span></span>
|
||||
<span class="line"><span class="code even" style="--layer: 1" title="31:5-31:7: @0[1]: _2 = &(*_1)
|
||||
31:5-31:13: @0.Call: _0 = core::slice::<impl [T]>::len(move _2) -> [return: bb1, unwind: bb2]
|
||||
32:2-32:2: @1.Return: return">}<span class="annotation">⦉@0,1</span></span></span></span></div>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,94 @@
|
||||
<!DOCTYPE html>
|
||||
<!--
|
||||
|
||||
Preview this file as rendered HTML from the github source at:
|
||||
https://htmlpreview.github.io/?https://github.com/rust-lang/rust/blob/master/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.inline/inline.main.-------.InstrumentCoverage.0.html
|
||||
|
||||
For revisions in Pull Requests (PR):
|
||||
* Replace "rust-lang" with the github PR author
|
||||
* Replace "master" with the PR branch name
|
||||
|
||||
-->
|
||||
<html>
|
||||
<head>
|
||||
<title>inline.main - Coverage Spans</title>
|
||||
<style>
|
||||
.line {
|
||||
counter-increment: line;
|
||||
}
|
||||
.line:before {
|
||||
content: counter(line) ": ";
|
||||
font-family: Menlo, Monaco, monospace;
|
||||
font-style: italic;
|
||||
width: 3.8em;
|
||||
display: inline-block;
|
||||
text-align: right;
|
||||
filter: opacity(50%);
|
||||
-webkit-user-select: none;
|
||||
}
|
||||
.code {
|
||||
color: #dddddd;
|
||||
background-color: #222222;
|
||||
font-family: Menlo, Monaco, monospace;
|
||||
line-height: 1.4em;
|
||||
border-bottom: 2px solid #222222;
|
||||
white-space: pre;
|
||||
display: inline-block;
|
||||
}
|
||||
.odd {
|
||||
background-color: #55bbff;
|
||||
color: #223311;
|
||||
}
|
||||
.even {
|
||||
background-color: #ee7756;
|
||||
color: #551133;
|
||||
}
|
||||
.code {
|
||||
--index: calc(var(--layer) - 1);
|
||||
padding-top: calc(var(--index) * 0.15em);
|
||||
filter:
|
||||
hue-rotate(calc(var(--index) * 25deg))
|
||||
saturate(calc(100% - (var(--index) * 2%)))
|
||||
brightness(calc(100% - (var(--index) * 1.5%)));
|
||||
}
|
||||
.annotation {
|
||||
color: #4444ff;
|
||||
font-family: monospace;
|
||||
font-style: italic;
|
||||
display: none;
|
||||
-webkit-user-select: none;
|
||||
}
|
||||
body:active .annotation {
|
||||
/* requires holding mouse down anywhere on the page */
|
||||
display: inline-block;
|
||||
}
|
||||
span:hover .annotation {
|
||||
/* requires hover over a span ONLY on its first line */
|
||||
display: inline-block;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="code" style="counter-reset: line 4"><span class="line"><span><span class="code even" style="--layer: 1" title="6:18-6:34: @0[4]: _6 = const main::promoted[0]
|
||||
6:18-6:34: @0[5]: _4 = &(*_6)
|
||||
6:18-6:34: @0[6]: _3 = &(*_4)
|
||||
6:18-6:34: @0[7]: _2 = move _3 as &[char] (Pointer(Unsize))
|
||||
6:5-6:35: @0.Call: _1 = permutations::<char>(move _2) -> [return: bb1, unwind: bb2]
|
||||
5:11-7:2: @1[3]: _0 = const ()
|
||||
7:2-7:2: @1.Return: return"><span class="annotation">@0,1⦊</span>fn main() {</span></span>
|
||||
<span class="line"><span class="code even" style="--layer: 1" title="6:18-6:34: @0[4]: _6 = const main::promoted[0]
|
||||
6:18-6:34: @0[5]: _4 = &(*_6)
|
||||
6:18-6:34: @0[6]: _3 = &(*_4)
|
||||
6:18-6:34: @0[7]: _2 = move _3 as &[char] (Pointer(Unsize))
|
||||
6:5-6:35: @0.Call: _1 = permutations::<char>(move _2) -> [return: bb1, unwind: bb2]
|
||||
5:11-7:2: @1[3]: _0 = const ()
|
||||
7:2-7:2: @1.Return: return"> permutations(&['a', 'b', 'c']);</span></span>
|
||||
<span class="line"><span class="code even" style="--layer: 1" title="6:18-6:34: @0[4]: _6 = const main::promoted[0]
|
||||
6:18-6:34: @0[5]: _4 = &(*_6)
|
||||
6:18-6:34: @0[6]: _3 = &(*_4)
|
||||
6:18-6:34: @0[7]: _2 = move _3 as &[char] (Pointer(Unsize))
|
||||
6:5-6:35: @0.Call: _1 = permutations::<char>(move _2) -> [return: bb1, unwind: bb2]
|
||||
5:11-7:2: @1[3]: _0 = const ()
|
||||
7:2-7:2: @1.Return: return">}<span class="annotation">⦉@0,1</span></span></span></span></div>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,183 @@
|
||||
<!DOCTYPE html>
|
||||
<!--
|
||||
|
||||
Preview this file as rendered HTML from the github source at:
|
||||
https://htmlpreview.github.io/?https://github.com/rust-lang/rust/blob/master/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.inline/inline.permutate.-------.InstrumentCoverage.0.html
|
||||
|
||||
For revisions in Pull Requests (PR):
|
||||
* Replace "rust-lang" with the github PR author
|
||||
* Replace "master" with the PR branch name
|
||||
|
||||
-->
|
||||
<html>
|
||||
<head>
|
||||
<title>inline.permutate - Coverage Spans</title>
|
||||
<style>
|
||||
.line {
|
||||
counter-increment: line;
|
||||
}
|
||||
.line:before {
|
||||
content: counter(line) ": ";
|
||||
font-family: Menlo, Monaco, monospace;
|
||||
font-style: italic;
|
||||
width: 3.8em;
|
||||
display: inline-block;
|
||||
text-align: right;
|
||||
filter: opacity(50%);
|
||||
-webkit-user-select: none;
|
||||
}
|
||||
.code {
|
||||
color: #dddddd;
|
||||
background-color: #222222;
|
||||
font-family: Menlo, Monaco, monospace;
|
||||
line-height: 1.4em;
|
||||
border-bottom: 2px solid #222222;
|
||||
white-space: pre;
|
||||
display: inline-block;
|
||||
}
|
||||
.odd {
|
||||
background-color: #55bbff;
|
||||
color: #223311;
|
||||
}
|
||||
.even {
|
||||
background-color: #ee7756;
|
||||
color: #551133;
|
||||
}
|
||||
.code {
|
||||
--index: calc(var(--layer) - 1);
|
||||
padding-top: calc(var(--index) * 0.15em);
|
||||
filter:
|
||||
hue-rotate(calc(var(--index) * 25deg))
|
||||
saturate(calc(100% - (var(--index) * 2%)))
|
||||
brightness(calc(100% - (var(--index) * 1.5%)));
|
||||
}
|
||||
.annotation {
|
||||
color: #4444ff;
|
||||
font-family: monospace;
|
||||
font-style: italic;
|
||||
display: none;
|
||||
-webkit-user-select: none;
|
||||
}
|
||||
body:active .annotation {
|
||||
/* requires holding mouse down anywhere on the page */
|
||||
display: inline-block;
|
||||
}
|
||||
span:hover .annotation {
|
||||
/* requires hover over a span ONLY on its first line */
|
||||
display: inline-block;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="code" style="counter-reset: line 14"><span class="line"><span><span class="code even" style="--layer: 1" title="16:20-16:22: @0[2]: _4 = &(*_1)
|
||||
16:13-16:23: @0.Call: _3 = length::<T>(move _4) -> [return: bb1, unwind: bb22]
|
||||
16:9-16:10: @1[1]: FakeRead(ForLet, _3)
|
||||
17:8-17:9: @1[4]: _6 = _2
|
||||
17:13-17:14: @1[6]: _7 = _3
|
||||
17:8-17:14: @1[7]: _5 = Eq(move _6, move _7)"><span class="annotation">@0,1⦊</span>fn permutate<T: Copy + Display>(xs: &mut [T], k: usize) {</span></span>
|
||||
<span class="line"><span class="code even" style="--layer: 1" title="16:20-16:22: @0[2]: _4 = &(*_1)
|
||||
16:13-16:23: @0.Call: _3 = length::<T>(move _4) -> [return: bb1, unwind: bb22]
|
||||
16:9-16:10: @1[1]: FakeRead(ForLet, _3)
|
||||
17:8-17:9: @1[4]: _6 = _2
|
||||
17:13-17:14: @1[6]: _7 = _3
|
||||
17:8-17:14: @1[7]: _5 = Eq(move _6, move _7)"> let n = length(xs);</span></span>
|
||||
<span class="line"><span class="code even" style="--layer: 1" title="16:20-16:22: @0[2]: _4 = &(*_1)
|
||||
16:13-16:23: @0.Call: _3 = length::<T>(move _4) -> [return: bb1, unwind: bb22]
|
||||
16:9-16:10: @1[1]: FakeRead(ForLet, _3)
|
||||
17:8-17:9: @1[4]: _6 = _2
|
||||
17:13-17:14: @1[6]: _7 = _3
|
||||
17:8-17:14: @1[7]: _5 = Eq(move _6, move _7)"> if k == n<span class="annotation">⦉@0,1</span></span></span><span class="code" style="--layer: 0"> </span><span><span class="code odd" style="--layer: 1" title="18:17-18:19: @2[2]: _9 = &(*_1)
|
||||
18:9-18:20: @2.Call: _8 = display::<T>(move _9) -> [return: bb4, unwind: bb22]
|
||||
17:15-19:6: @4[2]: _0 = const ()"><span class="annotation">@2,4⦊</span>{</span></span>
|
||||
<span class="line"><span class="code odd" style="--layer: 1" title="18:17-18:19: @2[2]: _9 = &(*_1)
|
||||
18:9-18:20: @2.Call: _8 = display::<T>(move _9) -> [return: bb4, unwind: bb22]
|
||||
17:15-19:6: @4[2]: _0 = const ()"> display(xs);</span></span>
|
||||
<span class="line"><span class="code odd" style="--layer: 1" title="18:17-18:19: @2[2]: _9 = &(*_1)
|
||||
18:9-18:20: @2.Call: _8 = display::<T>(move _9) -> [return: bb4, unwind: bb22]
|
||||
17:15-19:6: @4[2]: _0 = const ()"> }<span class="annotation">⦉@2,4</span></span></span><span class="code" style="--layer: 0"> else if </span><span><span class="code even" style="--layer: 1" title="19:15-19:16: @3[2]: _11 = _2
|
||||
19:19-19:20: @3[4]: _12 = _3
|
||||
19:15-19:20: @3[5]: _10 = Lt(move _11, move _12)"><span class="annotation">@3⦊</span>k < n<span class="annotation">⦉@3</span></span></span><span class="code" style="--layer: 0"> {</span></span>
|
||||
<span class="line"><span class="code" style="--layer: 0"> for </span><span><span class="code odd" style="--layer: 1" title="20:13-20:14: @14[1]: _25 = ((_21 as Some).0: usize)
|
||||
20:13-20:14: @14[3]: _26 = _25
|
||||
20:13-20:14: @14[4]: _19 = move _26
|
||||
20:13-20:14: @14[5]: _20 = const ()
|
||||
20:13-20:14: @14[13]: FakeRead(ForLet, _28)"><span class="annotation">@12,14,15,16,17,18⦊</span>i<span class="annotation">⦉@12,14,15,16,17,18</span></span></span><span class="code" style="--layer: 0"> in </span><span><span class="code even" style="--layer: 1" title="20:18-20:19: @5[3]: _15 = _2
|
||||
20:21-20:22: @5[5]: _16 = _3"><span class="annotation">@5,7⦊</span>k..n<span class="annotation">⦉@5,7</span></span></span><span class="code" style="--layer: 0"> </span><span><span class="code odd" style="--layer: 1" title="21:18-21:20: @14[17]: _31 = &mut (*_1)
|
||||
21:22-21:23: @14[19]: _32 = _28
|
||||
21:25-21:26: @14[21]: _33 = _2
|
||||
21:13-21:27: @14.Call: _30 = swap::<T>(move _31, move _32, move _33) -> [return: bb15, unwind: bb22]
|
||||
22:23-22:25: @15[6]: _35 = &mut (*_1)
|
||||
22:27-22:28: @15[9]: _37 = _2
|
||||
22:27-22:32: @15[10]: _38 = CheckedAdd(_37, const 1_usize)
|
||||
22:27-22:32: @16[0]: _36 = move (_38.0: usize)
|
||||
22:13-22:33: @16.Call: _34 = permutate::<T>(move _35, move _36) -> [return: bb17, unwind: bb22]
|
||||
23:18-23:20: @17[5]: _40 = &mut (*_1)
|
||||
23:22-23:23: @17[7]: _41 = _28
|
||||
23:25-23:26: @17[9]: _42 = _2
|
||||
23:13-23:27: @17.Call: _39 = swap::<T>(move _40, move _41, move _42) -> [return: bb18, unwind: bb22]
|
||||
20:23-24:10: @18[4]: _29 = const ()"><span class="annotation">@12,14,15,16,17,18⦊</span>{</span></span>
|
||||
<span class="line"><span class="code odd" style="--layer: 1" title="21:18-21:20: @14[17]: _31 = &mut (*_1)
|
||||
21:22-21:23: @14[19]: _32 = _28
|
||||
21:25-21:26: @14[21]: _33 = _2
|
||||
21:13-21:27: @14.Call: _30 = swap::<T>(move _31, move _32, move _33) -> [return: bb15, unwind: bb22]
|
||||
22:23-22:25: @15[6]: _35 = &mut (*_1)
|
||||
22:27-22:28: @15[9]: _37 = _2
|
||||
22:27-22:32: @15[10]: _38 = CheckedAdd(_37, const 1_usize)
|
||||
22:27-22:32: @16[0]: _36 = move (_38.0: usize)
|
||||
22:13-22:33: @16.Call: _34 = permutate::<T>(move _35, move _36) -> [return: bb17, unwind: bb22]
|
||||
23:18-23:20: @17[5]: _40 = &mut (*_1)
|
||||
23:22-23:23: @17[7]: _41 = _28
|
||||
23:25-23:26: @17[9]: _42 = _2
|
||||
23:13-23:27: @17.Call: _39 = swap::<T>(move _40, move _41, move _42) -> [return: bb18, unwind: bb22]
|
||||
20:23-24:10: @18[4]: _29 = const ()"> swap(xs, i, k);</span></span>
|
||||
<span class="line"><span class="code odd" style="--layer: 1" title="21:18-21:20: @14[17]: _31 = &mut (*_1)
|
||||
21:22-21:23: @14[19]: _32 = _28
|
||||
21:25-21:26: @14[21]: _33 = _2
|
||||
21:13-21:27: @14.Call: _30 = swap::<T>(move _31, move _32, move _33) -> [return: bb15, unwind: bb22]
|
||||
22:23-22:25: @15[6]: _35 = &mut (*_1)
|
||||
22:27-22:28: @15[9]: _37 = _2
|
||||
22:27-22:32: @15[10]: _38 = CheckedAdd(_37, const 1_usize)
|
||||
22:27-22:32: @16[0]: _36 = move (_38.0: usize)
|
||||
22:13-22:33: @16.Call: _34 = permutate::<T>(move _35, move _36) -> [return: bb17, unwind: bb22]
|
||||
23:18-23:20: @17[5]: _40 = &mut (*_1)
|
||||
23:22-23:23: @17[7]: _41 = _28
|
||||
23:25-23:26: @17[9]: _42 = _2
|
||||
23:13-23:27: @17.Call: _39 = swap::<T>(move _40, move _41, move _42) -> [return: bb18, unwind: bb22]
|
||||
20:23-24:10: @18[4]: _29 = const ()"> permutate(xs, k + 1);</span></span>
|
||||
<span class="line"><span class="code odd" style="--layer: 1" title="21:18-21:20: @14[17]: _31 = &mut (*_1)
|
||||
21:22-21:23: @14[19]: _32 = _28
|
||||
21:25-21:26: @14[21]: _33 = _2
|
||||
21:13-21:27: @14.Call: _30 = swap::<T>(move _31, move _32, move _33) -> [return: bb15, unwind: bb22]
|
||||
22:23-22:25: @15[6]: _35 = &mut (*_1)
|
||||
22:27-22:28: @15[9]: _37 = _2
|
||||
22:27-22:32: @15[10]: _38 = CheckedAdd(_37, const 1_usize)
|
||||
22:27-22:32: @16[0]: _36 = move (_38.0: usize)
|
||||
22:13-22:33: @16.Call: _34 = permutate::<T>(move _35, move _36) -> [return: bb17, unwind: bb22]
|
||||
23:18-23:20: @17[5]: _40 = &mut (*_1)
|
||||
23:22-23:23: @17[7]: _41 = _28
|
||||
23:25-23:26: @17[9]: _42 = _2
|
||||
23:13-23:27: @17.Call: _39 = swap::<T>(move _40, move _41, move _42) -> [return: bb18, unwind: bb22]
|
||||
20:23-24:10: @18[4]: _29 = const ()"> swap(xs, i, k);</span></span>
|
||||
<span class="line"><span class="code odd" style="--layer: 1" title="21:18-21:20: @14[17]: _31 = &mut (*_1)
|
||||
21:22-21:23: @14[19]: _32 = _28
|
||||
21:25-21:26: @14[21]: _33 = _2
|
||||
21:13-21:27: @14.Call: _30 = swap::<T>(move _31, move _32, move _33) -> [return: bb15, unwind: bb22]
|
||||
22:23-22:25: @15[6]: _35 = &mut (*_1)
|
||||
22:27-22:28: @15[9]: _37 = _2
|
||||
22:27-22:32: @15[10]: _38 = CheckedAdd(_37, const 1_usize)
|
||||
22:27-22:32: @16[0]: _36 = move (_38.0: usize)
|
||||
22:13-22:33: @16.Call: _34 = permutate::<T>(move _35, move _36) -> [return: bb17, unwind: bb22]
|
||||
23:18-23:20: @17[5]: _40 = &mut (*_1)
|
||||
23:22-23:23: @17[7]: _41 = _28
|
||||
23:25-23:26: @17[9]: _42 = _2
|
||||
23:13-23:27: @17.Call: _39 = swap::<T>(move _40, move _41, move _42) -> [return: bb18, unwind: bb22]
|
||||
20:23-24:10: @18[4]: _29 = const ()"> }<span class="annotation">⦉@12,14,15,16,17,18</span></span></span><span class="code" style="--layer: 0"></span></span>
|
||||
<span class="line"><span class="code" style="--layer: 0"> } else </span><span><span class="code even" style="--layer: 1" title="26:9-26:16: @6.Call: _43 = error() -> [return: bb19, unwind: bb22]
|
||||
25:12-27:6: @19[1]: _0 = const ()"><span class="annotation">@6,19⦊</span>{</span></span>
|
||||
<span class="line"><span class="code even" style="--layer: 1" title="26:9-26:16: @6.Call: _43 = error() -> [return: bb19, unwind: bb22]
|
||||
25:12-27:6: @19[1]: _0 = const ()"> error();</span></span>
|
||||
<span class="line"><span class="code even" style="--layer: 1" title="26:9-26:16: @6.Call: _43 = error() -> [return: bb19, unwind: bb22]
|
||||
25:12-27:6: @19[1]: _0 = const ()"> }<span class="annotation">⦉@6,19</span></span></span><span class="code" style="--layer: 0"></span></span>
|
||||
<span class="line"><span class="code" style="--layer: 0">}</span><span><span class="code odd" style="--layer: 1" title="28:2-28:2: @21.Return: return"><span class="annotation">@21⦊</span>‸<span class="annotation">⦉@21</span></span></span></span></div>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,113 @@
|
||||
<!DOCTYPE html>
|
||||
<!--
|
||||
|
||||
Preview this file as rendered HTML from the github source at:
|
||||
https://htmlpreview.github.io/?https://github.com/rust-lang/rust/blob/master/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.inline/inline.permutations.-------.InstrumentCoverage.0.html
|
||||
|
||||
For revisions in Pull Requests (PR):
|
||||
* Replace "rust-lang" with the github PR author
|
||||
* Replace "master" with the PR branch name
|
||||
|
||||
-->
|
||||
<html>
|
||||
<head>
|
||||
<title>inline.permutations - Coverage Spans</title>
|
||||
<style>
|
||||
.line {
|
||||
counter-increment: line;
|
||||
}
|
||||
.line:before {
|
||||
content: counter(line) ": ";
|
||||
font-family: Menlo, Monaco, monospace;
|
||||
font-style: italic;
|
||||
width: 3.8em;
|
||||
display: inline-block;
|
||||
text-align: right;
|
||||
filter: opacity(50%);
|
||||
-webkit-user-select: none;
|
||||
}
|
||||
.code {
|
||||
color: #dddddd;
|
||||
background-color: #222222;
|
||||
font-family: Menlo, Monaco, monospace;
|
||||
line-height: 1.4em;
|
||||
border-bottom: 2px solid #222222;
|
||||
white-space: pre;
|
||||
display: inline-block;
|
||||
}
|
||||
.odd {
|
||||
background-color: #55bbff;
|
||||
color: #223311;
|
||||
}
|
||||
.even {
|
||||
background-color: #ee7756;
|
||||
color: #551133;
|
||||
}
|
||||
.code {
|
||||
--index: calc(var(--layer) - 1);
|
||||
padding-top: calc(var(--index) * 0.15em);
|
||||
filter:
|
||||
hue-rotate(calc(var(--index) * 25deg))
|
||||
saturate(calc(100% - (var(--index) * 2%)))
|
||||
brightness(calc(100% - (var(--index) * 1.5%)));
|
||||
}
|
||||
.annotation {
|
||||
color: #4444ff;
|
||||
font-family: monospace;
|
||||
font-style: italic;
|
||||
display: none;
|
||||
-webkit-user-select: none;
|
||||
}
|
||||
body:active .annotation {
|
||||
/* requires holding mouse down anywhere on the page */
|
||||
display: inline-block;
|
||||
}
|
||||
span:hover .annotation {
|
||||
/* requires hover over a span ONLY on its first line */
|
||||
display: inline-block;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="code" style="counter-reset: line 9"><span class="line"><span><span class="code even" style="--layer: 1" title="11:18-11:20: @0[2]: _3 = &(*_1)
|
||||
11:18-11:31: @0.Call: _2 = <[T] as std::borrow::ToOwned>::to_owned(move _3) -> [return: bb1, unwind: bb6]
|
||||
11:9-11:15: @1[1]: FakeRead(ForLet, _2)
|
||||
12:15-12:22: @1[7]: _8 = &mut _2
|
||||
12:15-12:22: @1[8]: _7 = &mut (*_8)
|
||||
12:15-12:22: @1.Call: _6 = <std::vec::Vec<T> as std::ops::DerefMut>::deref_mut(move _7) -> [return: bb2, unwind: bb5]
|
||||
12:15-12:22: @2[0]: _5 = &mut (*_6)
|
||||
12:5-12:26: @2.Call: _4 = permutate::<T>(move _5, const 0_usize) -> [return: bb3, unwind: bb5]
|
||||
10:46-13:2: @3[4]: _0 = const ()
|
||||
13:2-13:2: @4.Return: return"><span class="annotation">@0,1,2,3,4⦊</span>fn permutations<T: Copy + Display>(xs: &[T]) {</span></span>
|
||||
<span class="line"><span class="code even" style="--layer: 1" title="11:18-11:20: @0[2]: _3 = &(*_1)
|
||||
11:18-11:31: @0.Call: _2 = <[T] as std::borrow::ToOwned>::to_owned(move _3) -> [return: bb1, unwind: bb6]
|
||||
11:9-11:15: @1[1]: FakeRead(ForLet, _2)
|
||||
12:15-12:22: @1[7]: _8 = &mut _2
|
||||
12:15-12:22: @1[8]: _7 = &mut (*_8)
|
||||
12:15-12:22: @1.Call: _6 = <std::vec::Vec<T> as std::ops::DerefMut>::deref_mut(move _7) -> [return: bb2, unwind: bb5]
|
||||
12:15-12:22: @2[0]: _5 = &mut (*_6)
|
||||
12:5-12:26: @2.Call: _4 = permutate::<T>(move _5, const 0_usize) -> [return: bb3, unwind: bb5]
|
||||
10:46-13:2: @3[4]: _0 = const ()
|
||||
13:2-13:2: @4.Return: return"> let mut ys = xs.to_owned();</span></span>
|
||||
<span class="line"><span class="code even" style="--layer: 1" title="11:18-11:20: @0[2]: _3 = &(*_1)
|
||||
11:18-11:31: @0.Call: _2 = <[T] as std::borrow::ToOwned>::to_owned(move _3) -> [return: bb1, unwind: bb6]
|
||||
11:9-11:15: @1[1]: FakeRead(ForLet, _2)
|
||||
12:15-12:22: @1[7]: _8 = &mut _2
|
||||
12:15-12:22: @1[8]: _7 = &mut (*_8)
|
||||
12:15-12:22: @1.Call: _6 = <std::vec::Vec<T> as std::ops::DerefMut>::deref_mut(move _7) -> [return: bb2, unwind: bb5]
|
||||
12:15-12:22: @2[0]: _5 = &mut (*_6)
|
||||
12:5-12:26: @2.Call: _4 = permutate::<T>(move _5, const 0_usize) -> [return: bb3, unwind: bb5]
|
||||
10:46-13:2: @3[4]: _0 = const ()
|
||||
13:2-13:2: @4.Return: return"> permutate(&mut ys, 0);</span></span>
|
||||
<span class="line"><span class="code even" style="--layer: 1" title="11:18-11:20: @0[2]: _3 = &(*_1)
|
||||
11:18-11:31: @0.Call: _2 = <[T] as std::borrow::ToOwned>::to_owned(move _3) -> [return: bb1, unwind: bb6]
|
||||
11:9-11:15: @1[1]: FakeRead(ForLet, _2)
|
||||
12:15-12:22: @1[7]: _8 = &mut _2
|
||||
12:15-12:22: @1[8]: _7 = &mut (*_8)
|
||||
12:15-12:22: @1.Call: _6 = <std::vec::Vec<T> as std::ops::DerefMut>::deref_mut(move _7) -> [return: bb2, unwind: bb5]
|
||||
12:15-12:22: @2[0]: _5 = &mut (*_6)
|
||||
12:5-12:26: @2.Call: _4 = permutate::<T>(move _5, const 0_usize) -> [return: bb3, unwind: bb5]
|
||||
10:46-13:2: @3[4]: _0 = const ()
|
||||
13:2-13:2: @4.Return: return">}<span class="annotation">⦉@0,1,2,3,4</span></span></span></span></div>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,173 @@
|
||||
<!DOCTYPE html>
|
||||
<!--
|
||||
|
||||
Preview this file as rendered HTML from the github source at:
|
||||
https://htmlpreview.github.io/?https://github.com/rust-lang/rust/blob/master/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.inline/inline.swap.-------.InstrumentCoverage.0.html
|
||||
|
||||
For revisions in Pull Requests (PR):
|
||||
* Replace "rust-lang" with the github PR author
|
||||
* Replace "master" with the PR branch name
|
||||
|
||||
-->
|
||||
<html>
|
||||
<head>
|
||||
<title>inline.swap - Coverage Spans</title>
|
||||
<style>
|
||||
.line {
|
||||
counter-increment: line;
|
||||
}
|
||||
.line:before {
|
||||
content: counter(line) ": ";
|
||||
font-family: Menlo, Monaco, monospace;
|
||||
font-style: italic;
|
||||
width: 3.8em;
|
||||
display: inline-block;
|
||||
text-align: right;
|
||||
filter: opacity(50%);
|
||||
-webkit-user-select: none;
|
||||
}
|
||||
.code {
|
||||
color: #dddddd;
|
||||
background-color: #222222;
|
||||
font-family: Menlo, Monaco, monospace;
|
||||
line-height: 1.4em;
|
||||
border-bottom: 2px solid #222222;
|
||||
white-space: pre;
|
||||
display: inline-block;
|
||||
}
|
||||
.odd {
|
||||
background-color: #55bbff;
|
||||
color: #223311;
|
||||
}
|
||||
.even {
|
||||
background-color: #ee7756;
|
||||
color: #551133;
|
||||
}
|
||||
.code {
|
||||
--index: calc(var(--layer) - 1);
|
||||
padding-top: calc(var(--index) * 0.15em);
|
||||
filter:
|
||||
hue-rotate(calc(var(--index) * 25deg))
|
||||
saturate(calc(100% - (var(--index) * 2%)))
|
||||
brightness(calc(100% - (var(--index) * 1.5%)));
|
||||
}
|
||||
.annotation {
|
||||
color: #4444ff;
|
||||
font-family: monospace;
|
||||
font-style: italic;
|
||||
display: none;
|
||||
-webkit-user-select: none;
|
||||
}
|
||||
body:active .annotation {
|
||||
/* requires holding mouse down anywhere on the page */
|
||||
display: inline-block;
|
||||
}
|
||||
span:hover .annotation {
|
||||
/* requires hover over a span ONLY on its first line */
|
||||
display: inline-block;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="code" style="counter-reset: line 34"><span class="line"><span><span class="code even" style="--layer: 1" title="36:16-36:17: @0[2]: _5 = _2
|
||||
36:13-36:18: @0[3]: _6 = Len((*_1))
|
||||
36:13-36:18: @0[4]: _7 = Lt(_5, _6)
|
||||
36:13-36:18: @1[0]: _4 = (*_1)[_5]
|
||||
36:9-36:10: @1[1]: FakeRead(ForLet, _4)
|
||||
37:16-37:17: @1[5]: _9 = _3
|
||||
37:13-37:18: @1[6]: _10 = Len((*_1))
|
||||
37:13-37:18: @1[7]: _11 = Lt(_9, _10)
|
||||
37:13-37:18: @2[0]: _8 = (*_1)[_9]
|
||||
37:8-37:9: @2[2]: _12 = _2
|
||||
37:5-37:10: @2[3]: _13 = Len((*_1))
|
||||
37:5-37:10: @2[4]: _14 = Lt(_12, _13)
|
||||
37:5-37:18: @3[0]: (*_1)[_12] = move _8
|
||||
38:13-38:14: @3[5]: _15 = _4
|
||||
38:8-38:9: @3[7]: _16 = _3
|
||||
38:5-38:10: @3[8]: _17 = Len((*_1))
|
||||
38:5-38:10: @3[9]: _18 = Lt(_16, _17)
|
||||
38:5-38:14: @4[0]: (*_1)[_16] = move _15
|
||||
35:52-39:2: @4[3]: _0 = const ()
|
||||
39:2-39:2: @4.Return: return"><span class="annotation">@0,1,2,3,4⦊</span>fn swap<T: Copy>(xs: &mut [T], i: usize, j: usize) {</span></span>
|
||||
<span class="line"><span class="code even" style="--layer: 1" title="36:16-36:17: @0[2]: _5 = _2
|
||||
36:13-36:18: @0[3]: _6 = Len((*_1))
|
||||
36:13-36:18: @0[4]: _7 = Lt(_5, _6)
|
||||
36:13-36:18: @1[0]: _4 = (*_1)[_5]
|
||||
36:9-36:10: @1[1]: FakeRead(ForLet, _4)
|
||||
37:16-37:17: @1[5]: _9 = _3
|
||||
37:13-37:18: @1[6]: _10 = Len((*_1))
|
||||
37:13-37:18: @1[7]: _11 = Lt(_9, _10)
|
||||
37:13-37:18: @2[0]: _8 = (*_1)[_9]
|
||||
37:8-37:9: @2[2]: _12 = _2
|
||||
37:5-37:10: @2[3]: _13 = Len((*_1))
|
||||
37:5-37:10: @2[4]: _14 = Lt(_12, _13)
|
||||
37:5-37:18: @3[0]: (*_1)[_12] = move _8
|
||||
38:13-38:14: @3[5]: _15 = _4
|
||||
38:8-38:9: @3[7]: _16 = _3
|
||||
38:5-38:10: @3[8]: _17 = Len((*_1))
|
||||
38:5-38:10: @3[9]: _18 = Lt(_16, _17)
|
||||
38:5-38:14: @4[0]: (*_1)[_16] = move _15
|
||||
35:52-39:2: @4[3]: _0 = const ()
|
||||
39:2-39:2: @4.Return: return"> let t = xs[i];</span></span>
|
||||
<span class="line"><span class="code even" style="--layer: 1" title="36:16-36:17: @0[2]: _5 = _2
|
||||
36:13-36:18: @0[3]: _6 = Len((*_1))
|
||||
36:13-36:18: @0[4]: _7 = Lt(_5, _6)
|
||||
36:13-36:18: @1[0]: _4 = (*_1)[_5]
|
||||
36:9-36:10: @1[1]: FakeRead(ForLet, _4)
|
||||
37:16-37:17: @1[5]: _9 = _3
|
||||
37:13-37:18: @1[6]: _10 = Len((*_1))
|
||||
37:13-37:18: @1[7]: _11 = Lt(_9, _10)
|
||||
37:13-37:18: @2[0]: _8 = (*_1)[_9]
|
||||
37:8-37:9: @2[2]: _12 = _2
|
||||
37:5-37:10: @2[3]: _13 = Len((*_1))
|
||||
37:5-37:10: @2[4]: _14 = Lt(_12, _13)
|
||||
37:5-37:18: @3[0]: (*_1)[_12] = move _8
|
||||
38:13-38:14: @3[5]: _15 = _4
|
||||
38:8-38:9: @3[7]: _16 = _3
|
||||
38:5-38:10: @3[8]: _17 = Len((*_1))
|
||||
38:5-38:10: @3[9]: _18 = Lt(_16, _17)
|
||||
38:5-38:14: @4[0]: (*_1)[_16] = move _15
|
||||
35:52-39:2: @4[3]: _0 = const ()
|
||||
39:2-39:2: @4.Return: return"> xs[i] = xs[j];</span></span>
|
||||
<span class="line"><span class="code even" style="--layer: 1" title="36:16-36:17: @0[2]: _5 = _2
|
||||
36:13-36:18: @0[3]: _6 = Len((*_1))
|
||||
36:13-36:18: @0[4]: _7 = Lt(_5, _6)
|
||||
36:13-36:18: @1[0]: _4 = (*_1)[_5]
|
||||
36:9-36:10: @1[1]: FakeRead(ForLet, _4)
|
||||
37:16-37:17: @1[5]: _9 = _3
|
||||
37:13-37:18: @1[6]: _10 = Len((*_1))
|
||||
37:13-37:18: @1[7]: _11 = Lt(_9, _10)
|
||||
37:13-37:18: @2[0]: _8 = (*_1)[_9]
|
||||
37:8-37:9: @2[2]: _12 = _2
|
||||
37:5-37:10: @2[3]: _13 = Len((*_1))
|
||||
37:5-37:10: @2[4]: _14 = Lt(_12, _13)
|
||||
37:5-37:18: @3[0]: (*_1)[_12] = move _8
|
||||
38:13-38:14: @3[5]: _15 = _4
|
||||
38:8-38:9: @3[7]: _16 = _3
|
||||
38:5-38:10: @3[8]: _17 = Len((*_1))
|
||||
38:5-38:10: @3[9]: _18 = Lt(_16, _17)
|
||||
38:5-38:14: @4[0]: (*_1)[_16] = move _15
|
||||
35:52-39:2: @4[3]: _0 = const ()
|
||||
39:2-39:2: @4.Return: return"> xs[j] = t;</span></span>
|
||||
<span class="line"><span class="code even" style="--layer: 1" title="36:16-36:17: @0[2]: _5 = _2
|
||||
36:13-36:18: @0[3]: _6 = Len((*_1))
|
||||
36:13-36:18: @0[4]: _7 = Lt(_5, _6)
|
||||
36:13-36:18: @1[0]: _4 = (*_1)[_5]
|
||||
36:9-36:10: @1[1]: FakeRead(ForLet, _4)
|
||||
37:16-37:17: @1[5]: _9 = _3
|
||||
37:13-37:18: @1[6]: _10 = Len((*_1))
|
||||
37:13-37:18: @1[7]: _11 = Lt(_9, _10)
|
||||
37:13-37:18: @2[0]: _8 = (*_1)[_9]
|
||||
37:8-37:9: @2[2]: _12 = _2
|
||||
37:5-37:10: @2[3]: _13 = Len((*_1))
|
||||
37:5-37:10: @2[4]: _14 = Lt(_12, _13)
|
||||
37:5-37:18: @3[0]: (*_1)[_12] = move _8
|
||||
38:13-38:14: @3[5]: _15 = _4
|
||||
38:8-38:9: @3[7]: _16 = _3
|
||||
38:5-38:10: @3[8]: _17 = Len((*_1))
|
||||
38:5-38:10: @3[9]: _18 = Lt(_16, _17)
|
||||
38:5-38:14: @4[0]: (*_1)[_16] = move _15
|
||||
35:52-39:2: @4[3]: _0 = const ()
|
||||
39:2-39:2: @4.Return: return">}<span class="annotation">⦉@0,1,2,3,4</span></span></span></span></div>
|
||||
</body>
|
||||
</html>
|
@ -1,6 +1,6 @@
|
||||
#![allow(unused_assignments, dead_code)]
|
||||
|
||||
// require-rust-edition-2018
|
||||
// compile-flags: --edition=2018
|
||||
|
||||
async fn c(x: u8) -> u8 {
|
||||
if x == 8 {
|
||||
|
51
src/test/run-make-fulldeps/coverage/inline.rs
Normal file
51
src/test/run-make-fulldeps/coverage/inline.rs
Normal file
@ -0,0 +1,51 @@
|
||||
// compile-flags: -Zinline-mir
|
||||
|
||||
use std::fmt::Display;
|
||||
|
||||
fn main() {
|
||||
permutations(&['a', 'b', 'c']);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn permutations<T: Copy + Display>(xs: &[T]) {
|
||||
let mut ys = xs.to_owned();
|
||||
permutate(&mut ys, 0);
|
||||
}
|
||||
|
||||
fn permutate<T: Copy + Display>(xs: &mut [T], k: usize) {
|
||||
let n = length(xs);
|
||||
if k == n {
|
||||
display(xs);
|
||||
} else if k < n {
|
||||
for i in k..n {
|
||||
swap(xs, i, k);
|
||||
permutate(xs, k + 1);
|
||||
swap(xs, i, k);
|
||||
}
|
||||
} else {
|
||||
error();
|
||||
}
|
||||
}
|
||||
|
||||
fn length<T>(xs: &[T]) -> usize {
|
||||
xs.len()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn swap<T: Copy>(xs: &mut [T], i: usize, j: usize) {
|
||||
let t = xs[i];
|
||||
xs[i] = xs[j];
|
||||
xs[j] = t;
|
||||
}
|
||||
|
||||
fn display<T: Display>(xs: &[T]) {
|
||||
for x in xs {
|
||||
print!("{}", x);
|
||||
}
|
||||
println!();
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn error() {
|
||||
panic!("error");
|
||||
}
|
14
src/test/ui/asm/inline-syntax.arm.stderr
Normal file
14
src/test/ui/asm/inline-syntax.arm.stderr
Normal file
@ -0,0 +1,14 @@
|
||||
error: att syntax is the default syntax on this target, and trying to use this directive may cause issues
|
||||
--> $DIR/inline-syntax.rs:22:15
|
||||
|
|
||||
LL | asm!(".att_syntax noprefix", "nop");
|
||||
| ^^^^^^^^^^^^^^^^^^^^ help: remove this assembler directive
|
||||
|
||||
error: att syntax is the default syntax on this target, and trying to use this directive may cause issues
|
||||
--> $DIR/inline-syntax.rs:25:15
|
||||
|
|
||||
LL | asm!(".att_syntax bbb noprefix", "nop");
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this assembler directive
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
38
src/test/ui/asm/inline-syntax.rs
Normal file
38
src/test/ui/asm/inline-syntax.rs
Normal file
@ -0,0 +1,38 @@
|
||||
// revisions: x86_64 arm
|
||||
//[x86_64] compile-flags: --target x86_64-unknown-linux-gnu
|
||||
//[arm] compile-flags: --target armv7-unknown-linux-gnueabihf
|
||||
|
||||
#![feature(no_core, lang_items, rustc_attrs)]
|
||||
#![no_core]
|
||||
|
||||
#[rustc_builtin_macro]
|
||||
macro_rules! asm {
|
||||
() => {};
|
||||
}
|
||||
|
||||
#[lang = "sized"]
|
||||
trait Sized {}
|
||||
|
||||
fn main() {
|
||||
unsafe {
|
||||
asm!(".intel_syntax noprefix", "nop");
|
||||
//[x86_64]~^ ERROR intel syntax is the default syntax on this target
|
||||
asm!(".intel_syntax aaa noprefix", "nop");
|
||||
//[x86_64]~^ ERROR intel syntax is the default syntax on this target
|
||||
asm!(".att_syntax noprefix", "nop");
|
||||
//[x86_64]~^ ERROR using the .att_syntax directive may cause issues
|
||||
//[arm]~^^ att syntax is the default syntax on this target
|
||||
asm!(".att_syntax bbb noprefix", "nop");
|
||||
//[x86_64]~^ ERROR using the .att_syntax directive may cause issues
|
||||
//[arm]~^^ att syntax is the default syntax on this target
|
||||
asm!(".intel_syntax noprefix; nop");
|
||||
//[x86_64]~^ ERROR intel syntax is the default syntax on this target
|
||||
|
||||
asm!(
|
||||
r"
|
||||
.intel_syntax noprefix
|
||||
nop"
|
||||
);
|
||||
//[x86_64]~^^^ ERROR intel syntax is the default syntax on this target
|
||||
}
|
||||
}
|
50
src/test/ui/asm/inline-syntax.x86_64.stderr
Normal file
50
src/test/ui/asm/inline-syntax.x86_64.stderr
Normal file
@ -0,0 +1,50 @@
|
||||
error: intel syntax is the default syntax on this target, and trying to use this directive may cause issues
|
||||
--> $DIR/inline-syntax.rs:18:15
|
||||
|
|
||||
LL | asm!(".intel_syntax noprefix", "nop");
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ help: remove this assembler directive
|
||||
|
||||
error: intel syntax is the default syntax on this target, and trying to use this directive may cause issues
|
||||
--> $DIR/inline-syntax.rs:20:15
|
||||
|
|
||||
LL | asm!(".intel_syntax aaa noprefix", "nop");
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this assembler directive
|
||||
|
||||
error: using the .att_syntax directive may cause issues, use the att_syntax option instead
|
||||
--> $DIR/inline-syntax.rs:22:15
|
||||
|
|
||||
LL | asm!(".att_syntax noprefix", "nop");
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: remove the assembler directive and replace it with options(att_syntax)
|
||||
|
|
||||
LL | asm!("", "nop", options(att_syntax));
|
||||
| -- ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: using the .att_syntax directive may cause issues, use the att_syntax option instead
|
||||
--> $DIR/inline-syntax.rs:25:15
|
||||
|
|
||||
LL | asm!(".att_syntax bbb noprefix", "nop");
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: remove the assembler directive and replace it with options(att_syntax)
|
||||
|
|
||||
LL | asm!("", "nop", options(att_syntax));
|
||||
| -- ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: intel syntax is the default syntax on this target, and trying to use this directive may cause issues
|
||||
--> $DIR/inline-syntax.rs:28:15
|
||||
|
|
||||
LL | asm!(".intel_syntax noprefix; nop");
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ help: remove this assembler directive
|
||||
|
||||
error: intel syntax is the default syntax on this target, and trying to use this directive may cause issues
|
||||
--> $DIR/inline-syntax.rs:33:14
|
||||
|
|
||||
LL | .intel_syntax noprefix
|
||||
| ______________^
|
||||
LL | | nop"
|
||||
| |_ help: remove this assembler directive
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
|
11
src/test/ui/lint/register-tool-lint.rs
Normal file
11
src/test/ui/lint/register-tool-lint.rs
Normal file
@ -0,0 +1,11 @@
|
||||
#![crate_type = "lib"]
|
||||
#![feature(register_tool)]
|
||||
#![register_tool(xyz)]
|
||||
#![warn(xyz::my_lint)] // this should not error
|
||||
#![warn(abc::my_lint)]
|
||||
//~^ ERROR unknown tool name `abc` found in scoped lint
|
||||
//~| HELP add `#![register_tool(abc)]`
|
||||
//~| ERROR unknown tool name `abc`
|
||||
//~| HELP add `#![register_tool(abc)]`
|
||||
//~| ERROR unknown tool name `abc`
|
||||
//~| HELP add `#![register_tool(abc)]`
|
27
src/test/ui/lint/register-tool-lint.stderr
Normal file
27
src/test/ui/lint/register-tool-lint.stderr
Normal file
@ -0,0 +1,27 @@
|
||||
error[E0710]: unknown tool name `abc` found in scoped lint: `abc::my_lint`
|
||||
--> $DIR/register-tool-lint.rs:5:9
|
||||
|
|
||||
LL | #![warn(abc::my_lint)]
|
||||
| ^^^
|
||||
|
|
||||
= help: add `#![register_tool(abc)]` to the crate root
|
||||
|
||||
error[E0710]: unknown tool name `abc` found in scoped lint: `abc::my_lint`
|
||||
--> $DIR/register-tool-lint.rs:5:9
|
||||
|
|
||||
LL | #![warn(abc::my_lint)]
|
||||
| ^^^
|
||||
|
|
||||
= help: add `#![register_tool(abc)]` to the crate root
|
||||
|
||||
error[E0710]: unknown tool name `abc` found in scoped lint: `abc::my_lint`
|
||||
--> $DIR/register-tool-lint.rs:5:9
|
||||
|
|
||||
LL | #![warn(abc::my_lint)]
|
||||
| ^^^
|
||||
|
|
||||
= help: add `#![register_tool(abc)]` to the crate root
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0710`.
|
@ -1,21 +0,0 @@
|
||||
// Ensures -Zmir-opt-level=3 (specifically, inlining) is not allowed with -Zinstrument-coverage.
|
||||
// Regression test for issue #80060.
|
||||
//
|
||||
// needs-profiler-support
|
||||
// build-pass
|
||||
// compile-flags: -Zmir-opt-level=3 -Zinstrument-coverage
|
||||
#[inline(never)]
|
||||
fn foo() {}
|
||||
|
||||
pub fn baz() {
|
||||
bar();
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn bar() {
|
||||
foo();
|
||||
}
|
||||
|
||||
fn main() {
|
||||
bar();
|
||||
}
|
@ -1,2 +0,0 @@
|
||||
warning: `-Z mir-opt-level=3` (or any level > 1) enables function inlining, which is incompatible with `-Z instrument-coverage`. Inlining will be disabled.
|
||||
|
13
src/test/ui/proc-macro/issue-73933-procedural-masquerade.rs
Normal file
13
src/test/ui/proc-macro/issue-73933-procedural-masquerade.rs
Normal file
@ -0,0 +1,13 @@
|
||||
// check-pass
|
||||
// aux-build:test-macros.rs
|
||||
|
||||
#[macro_use]
|
||||
extern crate test_macros;
|
||||
|
||||
#[derive(Print)]
|
||||
enum ProceduralMasqueradeDummyType { //~ WARN using
|
||||
//~| WARN this was previously
|
||||
Input
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -0,0 +1,25 @@
|
||||
warning: using `procedural-masquerade` crate
|
||||
--> $DIR/issue-73933-procedural-masquerade.rs:8:6
|
||||
|
|
||||
LL | enum ProceduralMasqueradeDummyType {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(proc_macro_back_compat)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #83125 <https://github.com/rust-lang/rust/issues/83125>
|
||||
= note: The `procedural-masquerade` crate has been unnecessary since Rust 1.30.0. Versions of this crate below 0.1.7 will eventually stop compiling.
|
||||
|
||||
warning: 1 warning emitted
|
||||
|
||||
Future incompatibility report: Future breakage date: None, diagnostic:
|
||||
warning: using `procedural-masquerade` crate
|
||||
--> $DIR/issue-73933-procedural-masquerade.rs:8:6
|
||||
|
|
||||
LL | enum ProceduralMasqueradeDummyType {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(proc_macro_back_compat)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #83125 <https://github.com/rust-lang/rust/issues/83125>
|
||||
= note: The `procedural-masquerade` crate has been unnecessary since Rust 1.30.0. Versions of this crate below 0.1.7 will eventually stop compiling.
|
||||
|
@ -0,0 +1,22 @@
|
||||
PRINT-DERIVE INPUT (DISPLAY): enum ProceduralMasqueradeDummyType { Input, }
|
||||
PRINT-DERIVE RE-COLLECTED (DISPLAY): enum ProceduralMasqueradeDummyType { Input }
|
||||
PRINT-DERIVE INPUT (DEBUG): TokenStream [
|
||||
Ident {
|
||||
ident: "enum",
|
||||
span: #0 bytes(100..104),
|
||||
},
|
||||
Ident {
|
||||
ident: "ProceduralMasqueradeDummyType",
|
||||
span: #0 bytes(105..134),
|
||||
},
|
||||
Group {
|
||||
delimiter: Brace,
|
||||
stream: TokenStream [
|
||||
Ident {
|
||||
ident: "Input",
|
||||
span: #0 bytes(186..191),
|
||||
},
|
||||
],
|
||||
span: #0 bytes(135..193),
|
||||
},
|
||||
]
|
@ -1,5 +1,5 @@
|
||||
#[warn(foo::bar)]
|
||||
//~^ ERROR an unknown tool name found in scoped lint: `foo::bar`
|
||||
//~| ERROR an unknown tool name found in scoped lint: `foo::bar`
|
||||
//~| ERROR an unknown tool name found in scoped lint: `foo::bar`
|
||||
//~^ ERROR unknown tool name `foo` found in scoped lint: `foo::bar`
|
||||
//~| ERROR unknown tool name `foo` found in scoped lint: `foo::bar`
|
||||
//~| ERROR unknown tool name `foo` found in scoped lint: `foo::bar`
|
||||
fn main() {}
|
||||
|
@ -1,20 +1,26 @@
|
||||
error[E0710]: an unknown tool name found in scoped lint: `foo::bar`
|
||||
error[E0710]: unknown tool name `foo` found in scoped lint: `foo::bar`
|
||||
--> $DIR/tool_lints.rs:1:8
|
||||
|
|
||||
LL | #[warn(foo::bar)]
|
||||
| ^^^
|
||||
|
|
||||
= help: add `#![register_tool(foo)]` to the crate root
|
||||
|
||||
error[E0710]: an unknown tool name found in scoped lint: `foo::bar`
|
||||
error[E0710]: unknown tool name `foo` found in scoped lint: `foo::bar`
|
||||
--> $DIR/tool_lints.rs:1:8
|
||||
|
|
||||
LL | #[warn(foo::bar)]
|
||||
| ^^^
|
||||
|
|
||||
= help: add `#![register_tool(foo)]` to the crate root
|
||||
|
||||
error[E0710]: an unknown tool name found in scoped lint: `foo::bar`
|
||||
error[E0710]: unknown tool name `foo` found in scoped lint: `foo::bar`
|
||||
--> $DIR/tool_lints.rs:1:8
|
||||
|
|
||||
LL | #[warn(foo::bar)]
|
||||
| ^^^
|
||||
|
|
||||
= help: add `#![register_tool(foo)]` to the crate root
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
#![deny(foo::bar)] //~ ERROR an unknown tool name found in scoped lint: `foo::bar`
|
||||
//~| ERROR an unknown tool name found in scoped lint: `foo::bar`
|
||||
//~| ERROR an unknown tool name found in scoped lint: `foo::bar`
|
||||
#![deny(foo::bar)] //~ ERROR unknown tool name `foo` found in scoped lint: `foo::bar`
|
||||
//~| ERROR unknown tool name `foo` found in scoped lint: `foo::bar`
|
||||
//~| ERROR unknown tool name `foo` found in scoped lint: `foo::bar`
|
||||
|
||||
#[allow(foo::bar)] //~ ERROR an unknown tool name found in scoped lint: `foo::bar`
|
||||
//~| ERROR an unknown tool name found in scoped lint: `foo::bar`
|
||||
//~| ERROR an unknown tool name found in scoped lint: `foo::bar`
|
||||
#[allow(foo::bar)] //~ ERROR unknown tool name `foo` found in scoped lint: `foo::bar`
|
||||
//~| ERROR unknown tool name `foo` found in scoped lint: `foo::bar`
|
||||
//~| ERROR unknown tool name `foo` found in scoped lint: `foo::bar`
|
||||
fn main() {}
|
||||
|
@ -1,38 +1,50 @@
|
||||
error[E0710]: an unknown tool name found in scoped lint: `foo::bar`
|
||||
error[E0710]: unknown tool name `foo` found in scoped lint: `foo::bar`
|
||||
--> $DIR/unknown-lint-tool-name.rs:1:9
|
||||
|
|
||||
LL | #![deny(foo::bar)]
|
||||
| ^^^
|
||||
|
|
||||
= help: add `#![register_tool(foo)]` to the crate root
|
||||
|
||||
error[E0710]: an unknown tool name found in scoped lint: `foo::bar`
|
||||
error[E0710]: unknown tool name `foo` found in scoped lint: `foo::bar`
|
||||
--> $DIR/unknown-lint-tool-name.rs:5:9
|
||||
|
|
||||
LL | #[allow(foo::bar)]
|
||||
| ^^^
|
||||
|
|
||||
= help: add `#![register_tool(foo)]` to the crate root
|
||||
|
||||
error[E0710]: an unknown tool name found in scoped lint: `foo::bar`
|
||||
error[E0710]: unknown tool name `foo` found in scoped lint: `foo::bar`
|
||||
--> $DIR/unknown-lint-tool-name.rs:1:9
|
||||
|
|
||||
LL | #![deny(foo::bar)]
|
||||
| ^^^
|
||||
|
|
||||
= help: add `#![register_tool(foo)]` to the crate root
|
||||
|
||||
error[E0710]: an unknown tool name found in scoped lint: `foo::bar`
|
||||
error[E0710]: unknown tool name `foo` found in scoped lint: `foo::bar`
|
||||
--> $DIR/unknown-lint-tool-name.rs:5:9
|
||||
|
|
||||
LL | #[allow(foo::bar)]
|
||||
| ^^^
|
||||
|
|
||||
= help: add `#![register_tool(foo)]` to the crate root
|
||||
|
||||
error[E0710]: an unknown tool name found in scoped lint: `foo::bar`
|
||||
error[E0710]: unknown tool name `foo` found in scoped lint: `foo::bar`
|
||||
--> $DIR/unknown-lint-tool-name.rs:1:9
|
||||
|
|
||||
LL | #![deny(foo::bar)]
|
||||
| ^^^
|
||||
|
|
||||
= help: add `#![register_tool(foo)]` to the crate root
|
||||
|
||||
error[E0710]: an unknown tool name found in scoped lint: `foo::bar`
|
||||
error[E0710]: unknown tool name `foo` found in scoped lint: `foo::bar`
|
||||
--> $DIR/unknown-lint-tool-name.rs:5:9
|
||||
|
|
||||
LL | #[allow(foo::bar)]
|
||||
| ^^^
|
||||
|
|
||||
= help: add `#![register_tool(foo)]` to the crate root
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
|
||||
|
@ -44,7 +44,7 @@ fn main() {
|
||||
}
|
||||
|
||||
if !config.has_tidy && config.mode == Mode::Rustdoc {
|
||||
eprintln!("warning: `tidy` is not installed; generated diffs will be harder to read");
|
||||
eprintln!("warning: `tidy` is not installed; diffs will not be generated");
|
||||
}
|
||||
|
||||
log_config(&config);
|
||||
|
@ -2367,6 +2367,9 @@ impl<'test> TestCx<'test> {
|
||||
}
|
||||
|
||||
fn compare_to_default_rustdoc(&mut self, out_dir: &Path) {
|
||||
if !self.config.has_tidy {
|
||||
return;
|
||||
}
|
||||
println!("info: generating a diff against nightly rustdoc");
|
||||
|
||||
let suffix =
|
||||
@ -2428,10 +2431,8 @@ impl<'test> TestCx<'test> {
|
||||
}
|
||||
}
|
||||
};
|
||||
if self.config.has_tidy {
|
||||
tidy_dir(out_dir);
|
||||
tidy_dir(&compare_dir);
|
||||
}
|
||||
tidy_dir(out_dir);
|
||||
tidy_dir(&compare_dir);
|
||||
|
||||
let pager = {
|
||||
let output = Command::new("git").args(&["config", "--get", "core.pager"]).output().ok();
|
||||
|
Loading…
Reference in New Issue
Block a user