diff options
| author | Bastian Kauschke <bastian_kauschke@hotmail.de> | 2020-09-22 11:36:54 +0200 |
|---|---|---|
| committer | Bastian Kauschke <bastian_kauschke@hotmail.de> | 2020-09-24 09:04:23 +0200 |
| commit | b8402d6a6e6cadd3d877c952a2c5bbd694afbc2d (patch) | |
| tree | ad616505fa0d6e76f9b766bd6ebd1c3d36e7c407 | |
| parent | f8d3f401df47cf680180c357fabdc8c76c2a08ab (diff) | |
| download | rust-b8402d6a6e6cadd3d877c952a2c5bbd694afbc2d.tar.gz rust-b8402d6a6e6cadd3d877c952a2c5bbd694afbc2d.zip | |
assign the correct `DefId` in `nominal_obligations`
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 |
