diff options
Diffstat (limited to 'compiler/rustc_middle')
| -rw-r--r-- | compiler/rustc_middle/src/lint.rs | 3 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/middle/codegen_fn_attrs.rs | 8 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/mir/interpret/allocation.rs | 3 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/mir/pretty.rs | 116 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/query/mod.rs | 19 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/context.rs | 11 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/parameterized.rs | 1 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/sty.rs | 7 |
8 files changed, 114 insertions, 54 deletions
diff --git a/compiler/rustc_middle/src/lint.rs b/compiler/rustc_middle/src/lint.rs index 8c27cac1ea8..70da66af64b 100644 --- a/compiler/rustc_middle/src/lint.rs +++ b/compiler/rustc_middle/src/lint.rs @@ -6,7 +6,7 @@ use rustc_errors::{Diag, MultiSpan}; use rustc_hir::{HirId, ItemLocalId}; use rustc_macros::HashStable; use rustc_session::lint::builtin::{self, FORBIDDEN_LINT_GROUPS}; -use rustc_session::lint::{FutureIncompatibilityReason, Level, Lint, LintId}; +use rustc_session::lint::{FutureIncompatibilityReason, Level, Lint, LintExpectationId, LintId}; use rustc_session::Session; use rustc_span::hygiene::{ExpnKind, MacroKind}; use rustc_span::{symbol, DesugaringKind, Span, Symbol, DUMMY_SP}; @@ -61,6 +61,7 @@ pub type LevelAndSource = (Level, LintLevelSource); /// by the attributes for *a single HirId*. #[derive(Default, Debug, HashStable)] pub struct ShallowLintLevelMap { + pub expectations: Vec<(LintExpectationId, LintExpectation)>, pub specs: SortedMap<ItemLocalId, FxIndexMap<LintId, LevelAndSource>>, } diff --git a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs index c098a739592..b7d290e58d2 100644 --- a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs +++ b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs @@ -26,8 +26,8 @@ pub struct CodegenFnAttrs { /// be set when `link_name` is set. This is for foreign items with the /// "raw-dylib" kind. pub link_ordinal: Option<u16>, - /// All the target features that are enabled for this function. Some features might be enabled - /// implicitly. + /// The `#[target_feature(enable = "...")]` attribute and the enabled + /// features (only enabled features are supported right now). pub target_features: Vec<TargetFeature>, /// The `#[linkage = "..."]` attribute on Rust-defined items and the value we found. pub linkage: Option<Linkage>, @@ -55,8 +55,8 @@ pub struct CodegenFnAttrs { pub struct TargetFeature { /// The name of the target feature (e.g. "avx") pub name: Symbol, - /// The feature is implied by another feature or by an argument, rather than explicitly - /// added by the `#[target_feature]` attribute + /// The feature is implied by another feature, rather than explicitly added by the + /// `#[target_feature]` attribute pub implied: bool, } diff --git a/compiler/rustc_middle/src/mir/interpret/allocation.rs b/compiler/rustc_middle/src/mir/interpret/allocation.rs index 3e101c0c635..5fb8af576ae 100644 --- a/compiler/rustc_middle/src/mir/interpret/allocation.rs +++ b/compiler/rustc_middle/src/mir/interpret/allocation.rs @@ -358,10 +358,11 @@ impl Allocation { pub fn adjust_from_tcx<Prov: Provenance, Bytes: AllocBytes, Err>( &self, cx: &impl HasDataLayout, + mut alloc_bytes: impl FnMut(&[u8], Align) -> Result<Bytes, Err>, mut adjust_ptr: impl FnMut(Pointer<CtfeProvenance>) -> Result<Pointer<Prov>, Err>, ) -> Result<Allocation<Prov, (), Bytes>, Err> { // Copy the data. - let mut bytes = Bytes::from_bytes(Cow::Borrowed(&*self.bytes), self.align); + let mut bytes = alloc_bytes(&*self.bytes, self.align)?; // Adjust provenance of pointers stored in this allocation. let mut new_provenance = Vec::with_capacity(self.provenance.ptrs().len()); let ptr_size = cx.data_layout().pointer_size.bytes_usize(); diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs index 6785805c27d..9906be60e3e 100644 --- a/compiler/rustc_middle/src/mir/pretty.rs +++ b/compiler/rustc_middle/src/mir/pretty.rs @@ -43,8 +43,23 @@ pub enum PassWhere { AfterTerminator(BasicBlock), } -/// If the session is properly configured, dumps a human-readable -/// representation of the mir into: +/// Cosmetic options for pretty-printing the MIR contents, gathered from the CLI. Each pass can +/// override these when dumping its own specific MIR information with [`dump_mir_with_options`]. +#[derive(Copy, Clone)] +pub struct PrettyPrintMirOptions { + /// Whether to include extra comments, like span info. From `-Z mir-include-spans`. + pub include_extra_comments: bool, +} + +impl PrettyPrintMirOptions { + /// Create the default set of MIR pretty-printing options from the CLI flags. + pub fn from_cli(tcx: TyCtxt<'_>) -> Self { + Self { include_extra_comments: tcx.sess.opts.unstable_opts.mir_include_spans.is_enabled() } + } +} + +/// If the session is properly configured, dumps a human-readable representation of the MIR (with +/// default pretty-printing options) into: /// /// ```text /// rustc.node<node_id>.<pass_num>.<pass_name>.<disambiguator> @@ -78,11 +93,39 @@ pub fn dump_mir<'tcx, F>( ) where F: FnMut(PassWhere, &mut dyn io::Write) -> io::Result<()>, { + dump_mir_with_options( + tcx, + pass_num, + pass_name, + disambiguator, + body, + extra_data, + PrettyPrintMirOptions::from_cli(tcx), + ); +} + +/// If the session is properly configured, dumps a human-readable representation of the MIR, with +/// the given [pretty-printing options][PrettyPrintMirOptions]. +/// +/// See [`dump_mir`] for more details. +/// +#[inline] +pub fn dump_mir_with_options<'tcx, F>( + tcx: TyCtxt<'tcx>, + pass_num: bool, + pass_name: &str, + disambiguator: &dyn Display, + body: &Body<'tcx>, + extra_data: F, + options: PrettyPrintMirOptions, +) where + F: FnMut(PassWhere, &mut dyn io::Write) -> io::Result<()>, +{ if !dump_enabled(tcx, pass_name, body.source.def_id()) { return; } - dump_matched_mir_node(tcx, pass_num, pass_name, disambiguator, body, extra_data); + dump_matched_mir_node(tcx, pass_num, pass_name, disambiguator, body, extra_data, options); } pub fn dump_enabled(tcx: TyCtxt<'_>, pass_name: &str, def_id: DefId) -> bool { @@ -112,6 +155,7 @@ fn dump_matched_mir_node<'tcx, F>( disambiguator: &dyn Display, body: &Body<'tcx>, mut extra_data: F, + options: PrettyPrintMirOptions, ) where F: FnMut(PassWhere, &mut dyn io::Write) -> io::Result<()>, { @@ -133,7 +177,7 @@ fn dump_matched_mir_node<'tcx, F>( writeln!(file)?; extra_data(PassWhere::BeforeCFG, &mut file)?; write_user_type_annotations(tcx, body, &mut file)?; - write_mir_fn(tcx, body, &mut extra_data, &mut file)?; + write_mir_fn(tcx, body, &mut extra_data, &mut file, options)?; extra_data(PassWhere::AfterCFG, &mut file)?; }; @@ -243,12 +287,15 @@ pub fn create_dump_file<'tcx>( /////////////////////////////////////////////////////////////////////////// // Whole MIR bodies -/// Write out a human-readable textual representation for the given MIR. +/// Write out a human-readable textual representation for the given MIR, with the default +/// [PrettyPrintMirOptions]. pub fn write_mir_pretty<'tcx>( tcx: TyCtxt<'tcx>, single: Option<DefId>, w: &mut dyn io::Write, ) -> io::Result<()> { + let options = PrettyPrintMirOptions::from_cli(tcx); + writeln!(w, "// WARNING: This output format is intended for human consumers only")?; writeln!(w, "// and is subject to change without notice. Knock yourself out.")?; @@ -262,11 +309,11 @@ pub fn write_mir_pretty<'tcx>( } let render_body = |w: &mut dyn io::Write, body| -> io::Result<()> { - write_mir_fn(tcx, body, &mut |_, _| Ok(()), w)?; + write_mir_fn(tcx, body, &mut |_, _| Ok(()), w, options)?; for body in tcx.promoted_mir(def_id) { writeln!(w)?; - write_mir_fn(tcx, body, &mut |_, _| Ok(()), w)?; + write_mir_fn(tcx, body, &mut |_, _| Ok(()), w, options)?; } Ok(()) }; @@ -278,7 +325,7 @@ pub fn write_mir_pretty<'tcx>( writeln!(w, "// MIR FOR CTFE")?; // Do not use `render_body`, as that would render the promoteds again, but these // are shared between mir_for_ctfe and optimized_mir - write_mir_fn(tcx, tcx.mir_for_ctfe(def_id), &mut |_, _| Ok(()), w)?; + write_mir_fn(tcx, tcx.mir_for_ctfe(def_id), &mut |_, _| Ok(()), w, options)?; } else { let instance_mir = tcx.instance_mir(ty::InstanceKind::Item(def_id)); render_body(w, instance_mir)?; @@ -293,14 +340,15 @@ pub fn write_mir_fn<'tcx, F>( body: &Body<'tcx>, extra_data: &mut F, w: &mut dyn io::Write, + options: PrettyPrintMirOptions, ) -> io::Result<()> where F: FnMut(PassWhere, &mut dyn io::Write) -> io::Result<()>, { - write_mir_intro(tcx, body, w)?; + write_mir_intro(tcx, body, w, options)?; for block in body.basic_blocks.indices() { extra_data(PassWhere::BeforeBlock(block), w)?; - write_basic_block(tcx, block, body, extra_data, w)?; + write_basic_block(tcx, block, body, extra_data, w, options)?; if block.index() + 1 != body.basic_blocks.len() { writeln!(w)?; } @@ -321,6 +369,7 @@ fn write_scope_tree( w: &mut dyn io::Write, parent: SourceScope, depth: usize, + options: PrettyPrintMirOptions, ) -> io::Result<()> { let indent = depth * INDENT.len(); @@ -333,7 +382,7 @@ fn write_scope_tree( let indented_debug_info = format!("{0:1$}debug {2:?};", INDENT, indent, var_debug_info); - if tcx.sess.opts.unstable_opts.mir_include_spans { + if options.include_extra_comments { writeln!( w, "{0:1$} // in {2}", @@ -373,7 +422,7 @@ fn write_scope_tree( let local_name = if local == RETURN_PLACE { " return place" } else { "" }; - if tcx.sess.opts.unstable_opts.mir_include_spans { + if options.include_extra_comments { writeln!( w, "{0:1$} //{2} in {3}", @@ -410,7 +459,7 @@ fn write_scope_tree( let indented_header = format!("{0:1$}scope {2}{3} {{", "", indent, child.index(), special); - if tcx.sess.opts.unstable_opts.mir_include_spans { + if options.include_extra_comments { if let Some(span) = span { writeln!( w, @@ -426,7 +475,7 @@ fn write_scope_tree( writeln!(w, "{indented_header}")?; } - write_scope_tree(tcx, body, scope_tree, w, child, depth + 1)?; + write_scope_tree(tcx, body, scope_tree, w, child, depth + 1, options)?; writeln!(w, "{0:1$}}}", "", depth * INDENT.len())?; } @@ -449,10 +498,11 @@ impl Debug for VarDebugInfo<'_> { /// Write out a human-readable textual representation of the MIR's `fn` type and the types of its /// local variables (both user-defined bindings and compiler temporaries). -pub fn write_mir_intro<'tcx>( +fn write_mir_intro<'tcx>( tcx: TyCtxt<'tcx>, body: &Body<'_>, w: &mut dyn io::Write, + options: PrettyPrintMirOptions, ) -> io::Result<()> { write_mir_sig(tcx, body, w)?; writeln!(w, "{{")?; @@ -468,7 +518,7 @@ pub fn write_mir_intro<'tcx>( } } - write_scope_tree(tcx, body, &scope_tree, w, OUTERMOST_SOURCE_SCOPE, 1)?; + write_scope_tree(tcx, body, &scope_tree, w, OUTERMOST_SOURCE_SCOPE, 1, options)?; // Add an empty line before the first block is printed. writeln!(w)?; @@ -651,12 +701,13 @@ pub fn dump_mir_def_ids(tcx: TyCtxt<'_>, single: Option<DefId>) -> Vec<DefId> { // Basic blocks and their parts (statements, terminators, ...) /// Write out a human-readable textual representation for the given basic block. -pub fn write_basic_block<'tcx, F>( +fn write_basic_block<'tcx, F>( tcx: TyCtxt<'tcx>, block: BasicBlock, body: &Body<'tcx>, extra_data: &mut F, w: &mut dyn io::Write, + options: PrettyPrintMirOptions, ) -> io::Result<()> where F: FnMut(PassWhere, &mut dyn io::Write) -> io::Result<()>, @@ -672,7 +723,7 @@ where for statement in &data.statements { extra_data(PassWhere::BeforeLocation(current_location), w)?; let indented_body = format!("{INDENT}{INDENT}{statement:?};"); - if tcx.sess.opts.unstable_opts.mir_include_spans { + if options.include_extra_comments { writeln!( w, "{:A$} // {}{}", @@ -689,9 +740,14 @@ where writeln!(w, "{indented_body}")?; } - write_extra(tcx, w, |visitor| { - visitor.visit_statement(statement, current_location); - })?; + write_extra( + tcx, + w, + |visitor| { + visitor.visit_statement(statement, current_location); + }, + options, + )?; extra_data(PassWhere::AfterLocation(current_location), w)?; @@ -701,7 +757,7 @@ where // Terminator at the bottom. extra_data(PassWhere::BeforeLocation(current_location), w)?; let indented_terminator = format!("{0}{0}{1:?};", INDENT, data.terminator().kind); - if tcx.sess.opts.unstable_opts.mir_include_spans { + if options.include_extra_comments { writeln!( w, "{:A$} // {}{}", @@ -718,9 +774,14 @@ where writeln!(w, "{indented_terminator}")?; } - write_extra(tcx, w, |visitor| { - visitor.visit_terminator(data.terminator(), current_location); - })?; + write_extra( + tcx, + w, + |visitor| { + visitor.visit_terminator(data.terminator(), current_location); + }, + options, + )?; extra_data(PassWhere::AfterLocation(current_location), w)?; extra_data(PassWhere::AfterTerminator(block), w)?; @@ -1271,11 +1332,12 @@ fn write_extra<'tcx, F>( tcx: TyCtxt<'tcx>, write: &mut dyn io::Write, mut visit_op: F, + options: PrettyPrintMirOptions, ) -> io::Result<()> where F: FnMut(&mut ExtraComments<'tcx>), { - if tcx.sess.opts.unstable_opts.mir_include_spans { + if options.include_extra_comments { let mut extra_comments = ExtraComments { tcx, comments: vec![] }; visit_op(&mut extra_comments); for comment in extra_comments.comments { @@ -1890,7 +1952,7 @@ pub(crate) fn pretty_print_const_value<'tcx>( /////////////////////////////////////////////////////////////////////////// // Miscellaneous -/// Calc converted u64 decimal into hex and return it's length in chars +/// Calc converted u64 decimal into hex and return its length in chars. /// /// ```ignore (cannot-test-private-function) /// assert_eq!(1, hex_number_length(0)); diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 6434bd0d7bf..d6bdc1af0d2 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -47,7 +47,7 @@ use {rustc_ast as ast, rustc_attr as attr, rustc_hir as hir}; use crate::infer::canonical::{self, Canonical}; use crate::lint::LintExpectation; use crate::metadata::ModChild; -use crate::middle::codegen_fn_attrs::{CodegenFnAttrs, TargetFeature}; +use crate::middle::codegen_fn_attrs::CodegenFnAttrs; use crate::middle::debugger_visualizer::DebuggerVisualizerFile; use crate::middle::exported_symbols::{ExportedSymbol, SymbolExportInfo}; use crate::middle::lib_features::LibFeatures; @@ -651,7 +651,7 @@ rustc_queries! { /// is a subset of the full list of predicates. We store these in a separate map /// because we must evaluate them even during type conversion, often before the full /// predicates are available (note that super-predicates must not be cyclic). - query explicit_super_predicates_of(key: DefId) -> ty::GenericPredicates<'tcx> { + query explicit_super_predicates_of(key: DefId) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> { desc { |tcx| "computing the super predicates of `{}`", tcx.def_path_str(key) } cache_on_disk_if { key.is_local() } separate_provide_extern @@ -662,7 +662,7 @@ rustc_queries! { /// of the trait. For regular traits, this includes all super-predicates and their /// associated type bounds. For trait aliases, currently, this includes all of the /// predicates of the trait alias. - query explicit_implied_predicates_of(key: DefId) -> ty::GenericPredicates<'tcx> { + query explicit_implied_predicates_of(key: DefId) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> { desc { |tcx| "computing the implied predicates of `{}`", tcx.def_path_str(key) } cache_on_disk_if { key.is_local() } separate_provide_extern @@ -671,7 +671,9 @@ rustc_queries! { /// The Ident is the name of an associated type.The query returns only the subset /// of supertraits that define the given associated type. This is used to avoid /// cycles in resolving type-dependent associated item paths like `T::Item`. - query explicit_supertraits_containing_assoc_item(key: (DefId, rustc_span::symbol::Ident)) -> ty::GenericPredicates<'tcx> { + query explicit_supertraits_containing_assoc_item( + key: (DefId, rustc_span::symbol::Ident) + ) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> { desc { |tcx| "computing the super traits of `{}` with associated type name `{}`", tcx.def_path_str(key.0), key.1 @@ -680,7 +682,9 @@ rustc_queries! { /// To avoid cycles within the predicates of a single item we compute /// per-type-parameter predicates for resolving `T::AssocTy`. - query type_param_predicates(key: (LocalDefId, LocalDefId, rustc_span::symbol::Ident)) -> ty::GenericPredicates<'tcx> { + query type_param_predicates( + key: (LocalDefId, LocalDefId, rustc_span::symbol::Ident) + ) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> { desc { |tcx| "computing the bounds for type parameter `{}`", tcx.hir().ty_param_name(key.1) } } @@ -1245,11 +1249,6 @@ rustc_queries! { feedable } - query struct_target_features(def_id: DefId) -> &'tcx [TargetFeature] { - separate_provide_extern - desc { |tcx| "computing target features for struct `{}`", tcx.def_path_str(def_id) } - } - query asm_target_features(def_id: DefId) -> &'tcx FxIndexSet<Symbol> { desc { |tcx| "computing target features for inline asm of `{}`", tcx.def_path_str(def_id) } } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 70df205d893..43dda252f83 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -349,16 +349,14 @@ impl<'tcx> Interner for TyCtxt<'tcx> { self, def_id: DefId, ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = (ty::Clause<'tcx>, Span)>> { - ty::EarlyBinder::bind(self.explicit_super_predicates_of(def_id).instantiate_identity(self)) + self.explicit_super_predicates_of(def_id).map_bound(|preds| preds.into_iter().copied()) } fn explicit_implied_predicates_of( self, def_id: DefId, ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = (ty::Clause<'tcx>, Span)>> { - ty::EarlyBinder::bind( - self.explicit_implied_predicates_of(def_id).instantiate_identity(self), - ) + self.explicit_implied_predicates_of(def_id).map_bound(|preds| preds.into_iter().copied()) } fn has_target_features(self, def_id: DefId) -> bool { @@ -3095,10 +3093,7 @@ impl<'tcx> TyCtxt<'tcx> { Some(stability) if stability.is_const_unstable() => { // has a `rustc_const_unstable` attribute, check whether the user enabled the // corresponding feature gate. - self.features() - .declared_lib_features - .iter() - .any(|&(sym, _)| sym == stability.feature) + self.features().declared(stability.feature) } // functions without const stability are either stable user written // const fn or the user is using feature gates and we thus don't diff --git a/compiler/rustc_middle/src/ty/parameterized.rs b/compiler/rustc_middle/src/ty/parameterized.rs index be611e19b49..7e1255f606c 100644 --- a/compiler/rustc_middle/src/ty/parameterized.rs +++ b/compiler/rustc_middle/src/ty/parameterized.rs @@ -59,7 +59,6 @@ trivially_parameterized_over_tcx! { std::string::String, crate::metadata::ModChild, crate::middle::codegen_fn_attrs::CodegenFnAttrs, - crate::middle::codegen_fn_attrs::TargetFeature, crate::middle::debugger_visualizer::DebuggerVisualizerFile, crate::middle::exported_symbols::SymbolExportInfo, crate::middle::lib_features::FeatureStability, diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index d60bfb9faa1..b144fd0feb0 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -1000,7 +1000,7 @@ impl<'tcx> Ty<'tcx> { #[inline] pub fn is_primitive(self) -> bool { - self.kind().is_primitive() + matches!(self.kind(), Bool | Char | Int(_) | Uint(_) | Float(_)) } #[inline] @@ -1149,7 +1149,10 @@ impl<'tcx> Ty<'tcx> { } } - /// Tests whether this is a Box using the global allocator. + /// Tests whether this is a Box definitely using the global allocator. + /// + /// If the allocator is still generic, the answer is `false`, but it may + /// later turn out that it does use the global allocator. #[inline] pub fn is_box_global(self, tcx: TyCtxt<'tcx>) -> bool { match self.kind() { |
