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

``

`-

&param_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

`+

&param_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)) => {

`