Skip to content

Commit 070c5f2

Browse files
authored
Rollup merge of rust-lang#93593 - JulianKnodt:master, r=oli-obk
Fix ret > 1 bound if shadowed by const Prior to a change, it would only look at types in bounds. When it started looking for consts, shadowing type variables with a const would cause an ICE, so now defer looking at consts only if there are no types present. cc `````@compiler-errors````` Should Fix rust-lang#93553
2 parents 2fbf12b + 2dfd77d commit 070c5f2

File tree

4 files changed

+63
-32
lines changed

4 files changed

+63
-32
lines changed

compiler/rustc_middle/src/ty/assoc.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -160,12 +160,11 @@ impl<'tcx> AssocItems<'tcx> {
160160
&self,
161161
tcx: TyCtxt<'_>,
162162
ident: Ident,
163+
// Sorted in order of what kinds to look at
163164
kinds: &[AssocKind],
164165
parent_def_id: DefId,
165166
) -> Option<&ty::AssocItem> {
166-
self.filter_by_name_unhygienic(ident.name)
167-
.filter(|item| kinds.contains(&item.kind))
168-
.find(|item| tcx.hygienic_eq(ident, item.ident(tcx), parent_def_id))
167+
kinds.iter().find_map(|kind| self.find_by_name_and_kind(tcx, ident, *kind, parent_def_id))
169168
}
170169

171170
/// Returns the associated item with the given name in the given `Namespace`, if one exists.

compiler/rustc_typeck/src/astconv/mod.rs

+30-29
Original file line numberDiff line numberDiff line change
@@ -887,15 +887,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
887887
.find_by_name_and_kind(self.tcx(), assoc_name, ty::AssocKind::Type, trait_def_id)
888888
.is_some()
889889
}
890-
fn trait_defines_associated_named(&self, trait_def_id: DefId, assoc_name: Ident) -> bool {
890+
fn trait_defines_associated_const_named(&self, trait_def_id: DefId, assoc_name: Ident) -> bool {
891891
self.tcx()
892892
.associated_items(trait_def_id)
893-
.find_by_name_and_kinds(
894-
self.tcx(),
895-
assoc_name,
896-
&[ty::AssocKind::Type, ty::AssocKind::Const],
897-
trait_def_id,
898-
)
893+
.find_by_name_and_kind(self.tcx(), assoc_name, ty::AssocKind::Const, trait_def_id)
899894
.is_some()
900895
}
901896

@@ -1145,13 +1140,13 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
11451140

11461141
// We have already adjusted the item name above, so compare with `ident.normalize_to_macros_2_0()` instead
11471142
// of calling `filter_by_name_and_kind`.
1148-
let assoc_item = tcx
1149-
.associated_items(candidate.def_id())
1150-
.filter_by_name_unhygienic(assoc_ident.name)
1151-
.find(|i| {
1152-
(i.kind == ty::AssocKind::Type || i.kind == ty::AssocKind::Const)
1153-
&& i.ident(tcx).normalize_to_macros_2_0() == assoc_ident
1154-
})
1143+
let find_item_of_kind = |kind| {
1144+
tcx.associated_items(candidate.def_id())
1145+
.filter_by_name_unhygienic(assoc_ident.name)
1146+
.find(|i| i.kind == kind && i.ident(tcx).normalize_to_macros_2_0() == assoc_ident)
1147+
};
1148+
let assoc_item = find_item_of_kind(ty::AssocKind::Type)
1149+
.or_else(|| find_item_of_kind(ty::AssocKind::Const))
11551150
.expect("missing associated type");
11561151

11571152
if !assoc_item.vis.is_accessible_from(def_scope, tcx) {
@@ -1657,11 +1652,14 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
16571652
I: Iterator<Item = ty::PolyTraitRef<'tcx>>,
16581653
{
16591654
let mut matching_candidates = all_candidates()
1660-
.filter(|r| self.trait_defines_associated_named(r.def_id(), assoc_name));
1661-
1662-
let bound = match matching_candidates.next() {
1663-
Some(bound) => bound,
1664-
None => {
1655+
.filter(|r| self.trait_defines_associated_type_named(r.def_id(), assoc_name));
1656+
let mut const_candidates = all_candidates()
1657+
.filter(|r| self.trait_defines_associated_const_named(r.def_id(), assoc_name));
1658+
1659+
let (bound, next_cand) = match (matching_candidates.next(), const_candidates.next()) {
1660+
(Some(bound), _) => (bound, matching_candidates.next()),
1661+
(None, Some(bound)) => (bound, const_candidates.next()),
1662+
(None, None) => {
16651663
self.complain_about_assoc_type_not_found(
16661664
all_candidates,
16671665
&ty_param_name(),
@@ -1671,10 +1669,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
16711669
return Err(ErrorReported);
16721670
}
16731671
};
1674-
16751672
debug!("one_bound_for_assoc_type: bound = {:?}", bound);
16761673

1677-
if let Some(bound2) = matching_candidates.next() {
1674+
if let Some(bound2) = next_cand {
16781675
debug!("one_bound_for_assoc_type: bound2 = {:?}", bound2);
16791676

16801677
let is_equality = is_equality();
@@ -1759,6 +1756,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
17591756
return Err(ErrorReported);
17601757
}
17611758
}
1759+
17621760
Ok(bound)
17631761
}
17641762

@@ -1893,14 +1891,17 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
18931891

18941892
// We have already adjusted the item name above, so compare with `ident.normalize_to_macros_2_0()` instead
18951893
// of calling `filter_by_name_and_kind`.
1896-
let item = tcx
1897-
.associated_items(trait_did)
1898-
.in_definition_order()
1899-
.find(|i| {
1900-
i.kind.namespace() == Namespace::TypeNS
1901-
&& i.ident(tcx).normalize_to_macros_2_0() == assoc_ident
1902-
})
1903-
.expect("missing associated type");
1894+
let item = tcx.associated_items(trait_did).in_definition_order().find(|i| {
1895+
i.kind.namespace() == Namespace::TypeNS
1896+
&& i.ident(tcx).normalize_to_macros_2_0() == assoc_ident
1897+
});
1898+
// Assume that if it's not matched, there must be a const defined with the same name
1899+
// but it was used in a type position.
1900+
let Some(item) = item else {
1901+
let msg = format!("found associated const `{assoc_ident}` when type was expected");
1902+
tcx.sess.struct_span_err(span, &msg).emit();
1903+
return Err(ErrorReported);
1904+
};
19041905

19051906
let ty = self.projected_ty_from_poly_trait_ref(span, item.def_id, assoc_segment, bound);
19061907
let ty = self.normalize_ty(span, ty);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Checking that none of these ICE, which was introduced in
2+
// https://github.com/rust-lang/rust/issues/93553
3+
trait Foo {
4+
type Bar;
5+
}
6+
7+
trait Baz: Foo {
8+
const Bar: Self::Bar;
9+
}
10+
11+
trait Baz2: Foo {
12+
const Bar: u32;
13+
14+
fn foo() -> Self::Bar;
15+
}
16+
17+
trait Baz3 {
18+
const BAR: usize;
19+
const QUX: Self::BAR;
20+
//~^ ERROR found associated const
21+
}
22+
23+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
error: found associated const `BAR` when type was expected
2+
--> $DIR/shadowed-const.rs:19:14
3+
|
4+
LL | const QUX: Self::BAR;
5+
| ^^^^^^^^^
6+
7+
error: aborting due to previous error
8+

0 commit comments

Comments
 (0)