about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-11-17 15:27:29 +0000
committerbors <bors@rust-lang.org>2020-11-17 15:27:29 +0000
commitc919f490bbcd2b29b74016101f7ec71aaa24bdbb (patch)
treece8406ee4a726bc8db7c864518f3d8ea16ea8c6e /compiler
parente0ef0fc392963438af5f0343bf7caa46fb9c3ec3 (diff)
parentf698505177eb1853b3d905bbe1005140acd50d53 (diff)
downloadrust-c919f490bbcd2b29b74016101f7ec71aaa24bdbb.tar.gz
rust-c919f490bbcd2b29b74016101f7ec71aaa24bdbb.zip
Auto merge of #79138 - m-ou-se:rollup-owel5ld, r=m-ou-se
Rollup of 8 pull requests

Successful merges:

 - #74293 (Rustdoc test compiler output color)
 - #78702 ([self-profiling] Include the estimated size of each cgu in the profile)
 - #79069 (Get rid of `highlight::Class::None`)
 - #79072 (Fix exhaustiveness in case a byte string literal is used at slice type)
 - #79120 (update rustfmt to v1.4.27)
 - #79125 (Get rid of clean::{Method, TyMethod})
 - #79126 (Remove duplicate `Trait::auto` field)
 - #79130 (extend macro braces test)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_codegen_llvm/src/base.rs6
-rw-r--r--compiler/rustc_data_structures/src/profiling.rs22
-rw-r--r--compiler/rustc_errors/src/emitter.rs17
-rw-r--r--compiler/rustc_middle/src/ty/context.rs9
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs44
-rw-r--r--compiler/rustc_typeck/src/check/pat.rs8
-rw-r--r--compiler/rustc_typeck/src/check/writeback.rs3
7 files changed, 97 insertions, 12 deletions
diff --git a/compiler/rustc_codegen_llvm/src/base.rs b/compiler/rustc_codegen_llvm/src/base.rs
index 1090d4a25c7..7d01f6a5499 100644
--- a/compiler/rustc_codegen_llvm/src/base.rs
+++ b/compiler/rustc_codegen_llvm/src/base.rs
@@ -97,14 +97,12 @@ pub fn compile_codegen_unit(
     tcx: TyCtxt<'tcx>,
     cgu_name: Symbol,
 ) -> (ModuleCodegen<ModuleLlvm>, u64) {
-    let prof_timer = tcx.prof.generic_activity_with_arg("codegen_module", cgu_name.to_string());
     let start_time = Instant::now();
 
     let dep_node = tcx.codegen_unit(cgu_name).codegen_dep_node(tcx);
     let (module, _) =
         tcx.dep_graph.with_task(dep_node, tcx, cgu_name, module_codegen, dep_graph::hash_result);
     let time_to_codegen = start_time.elapsed();
-    drop(prof_timer);
 
     // We assume that the cost to run LLVM on a CGU is proportional to
     // the time we needed for codegenning it.
@@ -112,6 +110,10 @@ pub fn compile_codegen_unit(
 
     fn module_codegen(tcx: TyCtxt<'_>, cgu_name: Symbol) -> ModuleCodegen<ModuleLlvm> {
         let cgu = tcx.codegen_unit(cgu_name);
+        let _prof_timer = tcx.prof.generic_activity_with_args(
+            "codegen_module",
+            &[cgu_name.to_string(), cgu.size_estimate().to_string()],
+        );
         // Instantiate monomorphizations without filling out definitions yet...
         let llvm_module = ModuleLlvm::new(tcx, &cgu_name.as_str());
         {
diff --git a/compiler/rustc_data_structures/src/profiling.rs b/compiler/rustc_data_structures/src/profiling.rs
index e598d7a683d..5d13b7f27c7 100644
--- a/compiler/rustc_data_structures/src/profiling.rs
+++ b/compiler/rustc_data_structures/src/profiling.rs
@@ -272,6 +272,28 @@ impl SelfProfilerRef {
         })
     }
 
+    #[inline(always)]
+    pub fn generic_activity_with_args(
+        &self,
+        event_label: &'static str,
+        event_args: &[String],
+    ) -> TimingGuard<'_> {
+        self.exec(EventFilter::GENERIC_ACTIVITIES, |profiler| {
+            let builder = EventIdBuilder::new(&profiler.profiler);
+            let event_label = profiler.get_or_alloc_cached_string(event_label);
+            let event_id = if profiler.event_filter_mask.contains(EventFilter::FUNCTION_ARGS) {
+                let event_args: Vec<_> = event_args
+                    .iter()
+                    .map(|s| profiler.get_or_alloc_cached_string(&s[..]))
+                    .collect();
+                builder.from_label_and_args(event_label, &event_args)
+            } else {
+                builder.from_label(event_label)
+            };
+            TimingGuard::start(profiler, profiler.generic_activity_event_kind, event_id)
+        })
+    }
+
     /// Start profiling a query provider. Profiling continues until the
     /// TimingGuard returned from this call is dropped.
     #[inline(always)]
diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs
index 302713a21db..32104e6f00d 100644
--- a/compiler/rustc_errors/src/emitter.rs
+++ b/compiler/rustc_errors/src/emitter.rs
@@ -200,6 +200,11 @@ pub trait Emitter {
         true
     }
 
+    /// Checks if we can use colors in the current output stream.
+    fn supports_color(&self) -> bool {
+        false
+    }
+
     fn source_map(&self) -> Option<&Lrc<SourceMap>>;
 
     /// Formats the substitutions of the primary_span
@@ -504,6 +509,10 @@ impl Emitter for EmitterWriter {
     fn should_show_explain(&self) -> bool {
         !self.short_message
     }
+
+    fn supports_color(&self) -> bool {
+        self.dst.supports_color()
+    }
 }
 
 /// An emitter that does nothing when emitting a diagnostic.
@@ -2057,6 +2066,14 @@ impl Destination {
             Destination::Raw(ref mut t, true) => WritableDst::ColoredRaw(Ansi::new(t)),
         }
     }
+
+    fn supports_color(&self) -> bool {
+        match *self {
+            Self::Terminal(ref stream) => stream.supports_color(),
+            Self::Buffered(ref buffer) => buffer.buffer().supports_color(),
+            Self::Raw(_, supports_color) => supports_color,
+        }
+    }
 }
 
 impl<'a> WritableDst<'a> {
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index a5237ffaf78..36cbd36a770 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -422,6 +422,12 @@ pub struct TypeckResults<'tcx> {
     /// Stores the type, expression, span and optional scope span of all types
     /// that are live across the yield of this generator (if a generator).
     pub generator_interior_types: Vec<GeneratorInteriorTypeCause<'tcx>>,
+
+    /// We sometimes treat byte string literals (which are of type `&[u8; N]`)
+    /// as `&[u8]`, depending on the pattern  in which they are used.
+    /// This hashset records all instances where we behave
+    /// like this to allow `const_to_pat` to reliably handle this situation.
+    pub treat_byte_string_as_slice: ItemLocalSet,
 }
 
 impl<'tcx> TypeckResults<'tcx> {
@@ -448,6 +454,7 @@ impl<'tcx> TypeckResults<'tcx> {
             closure_captures: Default::default(),
             closure_min_captures: Default::default(),
             generator_interior_types: Default::default(),
+            treat_byte_string_as_slice: Default::default(),
         }
     }
 
@@ -683,6 +690,7 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for TypeckResults<'tcx> {
             ref closure_captures,
             ref closure_min_captures,
             ref generator_interior_types,
+            ref treat_byte_string_as_slice,
         } = *self;
 
         hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
@@ -717,6 +725,7 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for TypeckResults<'tcx> {
             closure_captures.hash_stable(hcx, hasher);
             closure_min_captures.hash_stable(hcx, hasher);
             generator_interior_types.hash_stable(hcx, hasher);
+            treat_byte_string_as_slice.hash_stable(hcx, hasher);
         })
     }
 }
diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
index 6370f8c375b..32fc0f008e9 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
@@ -18,6 +18,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
     /// Converts an evaluated constant to a pattern (if possible).
     /// This means aggregate values (like structs and enums) are converted
     /// to a pattern that matches the value (as if you'd compared via structural equality).
+    #[instrument(skip(self))]
     pub(super) fn const_to_pat(
         &self,
         cv: &'tcx ty::Const<'tcx>,
@@ -25,15 +26,12 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
         span: Span,
         mir_structural_match_violation: bool,
     ) -> Pat<'tcx> {
-        debug!("const_to_pat: cv={:#?} id={:?}", cv, id);
-        debug!("const_to_pat: cv.ty={:?} span={:?}", cv.ty, span);
-
         let pat = self.tcx.infer_ctxt().enter(|infcx| {
             let mut convert = ConstToPat::new(self, id, span, infcx);
             convert.to_pat(cv, mir_structural_match_violation)
         });
 
-        debug!("const_to_pat: pat={:?}", pat);
+        debug!(?pat);
         pat
     }
 }
@@ -61,6 +59,8 @@ struct ConstToPat<'a, 'tcx> {
     infcx: InferCtxt<'a, 'tcx>,
 
     include_lint_checks: bool,
+
+    treat_byte_string_as_slice: bool,
 }
 
 mod fallback_to_const_ref {
@@ -88,6 +88,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
         span: Span,
         infcx: InferCtxt<'a, 'tcx>,
     ) -> Self {
+        trace!(?pat_ctxt.typeck_results.hir_owner);
         ConstToPat {
             id,
             span,
@@ -97,6 +98,10 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
             saw_const_match_error: Cell::new(false),
             saw_const_match_lint: Cell::new(false),
             behind_reference: Cell::new(false),
+            treat_byte_string_as_slice: pat_ctxt
+                .typeck_results
+                .treat_byte_string_as_slice
+                .contains(&id.local_id),
         }
     }
 
@@ -153,6 +158,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
         cv: &'tcx ty::Const<'tcx>,
         mir_structural_match_violation: bool,
     ) -> Pat<'tcx> {
+        trace!(self.treat_byte_string_as_slice);
         // This method is just a wrapper handling a validity check; the heavy lifting is
         // performed by the recursive `recur` method, which is not meant to be
         // invoked except by this method.
@@ -384,7 +390,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
                     }
                     PatKind::Wild
                 }
-                // `&str` and `&[u8]` are represented as `ConstValue::Slice`, let's keep using this
+                // `&str` is represented as `ConstValue::Slice`, let's keep using this
                 // optimization for now.
                 ty::Str => PatKind::Constant { value: cv },
                 // `b"foo"` produces a `&[u8; 3]`, but you can't use constants of array type when
@@ -393,11 +399,33 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
                 // as slices. This means we turn `&[T; N]` constants into slice patterns, which
                 // has no negative effects on pattern matching, even if we're actually matching on
                 // arrays.
-                ty::Array(..) |
+                ty::Array(..) if !self.treat_byte_string_as_slice => {
+                    let old = self.behind_reference.replace(true);
+                    let array = tcx.deref_const(self.param_env.and(cv));
+                    let val = PatKind::Deref {
+                        subpattern: Pat {
+                            kind: Box::new(PatKind::Array {
+                                prefix: tcx
+                                    .destructure_const(param_env.and(array))
+                                    .fields
+                                    .iter()
+                                    .map(|val| self.recur(val, false))
+                                    .collect::<Result<_, _>>()?,
+                                slice: None,
+                                suffix: vec![],
+                            }),
+                            span,
+                            ty: pointee_ty,
+                        },
+                    };
+                    self.behind_reference.set(old);
+                    val
+                }
+                ty::Array(elem_ty, _) |
                 // Cannot merge this with the catch all branch below, because the `const_deref`
                 // changes the type from slice to array, we need to keep the original type in the
                 // pattern.
-                ty::Slice(..) => {
+                ty::Slice(elem_ty) => {
                     let old = self.behind_reference.replace(true);
                     let array = tcx.deref_const(self.param_env.and(cv));
                     let val = PatKind::Deref {
@@ -413,7 +441,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
                                 suffix: vec![],
                             }),
                             span,
-                            ty: pointee_ty,
+                            ty: tcx.mk_slice(elem_ty),
                         },
                     };
                     self.behind_reference.set(old);
diff --git a/compiler/rustc_typeck/src/check/pat.rs b/compiler/rustc_typeck/src/check/pat.rs
index dd8f4152c7c..a729912126e 100644
--- a/compiler/rustc_typeck/src/check/pat.rs
+++ b/compiler/rustc_typeck/src/check/pat.rs
@@ -149,6 +149,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     ///
     /// Outside of this module, `check_pat_top` should always be used.
     /// Conversely, inside this module, `check_pat_top` should never be used.
+    #[instrument(skip(self, ti))]
     fn check_pat(
         &self,
         pat: &'tcx Pat<'tcx>,
@@ -156,8 +157,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         def_bm: BindingMode,
         ti: TopInfo<'tcx>,
     ) {
-        debug!("check_pat(pat={:?},expected={:?},def_bm={:?})", pat, expected, def_bm);
-
         let path_res = match &pat.kind {
             PatKind::Path(qpath) => Some(self.resolve_ty_and_res_ufcs(qpath, pat.hir_id, pat.span)),
             _ => None,
@@ -398,6 +397,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             if let ty::Ref(_, inner_ty, _) = expected.kind() {
                 if matches!(inner_ty.kind(), ty::Slice(_)) {
                     let tcx = self.tcx;
+                    trace!(?lt.hir_id.local_id, "polymorphic byte string lit");
+                    self.typeck_results
+                        .borrow_mut()
+                        .treat_byte_string_as_slice
+                        .insert(lt.hir_id.local_id);
                     pat_ty = tcx.mk_imm_ref(tcx.lifetimes.re_static, tcx.mk_slice(tcx.types.u8));
                 }
             }
diff --git a/compiler/rustc_typeck/src/check/writeback.rs b/compiler/rustc_typeck/src/check/writeback.rs
index e54e0086483..335f2cc2716 100644
--- a/compiler/rustc_typeck/src/check/writeback.rs
+++ b/compiler/rustc_typeck/src/check/writeback.rs
@@ -70,6 +70,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         debug!("used_trait_imports({:?}) = {:?}", item_def_id, used_trait_imports);
         wbcx.typeck_results.used_trait_imports = used_trait_imports;
 
+        wbcx.typeck_results.treat_byte_string_as_slice =
+            mem::take(&mut self.typeck_results.borrow_mut().treat_byte_string_as_slice);
+
         wbcx.typeck_results.closure_captures =
             mem::take(&mut self.typeck_results.borrow_mut().closure_captures);