diff options
79 files changed, 1997 insertions, 218 deletions
diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs index 40b0cefd83a..2c5e180f80d 100644 --- a/compiler/rustc_ast/src/attr/mod.rs +++ b/compiler/rustc_ast/src/attr/mod.rs @@ -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> { diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs index 093f7f2668c..7e58426d27d 100644 --- a/compiler/rustc_ast/src/token.rs +++ b/compiler/rustc_ast/src/token.rs @@ -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 { diff --git a/compiler/rustc_builtin_macros/src/asm.rs b/compiler/rustc_builtin_macros/src/asm.rs index 36cd6c281b4..8d8b3f4f6aa 100644 --- a/compiler/rustc_builtin_macros/src/asm.rs +++ b/compiler/rustc_builtin_macros/src/asm.rs @@ -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 + } +} diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs index 444a9d4ba04..352638aa88e 100644 --- a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs +++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs @@ -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) { diff --git a/compiler/rustc_codegen_ssa/src/coverageinfo/map.rs b/compiler/rustc_codegen_ssa/src/coverageinfo/map.rs index 549b8d41f51..af6482fdbc2 100644 --- a/compiler/rustc_codegen_ssa/src/coverageinfo/map.rs +++ b/compiler/rustc_codegen_ssa/src/coverageinfo/map.rs @@ -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". diff --git a/compiler/rustc_codegen_ssa/src/mir/coverageinfo.rs b/compiler/rustc_codegen_ssa/src/mir/coverageinfo.rs index a115d358666..5ab1baafb57 100644 --- a/compiler/rustc_codegen_ssa/src/mir/coverageinfo.rs +++ b/compiler/rustc_codegen_ssa/src/mir/coverageinfo.rs @@ -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"), ); } diff --git a/compiler/rustc_codegen_ssa/src/mir/statement.rs b/compiler/rustc_codegen_ssa/src/mir/statement.rs index 5523e5f2e86..fe7f6288adb 100644 --- a/compiler/rustc_codegen_ssa/src/mir/statement.rs +++ b/compiler/rustc_codegen_ssa/src/mir/statement.rs @@ -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 { diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index 05e5c13dab7..594b9a82ad0 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -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 +} diff --git a/compiler/rustc_expand/src/proc_macro.rs b/compiler/rustc_expand/src/proc_macro.rs index 8cbaa7c945a..61b776ff2d2 100644 --- a/compiler/rustc_expand/src/proc_macro.rs +++ b/compiler/rustc_expand/src/proc_macro.rs @@ -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) diff --git a/compiler/rustc_expand/src/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs index 837fad90580..67edfe19da3 100644 --- a/compiler/rustc_expand/src/proc_macro_server.rs +++ b/compiler/rustc_expand/src/proc_macro_server.rs @@ -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), }) } } diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index 3ba687124ae..c9de85a2f18 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -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, } } diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs index 5e6b090027c..a332c300787 100644 --- a/compiler/rustc_lint/src/levels.rs +++ b/compiler/rustc_lint/src/levels.rs @@ -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>, diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 872cf1ed194..ae367db019b 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -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" } } diff --git a/compiler/rustc_mir/src/monomorphize/partitioning/mod.rs b/compiler/rustc_mir/src/monomorphize/partitioning/mod.rs index b68a8104fba..dc2379fd92b 100644 --- a/compiler/rustc_mir/src/monomorphize/partitioning/mod.rs +++ b/compiler/rustc_mir/src/monomorphize/partitioning/mod.rs @@ -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); diff --git a/compiler/rustc_mir/src/transform/coverage/query.rs b/compiler/rustc_mir/src/transform/coverage/query.rs index 4b455a6a1ba..de8447f1974 100644 --- a/compiler/rustc_mir/src/transform/coverage/query.rs +++ b/compiler/rustc_mir/src/transform/coverage/query.rs @@ -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() +} diff --git a/compiler/rustc_mir/src/transform/inline.rs b/compiler/rustc_mir/src/transform/inline.rs index dd06daecd5d..12fdbd6582e 100644 --- a/compiler/rustc_mir/src/transform/inline.rs +++ b/compiler/rustc_mir/src/transform/inline.rs @@ -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; } diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 025415036b6..70dbaa53d38 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -204,6 +204,7 @@ impl<'a> Parser<'a> { def: &mut Defaultness, req_name: ReqName, ) -> PResult<'a, Option<ItemInfo>> { + let def_final = def == &Defaultness::Final; let mut def = || mem::replace(def, Defaultness::Final); let info = if self.eat_keyword(kw::Use) { @@ -226,7 +227,7 @@ impl<'a> Parser<'a> { } (Ident::invalid(), ItemKind::Use(tree)) - } else if self.check_fn_front_matter() { + } else if self.check_fn_front_matter(def_final) { // FUNCTION ITEM let (ident, sig, generics, body) = self.parse_fn(attrs, req_name, lo)?; (ident, ItemKind::Fn(box FnKind(def(), sig, generics, body))) @@ -1634,18 +1635,27 @@ impl<'a> Parser<'a> { } /// Is the current token the start of an `FnHeader` / not a valid parse? - pub(super) fn check_fn_front_matter(&mut self) -> bool { + /// + /// `check_pub` adds additional `pub` to the checks in case users place it + /// wrongly, can be used to ensure `pub` never comes after `default`. + pub(super) fn check_fn_front_matter(&mut self, check_pub: bool) -> bool { // We use an over-approximation here. // `const const`, `fn const` won't parse, but we're not stepping over other syntax either. - const QUALS: [Symbol; 4] = [kw::Const, kw::Async, kw::Unsafe, kw::Extern]; + // `pub` is added in case users got confused with the ordering like `async pub fn`, + // only if it wasn't preceeded by `default` as `default pub` is invalid. + let quals: &[Symbol] = if check_pub { + &[kw::Pub, kw::Const, kw::Async, kw::Unsafe, kw::Extern] + } else { + &[kw::Const, kw::Async, kw::Unsafe, kw::Extern] + }; self.check_keyword(kw::Fn) // Definitely an `fn`. // `$qual fn` or `$qual $qual`: - || QUALS.iter().any(|&kw| self.check_keyword(kw)) + || quals.iter().any(|&kw| self.check_keyword(kw)) && self.look_ahead(1, |t| { // `$qual fn`, e.g. `const fn` or `async fn`. t.is_keyword(kw::Fn) // Two qualifiers `$qual $qual` is enough, e.g. `async unsafe`. - || t.is_non_raw_ident_where(|i| QUALS.contains(&i.name) + || t.is_non_raw_ident_where(|i| quals.contains(&i.name) // Rule out 2015 `const async: T = val`. && i.is_reserved() // Rule out unsafe extern block. @@ -1666,6 +1676,7 @@ impl<'a> Parser<'a> { /// FnFrontMatter = FnQual "fn" ; /// ``` pub(super) fn parse_fn_front_matter(&mut self) -> PResult<'a, FnHeader> { + let sp_start = self.token.span; let constness = self.parse_constness(); let asyncness = self.parse_asyncness(); let unsafety = self.parse_unsafety(); @@ -1679,8 +1690,27 @@ impl<'a> Parser<'a> { // It is possible for `expect_one_of` to recover given the contents of // `self.expected_tokens`, therefore, do not use `self.unexpected()` which doesn't // account for this. - if !self.expect_one_of(&[], &[])? { - unreachable!() + match self.expect_one_of(&[], &[]) { + Ok(true) => {} + Ok(false) => unreachable!(), + Err(mut err) => { + // Recover incorrect visibility order such as `async pub`. + if self.check_keyword(kw::Pub) { + let sp = sp_start.to(self.prev_token.span); + if let Ok(snippet) = self.span_to_snippet(sp) { + let vis = self.parse_visibility(FollowedByType::No)?; + let vs = pprust::vis_to_string(&vis); + let vs = vs.trim_end(); + err.span_suggestion( + sp_start.to(self.prev_token.span), + &format!("visibility `{}` must come before `{}`", vs, snippet), + format!("{} {}", vs, snippet), + Applicability::MachineApplicable, + ); + } + } + return Err(err); + } } } diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index 8f03bfd4c3a..0f7b8ebd376 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -209,7 +209,7 @@ impl<'a> Parser<'a> { } else if self.eat_keyword(kw::Underscore) { // A type to be inferred `_` TyKind::Infer - } else if self.check_fn_front_matter() { + } else if self.check_fn_front_matter(false) { // Function pointer type self.parse_ty_bare_fn(lo, Vec::new(), recover_return_sign)? } else if self.check_keyword(kw::For) { @@ -217,7 +217,7 @@ impl<'a> Parser<'a> { // `for<'lt> [unsafe] [extern "ABI"] fn (&'lt S) -> T` // `for<'lt> Trait1<'lt> + Trait2 + 'a` let lifetime_defs = self.parse_late_bound_lifetime_defs()?; - if self.check_fn_front_matter() { + if self.check_fn_front_matter(false) { self.parse_ty_bare_fn(lo, lifetime_defs, recover_return_sign)? } else { let path = self.parse_path(PathStyle::Type)?; diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index c1be90efc72..75078a12311 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -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") { diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 4f611118360..fc57b6b8ace 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -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) } diff --git a/compiler/rustc_target/src/spec/riscv64gc_unknown_none_elf.rs b/compiler/rustc_target/src/spec/riscv64gc_unknown_none_elf.rs index 33a785fdfee..aa823b13fdd 100644 --- a/compiler/rustc_target/src/spec/riscv64gc_unknown_none_elf.rs +++ b/compiler/rustc_target/src/spec/riscv64gc_unknown_none_elf.rs @@ -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, diff --git a/library/alloc/benches/lib.rs b/library/alloc/benches/lib.rs index 32edb86d101..38a8f65f169 100644 --- a/library/alloc/benches/lib.rs +++ b/library/alloc/benches/lib.rs @@ -4,6 +4,7 @@ #![feature(btree_drain_filter)] #![feature(map_first_last)] #![feature(repr_simd)] +#![feature(slice_partition_dedup)] #![feature(test)] extern crate test; diff --git a/library/alloc/benches/vec.rs b/library/alloc/benches/vec.rs index 89893b6209c..73eb353f6e7 100644 --- a/library/alloc/benches/vec.rs +++ b/library/alloc/benches/vec.rs @@ -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); +} diff --git a/library/alloc/src/collections/btree/map.rs b/library/alloc/src/collections/btree/map.rs index 622983996aa..a0dbb289252 100644 --- a/library/alloc/src/collections/btree/map.rs +++ b/library/alloc/src/collections/btree/map.rs @@ -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 /// diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index 9731a8e1d1d..135279874bb 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -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. diff --git a/library/alloc/tests/lib.rs b/library/alloc/tests/lib.rs index 799499b9b77..11673ed8262 100644 --- a/library/alloc/tests/lib.rs +++ b/library/alloc/tests/lib.rs @@ -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)] diff --git a/library/alloc/tests/vec.rs b/library/alloc/tests/vec.rs index 1ba2315ca73..c142536cd2d 100644 --- a/library/alloc/tests/vec.rs +++ b/library/alloc/tests/vec.rs @@ -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() { diff --git a/library/core/src/hash/mod.rs b/library/core/src/hash/mod.rs index dcdf0192660..7bfa58d34ed 100644 --- a/library/core/src/hash/mod.rs +++ b/library/core/src/hash/mod.rs @@ -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 //! diff --git a/library/std/src/collections/hash/map.rs b/library/std/src/collections/hash/map.rs index 233afa92389..ed32668456d 100644 --- a/library/std/src/collections/hash/map.rs +++ b/library/std/src/collections/hash/map.rs @@ -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 diff --git a/library/std/src/collections/hash/set.rs b/library/std/src/collections/hash/set.rs index 912e975aa0a..8c801b9f128 100644 --- a/library/std/src/collections/hash/set.rs +++ b/library/std/src/collections/hash/set.rs @@ -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 diff --git a/library/std/src/sys/unix/stack_overflow.rs b/library/std/src/sys/unix/stack_overflow.rs index d7bba50c76a..2a487fff54a 100644 --- a/library/std/src/sys/unix/stack_overflow.rs +++ b/library/std/src/sys/unix/stack_overflow.rs @@ -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()) } diff --git a/library/std/src/sys/unix/thread.rs b/library/std/src/sys/unix/thread.rs index 40c96307514..01a12dcf5a2 100644 --- a/library/std/src/sys/unix/thread.rs +++ b/library/std/src/sys/unix/thread.rs @@ -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; diff --git a/src/ci/docker/host-x86_64/dist-android/Dockerfile b/src/ci/docker/host-x86_64/dist-android/Dockerfile index ee727359f39..2f0496d7dd4 100644 --- a/src/ci/docker/host-x86_64/dist-android/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-android/Dockerfile @@ -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 diff --git a/src/ci/docker/host-x86_64/dist-various-2/Dockerfile b/src/ci/docker/host-x86_64/dist-various-2/Dockerfile index 7bb3cb14516..de3a99f34fc 100644 --- a/src/ci/docker/host-x86_64/dist-various-2/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-various-2/Dockerfile @@ -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/ diff --git a/src/ci/docker/host-x86_64/dist-various-2/x86_64-fortanix-unknown-sgx-clang-wrap.sh b/src/ci/docker/host-x86_64/dist-various-2/x86_64-fortanix-unknown-sgx-clang-wrap.sh deleted file mode 100755 index c4ff44c37b1..00000000000 --- a/src/ci/docker/host-x86_64/dist-various-2/x86_64-fortanix-unknown-sgx-clang-wrap.sh +++ /dev/null @@ -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[@]}" diff --git a/src/test/run-make-fulldeps/coverage-reports/Makefile b/src/test/run-make-fulldeps/coverage-reports/Makefile index 31583eaa8fe..af75ec5e24d 100644 --- a/src/test/run-make-fulldeps/coverage-reports/Makefile +++ b/src/test/run-make-fulldeps/coverage-reports/Makefile @@ -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-$@ diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.async.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.async.txt index 824bddaa401..3f9403e6f70 100644 --- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.async.txt +++ b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.async.txt @@ -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 { diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.inline.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.inline.txt new file mode 100644 index 00000000000..6148d89ed75 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.inline.txt @@ -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| |} + diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.uses_crate.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.uses_crate.txt index 0c28305dd77..bc2f673349a 100644 --- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.uses_crate.txt +++ b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.uses_crate.txt @@ -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|} diff --git a/src/test/run-make-fulldeps/coverage-spanview/Makefile b/src/test/run-make-fulldeps/coverage-spanview/Makefile index cd54ac0ed4c..b0bfa7074db 100644 --- a/src/test/run-make-fulldeps/coverage-spanview/Makefile +++ b/src/test/run-make-fulldeps/coverage-spanview/Makefile @@ -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 \ diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.inline/inline.display.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.inline/inline.display.-------.InstrumentCoverage.0.html new file mode 100644 index 00000000000..6287516636e --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.inline/inline.display.-------.InstrumentCoverage.0.html @@ -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> diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.inline/inline.error.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.inline/inline.error.-------.InstrumentCoverage.0.html new file mode 100644 index 00000000000..bbf19c3e446 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.inline/inline.error.-------.InstrumentCoverage.0.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> diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.inline/inline.length.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.inline/inline.length.-------.InstrumentCoverage.0.html new file mode 100644 index 00000000000..8e8efb6d9f6 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.inline/inline.length.-------.InstrumentCoverage.0.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> diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.inline/inline.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.inline/inline.main.-------.InstrumentCoverage.0.html new file mode 100644 index 00000000000..4ec2e9beede --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.inline/inline.main.-------.InstrumentCoverage.0.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> diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.inline/inline.permutate.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.inline/inline.permutate.-------.InstrumentCoverage.0.html new file mode 100644 index 00000000000..fd72973ccd0 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.inline/inline.permutate.-------.InstrumentCoverage.0.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> diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.inline/inline.permutations.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.inline/inline.permutations.-------.InstrumentCoverage.0.html new file mode 100644 index 00000000000..4bfd22f3cd9 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.inline/inline.permutations.-------.InstrumentCoverage.0.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> diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.inline/inline.swap.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.inline/inline.swap.-------.InstrumentCoverage.0.html new file mode 100644 index 00000000000..4c3f63093d3 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.inline/inline.swap.-------.InstrumentCoverage.0.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> diff --git a/src/test/run-make-fulldeps/coverage/async.rs b/src/test/run-make-fulldeps/coverage/async.rs index 5553af92465..d5ec32deac1 100644 --- a/src/test/run-make-fulldeps/coverage/async.rs +++ b/src/test/run-make-fulldeps/coverage/async.rs @@ -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 { diff --git a/src/test/run-make-fulldeps/coverage/inline.rs b/src/test/run-make-fulldeps/coverage/inline.rs new file mode 100644 index 00000000000..9cfab9ddbad --- /dev/null +++ b/src/test/run-make-fulldeps/coverage/inline.rs @@ -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"); +} diff --git a/src/test/ui/asm/inline-syntax.arm.stderr b/src/test/ui/asm/inline-syntax.arm.stderr new file mode 100644 index 00000000000..b1b61f0211a --- /dev/null +++ b/src/test/ui/asm/inline-syntax.arm.stderr @@ -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 + diff --git a/src/test/ui/asm/inline-syntax.rs b/src/test/ui/asm/inline-syntax.rs new file mode 100644 index 00000000000..9e9c7badfca --- /dev/null +++ b/src/test/ui/asm/inline-syntax.rs @@ -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 + } +} diff --git a/src/test/ui/asm/inline-syntax.x86_64.stderr b/src/test/ui/asm/inline-syntax.x86_64.stderr new file mode 100644 index 00000000000..c54c2742a57 --- /dev/null +++ b/src/test/ui/asm/inline-syntax.x86_64.stderr @@ -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 + diff --git a/src/test/ui/lint/register-tool-lint.rs b/src/test/ui/lint/register-tool-lint.rs new file mode 100644 index 00000000000..0ba5a37b167 --- /dev/null +++ b/src/test/ui/lint/register-tool-lint.rs @@ -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)]` diff --git a/src/test/ui/lint/register-tool-lint.stderr b/src/test/ui/lint/register-tool-lint.stderr new file mode 100644 index 00000000000..750c74cec1e --- /dev/null +++ b/src/test/ui/lint/register-tool-lint.stderr @@ -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`. diff --git a/src/test/ui/mir/mir-inlining/inline-instrument-coverage-fail.rs b/src/test/ui/mir/mir-inlining/inline-instrument-coverage-fail.rs deleted file mode 100644 index 8ed7f25d2bb..00000000000 --- a/src/test/ui/mir/mir-inlining/inline-instrument-coverage-fail.rs +++ /dev/null @@ -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(); -} diff --git a/src/test/ui/mir/mir-inlining/inline-instrument-coverage-fail.stderr b/src/test/ui/mir/mir-inlining/inline-instrument-coverage-fail.stderr deleted file mode 100644 index d482afc395d..00000000000 --- a/src/test/ui/mir/mir-inlining/inline-instrument-coverage-fail.stderr +++ /dev/null @@ -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. - diff --git a/src/test/ui/parser/duplicate-visibility.rs b/src/test/ui/parser/duplicate-visibility.rs index 547329cfb1b..97f19b3da45 100644 --- a/src/test/ui/parser/duplicate-visibility.rs +++ b/src/test/ui/parser/duplicate-visibility.rs @@ -1,7 +1,8 @@ +// ignore-tidy-linelength + fn main() {} extern "C" { pub pub fn foo(); - //~^ ERROR visibility `pub` is not followed by an item - //~| ERROR non-item in item list + //~^ ERROR expected one of `(`, `async`, `const`, `default`, `extern`, `fn`, `pub`, `unsafe`, or `use`, found keyword `pub` } diff --git a/src/test/ui/parser/duplicate-visibility.stderr b/src/test/ui/parser/duplicate-visibility.stderr index 8d8122292ae..6ac27078ea3 100644 --- a/src/test/ui/parser/duplicate-visibility.stderr +++ b/src/test/ui/parser/duplicate-visibility.stderr @@ -1,21 +1,16 @@ -error: visibility `pub` is not followed by an item - --> $DIR/duplicate-visibility.rs:4:5 - | -LL | pub pub fn foo(); - | ^^^ the visibility - | - = help: you likely meant to define an item, e.g., `pub fn foo() {}` - -error: non-item in item list - --> $DIR/duplicate-visibility.rs:4:9 +error: expected one of `(`, `async`, `const`, `default`, `extern`, `fn`, `pub`, `unsafe`, or `use`, found keyword `pub` + --> $DIR/duplicate-visibility.rs:6:9 | LL | extern "C" { - | - item list starts here + | - while parsing this item list starting here LL | pub pub fn foo(); - | ^^^ non-item starts here -... + | ^^^ + | | + | expected one of 9 possible tokens + | help: visibility `pub` must come before `pub pub`: `pub pub pub` +LL | LL | } - | - item list ends here + | - the item list ends here -error: aborting due to 2 previous errors +error: aborting due to previous error diff --git a/src/test/ui/parser/issue-76437-async.rs b/src/test/ui/parser/issue-76437-async.rs new file mode 100644 index 00000000000..84ee3dd2112 --- /dev/null +++ b/src/test/ui/parser/issue-76437-async.rs @@ -0,0 +1,7 @@ +// edition:2018 + +mod t { + async pub fn t() {} + //~^ ERROR expected one of `extern`, `fn`, or `unsafe`, found keyword `pub` + //~| HELP visibility `pub` must come before `async` +} diff --git a/src/test/ui/parser/issue-76437-async.stderr b/src/test/ui/parser/issue-76437-async.stderr new file mode 100644 index 00000000000..2c9c2a8cfba --- /dev/null +++ b/src/test/ui/parser/issue-76437-async.stderr @@ -0,0 +1,11 @@ +error: expected one of `extern`, `fn`, or `unsafe`, found keyword `pub` + --> $DIR/issue-76437-async.rs:4:11 + | +LL | async pub fn t() {} + | ------^^^ + | | | + | | expected one of `extern`, `fn`, or `unsafe` + | help: visibility `pub` must come before `async`: `pub async` + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issue-76437-const-async-unsafe.rs b/src/test/ui/parser/issue-76437-const-async-unsafe.rs new file mode 100644 index 00000000000..f1e06e4ad89 --- /dev/null +++ b/src/test/ui/parser/issue-76437-const-async-unsafe.rs @@ -0,0 +1,7 @@ +// edition:2018 + +mod t { + const async unsafe pub fn t() {} + //~^ ERROR expected one of `extern` or `fn`, found keyword `pub` + //~| HELP visibility `pub` must come before `const async unsafe` +} diff --git a/src/test/ui/parser/issue-76437-const-async-unsafe.stderr b/src/test/ui/parser/issue-76437-const-async-unsafe.stderr new file mode 100644 index 00000000000..2e91beda116 --- /dev/null +++ b/src/test/ui/parser/issue-76437-const-async-unsafe.stderr @@ -0,0 +1,11 @@ +error: expected one of `extern` or `fn`, found keyword `pub` + --> $DIR/issue-76437-const-async-unsafe.rs:4:24 + | +LL | const async unsafe pub fn t() {} + | -------------------^^^ + | | | + | | expected one of `extern` or `fn` + | help: visibility `pub` must come before `const async unsafe`: `pub const async unsafe` + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issue-76437-const-async.rs b/src/test/ui/parser/issue-76437-const-async.rs new file mode 100644 index 00000000000..3c789fdcd02 --- /dev/null +++ b/src/test/ui/parser/issue-76437-const-async.rs @@ -0,0 +1,7 @@ +// edition:2018 + +mod t { + const async pub fn t() {} + //~^ ERROR expected one of `extern`, `fn`, or `unsafe`, found keyword `pub` + //~| HELP visibility `pub` must come before `const async` +} diff --git a/src/test/ui/parser/issue-76437-const-async.stderr b/src/test/ui/parser/issue-76437-const-async.stderr new file mode 100644 index 00000000000..21b96c14d7d --- /dev/null +++ b/src/test/ui/parser/issue-76437-const-async.stderr @@ -0,0 +1,11 @@ +error: expected one of `extern`, `fn`, or `unsafe`, found keyword `pub` + --> $DIR/issue-76437-const-async.rs:4:17 + | +LL | const async pub fn t() {} + | ------------^^^ + | | | + | | expected one of `extern`, `fn`, or `unsafe` + | help: visibility `pub` must come before `const async`: `pub const async` + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issue-76437-const.rs b/src/test/ui/parser/issue-76437-const.rs new file mode 100644 index 00000000000..d3815a52346 --- /dev/null +++ b/src/test/ui/parser/issue-76437-const.rs @@ -0,0 +1,7 @@ +// edition:2018 + +mod t { + const pub fn t() {} + //~^ ERROR expected one of `async`, `extern`, `fn`, or `unsafe`, found keyword `pub` + //~| HELP visibility `pub` must come before `const` +} diff --git a/src/test/ui/parser/issue-76437-const.stderr b/src/test/ui/parser/issue-76437-const.stderr new file mode 100644 index 00000000000..cf80d9a9037 --- /dev/null +++ b/src/test/ui/parser/issue-76437-const.stderr @@ -0,0 +1,11 @@ +error: expected one of `async`, `extern`, `fn`, or `unsafe`, found keyword `pub` + --> $DIR/issue-76437-const.rs:4:11 + | +LL | const pub fn t() {} + | ------^^^ + | | | + | | expected one of `async`, `extern`, `fn`, or `unsafe` + | help: visibility `pub` must come before `const`: `pub const` + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issue-76437-pub-crate-unsafe.rs b/src/test/ui/parser/issue-76437-pub-crate-unsafe.rs new file mode 100644 index 00000000000..daa1d120795 --- /dev/null +++ b/src/test/ui/parser/issue-76437-pub-crate-unsafe.rs @@ -0,0 +1,7 @@ +// edition:2018 + +mod t { + unsafe pub(crate) fn t() {} + //~^ ERROR expected one of `extern` or `fn`, found keyword `pub` + //~| HELP visibility `pub(crate)` must come before `unsafe` +} diff --git a/src/test/ui/parser/issue-76437-pub-crate-unsafe.stderr b/src/test/ui/parser/issue-76437-pub-crate-unsafe.stderr new file mode 100644 index 00000000000..fa8f13721c8 --- /dev/null +++ b/src/test/ui/parser/issue-76437-pub-crate-unsafe.stderr @@ -0,0 +1,11 @@ +error: expected one of `extern` or `fn`, found keyword `pub` + --> $DIR/issue-76437-pub-crate-unsafe.rs:4:12 + | +LL | unsafe pub(crate) fn t() {} + | -------^^^------- + | | | + | | expected one of `extern` or `fn` + | help: visibility `pub(crate)` must come before `unsafe`: `pub(crate) unsafe` + +error: aborting due to previous error + diff --git a/src/test/ui/parser/issue-76437-unsafe.rs b/src/test/ui/parser/issue-76437-unsafe.rs new file mode 100644 index 00000000000..785a79a79a2 --- /dev/null +++ b/src/test/ui/parser/issue-76437-unsafe.rs @@ -0,0 +1,7 @@ +// edition:2018 + +mod t { + unsafe pub fn t() {} + //~^ ERROR expected one of `extern` or `fn`, found keyword `pub` + //~| HELP visibility `pub` must come before `unsafe` +} diff --git a/src/test/ui/parser/issue-76437-unsafe.stderr b/src/test/ui/parser/issue-76437-unsafe.stderr new file mode 100644 index 00000000000..c63292ef853 --- /dev/null +++ b/src/test/ui/parser/issue-76437-unsafe.stderr @@ -0,0 +1,11 @@ +error: expected one of `extern` or `fn`, found keyword `pub` + --> $DIR/issue-76437-unsafe.rs:4:12 + | +LL | unsafe pub fn t() {} + | -------^^^ + | | | + | | expected one of `extern` or `fn` + | help: visibility `pub` must come before `unsafe`: `pub unsafe` + +error: aborting due to previous error + diff --git a/src/test/ui/proc-macro/issue-73933-procedural-masquerade.rs b/src/test/ui/proc-macro/issue-73933-procedural-masquerade.rs new file mode 100644 index 00000000000..abc3d2691a3 --- /dev/null +++ b/src/test/ui/proc-macro/issue-73933-procedural-masquerade.rs @@ -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() {} diff --git a/src/test/ui/proc-macro/issue-73933-procedural-masquerade.stderr b/src/test/ui/proc-macro/issue-73933-procedural-masquerade.stderr new file mode 100644 index 00000000000..0b930705e35 --- /dev/null +++ b/src/test/ui/proc-macro/issue-73933-procedural-masquerade.stderr @@ -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. + diff --git a/src/test/ui/proc-macro/issue-73933-procedural-masquerade.stdout b/src/test/ui/proc-macro/issue-73933-procedural-masquerade.stdout new file mode 100644 index 00000000000..8edd68f8a3b --- /dev/null +++ b/src/test/ui/proc-macro/issue-73933-procedural-masquerade.stdout @@ -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), + }, +] diff --git a/src/test/ui/tool_lints.rs b/src/test/ui/tool_lints.rs index 9c8540eede7..9e4aa7a939a 100644 --- a/src/test/ui/tool_lints.rs +++ b/src/test/ui/tool_lints.rs @@ -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() {} diff --git a/src/test/ui/tool_lints.stderr b/src/test/ui/tool_lints.stderr index 1bcd7fd735d..e06f6ddc1ca 100644 --- a/src/test/ui/tool_lints.stderr +++ b/src/test/ui/tool_lints.stderr @@ -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 diff --git a/src/test/ui/unknown-lint-tool-name.rs b/src/test/ui/unknown-lint-tool-name.rs index 182aec34b47..84ab7c1944a 100644 --- a/src/test/ui/unknown-lint-tool-name.rs +++ b/src/test/ui/unknown-lint-tool-name.rs @@ -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() {} diff --git a/src/test/ui/unknown-lint-tool-name.stderr b/src/test/ui/unknown-lint-tool-name.stderr index 414816d229c..1d145515abf 100644 --- a/src/test/ui/unknown-lint-tool-name.stderr +++ b/src/test/ui/unknown-lint-tool-name.stderr @@ -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 diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs index b32a6f08638..1d4b5e1247d 100644 --- a/src/tools/compiletest/src/main.rs +++ b/src/tools/compiletest/src/main.rs @@ -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); diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index f3286d88366..7aa3d4ab09e 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -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(); |
