Skip to content

Commit c654e4d

Browse files
committed
Add ValuePairs::Terms & Fix compile error
And use correct substs.
1 parent bd03d81 commit c654e4d

38 files changed

+143
-181
lines changed

compiler/rustc_infer/src/infer/at.rs

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

289289
impl<'tcx> ToTrace<'tcx> for ty::Term<'tcx> {
290290
fn to_trace(
291-
tcx: TyCtxt<'tcx>,
291+
_: TyCtxt<'tcx>,
292292
cause: &ObligationCause<'tcx>,
293293
a_is_expected: bool,
294294
a: Self,
295295
b: Self,
296296
) -> TypeTrace<'tcx> {
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-
(_, _) => span_bug!(cause.span, "Unexpected type/const mismatch"),
305-
}
297+
TypeTrace { cause: cause.clone(), values: Terms(ExpectedFound::new(a_is_expected, a, b)) }
306298
}
307299
}
308300

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

+1
Original file line numberDiff line numberDiff line change
@@ -2127,6 +2127,7 @@ 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),
21302131
infer::TraitRefs(exp_found) => {
21312132
let pretty_exp_found = ty::error::ExpectedFound {
21322133
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,6 +371,7 @@ 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>>),
374375
TraitRefs(ExpectedFound<ty::TraitRef<'tcx>>),
375376
PolyTraitRefs(ExpectedFound<ty::PolyTraitRef<'tcx>>),
376377
}

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

+5-20
Original file line numberDiff line numberDiff line change
@@ -1356,26 +1356,11 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
13561356
normalized_ty,
13571357
data.term,
13581358
) {
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-
});
1359+
values = Some(infer::ValuePairs::Terms(ExpectedFound::new(
1360+
is_normalized_ty_expected,
1361+
normalized_ty,
1362+
data.term,
1363+
)));
13791364
err_buf = error;
13801365
err = &err_buf;
13811366
}

compiler/rustc_trait_selection/src/traits/project.rs

+20-19
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ use crate::traits::error_reporting::InferCtxtExt as _;
2222
use rustc_data_structures::sso::SsoHashSet;
2323
use rustc_data_structures::stack::ensure_sufficient_stack;
2424
use rustc_errors::ErrorReported;
25+
use rustc_hir::def::DefKind;
2526
use rustc_hir::def_id::DefId;
2627
use rustc_hir::lang_items::LangItem;
2728
use rustc_infer::infer::resolve::OpportunisticRegionResolver;
@@ -200,7 +201,7 @@ fn project_and_unify_type<'cx, 'tcx>(
200201
let infcx = selcx.infcx();
201202
match obligation.predicate.term {
202203
ty::Term::Ty(obligation_pred_ty) => {
203-
let normalized_ty = match opt_normalize_projection_type::<false>(
204+
let normalized_ty = match opt_normalize_projection_type(
204205
selcx,
205206
obligation.param_env,
206207
obligation.predicate.projection_ty,
@@ -215,7 +216,7 @@ fn project_and_unify_type<'cx, 'tcx>(
215216
debug!(?normalized_ty, ?obligations, "project_and_unify_type result");
216217
match infcx
217218
.at(&obligation.cause, obligation.param_env)
218-
.eq(normalized_ty, obligation_pred_ty.into())
219+
.eq(normalized_ty, obligation_pred_ty)
219220
{
220221
Ok(InferOk { obligations: inferred_obligations, value: () }) => {
221222
obligations.extend(inferred_obligations);
@@ -228,7 +229,7 @@ fn project_and_unify_type<'cx, 'tcx>(
228229
}
229230
}
230231
ty::Term::Const(obligation_pred_const) => {
231-
let normalized_const = match opt_normalize_projection_type::<true>(
232+
let normalized_const = match opt_normalize_projection_type(
232233
selcx,
233234
obligation.param_env,
234235
obligation.predicate.projection_ty,
@@ -492,7 +493,7 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> {
492493
let (data, mapped_regions, mapped_types, mapped_consts) =
493494
BoundVarReplacer::replace_bound_vars(infcx, &mut self.universes, data);
494495
let data = data.super_fold_with(self);
495-
let normalized_ty = opt_normalize_projection_type::<false>(
496+
let normalized_ty = opt_normalize_projection_type(
496497
self.selcx,
497498
self.param_env,
498499
data,
@@ -826,7 +827,7 @@ pub fn normalize_projection_type<'a, 'b, 'tcx>(
826827
depth: usize,
827828
obligations: &mut Vec<PredicateObligation<'tcx>>,
828829
) -> Term<'tcx> {
829-
opt_normalize_projection_type::<false>(
830+
opt_normalize_projection_type(
830831
selcx,
831832
param_env,
832833
projection_ty,
@@ -859,7 +860,7 @@ pub fn normalize_projection_type<'a, 'b, 'tcx>(
859860
/// function takes an obligations vector and appends to it directly, which is
860861
/// slightly uglier but avoids the need for an extra short-lived allocation.
861862
#[instrument(level = "debug", skip(selcx, param_env, cause, obligations))]
862-
fn opt_normalize_projection_type<'a, 'b, 'tcx, const INTO_CONST: bool>(
863+
fn opt_normalize_projection_type<'a, 'b, 'tcx>(
863864
selcx: &'a mut SelectionContext<'b, 'tcx>,
864865
param_env: ty::ParamEnv<'tcx>,
865866
projection_ty: ty::ProjectionTy<'tcx>,
@@ -946,7 +947,7 @@ fn opt_normalize_projection_type<'a, 'b, 'tcx, const INTO_CONST: bool>(
946947

947948
let obligation = Obligation::with_depth(cause.clone(), depth, param_env, projection_ty);
948949

949-
match project::<INTO_CONST>(selcx, &obligation) {
950+
match project(selcx, &obligation) {
950951
Ok(Projected::Progress(Progress {
951952
term: projected_term,
952953
obligations: mut projected_obligations,
@@ -1087,7 +1088,7 @@ impl<'tcx> Progress<'tcx> {
10871088
/// IMPORTANT:
10881089
/// - `obligation` must be fully normalized
10891090
#[tracing::instrument(level = "info", skip(selcx))]
1090-
fn project<'cx, 'tcx, const INTO_CONST: bool>(
1091+
fn project<'cx, 'tcx>(
10911092
selcx: &mut SelectionContext<'cx, 'tcx>,
10921093
obligation: &ProjectionTyObligation<'tcx>,
10931094
) -> Result<Projected<'tcx>, ProjectionError<'tcx>> {
@@ -1123,7 +1124,7 @@ fn project<'cx, 'tcx, const INTO_CONST: bool>(
11231124

11241125
match candidates {
11251126
ProjectionCandidateSet::Single(candidate) => {
1126-
Ok(Projected::Progress(confirm_candidate::<INTO_CONST>(selcx, obligation, candidate)))
1127+
Ok(Projected::Progress(confirm_candidate(selcx, obligation, candidate)))
11271128
}
11281129
ProjectionCandidateSet::None => Ok(Projected::NoProgress(
11291130
selcx
@@ -1525,7 +1526,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
15251526
});
15261527
}
15271528

1528-
fn confirm_candidate<'cx, 'tcx, const INTO_CONST: bool>(
1529+
fn confirm_candidate<'cx, 'tcx>(
15291530
selcx: &mut SelectionContext<'cx, 'tcx>,
15301531
obligation: &ProjectionTyObligation<'tcx>,
15311532
candidate: ProjectionCandidate<'tcx>,
@@ -1542,7 +1543,7 @@ fn confirm_candidate<'cx, 'tcx, const INTO_CONST: bool>(
15421543
}
15431544

15441545
ProjectionCandidate::Select(impl_source) => {
1545-
confirm_select_candidate::<INTO_CONST>(selcx, obligation, impl_source)
1546+
confirm_select_candidate(selcx, obligation, impl_source)
15461547
}
15471548
};
15481549

@@ -1558,15 +1559,13 @@ fn confirm_candidate<'cx, 'tcx, const INTO_CONST: bool>(
15581559
progress
15591560
}
15601561

1561-
fn confirm_select_candidate<'cx, 'tcx, const INTO_CONST: bool>(
1562+
fn confirm_select_candidate<'cx, 'tcx>(
15621563
selcx: &mut SelectionContext<'cx, 'tcx>,
15631564
obligation: &ProjectionTyObligation<'tcx>,
15641565
impl_source: Selection<'tcx>,
15651566
) -> Progress<'tcx> {
15661567
match impl_source {
1567-
super::ImplSource::UserDefined(data) => {
1568-
confirm_impl_candidate::<INTO_CONST>(selcx, obligation, data)
1569-
}
1568+
super::ImplSource::UserDefined(data) => confirm_impl_candidate(selcx, obligation, data),
15701569
super::ImplSource::Generator(data) => confirm_generator_candidate(selcx, obligation, data),
15711570
super::ImplSource::Closure(data) => confirm_closure_candidate(selcx, obligation, data),
15721571
super::ImplSource::FnPointer(data) => confirm_fn_pointer_candidate(selcx, obligation, data),
@@ -1836,7 +1835,7 @@ fn confirm_param_env_candidate<'cx, 'tcx>(
18361835
}
18371836
}
18381837

1839-
fn confirm_impl_candidate<'cx, 'tcx, const INTO_CONST: bool>(
1838+
fn confirm_impl_candidate<'cx, 'tcx>(
18401839
selcx: &mut SelectionContext<'cx, 'tcx>,
18411840
obligation: &ProjectionTyObligation<'tcx>,
18421841
impl_impl_source: ImplSourceUserDefinedData<'tcx, PredicateObligation<'tcx>>,
@@ -1874,10 +1873,12 @@ fn confirm_impl_candidate<'cx, 'tcx, const INTO_CONST: bool>(
18741873
let substs =
18751874
translate_substs(selcx.infcx(), param_env, impl_def_id, substs, assoc_ty.defining_node);
18761875
let ty = tcx.type_of(assoc_ty.item.def_id);
1877-
let term: ty::Term<'tcx> = if INTO_CONST {
1878-
// FIXME(associated_const_equality): what are the right substs?
1876+
let is_const = matches!(tcx.def_kind(assoc_ty.item.def_id), DefKind::AssocConst);
1877+
let term: ty::Term<'tcx> = if is_const {
1878+
let identity_substs =
1879+
crate::traits::InternalSubsts::identity_for_item(tcx, assoc_ty.item.def_id);
18791880
let did = ty::WithOptConstParam::unknown(assoc_ty.item.def_id);
1880-
let val = ty::ConstKind::Unevaluated(ty::Unevaluated::new(did, substs));
1881+
let val = ty::ConstKind::Unevaluated(ty::Unevaluated::new(did, identity_substs));
18811882
tcx.mk_const(ty::Const { ty, val }).into()
18821883
} else {
18831884
ty.into()

compiler/rustc_typeck/src/astconv/mod.rs

+14
Original file line numberDiff line numberDiff line change
@@ -1244,6 +1244,20 @@ 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);
1248+
match (def_kind, term) {
1249+
(hir::def::DefKind::AssocTy, ty::Term::Ty(_))
1250+
| (hir::def::DefKind::AssocConst, ty::Term::Const(_)) => (),
1251+
(_, _) => {
1252+
tcx.sess
1253+
.struct_span_err(
1254+
binding.span,
1255+
"type/const mismatch in equality bind of associated field",
1256+
)
1257+
.span_label(binding.span, "type/const Mismatch")
1258+
.emit();
1259+
}
1260+
}
12471261
bounds.projection_bounds.push((
12481262
projection_ty.map_bound(|projection_ty| ty::ProjectionPredicate {
12491263
projection_ty,

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

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

2222

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

2628
fn main() {
2729
foo::<Bar>();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
error: type/const mismatch in equality bind of associated field
2+
--> $DIR/assoc-const-ty-mismatch.rs:23:15
3+
|
4+
LL | fn foo<F: Foo<N=usize>>() {}
5+
| ^^^^^^^ type/const Mismatch
6+
7+
error: type/const mismatch in equality bind of associated field
8+
--> $DIR/assoc-const-ty-mismatch.rs:25:18
9+
|
10+
LL | fn foo2<F: FooTy<T=3usize>>() {}
11+
| ^^^^^^^^ type/const Mismatch
12+
13+
error: aborting due to 2 previous errors
14+

src/test/ui/associated-types/associated-types-binding-to-type-defined-in-supertrait.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ error[E0271]: type mismatch resolving `<ModelT as Vehicle>::Color == Blue`
44
LL | fn b() { blue_car(ModelT); }
55
| ^^^^^^^^ type mismatch resolving `<ModelT as Vehicle>::Color == Blue`
66
|
7-
note: expected this to be `Blue`
7+
note: expected struct `Blue`, found struct `Black`
88
--> $DIR/associated-types-binding-to-type-defined-in-supertrait.rs:16:40
99
|
1010
LL | impl Vehicle for ModelT { type Color = Black; }
@@ -21,7 +21,7 @@ error[E0271]: type mismatch resolving `<ModelU as Vehicle>::Color == Black`
2121
LL | fn c() { black_car(ModelU); }
2222
| ^^^^^^^^^ type mismatch resolving `<ModelU as Vehicle>::Color == Black`
2323
|
24-
note: expected this to be `Black`
24+
note: expected struct `Black`, found struct `Blue`
2525
--> $DIR/associated-types-binding-to-type-defined-in-supertrait.rs:21:40
2626
|
2727
LL | impl Vehicle for ModelU { type Color = Blue; }

src/test/ui/associated-types/associated-types-eq-3.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ error[E0271]: type mismatch resolving `<isize as Foo>::A == Bar`
1919
LL | foo1(a);
2020
| ^^^^ type mismatch resolving `<isize as Foo>::A == Bar`
2121
|
22-
note: expected this to be `Bar`
22+
note: expected struct `Bar`, found `usize`
2323
--> $DIR/associated-types-eq-3.rs:12:14
2424
|
2525
LL | type A = usize;
@@ -36,7 +36,7 @@ error[E0271]: type mismatch resolving `<isize as Foo>::A == Bar`
3636
LL | baz(&a);
3737
| ^^ type mismatch resolving `<isize as Foo>::A == Bar`
3838
|
39-
note: expected this to be `Bar`
39+
note: expected struct `Bar`, found `usize`
4040
--> $DIR/associated-types-eq-3.rs:12:14
4141
|
4242
LL | type A = usize;

src/test/ui/associated-types/associated-types-eq-hr.stderr

+2-6
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,11 @@ error[E0271]: type mismatch resolving `for<'x> <UintStruct as TheTrait<&'x isize
44
LL | foo::<UintStruct>();
55
| ^^^^^^^^^^^^^^^^^ type mismatch resolving `for<'x> <UintStruct as TheTrait<&'x isize>>::A == &'x isize`
66
|
7-
note: expected this to be `&isize`
7+
note: expected `isize`, found `usize`
88
--> $DIR/associated-types-eq-hr.rs:26:14
99
|
1010
LL | type A = &'a usize;
1111
| ^^^^^^^^^
12-
= note: expected reference `&isize`
13-
found reference `&usize`
1412
note: required by a bound in `foo`
1513
--> $DIR/associated-types-eq-hr.rs:45:36
1614
|
@@ -26,13 +24,11 @@ error[E0271]: type mismatch resolving `for<'x> <IntStruct as TheTrait<&'x isize>
2624
LL | bar::<IntStruct>();
2725
| ^^^^^^^^^^^^^^^^ type mismatch resolving `for<'x> <IntStruct as TheTrait<&'x isize>>::A == &'x usize`
2826
|
29-
note: expected this to be `&usize`
27+
note: expected `usize`, found `isize`
3028
--> $DIR/associated-types-eq-hr.rs:14:14
3129
|
3230
LL | type A = &'a isize;
3331
| ^^^^^^^^^
34-
= note: expected reference `&usize`
35-
found reference `&isize`
3632
note: required by a bound in `bar`
3733
--> $DIR/associated-types-eq-hr.rs:52:36
3834
|

src/test/ui/associated-types/associated-types-issue-20346.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@ LL | fn test_adapter<T, I: Iterator<Item=Option<T>>>(it: I) {
77
LL | is_iterator_of::<Option<T>, _>(&adapter);
88
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type mismatch resolving `<Adapter<I> as Iterator>::Item == Option<T>`
99
|
10-
note: expected this to be `Option<T>`
10+
note: expected enum `Option`, found type parameter `T`
1111
--> $DIR/associated-types-issue-20346.rs:23:17
1212
|
1313
LL | type Item = T;
1414
| ^
15-
= note: expected enum `Option<T>`
15+
= note: expected type `Option<T>`
1616
found type `T`
1717
note: required by a bound in `is_iterator_of`
1818
--> $DIR/associated-types-issue-20346.rs:15:34

src/test/ui/associated-types/associated-types-multiple-types-one-trait.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ error[E0271]: type mismatch resolving `<T as Foo>::Y == i32`
44
LL | want_y(t);
55
| ^^^^^^ expected `i32`, found associated type
66
|
7-
= note: expected type `i32`
8-
found associated type `<T as Foo>::Y`
7+
= note: expected type `i32`
8+
found type `<T as Foo>::Y`
99
note: required by a bound in `want_y`
1010
--> $DIR/associated-types-multiple-types-one-trait.rs:44:17
1111
|
@@ -22,8 +22,8 @@ error[E0271]: type mismatch resolving `<T as Foo>::X == u32`
2222
LL | want_x(t);
2323
| ^^^^^^ expected `u32`, found associated type
2424
|
25-
= note: expected type `u32`
26-
found associated type `<T as Foo>::X`
25+
= note: expected type `u32`
26+
found type `<T as Foo>::X`
2727
note: required by a bound in `want_x`
2828
--> $DIR/associated-types-multiple-types-one-trait.rs:42:17
2929
|

src/test/ui/associated-types/hr-associated-type-projection-1.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ error[E0271]: type mismatch resolving `<T as Deref>::Target == T`
44
LL | impl<T: Copy + std::ops::Deref> UnsafeCopy<'_, T> for T {
55
| - this type parameter ^^^^^^^^^^^^^^^^^ expected associated type, found type parameter `T`
66
|
7-
= note: expected associated type `<T as Deref>::Target`
8-
found type parameter `T`
7+
= note: expected type `<T as Deref>::Target`
8+
found type `T`
99
help: consider further restricting this bound
1010
|
1111
LL | impl<T: Copy + std::ops::Deref + Deref<Target = T>> UnsafeCopy<'_, T> for T {

src/test/ui/associated-types/impl-trait-return-missing-constraint.stderr

+2-5
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,11 @@
11
error[E0271]: type mismatch resolving `<impl Bar as Foo>::Item == i32`
22
--> $DIR/impl-trait-return-missing-constraint.rs:25:13
33
|
4-
LL | fn bar() -> impl Bar {
5-
| -------- the found opaque type
6-
...
74
LL | fn baz() -> impl Bar<Item = i32> {
85
| ^^^^^^^^^^^^^^^^^^^^ expected `i32`, found associated type
96
|
10-
= note: expected type `i32`
11-
found associated type `<impl Bar as Foo>::Item`
7+
= note: expected type `i32`
8+
found type `<impl Bar as Foo>::Item`
129
help: consider constraining the associated type `<impl Bar as Foo>::Item` to `i32`
1310
|
1411
LL | fn bar() -> impl Bar<Item = i32> {

0 commit comments

Comments
 (0)