about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBastian Kauschke <bastian_kauschke@hotmail.de>2020-09-22 11:36:54 +0200
committerBastian Kauschke <bastian_kauschke@hotmail.de>2020-09-24 09:04:23 +0200
commitb8402d6a6e6cadd3d877c952a2c5bbd694afbc2d (patch)
treead616505fa0d6e76f9b766bd6ebd1c3d36e7c407
parentf8d3f401df47cf680180c357fabdc8c76c2a08ab (diff)
downloadrust-b8402d6a6e6cadd3d877c952a2c5bbd694afbc2d.tar.gz
rust-b8402d6a6e6cadd3d877c952a2c5bbd694afbc2d.zip
assign the correct `DefId` in `nominal_obligations`
-rw-r--r--compiler/rustc_trait_selection/src/traits/wf.rs20
-rw-r--r--src/test/ui/const-generics/const_evaluatable_checked/cross_crate_predicate.stderr4
-rw-r--r--src/test/ui/const-generics/const_evaluatable_checked/let-bindings.stderr2
3 files changed, 19 insertions, 7 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs
index 998990f374c..909cd2aa155 100644
--- a/compiler/rustc_trait_selection/src/traits/wf.rs
+++ b/compiler/rustc_trait_selection/src/traits/wf.rs
@@ -7,8 +7,9 @@ use rustc_hir::lang_items::LangItem;
 use rustc_middle::ty::subst::{GenericArg, GenericArgKind, SubstsRef};
 use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness};
 use rustc_span::Span;
-use std::rc::Rc;
 
+use std::iter;
+use std::rc::Rc;
 /// Returns the set of obligations needed to make `arg` well-formed.
 /// If `arg` contains unresolved inference variables, this may include
 /// further WF obligations. However, if `arg` IS an unresolved
@@ -616,13 +617,24 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
         def_id: DefId,
         substs: SubstsRef<'tcx>,
     ) -> Vec<traits::PredicateObligation<'tcx>> {
-        let predicates = self.infcx.tcx.predicates_of(def_id).instantiate(self.infcx.tcx, substs);
+        let predicates = self.infcx.tcx.predicates_of(def_id);
+        let mut origins = vec![def_id; predicates.predicates.len()];
+        let mut head = predicates;
+        while let Some(parent) = head.parent {
+            head = self.infcx.tcx.predicates_of(parent);
+            origins.extend(iter::repeat(parent).take(head.predicates.len()));
+        }
+
+        let predicates = predicates.instantiate(self.infcx.tcx, substs);
+        debug_assert_eq!(predicates.predicates.len(), origins.len());
+
         predicates
             .predicates
             .into_iter()
             .zip(predicates.spans.into_iter())
-            .map(|(pred, span)| {
-                let cause = self.cause(traits::BindingObligation(def_id, span));
+            .zip(origins.into_iter().rev())
+            .map(|((pred, span), origin_def_id)| {
+                let cause = self.cause(traits::BindingObligation(origin_def_id, span));
                 traits::Obligation::new(cause, self.param_env, pred)
             })
             .filter(|pred| !pred.has_escaping_bound_vars())
diff --git a/src/test/ui/const-generics/const_evaluatable_checked/cross_crate_predicate.stderr b/src/test/ui/const-generics/const_evaluatable_checked/cross_crate_predicate.stderr
index e7da191e670..4af68118be3 100644
--- a/src/test/ui/const-generics/const_evaluatable_checked/cross_crate_predicate.stderr
+++ b/src/test/ui/const-generics/const_evaluatable_checked/cross_crate_predicate.stderr
@@ -33,7 +33,7 @@ LL |     let _ = const_evaluatable_lib::test1::<T>();
   ::: $DIR/auxiliary/const_evaluatable_lib.rs:6:10
    |
 LL |     [u8; std::mem::size_of::<T>() - 1]: Sized,
-   |          ---------------------------- required by this bound in `test1::{{constant}}#1`
+   |          ---------------------------- required by this bound in `test1`
    |
    = note: this may fail depending on what value the parameter takes
 
@@ -46,7 +46,7 @@ LL |     let _ = const_evaluatable_lib::test1::<T>();
   ::: $DIR/auxiliary/const_evaluatable_lib.rs:4:27
    |
 LL | pub fn test1<T>() -> [u8; std::mem::size_of::<T>() - 1]
-   |                           ---------------------------- required by this bound in `test1::{{constant}}#1`
+   |                           ---------------------------- required by this bound in `test1`
    |
    = note: this may fail depending on what value the parameter takes
 
diff --git a/src/test/ui/const-generics/const_evaluatable_checked/let-bindings.stderr b/src/test/ui/const-generics/const_evaluatable_checked/let-bindings.stderr
index b76e300663d..dd27b81ee03 100644
--- a/src/test/ui/const-generics/const_evaluatable_checked/let-bindings.stderr
+++ b/src/test/ui/const-generics/const_evaluatable_checked/let-bindings.stderr
@@ -2,7 +2,7 @@ error: constant expression depends on a generic parameter
   --> $DIR/let-bindings.rs:6:68
    |
 LL | fn test<const N: usize>() -> [u8; { let x = N; N + 1 }] where [u8; { let x = N; N + 1 }]: Default {
-   |                                                                    ^^^^^^^^^^^^^^^^^^^^ required by this bound in `test::{{constant}}#0`
+   |                                                                    ^^^^^^^^^^^^^^^^^^^^ required by this bound in `test`
    |
    = help: consider moving this anonymous constant into a `const` function