Skip to content

Commit 78fb74a

Browse files
committed
Fix w/ comments
1 parent c654e4d commit 78fb74a

40 files changed

+281
-199
lines changed

compiler/rustc_hir/src/hir.rs

+6
Original file line numberDiff line numberDiff line change
@@ -2165,6 +2165,12 @@ impl TypeBinding<'_> {
21652165
_ => panic!("expected equality type binding for parenthesized generic args"),
21662166
}
21672167
}
2168+
pub fn opt_const(&self) -> Option<&'_ AnonConst> {
2169+
match self.kind {
2170+
TypeBindingKind::Equality { term: Term::Const(ref c) } => Some(c),
2171+
_ => None,
2172+
}
2173+
}
21682174
}
21692175

21702176
#[derive(Debug)]

compiler/rustc_infer/src/infer/at.rs

+10-2
Original file line numberDiff line numberDiff line change
@@ -288,13 +288,21 @@ impl<'tcx> ToTrace<'tcx> for &'tcx Const<'tcx> {
288288

289289
impl<'tcx> ToTrace<'tcx> for ty::Term<'tcx> {
290290
fn to_trace(
291-
_: TyCtxt<'tcx>,
291+
tcx: TyCtxt<'tcx>,
292292
cause: &ObligationCause<'tcx>,
293293
a_is_expected: bool,
294294
a: Self,
295295
b: Self,
296296
) -> TypeTrace<'tcx> {
297-
TypeTrace { cause: cause.clone(), values: Terms(ExpectedFound::new(a_is_expected, a, b)) }
297+
match (a, b) {
298+
(ty::Term::Ty(a), ty::Term::Ty(b)) => {
299+
ToTrace::to_trace(tcx, cause, a_is_expected, a, b)
300+
}
301+
(ty::Term::Const(a), ty::Term::Const(b)) => {
302+
ToTrace::to_trace(tcx, cause, a_is_expected, a, b)
303+
}
304+
(_, _) => todo!(),
305+
}
298306
}
299307
}
300308

compiler/rustc_infer/src/infer/error_reporting/mod.rs

-1
Original file line numberDiff line numberDiff line change
@@ -2127,7 +2127,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
21272127
infer::Types(exp_found) => self.expected_found_str_ty(exp_found),
21282128
infer::Regions(exp_found) => self.expected_found_str(exp_found),
21292129
infer::Consts(exp_found) => self.expected_found_str(exp_found),
2130-
infer::Terms(exp_found) => self.expected_found_str(exp_found),
21312130
infer::TraitRefs(exp_found) => {
21322131
let pretty_exp_found = ty::error::ExpectedFound {
21332132
expected: exp_found.expected.print_only_trait_path(),

compiler/rustc_infer/src/infer/mod.rs

-1
Original file line numberDiff line numberDiff line change
@@ -371,7 +371,6 @@ pub enum ValuePairs<'tcx> {
371371
Types(ExpectedFound<Ty<'tcx>>),
372372
Regions(ExpectedFound<ty::Region<'tcx>>),
373373
Consts(ExpectedFound<&'tcx ty::Const<'tcx>>),
374-
Terms(ExpectedFound<ty::Term<'tcx>>),
375374
TraitRefs(ExpectedFound<ty::TraitRef<'tcx>>),
376375
PolyTraitRefs(ExpectedFound<ty::PolyTraitRef<'tcx>>),
377376
}

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

+20-5
Original file line numberDiff line numberDiff line change
@@ -1356,11 +1356,26 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
13561356
normalized_ty,
13571357
data.term,
13581358
) {
1359-
values = Some(infer::ValuePairs::Terms(ExpectedFound::new(
1360-
is_normalized_ty_expected,
1361-
normalized_ty,
1362-
data.term,
1363-
)));
1359+
values = Some(match (normalized_ty, data.term) {
1360+
(ty::Term::Ty(normalized_ty), ty::Term::Ty(ty)) => {
1361+
infer::ValuePairs::Types(ExpectedFound::new(
1362+
is_normalized_ty_expected,
1363+
normalized_ty,
1364+
ty,
1365+
))
1366+
}
1367+
(ty::Term::Const(normalized_ct), ty::Term::Const(ct)) => {
1368+
infer::ValuePairs::Consts(ExpectedFound::new(
1369+
is_normalized_ty_expected,
1370+
normalized_ct,
1371+
ct,
1372+
))
1373+
}
1374+
(_, _) => span_bug!(
1375+
obligation.cause.span,
1376+
"found const or type where other expected"
1377+
),
1378+
});
13641379
err_buf = error;
13651380
err = &err_buf;
13661381
}

compiler/rustc_trait_selection/src/traits/project.rs

+27-54
Original file line numberDiff line numberDiff line change
@@ -199,61 +199,30 @@ fn project_and_unify_type<'cx, 'tcx>(
199199
let mut obligations = vec![];
200200

201201
let infcx = selcx.infcx();
202-
match obligation.predicate.term {
203-
ty::Term::Ty(obligation_pred_ty) => {
204-
let normalized_ty = match opt_normalize_projection_type(
205-
selcx,
206-
obligation.param_env,
207-
obligation.predicate.projection_ty,
208-
obligation.cause.clone(),
209-
obligation.recursion_depth,
210-
&mut obligations,
211-
) {
212-
Ok(Some(n)) => n.ty().unwrap(),
213-
Ok(None) => return Ok(Ok(None)),
214-
Err(InProgress) => return Ok(Err(InProgress)),
215-
};
216-
debug!(?normalized_ty, ?obligations, "project_and_unify_type result");
217-
match infcx
218-
.at(&obligation.cause, obligation.param_env)
219-
.eq(normalized_ty, obligation_pred_ty)
220-
{
221-
Ok(InferOk { obligations: inferred_obligations, value: () }) => {
222-
obligations.extend(inferred_obligations);
223-
Ok(Ok(Some(obligations)))
224-
}
225-
Err(err) => {
226-
debug!("project_and_unify_type: equating types encountered error {:?}", err);
227-
Err(MismatchedProjectionTypes { err })
228-
}
229-
}
202+
let normalized = match opt_normalize_projection_type(
203+
selcx,
204+
obligation.param_env,
205+
obligation.predicate.projection_ty,
206+
obligation.cause.clone(),
207+
obligation.recursion_depth,
208+
&mut obligations,
209+
) {
210+
Ok(Some(n)) => n,
211+
Ok(None) => return Ok(Ok(None)),
212+
Err(InProgress) => return Ok(Err(InProgress)),
213+
};
214+
debug!(?normalized, ?obligations, "project_and_unify_type result");
215+
match infcx
216+
.at(&obligation.cause, obligation.param_env)
217+
.eq(normalized, obligation.predicate.term)
218+
{
219+
Ok(InferOk { obligations: inferred_obligations, value: () }) => {
220+
obligations.extend(inferred_obligations);
221+
Ok(Ok(Some(obligations)))
230222
}
231-
ty::Term::Const(obligation_pred_const) => {
232-
let normalized_const = match opt_normalize_projection_type(
233-
selcx,
234-
obligation.param_env,
235-
obligation.predicate.projection_ty,
236-
obligation.cause.clone(),
237-
obligation.recursion_depth,
238-
&mut obligations,
239-
) {
240-
Ok(Some(n)) => n.ct().unwrap(),
241-
Ok(None) => return Ok(Ok(None)),
242-
Err(InProgress) => return Ok(Err(InProgress)),
243-
};
244-
match infcx
245-
.at(&obligation.cause, obligation.param_env)
246-
.eq(normalized_const, obligation_pred_const)
247-
{
248-
Ok(InferOk { obligations: inferred_obligations, value: () }) => {
249-
obligations.extend(inferred_obligations);
250-
Ok(Ok(Some(obligations)))
251-
}
252-
Err(err) => {
253-
debug!("project_and_unify_type: equating consts encountered error {:?}", err);
254-
Err(MismatchedProjectionTypes { err })
255-
}
256-
}
223+
Err(err) => {
224+
debug!("project_and_unify_type: equating types encountered error {:?}", err);
225+
Err(MismatchedProjectionTypes { err })
257226
}
258227
}
259228
}
@@ -934,6 +903,8 @@ fn opt_normalize_projection_type<'a, 'b, 'tcx>(
934903
// created (and hence the new ones will quickly be
935904
// discarded as duplicated). But when doing trait
936905
// evaluation this is not the case, and dropping the trait
906+
// evaluations can causes ICEs (e.g., #43132).
907+
debug!(?ty, "found normalized ty");
937908
obligations.extend(ty.obligations);
938909
return Ok(Some(ty.value));
939910
}
@@ -1127,6 +1098,8 @@ fn project<'cx, 'tcx>(
11271098
Ok(Projected::Progress(confirm_candidate(selcx, obligation, candidate)))
11281099
}
11291100
ProjectionCandidateSet::None => Ok(Projected::NoProgress(
1101+
// FIXME(associated_const_generics): this may need to change in the future?
1102+
// need to investigate whether or not this is fine.
11301103
selcx
11311104
.tcx()
11321105
.mk_projection(obligation.predicate.item_def_id, obligation.predicate.substs)

compiler/rustc_typeck/src/astconv/mod.rs

+9-3
Original file line numberDiff line numberDiff line change
@@ -1244,17 +1244,23 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
12441244
// the "projection predicate" for:
12451245
//
12461246
// `<T as Iterator>::Item = u32`
1247-
let def_kind = tcx.def_kind(projection_ty.skip_binder().item_def_id);
1247+
let assoc_item_def_id = projection_ty.skip_binder().item_def_id;
1248+
let def_kind = tcx.def_kind(assoc_item_def_id);
12481249
match (def_kind, term) {
12491250
(hir::def::DefKind::AssocTy, ty::Term::Ty(_))
12501251
| (hir::def::DefKind::AssocConst, ty::Term::Const(_)) => (),
12511252
(_, _) => {
1253+
let got = if let ty::Term::Ty(_) = term { "type" } else { "const" };
1254+
let expected = def_kind.descr(assoc_item_def_id);
12521255
tcx.sess
12531256
.struct_span_err(
12541257
binding.span,
1255-
"type/const mismatch in equality bind of associated field",
1258+
&format!("mismatch in bind of {expected}, got {got}"),
1259+
)
1260+
.span_note(
1261+
tcx.def_span(assoc_item_def_id),
1262+
&format!("{expected} defined here does not match {got}"),
12561263
)
1257-
.span_label(binding.span, "type/const Mismatch")
12581264
.emit();
12591265
}
12601266
}

compiler/rustc_typeck/src/collect/type_of.rs

+20-44
Original file line numberDiff line numberDiff line change
@@ -161,40 +161,26 @@ pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<
161161
// We've encountered an `AnonConst` in some path, so we need to
162162
// figure out which generic parameter it corresponds to and return
163163
// the relevant type.
164-
let filtered = path
165-
.segments
166-
.iter()
167-
.filter_map(|seg| seg.args.map(|args| (args.args, seg)))
168-
.find_map(|(args, seg)| {
169-
args.iter()
170-
.filter(|arg| arg.is_ty_or_const())
171-
.position(|arg| arg.id() == hir_id)
172-
.map(|index| (index, seg))
173-
});
174-
// FIXME(associated_const_equality): recursively search through the bindings instead
175-
// of just top level.
164+
let filtered = path.segments.iter().find_map(|seg| {
165+
seg.args?
166+
.args
167+
.iter()
168+
.filter(|arg| arg.is_ty_or_const())
169+
.position(|arg| arg.id() == hir_id)
170+
.map(|index| (index, seg))
171+
});
176172

173+
// FIXME(associated_const_generics): can we blend this with iteration above?
177174
let (arg_index, segment) = match filtered {
178175
None => {
179-
let binding_filtered = path
180-
.segments
181-
.iter()
182-
.filter_map(|seg| seg.args.map(|args| (args.bindings, seg)))
183-
.find_map(|(bindings, seg)| {
184-
bindings
185-
.iter()
186-
.filter_map(|binding| {
187-
if let hir::TypeBindingKind::Equality { term: Term::Const(c) } =
188-
binding.kind
189-
{
190-
Some(c)
191-
} else {
192-
None
193-
}
194-
})
195-
.position(|ct| ct.hir_id == hir_id)
196-
.map(|idx| (idx, seg))
197-
});
176+
let binding_filtered = path.segments.iter().find_map(|seg| {
177+
seg.args?
178+
.bindings
179+
.iter()
180+
.filter_map(TypeBinding::opt_const)
181+
.position(|ct| ct.hir_id == hir_id)
182+
.map(|idx| (idx, seg))
183+
});
198184
match binding_filtered {
199185
Some(inner) => inner,
200186
None => {
@@ -518,20 +504,10 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
518504
path
519505
.segments
520506
.iter()
521-
.filter_map(|seg| seg.args.map(|args| (args.bindings, seg)))
522-
.find_map(|(bindings, seg)| {
523-
bindings
507+
.find_map(|seg| {
508+
seg.args?.bindings
524509
.iter()
525-
.filter_map(|binding| {
526-
if let hir::TypeBindingKind::Equality { term: Term::Const(c) } =
527-
binding.kind
528-
{
529-
Some((binding, c))
530-
} else {
531-
None
532-
}
533-
})
534-
.find_map(|(binding, ct)| if ct.hir_id == hir_id {
510+
.find_map(|binding| if binding.opt_const()?.hir_id == hir_id {
535511
Some((binding, seg))
536512
} else {
537513
None
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#![feature(associated_const_equality)]
2+
#![allow(unused)]
3+
4+
pub trait Foo {
5+
const N: usize;
6+
}
7+
8+
pub struct Bar;
9+
10+
impl Foo for Bar {
11+
const N: usize = 3;
12+
}
13+
14+
15+
fn foo1<F: Foo<Z=3>>() {}
16+
//~^ ERROR associated type
17+
fn foo2<F: Foo<Z=usize>>() {}
18+
//~^ ERROR associated type
19+
fn foo3<F: Foo<Z=5>>() {}
20+
//~^ ERROR associated type
21+
22+
fn main() {
23+
foo1::<Bar>();
24+
foo2::<Bar>();
25+
foo3::<Bar>();
26+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
error[E0220]: associated type `Z` not found for `Foo`
2+
--> $DIR/assoc-const-eq-missing.rs:15:16
3+
|
4+
LL | fn foo1<F: Foo<Z=3>>() {}
5+
| ^ associated type `Z` not found
6+
7+
error[E0220]: associated type `Z` not found for `Foo`
8+
--> $DIR/assoc-const-eq-missing.rs:17:16
9+
|
10+
LL | fn foo2<F: Foo<Z=usize>>() {}
11+
| ^ associated type `Z` not found
12+
13+
error[E0220]: associated type `Z` not found for `Foo`
14+
--> $DIR/assoc-const-eq-missing.rs:19:16
15+
|
16+
LL | fn foo3<F: Foo<Z=5>>() {}
17+
| ^ associated type `Z` not found
18+
19+
error: aborting due to 3 previous errors
20+
21+
For more information about this error, try `rustc --explain E0220`.

src/test/ui/associated-consts/assoc-const-ty-mismatch.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@ impl FooTy for Bar {
2121

2222

2323
fn foo<F: Foo<N=usize>>() {}
24-
//~^ ERROR type/const mismatch
24+
//~^ ERROR mismatch in
2525
fn foo2<F: FooTy<T=3usize>>() {}
26-
//~^ ERROR type/const mismatch
26+
//~^ ERROR mismatch in
2727

2828
fn main() {
2929
foo::<Bar>();
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,26 @@
1-
error: type/const mismatch in equality bind of associated field
1+
error: mismatch in bind of associated constant, got type
22
--> $DIR/assoc-const-ty-mismatch.rs:23:15
33
|
44
LL | fn foo<F: Foo<N=usize>>() {}
5-
| ^^^^^^^ type/const Mismatch
5+
| ^^^^^^^
6+
|
7+
note: associated constant defined here does not match type
8+
--> $DIR/assoc-const-ty-mismatch.rs:5:3
9+
|
10+
LL | const N: usize;
11+
| ^^^^^^^^^^^^^^^
612

7-
error: type/const mismatch in equality bind of associated field
13+
error: mismatch in bind of associated type, got const
814
--> $DIR/assoc-const-ty-mismatch.rs:25:18
915
|
1016
LL | fn foo2<F: FooTy<T=3usize>>() {}
11-
| ^^^^^^^^ type/const Mismatch
17+
| ^^^^^^^^
18+
|
19+
note: associated type defined here does not match const
20+
--> $DIR/assoc-const-ty-mismatch.rs:9:3
21+
|
22+
LL | type T;
23+
| ^^^^^^^
1224

1325
error: aborting due to 2 previous errors
1426

0 commit comments

Comments
 (0)