Auto merge of #67419 - Centril:rollup-v7b0ypv, r=Centril · rust-lang/rust@0de96d3 (original) (raw)
`@@ -1145,11 +1145,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
`
1145
1145
`} else {
`
1146
1146
`// Otherwise, we have to walk through the supertraits to find
`
1147
1147
`// those that do.
`
1148
``
`-
let candidates = traits::supertraits(tcx, trait_ref).filter(|r| {
`
1149
``
`-
self.trait_defines_associated_type_named(r.def_id(), binding.item_name)
`
1150
``
`-
});
`
1151
1148
`self.one_bound_for_assoc_type(
`
1152
``
`-
candidates,
`
``
1149
`+
|| traits::supertraits(tcx, trait_ref),
`
1153
1150
`&trait_ref.print_only_trait_path().to_string(),
`
1154
1151
` binding.item_name,
`
1155
1152
` binding.span
`
`@@ -1531,50 +1528,48 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
`
1531
1528
``
1532
1529
`debug!("find_bound_for_assoc_item: predicates={:#?}", predicates);
`
1533
1530
``
1534
``
`-
let bounds = predicates.iter().filter_map(|(p, _)| p.to_opt_poly_trait_ref());
`
1535
``
-
1536
``
`-
// Check that there is exactly one way to find an associated type with the
`
1537
``
`-
// correct name.
`
1538
``
`-
let suitable_bounds = traits::transitive_bounds(tcx, bounds)
`
1539
``
`-
.filter(|b| self.trait_defines_associated_type_named(b.def_id(), assoc_name));
`
1540
``
-
1541
1531
`let param_hir_id = tcx.hir().as_local_hir_id(ty_param_def_id).unwrap();
`
1542
1532
`let param_name = tcx.hir().ty_param_name(param_hir_id);
`
1543
``
`-
self.one_bound_for_assoc_type(suitable_bounds,
`
1544
``
`-
¶m_name.as_str(),
`
1545
``
`-
assoc_name,
`
1546
``
`-
span)
`
``
1533
`+
self.one_bound_for_assoc_type(
`
``
1534
`+
|| traits::transitive_bounds(tcx, predicates
`
``
1535
`+
.iter().filter_map(|(p, _)| p.to_opt_poly_trait_ref())),
`
``
1536
`+
¶m_name.as_str(),
`
``
1537
`+
assoc_name,
`
``
1538
`+
span,
`
``
1539
`+
)
`
1547
1540
`}
`
1548
1541
``
1549
``
`` -
// Checks that bounds
contains exactly one element and reports appropriate
``
1550
``
`-
// errors otherwise.
`
1551
1542
`fn one_bound_for_assoc_type(&self,
`
1552
``
`-
mut bounds: I,
`
``
1543
`+
all_candidates: impl Fn() -> I,
`
1553
1544
`ty_param_name: &str,
`
1554
1545
`assoc_name: ast::Ident,
`
1555
1546
`span: Span)
`
1556
1547
` -> Result<ty::PolyTraitRef<'tcx>, ErrorReported>
`
1557
1548
`where I: Iterator<Item = ty::PolyTraitRef<'tcx>>
`
1558
1549
`{
`
1559
``
`-
let bound = match bounds.next() {
`
``
1550
`+
let mut matching_candidates = all_candidates().filter(|r| {
`
``
1551
`+
self.trait_defines_associated_type_named(r.def_id(), assoc_name)
`
``
1552
`+
});
`
``
1553
+
``
1554
`+
let bound = match matching_candidates.next() {
`
1560
1555
`Some(bound) => bound,
`
1561
1556
`None => {
`
1562
``
`-
struct_span_err!(self.tcx().sess, span, E0220,
`
1563
``
`` -
"associated type {}
not found for {}
",
``
1564
``
`-
assoc_name,
`
1565
``
`-
ty_param_name)
`
1566
``
`` -
.span_label(span, format!("associated type {}
not found", assoc_name))
``
1567
``
`-
.emit();
`
``
1557
`+
self.complain_about_assoc_type_not_found(
`
``
1558
`+
all_candidates,
`
``
1559
`+
ty_param_name,
`
``
1560
`+
assoc_name,
`
``
1561
`+
span
`
``
1562
`+
);
`
1568
1563
`return Err(ErrorReported);
`
1569
1564
`}
`
1570
1565
`};
`
1571
1566
``
1572
1567
`debug!("one_bound_for_assoc_type: bound = {:?}", bound);
`
1573
1568
``
1574
``
`-
if let Some(bound2) = bounds.next() {
`
``
1569
`+
if let Some(bound2) = matching_candidates.next() {
`
1575
1570
`debug!("one_bound_for_assoc_type: bound2 = {:?}", bound2);
`
1576
1571
``
1577
``
`-
let bounds = iter::once(bound).chain(iter::once(bound2)).chain(bounds);
`
``
1572
`+
let bounds = iter::once(bound).chain(iter::once(bound2)).chain(matching_candidates);
`
1578
1573
`let mut err = struct_span_err!(
`
1579
1574
`self.tcx().sess, span, E0221,
`
1580
1575
`` "ambiguous associated type {}
in bounds of {}
",
``
`@@ -1606,6 +1601,50 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
`
1606
1601
`return Ok(bound);
`
1607
1602
`}
`
1608
1603
``
``
1604
`+
fn complain_about_assoc_type_not_found(&self,
`
``
1605
`+
all_candidates: impl Fn() -> I,
`
``
1606
`+
ty_param_name: &str,
`
``
1607
`+
assoc_name: ast::Ident,
`
``
1608
`+
span: Span)
`
``
1609
`+
where I: Iterator<Item = ty::PolyTraitRef<'tcx>> {
`
``
1610
`+
let mut err = struct_span_err!(self.tcx().sess, span, E0220,
`
``
1611
`` +
"associated type {}
not found for {}
",
``
``
1612
`+
assoc_name,
`
``
1613
`+
ty_param_name);
`
``
1614
+
``
1615
`+
let all_candidate_names: Vec<_> = all_candidates()
`
``
1616
`+
.map(|r| self.tcx().associated_items(r.def_id()))
`
``
1617
`+
.flatten()
`
``
1618
`+
.filter_map(|item|
`
``
1619
`+
if item.kind == ty::AssocKind::Type {
`
``
1620
`+
Some(item.ident.name)
`
``
1621
`+
} else {
`
``
1622
`+
None
`
``
1623
`+
}
`
``
1624
`+
)
`
``
1625
`+
.collect();
`
``
1626
+
``
1627
`+
if let Some(suggested_name) = find_best_match_for_name(
`
``
1628
`+
all_candidate_names.iter(),
`
``
1629
`+
&assoc_name.as_str(),
`
``
1630
`+
None,
`
``
1631
`+
) {
`
``
1632
`+
err.span_suggestion(
`
``
1633
`+
span,
`
``
1634
`+
"there is an associated type with a similar name",
`
``
1635
`+
suggested_name.to_string(),
`
``
1636
`+
Applicability::MaybeIncorrect,
`
``
1637
`+
);
`
``
1638
`+
} else {
`
``
1639
`+
err.span_label(
`
``
1640
`+
span,
`
``
1641
`` +
format!("associated type {}
not found", assoc_name)
``
``
1642
`+
);
`
``
1643
`+
}
`
``
1644
+
``
1645
`+
err.emit();
`
``
1646
`+
}
`
``
1647
+
1609
1648
`// Create a type from a path to an associated type.
`
1610
1649
`` // For a path A::B::C::D
, qself_ty
and qself_def
are the type and def for A::B::C
``
1611
1650
`` // and item_segment is the path segment for D
. We return a type and a def for
``
`@@ -1660,10 +1699,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
`
1660
1699
`}
`
1661
1700
`};
`
1662
1701
``
1663
``
`-
let candidates = traits::supertraits(tcx, ty::Binder::bind(trait_ref))
`
1664
``
`-
.filter(|r| self.trait_defines_associated_type_named(r.def_id(), assoc_ident));
`
1665
``
-
1666
``
`-
self.one_bound_for_assoc_type(candidates, "Self", assoc_ident, span)?
`
``
1702
`+
self.one_bound_for_assoc_type(
`
``
1703
`+
|| traits::supertraits(tcx, ty::Binder::bind(trait_ref)),
`
``
1704
`+
"Self",
`
``
1705
`+
assoc_ident,
`
``
1706
`+
span
`
``
1707
`+
)?
`
1667
1708
`}
`
1668
1709
`(&ty::Param(_), Res::SelfTy(Some(param_did), None)) |
`
1669
1710
`(&ty::Param(_), Res::Def(DefKind::TyParam, param_did)) => {
`