Skip to content

Commit dcb6566

Browse files
Use select in projection lookup
1 parent d2eadb7 commit dcb6566

File tree

3 files changed

+64
-20
lines changed

3 files changed

+64
-20
lines changed

compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs

+24-20
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId};
1515
use rustc_hir::intravisit::Visitor;
1616
use rustc_hir::{self as hir, LangItem, Node};
1717
use rustc_infer::infer::{InferOk, TypeTrace};
18+
use rustc_infer::traits::ImplSource;
1819
use rustc_infer::traits::solve::Goal;
1920
use rustc_middle::traits::SignatureMismatchData;
2021
use rustc_middle::traits::select::OverflowError;
@@ -48,8 +49,8 @@ use crate::infer::{self, InferCtxt, InferCtxtExt as _};
4849
use crate::traits::query::evaluate_obligation::InferCtxtExt as _;
4950
use crate::traits::{
5051
MismatchedProjectionTypes, NormalizeExt, Obligation, ObligationCause, ObligationCauseCode,
51-
ObligationCtxt, Overflow, PredicateObligation, SelectionError, SignatureMismatch,
52-
TraitDynIncompatible, elaborate,
52+
ObligationCtxt, Overflow, PredicateObligation, SelectionContext, SelectionError,
53+
SignatureMismatch, TraitDynIncompatible, elaborate, specialization_graph,
5354
};
5455

5556
impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
@@ -1495,32 +1496,35 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
14951496
}
14961497
}
14971498

1498-
let secondary_span = (|| {
1499+
let secondary_span = self.probe(|_| {
14991500
let ty::PredicateKind::Clause(ty::ClauseKind::Projection(proj)) =
15001501
predicate.kind().skip_binder()
15011502
else {
15021503
return None;
15031504
};
15041505

1505-
let mut associated_items = vec![];
1506-
self.tcx.for_each_relevant_impl(
1507-
self.tcx.trait_of_item(proj.projection_term.def_id)?,
1508-
proj.projection_term.self_ty(),
1509-
|impl_def_id| {
1510-
associated_items.extend(
1511-
self.tcx.associated_items(impl_def_id).in_definition_order().find(
1512-
|assoc| {
1513-
assoc.trait_item_def_id == Some(proj.projection_term.def_id)
1514-
},
1515-
),
1516-
);
1517-
},
1518-
);
1506+
let Ok(Some(ImplSource::UserDefined(impl_data))) = SelectionContext::new(self)
1507+
.poly_select(
1508+
&obligation.with(
1509+
self.tcx,
1510+
predicate.kind().rebind(proj.projection_term.trait_ref(self.tcx)),
1511+
),
1512+
)
1513+
else {
1514+
return None;
1515+
};
15191516

1520-
let [associated_item]: &[ty::AssocItem] = &associated_items[..] else {
1517+
let Ok(node) =
1518+
specialization_graph::assoc_def(self.tcx, impl_data.impl_def_id, proj.def_id())
1519+
else {
15211520
return None;
15221521
};
1523-
match self.tcx.hir_get_if_local(associated_item.def_id) {
1522+
1523+
if !node.is_final() {
1524+
return None;
1525+
}
1526+
1527+
match self.tcx.hir_get_if_local(node.item.def_id) {
15241528
Some(
15251529
hir::Node::TraitItem(hir::TraitItem {
15261530
kind: hir::TraitItemKind::Type(_, Some(ty)),
@@ -1543,7 +1547,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
15431547
)),
15441548
_ => None,
15451549
}
1546-
})();
1550+
});
15471551

15481552
self.note_type_err(
15491553
&mut diag,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
trait Tr {
2+
type Assoc;
3+
}
4+
5+
struct W<T>(T);
6+
7+
impl Tr for W<i32> {
8+
type Assoc = u32;
9+
}
10+
11+
impl Tr for W<u32> {
12+
type Assoc = i32;
13+
}
14+
15+
fn needs_unit<T: Tr<Assoc = ()>>() {}
16+
17+
fn main() {
18+
needs_unit::<W<i32>>();
19+
//~^ ERROR type mismatch resolving `<W<i32> as Tr>::Assoc == ()`
20+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
error[E0271]: type mismatch resolving `<W<i32> as Tr>::Assoc == ()`
2+
--> $DIR/mismatch-two-relevant-impls.rs:18:18
3+
|
4+
LL | needs_unit::<W<i32>>();
5+
| ^^^^^^ type mismatch resolving `<W<i32> as Tr>::Assoc == ()`
6+
|
7+
note: expected this to be `()`
8+
--> $DIR/mismatch-two-relevant-impls.rs:8:18
9+
|
10+
LL | type Assoc = u32;
11+
| ^^^
12+
note: required by a bound in `needs_unit`
13+
--> $DIR/mismatch-two-relevant-impls.rs:15:21
14+
|
15+
LL | fn needs_unit<T: Tr<Assoc = ()>>() {}
16+
| ^^^^^^^^^^ required by this bound in `needs_unit`
17+
18+
error: aborting due to 1 previous error
19+
20+
For more information about this error, try `rustc --explain E0271`.

0 commit comments

Comments
 (0)