Skip to content

Commit

Permalink
Add ValuePairs::Terms & Fix compile error
Browse files Browse the repository at this point in the history
And use correct substs.
  • Loading branch information
JulianKnodt committed Jan 31, 2022
1 parent bd03d81 commit c654e4d
Show file tree
Hide file tree
Showing 38 changed files with 143 additions and 181 deletions.
12 changes: 2 additions & 10 deletions compiler/rustc_infer/src/infer/at.rs
Expand Up @@ -288,21 +288,13 @@ impl<'tcx> ToTrace<'tcx> for &'tcx Const<'tcx> {

impl<'tcx> ToTrace<'tcx> for ty::Term<'tcx> {
fn to_trace(
tcx: TyCtxt<'tcx>,
_: TyCtxt<'tcx>,
cause: &ObligationCause<'tcx>,
a_is_expected: bool,
a: Self,
b: Self,
) -> TypeTrace<'tcx> {
match (a, b) {
(ty::Term::Ty(a), ty::Term::Ty(b)) => {
ToTrace::to_trace(tcx, cause, a_is_expected, a, b)
}
(ty::Term::Const(a), ty::Term::Const(b)) => {
ToTrace::to_trace(tcx, cause, a_is_expected, a, b)
}
(_, _) => span_bug!(cause.span, "Unexpected type/const mismatch"),
}
TypeTrace { cause: cause.clone(), values: Terms(ExpectedFound::new(a_is_expected, a, b)) }
}
}

Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_infer/src/infer/error_reporting/mod.rs
Expand Up @@ -2127,6 +2127,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
infer::Types(exp_found) => self.expected_found_str_ty(exp_found),
infer::Regions(exp_found) => self.expected_found_str(exp_found),
infer::Consts(exp_found) => self.expected_found_str(exp_found),
infer::Terms(exp_found) => self.expected_found_str(exp_found),
infer::TraitRefs(exp_found) => {
let pretty_exp_found = ty::error::ExpectedFound {
expected: exp_found.expected.print_only_trait_path(),
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_infer/src/infer/mod.rs
Expand Up @@ -371,6 +371,7 @@ pub enum ValuePairs<'tcx> {
Types(ExpectedFound<Ty<'tcx>>),
Regions(ExpectedFound<ty::Region<'tcx>>),
Consts(ExpectedFound<&'tcx ty::Const<'tcx>>),
Terms(ExpectedFound<ty::Term<'tcx>>),
TraitRefs(ExpectedFound<ty::TraitRef<'tcx>>),
PolyTraitRefs(ExpectedFound<ty::PolyTraitRef<'tcx>>),
}
Expand Down
25 changes: 5 additions & 20 deletions compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
Expand Up @@ -1356,26 +1356,11 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
normalized_ty,
data.term,
) {
values = Some(match (normalized_ty, data.term) {
(ty::Term::Ty(normalized_ty), ty::Term::Ty(ty)) => {
infer::ValuePairs::Types(ExpectedFound::new(
is_normalized_ty_expected,
normalized_ty,
ty,
))
}
(ty::Term::Const(normalized_ct), ty::Term::Const(ct)) => {
infer::ValuePairs::Consts(ExpectedFound::new(
is_normalized_ty_expected,
normalized_ct,
ct,
))
}
(_, _) => span_bug!(
obligation.cause.span,
"found const or type where other expected"
),
});
values = Some(infer::ValuePairs::Terms(ExpectedFound::new(
is_normalized_ty_expected,
normalized_ty,
data.term,
)));
err_buf = error;
err = &err_buf;
}
Expand Down
39 changes: 20 additions & 19 deletions compiler/rustc_trait_selection/src/traits/project.rs
Expand Up @@ -22,6 +22,7 @@ use crate::traits::error_reporting::InferCtxtExt as _;
use rustc_data_structures::sso::SsoHashSet;
use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_errors::ErrorReported;
use rustc_hir::def::DefKind;
use rustc_hir::def_id::DefId;
use rustc_hir::lang_items::LangItem;
use rustc_infer::infer::resolve::OpportunisticRegionResolver;
Expand Down Expand Up @@ -200,7 +201,7 @@ fn project_and_unify_type<'cx, 'tcx>(
let infcx = selcx.infcx();
match obligation.predicate.term {
ty::Term::Ty(obligation_pred_ty) => {
let normalized_ty = match opt_normalize_projection_type::<false>(
let normalized_ty = match opt_normalize_projection_type(
selcx,
obligation.param_env,
obligation.predicate.projection_ty,
Expand All @@ -215,7 +216,7 @@ fn project_and_unify_type<'cx, 'tcx>(
debug!(?normalized_ty, ?obligations, "project_and_unify_type result");
match infcx
.at(&obligation.cause, obligation.param_env)
.eq(normalized_ty, obligation_pred_ty.into())
.eq(normalized_ty, obligation_pred_ty)
{
Ok(InferOk { obligations: inferred_obligations, value: () }) => {
obligations.extend(inferred_obligations);
Expand All @@ -228,7 +229,7 @@ fn project_and_unify_type<'cx, 'tcx>(
}
}
ty::Term::Const(obligation_pred_const) => {
let normalized_const = match opt_normalize_projection_type::<true>(
let normalized_const = match opt_normalize_projection_type(
selcx,
obligation.param_env,
obligation.predicate.projection_ty,
Expand Down Expand Up @@ -492,7 +493,7 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> {
let (data, mapped_regions, mapped_types, mapped_consts) =
BoundVarReplacer::replace_bound_vars(infcx, &mut self.universes, data);
let data = data.super_fold_with(self);
let normalized_ty = opt_normalize_projection_type::<false>(
let normalized_ty = opt_normalize_projection_type(
self.selcx,
self.param_env,
data,
Expand Down Expand Up @@ -826,7 +827,7 @@ pub fn normalize_projection_type<'a, 'b, 'tcx>(
depth: usize,
obligations: &mut Vec<PredicateObligation<'tcx>>,
) -> Term<'tcx> {
opt_normalize_projection_type::<false>(
opt_normalize_projection_type(
selcx,
param_env,
projection_ty,
Expand Down Expand Up @@ -859,7 +860,7 @@ pub fn normalize_projection_type<'a, 'b, 'tcx>(
/// function takes an obligations vector and appends to it directly, which is
/// slightly uglier but avoids the need for an extra short-lived allocation.
#[instrument(level = "debug", skip(selcx, param_env, cause, obligations))]
fn opt_normalize_projection_type<'a, 'b, 'tcx, const INTO_CONST: bool>(
fn opt_normalize_projection_type<'a, 'b, 'tcx>(
selcx: &'a mut SelectionContext<'b, 'tcx>,
param_env: ty::ParamEnv<'tcx>,
projection_ty: ty::ProjectionTy<'tcx>,
Expand Down Expand Up @@ -946,7 +947,7 @@ fn opt_normalize_projection_type<'a, 'b, 'tcx, const INTO_CONST: bool>(

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

match project::<INTO_CONST>(selcx, &obligation) {
match project(selcx, &obligation) {
Ok(Projected::Progress(Progress {
term: projected_term,
obligations: mut projected_obligations,
Expand Down Expand Up @@ -1087,7 +1088,7 @@ impl<'tcx> Progress<'tcx> {
/// IMPORTANT:
/// - `obligation` must be fully normalized
#[tracing::instrument(level = "info", skip(selcx))]
fn project<'cx, 'tcx, const INTO_CONST: bool>(
fn project<'cx, 'tcx>(
selcx: &mut SelectionContext<'cx, 'tcx>,
obligation: &ProjectionTyObligation<'tcx>,
) -> Result<Projected<'tcx>, ProjectionError<'tcx>> {
Expand Down Expand Up @@ -1123,7 +1124,7 @@ fn project<'cx, 'tcx, const INTO_CONST: bool>(

match candidates {
ProjectionCandidateSet::Single(candidate) => {
Ok(Projected::Progress(confirm_candidate::<INTO_CONST>(selcx, obligation, candidate)))
Ok(Projected::Progress(confirm_candidate(selcx, obligation, candidate)))
}
ProjectionCandidateSet::None => Ok(Projected::NoProgress(
selcx
Expand Down Expand Up @@ -1525,7 +1526,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
});
}

fn confirm_candidate<'cx, 'tcx, const INTO_CONST: bool>(
fn confirm_candidate<'cx, 'tcx>(
selcx: &mut SelectionContext<'cx, 'tcx>,
obligation: &ProjectionTyObligation<'tcx>,
candidate: ProjectionCandidate<'tcx>,
Expand All @@ -1542,7 +1543,7 @@ fn confirm_candidate<'cx, 'tcx, const INTO_CONST: bool>(
}

ProjectionCandidate::Select(impl_source) => {
confirm_select_candidate::<INTO_CONST>(selcx, obligation, impl_source)
confirm_select_candidate(selcx, obligation, impl_source)
}
};

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

fn confirm_select_candidate<'cx, 'tcx, const INTO_CONST: bool>(
fn confirm_select_candidate<'cx, 'tcx>(
selcx: &mut SelectionContext<'cx, 'tcx>,
obligation: &ProjectionTyObligation<'tcx>,
impl_source: Selection<'tcx>,
) -> Progress<'tcx> {
match impl_source {
super::ImplSource::UserDefined(data) => {
confirm_impl_candidate::<INTO_CONST>(selcx, obligation, data)
}
super::ImplSource::UserDefined(data) => confirm_impl_candidate(selcx, obligation, data),
super::ImplSource::Generator(data) => confirm_generator_candidate(selcx, obligation, data),
super::ImplSource::Closure(data) => confirm_closure_candidate(selcx, obligation, data),
super::ImplSource::FnPointer(data) => confirm_fn_pointer_candidate(selcx, obligation, data),
Expand Down Expand Up @@ -1836,7 +1835,7 @@ fn confirm_param_env_candidate<'cx, 'tcx>(
}
}

fn confirm_impl_candidate<'cx, 'tcx, const INTO_CONST: bool>(
fn confirm_impl_candidate<'cx, 'tcx>(
selcx: &mut SelectionContext<'cx, 'tcx>,
obligation: &ProjectionTyObligation<'tcx>,
impl_impl_source: ImplSourceUserDefinedData<'tcx, PredicateObligation<'tcx>>,
Expand Down Expand Up @@ -1874,10 +1873,12 @@ fn confirm_impl_candidate<'cx, 'tcx, const INTO_CONST: bool>(
let substs =
translate_substs(selcx.infcx(), param_env, impl_def_id, substs, assoc_ty.defining_node);
let ty = tcx.type_of(assoc_ty.item.def_id);
let term: ty::Term<'tcx> = if INTO_CONST {
// FIXME(associated_const_equality): what are the right substs?
let is_const = matches!(tcx.def_kind(assoc_ty.item.def_id), DefKind::AssocConst);
let term: ty::Term<'tcx> = if is_const {
let identity_substs =
crate::traits::InternalSubsts::identity_for_item(tcx, assoc_ty.item.def_id);
let did = ty::WithOptConstParam::unknown(assoc_ty.item.def_id);
let val = ty::ConstKind::Unevaluated(ty::Unevaluated::new(did, substs));
let val = ty::ConstKind::Unevaluated(ty::Unevaluated::new(did, identity_substs));
tcx.mk_const(ty::Const { ty, val }).into()
} else {
ty.into()
Expand Down
14 changes: 14 additions & 0 deletions compiler/rustc_typeck/src/astconv/mod.rs
Expand Up @@ -1244,6 +1244,20 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
// the "projection predicate" for:
//
// `<T as Iterator>::Item = u32`
let def_kind = tcx.def_kind(projection_ty.skip_binder().item_def_id);
match (def_kind, term) {
(hir::def::DefKind::AssocTy, ty::Term::Ty(_))
| (hir::def::DefKind::AssocConst, ty::Term::Const(_)) => (),
(_, _) => {
tcx.sess
.struct_span_err(
binding.span,
"type/const mismatch in equality bind of associated field",
)
.span_label(binding.span, "type/const Mismatch")
.emit();
}
}
bounds.projection_bounds.push((
projection_ty.map_bound(|projection_ty| ty::ProjectionPredicate {
projection_ty,
Expand Down
2 changes: 2 additions & 0 deletions src/test/ui/associated-consts/assoc-const-ty-mismatch.rs
Expand Up @@ -21,7 +21,9 @@ impl FooTy for Bar {


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

fn main() {
foo::<Bar>();
Expand Down
14 changes: 14 additions & 0 deletions src/test/ui/associated-consts/assoc-const-ty-mismatch.stderr
@@ -0,0 +1,14 @@
error: type/const mismatch in equality bind of associated field
--> $DIR/assoc-const-ty-mismatch.rs:23:15
|
LL | fn foo<F: Foo<N=usize>>() {}
| ^^^^^^^ type/const Mismatch

error: type/const mismatch in equality bind of associated field
--> $DIR/assoc-const-ty-mismatch.rs:25:18
|
LL | fn foo2<F: FooTy<T=3usize>>() {}
| ^^^^^^^^ type/const Mismatch

error: aborting due to 2 previous errors

Expand Up @@ -4,7 +4,7 @@ error[E0271]: type mismatch resolving `<ModelT as Vehicle>::Color == Blue`
LL | fn b() { blue_car(ModelT); }
| ^^^^^^^^ type mismatch resolving `<ModelT as Vehicle>::Color == Blue`
|
note: expected this to be `Blue`
note: expected struct `Blue`, found struct `Black`
--> $DIR/associated-types-binding-to-type-defined-in-supertrait.rs:16:40
|
LL | impl Vehicle for ModelT { type Color = Black; }
Expand All @@ -21,7 +21,7 @@ error[E0271]: type mismatch resolving `<ModelU as Vehicle>::Color == Black`
LL | fn c() { black_car(ModelU); }
| ^^^^^^^^^ type mismatch resolving `<ModelU as Vehicle>::Color == Black`
|
note: expected this to be `Black`
note: expected struct `Black`, found struct `Blue`
--> $DIR/associated-types-binding-to-type-defined-in-supertrait.rs:21:40
|
LL | impl Vehicle for ModelU { type Color = Blue; }
Expand Down
4 changes: 2 additions & 2 deletions src/test/ui/associated-types/associated-types-eq-3.stderr
Expand Up @@ -19,7 +19,7 @@ error[E0271]: type mismatch resolving `<isize as Foo>::A == Bar`
LL | foo1(a);
| ^^^^ type mismatch resolving `<isize as Foo>::A == Bar`
|
note: expected this to be `Bar`
note: expected struct `Bar`, found `usize`
--> $DIR/associated-types-eq-3.rs:12:14
|
LL | type A = usize;
Expand All @@ -36,7 +36,7 @@ error[E0271]: type mismatch resolving `<isize as Foo>::A == Bar`
LL | baz(&a);
| ^^ type mismatch resolving `<isize as Foo>::A == Bar`
|
note: expected this to be `Bar`
note: expected struct `Bar`, found `usize`
--> $DIR/associated-types-eq-3.rs:12:14
|
LL | type A = usize;
Expand Down
8 changes: 2 additions & 6 deletions src/test/ui/associated-types/associated-types-eq-hr.stderr
Expand Up @@ -4,13 +4,11 @@ error[E0271]: type mismatch resolving `for<'x> <UintStruct as TheTrait<&'x isize
LL | foo::<UintStruct>();
| ^^^^^^^^^^^^^^^^^ type mismatch resolving `for<'x> <UintStruct as TheTrait<&'x isize>>::A == &'x isize`
|
note: expected this to be `&isize`
note: expected `isize`, found `usize`
--> $DIR/associated-types-eq-hr.rs:26:14
|
LL | type A = &'a usize;
| ^^^^^^^^^
= note: expected reference `&isize`
found reference `&usize`
note: required by a bound in `foo`
--> $DIR/associated-types-eq-hr.rs:45:36
|
Expand All @@ -26,13 +24,11 @@ error[E0271]: type mismatch resolving `for<'x> <IntStruct as TheTrait<&'x isize>
LL | bar::<IntStruct>();
| ^^^^^^^^^^^^^^^^ type mismatch resolving `for<'x> <IntStruct as TheTrait<&'x isize>>::A == &'x usize`
|
note: expected this to be `&usize`
note: expected `usize`, found `isize`
--> $DIR/associated-types-eq-hr.rs:14:14
|
LL | type A = &'a isize;
| ^^^^^^^^^
= note: expected reference `&usize`
found reference `&isize`
note: required by a bound in `bar`
--> $DIR/associated-types-eq-hr.rs:52:36
|
Expand Down
Expand Up @@ -7,12 +7,12 @@ LL | fn test_adapter<T, I: Iterator<Item=Option<T>>>(it: I) {
LL | is_iterator_of::<Option<T>, _>(&adapter);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type mismatch resolving `<Adapter<I> as Iterator>::Item == Option<T>`
|
note: expected this to be `Option<T>`
note: expected enum `Option`, found type parameter `T`
--> $DIR/associated-types-issue-20346.rs:23:17
|
LL | type Item = T;
| ^
= note: expected enum `Option<T>`
= note: expected type `Option<T>`
found type `T`
note: required by a bound in `is_iterator_of`
--> $DIR/associated-types-issue-20346.rs:15:34
Expand Down
Expand Up @@ -4,8 +4,8 @@ error[E0271]: type mismatch resolving `<T as Foo>::Y == i32`
LL | want_y(t);
| ^^^^^^ expected `i32`, found associated type
|
= note: expected type `i32`
found associated type `<T as Foo>::Y`
= note: expected type `i32`
found type `<T as Foo>::Y`
note: required by a bound in `want_y`
--> $DIR/associated-types-multiple-types-one-trait.rs:44:17
|
Expand All @@ -22,8 +22,8 @@ error[E0271]: type mismatch resolving `<T as Foo>::X == u32`
LL | want_x(t);
| ^^^^^^ expected `u32`, found associated type
|
= note: expected type `u32`
found associated type `<T as Foo>::X`
= note: expected type `u32`
found type `<T as Foo>::X`
note: required by a bound in `want_x`
--> $DIR/associated-types-multiple-types-one-trait.rs:42:17
|
Expand Down
Expand Up @@ -4,8 +4,8 @@ error[E0271]: type mismatch resolving `<T as Deref>::Target == T`
LL | impl<T: Copy + std::ops::Deref> UnsafeCopy<'_, T> for T {
| - this type parameter ^^^^^^^^^^^^^^^^^ expected associated type, found type parameter `T`
|
= note: expected associated type `<T as Deref>::Target`
found type parameter `T`
= note: expected type `<T as Deref>::Target`
found type `T`
help: consider further restricting this bound
|
LL | impl<T: Copy + std::ops::Deref + Deref<Target = T>> UnsafeCopy<'_, T> for T {
Expand Down
@@ -1,14 +1,11 @@
error[E0271]: type mismatch resolving `<impl Bar as Foo>::Item == i32`
--> $DIR/impl-trait-return-missing-constraint.rs:25:13
|
LL | fn bar() -> impl Bar {
| -------- the found opaque type
...
LL | fn baz() -> impl Bar<Item = i32> {
| ^^^^^^^^^^^^^^^^^^^^ expected `i32`, found associated type
|
= note: expected type `i32`
found associated type `<impl Bar as Foo>::Item`
= note: expected type `i32`
found type `<impl Bar as Foo>::Item`
help: consider constraining the associated type `<impl Bar as Foo>::Item` to `i32`
|
LL | fn bar() -> impl Bar<Item = i32> {
Expand Down

0 comments on commit c654e4d

Please sign in to comment.