diff options
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_borrowck/src/constraints/graph.rs | 9 | ||||
| -rw-r--r-- | compiler/rustc_expand/src/proc_macro.rs | 15 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/thir.rs | 24 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/layout.rs | 37 | ||||
| -rw-r--r-- | compiler/rustc_span/src/lib.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_span/src/profiling.rs | 35 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/coherence/orphan.rs | 10 |
7 files changed, 93 insertions, 39 deletions
diff --git a/compiler/rustc_borrowck/src/constraints/graph.rs b/compiler/rustc_borrowck/src/constraints/graph.rs index 4ceca60e23c..c19a39c393f 100644 --- a/compiler/rustc_borrowck/src/constraints/graph.rs +++ b/compiler/rustc_borrowck/src/constraints/graph.rs @@ -190,7 +190,7 @@ impl<'s, 'tcx, D: ConstraintGraphDirecton> RegionGraph<'s, 'tcx, D> { /// Given a region `R`, iterate over all regions `R1` such that /// there exists a constraint `R: R1`. - crate fn outgoing_regions(&self, region_sup: RegionVid) -> Successors<'_, 'tcx, D> { + crate fn outgoing_regions(&self, region_sup: RegionVid) -> Successors<'s, 'tcx, D> { Successors { edges: self.constraint_graph.outgoing_edges(region_sup, self.set, self.static_region), } @@ -225,10 +225,7 @@ impl<'s, 'tcx, D: ConstraintGraphDirecton> graph::WithSuccessors for RegionGraph } } -impl<'s, 'graph, 'tcx, D: ConstraintGraphDirecton> graph::GraphSuccessors<'graph> - for RegionGraph<'s, 'tcx, D> -{ +impl<'s, 'tcx, D: ConstraintGraphDirecton> graph::GraphSuccessors<'_> for RegionGraph<'s, 'tcx, D> { type Item = RegionVid; - // FIXME - why can't this be `'graph, 'tcx` - type Iter = Successors<'graph, 'graph, D>; + type Iter = Successors<'s, 'tcx, D>; } diff --git a/compiler/rustc_expand/src/proc_macro.rs b/compiler/rustc_expand/src/proc_macro.rs index aec401a041c..8e1966a0711 100644 --- a/compiler/rustc_expand/src/proc_macro.rs +++ b/compiler/rustc_expand/src/proc_macro.rs @@ -9,6 +9,7 @@ use rustc_data_structures::sync::Lrc; use rustc_errors::ErrorGuaranteed; use rustc_parse::nt_to_tokenstream; use rustc_parse::parser::ForceCollect; +use rustc_span::profiling::SpannedEventArgRecorder; use rustc_span::{Span, DUMMY_SP}; const EXEC_STRATEGY: pm::bridge::server::SameThread = pm::bridge::server::SameThread; @@ -25,7 +26,10 @@ impl base::ProcMacro for BangProcMacro { input: TokenStream, ) -> Result<TokenStream, ErrorGuaranteed> { let _timer = - ecx.sess.prof.generic_activity_with_arg("expand_proc_macro", ecx.expansion_descr()); + ecx.sess.prof.generic_activity_with_arg_recorder("expand_proc_macro", |recorder| { + recorder.record_arg_with_span(ecx.expansion_descr(), span); + }); + let proc_macro_backtrace = ecx.ecfg.proc_macro_backtrace; let server = proc_macro_server::Rustc::new(ecx); self.client.run(&EXEC_STRATEGY, server, input, proc_macro_backtrace).map_err(|e| { @@ -51,7 +55,10 @@ impl base::AttrProcMacro for AttrProcMacro { annotated: TokenStream, ) -> Result<TokenStream, ErrorGuaranteed> { let _timer = - ecx.sess.prof.generic_activity_with_arg("expand_proc_macro", ecx.expansion_descr()); + ecx.sess.prof.generic_activity_with_arg_recorder("expand_proc_macro", |recorder| { + recorder.record_arg_with_span(ecx.expansion_descr(), span); + }); + let proc_macro_backtrace = ecx.ecfg.proc_macro_backtrace; let server = proc_macro_server::Rustc::new(ecx); self.client @@ -103,7 +110,9 @@ impl MultiItemModifier for ProcMacroDerive { let stream = { let _timer = - ecx.sess.prof.generic_activity_with_arg("expand_proc_macro", ecx.expansion_descr()); + ecx.sess.prof.generic_activity_with_arg_recorder("expand_proc_macro", |recorder| { + recorder.record_arg_with_span(ecx.expansion_descr(), span); + }); let proc_macro_backtrace = ecx.ecfg.proc_macro_backtrace; let server = proc_macro_server::Rustc::new(ecx); match self.client.run(&EXEC_STRATEGY, server, input, proc_macro_backtrace) { diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs index e56efb8d497..fdf5ecfdaf7 100644 --- a/compiler/rustc_middle/src/thir.rs +++ b/compiler/rustc_middle/src/thir.rs @@ -66,7 +66,7 @@ macro_rules! thir_with_elements { /// A container for a THIR body. /// /// This can be indexed directly by any THIR index (e.g. [`ExprId`]). - #[derive(Debug, HashStable)] + #[derive(Debug, HashStable, Clone)] pub struct Thir<'tcx> { $( pub $name: IndexVec<$id, $value>, @@ -106,7 +106,7 @@ pub enum LintLevel { Explicit(hir::HirId), } -#[derive(Debug, HashStable)] +#[derive(Clone, Debug, HashStable)] pub struct Block { /// Whether the block itself has a label. Used by `label: {}` /// and `try` blocks. @@ -125,7 +125,7 @@ pub struct Block { pub safety_mode: BlockSafety, } -#[derive(Debug, HashStable)] +#[derive(Clone, Debug, HashStable)] pub struct Adt<'tcx> { /// The ADT we're constructing. pub adt_def: AdtDef<'tcx>, @@ -151,13 +151,13 @@ pub enum BlockSafety { ExplicitUnsafe(hir::HirId), } -#[derive(Debug, HashStable)] +#[derive(Clone, Debug, HashStable)] pub struct Stmt<'tcx> { pub kind: StmtKind<'tcx>, pub opt_destruction_scope: Option<region::Scope>, } -#[derive(Debug, HashStable)] +#[derive(Clone, Debug, HashStable)] pub enum StmtKind<'tcx> { /// An expression with a trailing semicolon. Expr { @@ -196,7 +196,7 @@ pub enum StmtKind<'tcx> { rustc_data_structures::static_assert_size!(Expr<'_>, 104); /// A THIR expression. -#[derive(Debug, HashStable)] +#[derive(Clone, Debug, HashStable)] pub struct Expr<'tcx> { /// The type of this expression pub ty: Ty<'tcx>, @@ -212,7 +212,7 @@ pub struct Expr<'tcx> { pub kind: ExprKind<'tcx>, } -#[derive(Debug, HashStable)] +#[derive(Clone, Debug, HashStable)] pub enum ExprKind<'tcx> { /// `Scope`s are used to explicitly mark destruction scopes, /// and to track the `HirId` of the expressions within the scope. @@ -461,20 +461,20 @@ impl<'tcx> ExprKind<'tcx> { /// Represents the association of a field identifier and an expression. /// /// This is used in struct constructors. -#[derive(Debug, HashStable)] +#[derive(Clone, Debug, HashStable)] pub struct FieldExpr { pub name: Field, pub expr: ExprId, } -#[derive(Debug, HashStable)] +#[derive(Clone, Debug, HashStable)] pub struct FruInfo<'tcx> { pub base: ExprId, pub field_types: Box<[Ty<'tcx>]>, } /// A `match` arm. -#[derive(Debug, HashStable)] +#[derive(Clone, Debug, HashStable)] pub struct Arm<'tcx> { pub pattern: Pat<'tcx>, pub guard: Option<Guard<'tcx>>, @@ -485,7 +485,7 @@ pub struct Arm<'tcx> { } /// A `match` guard. -#[derive(Debug, HashStable)] +#[derive(Clone, Debug, HashStable)] pub enum Guard<'tcx> { If(ExprId), IfLet(Pat<'tcx>, ExprId), @@ -499,7 +499,7 @@ pub enum LogicalOp { Or, } -#[derive(Debug, HashStable)] +#[derive(Clone, Debug, HashStable)] pub enum InlineAsmOperand<'tcx> { In { reg: InlineAsmRegOrRegClass, diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index f6d139fe59d..7cf2984a63f 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -1120,21 +1120,12 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { match st[i].abi() { Abi::Scalar(_) => Abi::Scalar(niche_scalar), Abi::ScalarPair(first, second) => { - // We need to use scalar_unit to reset the - // valid range to the maximal one for that - // primitive, because only the niche is - // guaranteed to be initialised, not the - // other primitive. + // Only the niche is guaranteed to be initialised, + // so use union layout for the other primitive. if offset.bytes() == 0 { - Abi::ScalarPair( - niche_scalar, - scalar_unit(second.primitive()), - ) + Abi::ScalarPair(niche_scalar, second.to_union()) } else { - Abi::ScalarPair( - scalar_unit(first.primitive()), - niche_scalar, - ) + Abi::ScalarPair(first.to_union(), niche_scalar) } } _ => Abi::Aggregate { sized: true }, @@ -1329,6 +1320,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { } else { // Try to use a ScalarPair for all tagged enums. let mut common_prim = None; + let mut common_prim_initialized_in_all_variants = true; for (field_layouts, layout_variant) in iter::zip(&variants, &layout_variants) { let FieldsShape::Arbitrary { ref offsets, .. } = layout_variant.fields else { bug!(); @@ -1336,7 +1328,10 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { let mut fields = iter::zip(field_layouts, offsets).filter(|p| !p.0.is_zst()); let (field, offset) = match (fields.next(), fields.next()) { - (None, None) => continue, + (None, None) => { + common_prim_initialized_in_all_variants = false; + continue; + } (Some(pair), None) => pair, _ => { common_prim = None; @@ -1344,7 +1339,11 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { } }; let prim = match field.abi { - Abi::Scalar(scalar) => scalar.primitive(), + Abi::Scalar(scalar) => { + common_prim_initialized_in_all_variants &= + matches!(scalar, Scalar::Initialized { .. }); + scalar.primitive() + } _ => { common_prim = None; break; @@ -1364,7 +1363,13 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { } } if let Some((prim, offset)) = common_prim { - let pair = self.scalar_pair(tag, scalar_unit(prim)); + let prim_scalar = if common_prim_initialized_in_all_variants { + scalar_unit(prim) + } else { + // Common prim might be uninit. + Scalar::Union { value: prim } + }; + let pair = self.scalar_pair(tag, prim_scalar); let pair_offsets = match pair.fields { FieldsShape::Arbitrary { ref offsets, ref memory_index } => { assert_eq!(memory_index, &[0, 1]); diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index b0307cc20d1..f22faef2580 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -59,6 +59,8 @@ pub use symbol::{sym, Symbol}; mod analyze_source_file; pub mod fatal_error; +pub mod profiling; + use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::sync::{Lock, Lrc}; diff --git a/compiler/rustc_span/src/profiling.rs b/compiler/rustc_span/src/profiling.rs new file mode 100644 index 00000000000..f169007fab4 --- /dev/null +++ b/compiler/rustc_span/src/profiling.rs @@ -0,0 +1,35 @@ +use std::borrow::Borrow; + +use rustc_data_structures::profiling::EventArgRecorder; + +/// Extension trait for self-profiling purposes: allows to record spans within a generic activity's +/// event arguments. +pub trait SpannedEventArgRecorder { + /// Records the following event arguments within the current generic activity being profiled: + /// - the provided `event_arg` + /// - a string representation of the provided `span` + /// + /// Note: when self-profiling with costly event arguments, at least one argument + /// needs to be recorded. A panic will be triggered if that doesn't happen. + fn record_arg_with_span<A>(&mut self, event_arg: A, span: crate::Span) + where + A: Borrow<str> + Into<String>; +} + +impl SpannedEventArgRecorder for EventArgRecorder<'_> { + fn record_arg_with_span<A>(&mut self, event_arg: A, span: crate::Span) + where + A: Borrow<str> + Into<String>, + { + self.record_arg(event_arg); + + let span_arg = crate::with_session_globals(|session_globals| { + if let Some(source_map) = &*session_globals.source_map.borrow() { + source_map.span_to_embeddable_string(span) + } else { + format!("{:?}", span) + } + }); + self.record_arg(span_arg); + } +} diff --git a/compiler/rustc_typeck/src/coherence/orphan.rs b/compiler/rustc_typeck/src/coherence/orphan.rs index 77a53744829..19e68f0b14f 100644 --- a/compiler/rustc_typeck/src/coherence/orphan.rs +++ b/compiler/rustc_typeck/src/coherence/orphan.rs @@ -50,6 +50,7 @@ fn orphan_check_impl(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), ErrorGua tcx, sp, tr.path.span, + trait_ref.self_ty(), impl_.self_ty.span, &impl_.generics, err, @@ -201,18 +202,23 @@ fn emit_orphan_check_error<'tcx>( tcx: TyCtxt<'tcx>, sp: Span, trait_span: Span, + self_ty: Ty<'tcx>, self_ty_span: Span, generics: &hir::Generics<'tcx>, err: traits::OrphanCheckErr<'tcx>, ) -> Result<!, ErrorGuaranteed> { Err(match err { traits::OrphanCheckErr::NonLocalInputType(tys) => { + let msg = match self_ty.kind() { + ty::Adt(..) => "can be implemented for types defined outside of the crate", + _ if self_ty.is_primitive() => "can be implemented for primitive types", + _ => "can be implemented for arbitrary types", + }; let mut err = struct_span_err!( tcx.sess, sp, E0117, - "only traits defined in the current crate can be implemented for \ - arbitrary types" + "only traits defined in the current crate {msg}" ); err.span_label(sp, "impl doesn't use only types from inside the current crate"); for (ty, is_target_ty) in &tys { |
