about summary refs log tree commit diff
path: root/compiler/rustc_const_eval/src
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_const_eval/src')
-rw-r--r--compiler/rustc_const_eval/src/check_consts/mod.rs5
-rw-r--r--compiler/rustc_const_eval/src/const_eval/error.rs23
-rw-r--r--compiler/rustc_const_eval/src/errors.rs27
-rw-r--r--compiler/rustc_const_eval/src/interpret/memory.rs15
-rw-r--r--compiler/rustc_const_eval/src/interpret/stack.rs10
-rw-r--r--compiler/rustc_const_eval/src/interpret/validity.rs2
-rw-r--r--compiler/rustc_const_eval/src/util/check_validity_requirement.rs2
7 files changed, 60 insertions, 24 deletions
diff --git a/compiler/rustc_const_eval/src/check_consts/mod.rs b/compiler/rustc_const_eval/src/check_consts/mod.rs
index 659d4a30456..607cb2e497d 100644
--- a/compiler/rustc_const_eval/src/check_consts/mod.rs
+++ b/compiler/rustc_const_eval/src/check_consts/mod.rs
@@ -94,6 +94,11 @@ pub fn rustc_allow_const_fn_unstable(
 /// world into two functions: those that are safe to expose on stable (and hence may not use
 /// unstable features, not even recursively), and those that are not.
 pub fn is_fn_or_trait_safe_to_expose_on_stable(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
+    // A default body in a `#[const_trait]` is const-stable when the trait is const-stable.
+    if tcx.is_const_default_method(def_id) {
+        return is_fn_or_trait_safe_to_expose_on_stable(tcx, tcx.parent(def_id));
+    }
+
     match tcx.lookup_const_stability(def_id) {
         None => {
             // In a `staged_api` crate, we do enforce recursive const stability for all unmarked
diff --git a/compiler/rustc_const_eval/src/const_eval/error.rs b/compiler/rustc_const_eval/src/const_eval/error.rs
index cc21a18af3a..ffb32fa41eb 100644
--- a/compiler/rustc_const_eval/src/const_eval/error.rs
+++ b/compiler/rustc_const_eval/src/const_eval/error.rs
@@ -48,11 +48,8 @@ impl MachineStopType for ConstEvalErrKind {
             | ModifiedGlobal
             | WriteThroughImmutablePointer => {}
             AssertFailure(kind) => kind.add_args(adder),
-            Panic { msg, line, col, file } => {
-                adder("msg".into(), msg.into_diag_arg());
-                adder("file".into(), file.into_diag_arg());
-                adder("line".into(), line.into_diag_arg());
-                adder("col".into(), col.into_diag_arg());
+            Panic { msg, .. } => {
+                adder("msg".into(), msg.into_diag_arg(&mut None));
             }
         }
     }
@@ -72,7 +69,7 @@ pub fn get_span_and_frames<'tcx>(
     let mut stacktrace = Frame::generate_stacktrace_from_stack(stack);
     // Filter out `requires_caller_location` frames.
     stacktrace.retain(|frame| !frame.instance.def.requires_caller_location(*tcx));
-    let span = stacktrace.first().map(|f| f.span).unwrap_or(tcx.span);
+    let span = stacktrace.last().map(|f| f.span).unwrap_or(tcx.span);
 
     let mut frames = Vec::new();
 
@@ -115,6 +112,20 @@ pub fn get_span_and_frames<'tcx>(
         }
     }
 
+    // In `rustc`, we present const-eval errors from the outer-most place first to the inner-most.
+    // So we reverse the frames here. The first frame will be the same as the span from the current
+    // `TyCtxtAt<'_>`, so we remove it as it would be redundant.
+    frames.reverse();
+    if frames.len() > 0 {
+        frames.remove(0);
+    }
+    if let Some(last) = frames.last_mut()
+        // If the span is not going to be printed, we don't want the span label for `is_last`.
+        && tcx.sess.source_map().span_to_snippet(last.span.source_callsite()).is_ok()
+    {
+        last.has_label = true;
+    }
+
     (span, frames)
 }
 
diff --git a/compiler/rustc_const_eval/src/errors.rs b/compiler/rustc_const_eval/src/errors.rs
index c08495c012f..b020eeccf71 100644
--- a/compiler/rustc_const_eval/src/errors.rs
+++ b/compiler/rustc_const_eval/src/errors.rs
@@ -6,6 +6,7 @@ use rustc_abi::WrappingRange;
 use rustc_errors::codes::*;
 use rustc_errors::{
     Diag, DiagArgValue, DiagCtxtHandle, DiagMessage, Diagnostic, EmissionGuarantee, Level,
+    MultiSpan, SubdiagMessageOp, Subdiagnostic,
 };
 use rustc_hir::ConstContext;
 use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
@@ -17,6 +18,7 @@ use rustc_middle::mir::interpret::{
 use rustc_middle::ty::{self, Mutability, Ty};
 use rustc_span::{Span, Symbol};
 
+use crate::fluent_generated as fluent;
 use crate::interpret::InternKind;
 
 #[derive(Diagnostic)]
@@ -278,14 +280,31 @@ pub(crate) struct NonConstImplNote {
     pub span: Span,
 }
 
-#[derive(Subdiagnostic, Clone)]
-#[note(const_eval_frame_note)]
+#[derive(Clone)]
 pub struct FrameNote {
-    #[primary_span]
     pub span: Span,
     pub times: i32,
     pub where_: &'static str,
     pub instance: String,
+    pub has_label: bool,
+}
+
+impl Subdiagnostic for FrameNote {
+    fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
+        self,
+        diag: &mut Diag<'_, G>,
+        f: &F,
+    ) {
+        diag.arg("times", self.times);
+        diag.arg("where_", self.where_);
+        diag.arg("instance", self.instance);
+        let mut span: MultiSpan = self.span.into();
+        if self.has_label && !self.span.is_dummy() {
+            span.push_span_label(self.span, fluent::const_eval_frame_note_last);
+        }
+        let msg = f(diag, fluent::const_eval_frame_note.into());
+        diag.span_note(span, msg);
+    }
 }
 
 #[derive(Subdiagnostic)]
@@ -967,7 +986,7 @@ impl ReportErrorExt for ResourceExhaustionInfo {
 }
 
 impl rustc_errors::IntoDiagArg for InternKind {
-    fn into_diag_arg(self) -> DiagArgValue {
+    fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
         DiagArgValue::Str(Cow::Borrowed(match self {
             InternKind::Static(Mutability::Not) => "static",
             InternKind::Static(Mutability::Mut) => "static_mut",
diff --git a/compiler/rustc_const_eval/src/interpret/memory.rs b/compiler/rustc_const_eval/src/interpret/memory.rs
index 4f4b6785844..ce0b5a350e0 100644
--- a/compiler/rustc_const_eval/src/interpret/memory.rs
+++ b/compiler/rustc_const_eval/src/interpret/memory.rs
@@ -955,18 +955,13 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
 
     /// Handle the effect an FFI call might have on the state of allocations.
     /// This overapproximates the modifications which external code might make to memory:
-    /// We set all reachable allocations as initialized, mark all provenances as exposed
+    /// We set all reachable allocations as initialized, mark all reachable provenances as exposed
     /// and overwrite them with `Provenance::WILDCARD`.
-    pub fn prepare_for_native_call(
-        &mut self,
-        id: AllocId,
-        initial_prov: M::Provenance,
-    ) -> InterpResult<'tcx> {
-        // Expose provenance of the root allocation.
-        M::expose_provenance(self, initial_prov)?;
-
+    ///
+    /// The allocations in `ids` are assumed to be already exposed.
+    pub fn prepare_for_native_call(&mut self, ids: Vec<AllocId>) -> InterpResult<'tcx> {
         let mut done = FxHashSet::default();
-        let mut todo = vec![id];
+        let mut todo = ids;
         while let Some(id) = todo.pop() {
             if !done.insert(id) {
                 // We already saw this allocation before, don't process it again.
diff --git a/compiler/rustc_const_eval/src/interpret/stack.rs b/compiler/rustc_const_eval/src/interpret/stack.rs
index 7d0e0492792..d7b03776bc4 100644
--- a/compiler/rustc_const_eval/src/interpret/stack.rs
+++ b/compiler/rustc_const_eval/src/interpret/stack.rs
@@ -231,13 +231,19 @@ impl<'tcx> FrameInfo<'tcx> {
     pub fn as_note(&self, tcx: TyCtxt<'tcx>) -> errors::FrameNote {
         let span = self.span;
         if tcx.def_key(self.instance.def_id()).disambiguated_data.data == DefPathData::Closure {
-            errors::FrameNote { where_: "closure", span, instance: String::new(), times: 0 }
+            errors::FrameNote {
+                where_: "closure",
+                span,
+                instance: String::new(),
+                times: 0,
+                has_label: false,
+            }
         } else {
             let instance = format!("{}", self.instance);
             // Note: this triggers a `must_produce_diag` state, which means that if we ever get
             // here we must emit a diagnostic. We should never display a `FrameInfo` unless we
             // actually want to emit a warning or error to the user.
-            errors::FrameNote { where_: "instance", span, instance, times: 0 }
+            errors::FrameNote { where_: "instance", span, instance, times: 0, has_label: false }
         }
     }
 }
diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs
index 40dec0cb39e..eb3f552cd27 100644
--- a/compiler/rustc_const_eval/src/interpret/validity.rs
+++ b/compiler/rustc_const_eval/src/interpret/validity.rs
@@ -1296,7 +1296,7 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValueVisitor<'tcx, M> for ValidityVisitor<'rt,
                     self.visit_scalar(b, b_layout)?;
                 }
             }
-            BackendRepr::Vector { .. } => {
+            BackendRepr::SimdVector { .. } => {
                 // No checks here, we assume layout computation gets this right.
                 // (This is harder to check since Miri does not represent these as `Immediate`. We
                 // also cannot use field projections since this might be a newtype around a vector.)
diff --git a/compiler/rustc_const_eval/src/util/check_validity_requirement.rs b/compiler/rustc_const_eval/src/util/check_validity_requirement.rs
index 6426bca2332..d7e97f32bae 100644
--- a/compiler/rustc_const_eval/src/util/check_validity_requirement.rs
+++ b/compiler/rustc_const_eval/src/util/check_validity_requirement.rs
@@ -117,7 +117,7 @@ fn check_validity_requirement_lax<'tcx>(
             BackendRepr::ScalarPair(s1, s2) => {
                 scalar_allows_raw_init(s1) && scalar_allows_raw_init(s2)
             }
-            BackendRepr::Vector { element: s, count } => count == 0 || scalar_allows_raw_init(s),
+            BackendRepr::SimdVector { element: s, count } => count == 0 || scalar_allows_raw_init(s),
             BackendRepr::Memory { .. } => true, // Fields are checked below.
         };
     if !valid {