Skip to content

Commit b8402d6

Browse files
committed
assign the correct DefId in nominal_obligations
1 parent f8d3f40 commit b8402d6

File tree

3 files changed

+19
-7
lines changed

3 files changed

+19
-7
lines changed

compiler/rustc_trait_selection/src/traits/wf.rs

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,9 @@ use rustc_hir::lang_items::LangItem;
77
use rustc_middle::ty::subst::{GenericArg, GenericArgKind, SubstsRef};
88
use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness};
99
use rustc_span::Span;
10-
use std::rc::Rc;
1110

11+
use std::iter;
12+
use std::rc::Rc;
1213
/// Returns the set of obligations needed to make `arg` well-formed.
1314
/// If `arg` contains unresolved inference variables, this may include
1415
/// further WF obligations. However, if `arg` IS an unresolved
@@ -616,13 +617,24 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
616617
def_id: DefId,
617618
substs: SubstsRef<'tcx>,
618619
) -> Vec<traits::PredicateObligation<'tcx>> {
619-
let predicates = self.infcx.tcx.predicates_of(def_id).instantiate(self.infcx.tcx, substs);
620+
let predicates = self.infcx.tcx.predicates_of(def_id);
621+
let mut origins = vec![def_id; predicates.predicates.len()];
622+
let mut head = predicates;
623+
while let Some(parent) = head.parent {
624+
head = self.infcx.tcx.predicates_of(parent);
625+
origins.extend(iter::repeat(parent).take(head.predicates.len()));
626+
}
627+
628+
let predicates = predicates.instantiate(self.infcx.tcx, substs);
629+
debug_assert_eq!(predicates.predicates.len(), origins.len());
630+
620631
predicates
621632
.predicates
622633
.into_iter()
623634
.zip(predicates.spans.into_iter())
624-
.map(|(pred, span)| {
625-
let cause = self.cause(traits::BindingObligation(def_id, span));
635+
.zip(origins.into_iter().rev())
636+
.map(|((pred, span), origin_def_id)| {
637+
let cause = self.cause(traits::BindingObligation(origin_def_id, span));
626638
traits::Obligation::new(cause, self.param_env, pred)
627639
})
628640
.filter(|pred| !pred.has_escaping_bound_vars())

src/test/ui/const-generics/const_evaluatable_checked/cross_crate_predicate.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ LL | let _ = const_evaluatable_lib::test1::<T>();
3333
::: $DIR/auxiliary/const_evaluatable_lib.rs:6:10
3434
|
3535
LL | [u8; std::mem::size_of::<T>() - 1]: Sized,
36-
| ---------------------------- required by this bound in `test1::{{constant}}#1`
36+
| ---------------------------- required by this bound in `test1`
3737
|
3838
= note: this may fail depending on what value the parameter takes
3939

@@ -46,7 +46,7 @@ LL | let _ = const_evaluatable_lib::test1::<T>();
4646
::: $DIR/auxiliary/const_evaluatable_lib.rs:4:27
4747
|
4848
LL | pub fn test1<T>() -> [u8; std::mem::size_of::<T>() - 1]
49-
| ---------------------------- required by this bound in `test1::{{constant}}#1`
49+
| ---------------------------- required by this bound in `test1`
5050
|
5151
= note: this may fail depending on what value the parameter takes
5252

src/test/ui/const-generics/const_evaluatable_checked/let-bindings.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error: constant expression depends on a generic parameter
22
--> $DIR/let-bindings.rs:6:68
33
|
44
LL | fn test<const N: usize>() -> [u8; { let x = N; N + 1 }] where [u8; { let x = N; N + 1 }]: Default {
5-
| ^^^^^^^^^^^^^^^^^^^^ required by this bound in `test::{{constant}}#0`
5+
| ^^^^^^^^^^^^^^^^^^^^ required by this bound in `test`
66
|
77
= help: consider moving this anonymous constant into a `const` function
88

0 commit comments

Comments
 (0)