Rollup merge of #105633 - compiler-errors:term-agnostic, r=oli-obk
Make `report_projection_error` more `Term` agnostic Fixes #105632
This commit is contained in:
commit
78cf8cc02e
5 changed files with 91 additions and 20 deletions
|
@ -1636,17 +1636,30 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||||
infer::LateBoundRegionConversionTime::HigherRankedType,
|
infer::LateBoundRegionConversionTime::HigherRankedType,
|
||||||
bound_predicate.rebind(data),
|
bound_predicate.rebind(data),
|
||||||
);
|
);
|
||||||
let normalized_ty = ocx.normalize(
|
let unnormalized_term = match data.term.unpack() {
|
||||||
&obligation.cause,
|
ty::TermKind::Ty(_) => self
|
||||||
obligation.param_env,
|
.tcx
|
||||||
self.tcx.mk_projection(data.projection_ty.def_id, data.projection_ty.substs),
|
.mk_projection(data.projection_ty.def_id, data.projection_ty.substs)
|
||||||
);
|
.into(),
|
||||||
|
ty::TermKind::Const(ct) => self
|
||||||
|
.tcx
|
||||||
|
.mk_const(
|
||||||
|
ty::UnevaluatedConst {
|
||||||
|
def: ty::WithOptConstParam::unknown(data.projection_ty.def_id),
|
||||||
|
substs: data.projection_ty.substs,
|
||||||
|
},
|
||||||
|
ct.ty(),
|
||||||
|
)
|
||||||
|
.into(),
|
||||||
|
};
|
||||||
|
let normalized_term =
|
||||||
|
ocx.normalize(&obligation.cause, obligation.param_env, unnormalized_term);
|
||||||
|
|
||||||
debug!(?obligation.cause, ?obligation.param_env);
|
debug!(?obligation.cause, ?obligation.param_env);
|
||||||
|
|
||||||
debug!(?normalized_ty, data.ty = ?data.term);
|
debug!(?normalized_term, data.ty = ?data.term);
|
||||||
|
|
||||||
let is_normalized_ty_expected = !matches!(
|
let is_normalized_term_expected = !matches!(
|
||||||
obligation.cause.code().peel_derives(),
|
obligation.cause.code().peel_derives(),
|
||||||
ObligationCauseCode::ItemObligation(_)
|
ObligationCauseCode::ItemObligation(_)
|
||||||
| ObligationCauseCode::BindingObligation(_, _)
|
| ObligationCauseCode::BindingObligation(_, _)
|
||||||
|
@ -1655,7 +1668,6 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||||
| ObligationCauseCode::ObjectCastObligation(..)
|
| ObligationCauseCode::ObjectCastObligation(..)
|
||||||
| ObligationCauseCode::OpaqueType
|
| ObligationCauseCode::OpaqueType
|
||||||
);
|
);
|
||||||
let expected_ty = data.term.ty().unwrap_or_else(|| self.tcx.ty_error());
|
|
||||||
|
|
||||||
// constrain inference variables a bit more to nested obligations from normalize so
|
// constrain inference variables a bit more to nested obligations from normalize so
|
||||||
// we can have more helpful errors.
|
// we can have more helpful errors.
|
||||||
|
@ -1664,11 +1676,11 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||||
if let Err(new_err) = ocx.eq_exp(
|
if let Err(new_err) = ocx.eq_exp(
|
||||||
&obligation.cause,
|
&obligation.cause,
|
||||||
obligation.param_env,
|
obligation.param_env,
|
||||||
is_normalized_ty_expected,
|
is_normalized_term_expected,
|
||||||
normalized_ty,
|
normalized_term,
|
||||||
expected_ty,
|
data.term,
|
||||||
) {
|
) {
|
||||||
(Some((data, is_normalized_ty_expected, normalized_ty, expected_ty)), new_err)
|
(Some((data, is_normalized_term_expected, normalized_term, data.term)), new_err)
|
||||||
} else {
|
} else {
|
||||||
(None, error.err)
|
(None, error.err)
|
||||||
}
|
}
|
||||||
|
@ -1677,12 +1689,8 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||||
};
|
};
|
||||||
|
|
||||||
let msg = values
|
let msg = values
|
||||||
.and_then(|(predicate, _, normalized_ty, expected_ty)| {
|
.and_then(|(predicate, _, normalized_term, expected_term)| {
|
||||||
self.maybe_detailed_projection_msg(
|
self.maybe_detailed_projection_msg(predicate, normalized_term, expected_term)
|
||||||
predicate,
|
|
||||||
normalized_ty.into(),
|
|
||||||
expected_ty.into(),
|
|
||||||
)
|
|
||||||
})
|
})
|
||||||
.unwrap_or_else(|| format!("type mismatch resolving `{}`", predicate));
|
.unwrap_or_else(|| format!("type mismatch resolving `{}`", predicate));
|
||||||
let mut diag = struct_span_err!(self.tcx.sess, obligation.cause.span, E0271, "{msg}");
|
let mut diag = struct_span_err!(self.tcx.sess, obligation.cause.span, E0271, "{msg}");
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||||
|
--> $DIR/const-projection-err.rs:4:26
|
||||||
|
|
|
||||||
|
LL | #![cfg_attr(gce, feature(generic_const_exprs))]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
|
||||||
|
= note: `#[warn(incomplete_features)]` on by default
|
||||||
|
|
||||||
|
error[E0271]: type mismatch resolving `<T as TraitWAssocConst>::A == 1`
|
||||||
|
--> $DIR/const-projection-err.rs:14:11
|
||||||
|
|
|
||||||
|
LL | foo::<T>();
|
||||||
|
| ^ expected `0`, found `1`
|
||||||
|
|
|
||||||
|
note: required by a bound in `foo`
|
||||||
|
--> $DIR/const-projection-err.rs:11:28
|
||||||
|
|
|
||||||
|
LL | fn foo<T: TraitWAssocConst<A = 1>>() {}
|
||||||
|
| ^^^^^ required by this bound in `foo`
|
||||||
|
|
||||||
|
error: aborting due to previous error; 1 warning emitted
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0271`.
|
18
src/test/ui/associated-type-bounds/const-projection-err.rs
Normal file
18
src/test/ui/associated-type-bounds/const-projection-err.rs
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
// revisions: stock gce
|
||||||
|
|
||||||
|
#![feature(associated_const_equality)]
|
||||||
|
#![cfg_attr(gce, feature(generic_const_exprs))]
|
||||||
|
//[gce]~^ WARN the feature `generic_const_exprs` is incomplete
|
||||||
|
|
||||||
|
trait TraitWAssocConst {
|
||||||
|
const A: usize;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn foo<T: TraitWAssocConst<A = 1>>() {}
|
||||||
|
|
||||||
|
fn bar<T: TraitWAssocConst<A = 0>>() {
|
||||||
|
foo::<T>();
|
||||||
|
//~^ ERROR type mismatch resolving `<T as TraitWAssocConst>::A == 1`
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -0,0 +1,17 @@
|
||||||
|
error[E0271]: type mismatch resolving `<T as TraitWAssocConst>::A == 1`
|
||||||
|
--> $DIR/const-projection-err.rs:14:11
|
||||||
|
|
|
||||||
|
LL | foo::<T>();
|
||||||
|
| ^ expected `1`, found `<T as TraitWAssocConst>::A`
|
||||||
|
|
|
||||||
|
= note: expected constant `1`
|
||||||
|
found constant `<T as TraitWAssocConst>::A`
|
||||||
|
note: required by a bound in `foo`
|
||||||
|
--> $DIR/const-projection-err.rs:11:28
|
||||||
|
|
|
||||||
|
LL | fn foo<T: TraitWAssocConst<A = 1>>() {}
|
||||||
|
| ^^^^^ required by this bound in `foo`
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0271`.
|
|
@ -55,8 +55,10 @@ error[E0271]: type mismatch resolving `<Demo as TraitWAssocConst>::A == 32`
|
||||||
--> $DIR/issue-105330.rs:12:11
|
--> $DIR/issue-105330.rs:12:11
|
||||||
|
|
|
|
||||||
LL | foo::<Demo>()();
|
LL | foo::<Demo>()();
|
||||||
| ^^^^ types differ
|
| ^^^^ expected `32`, found `<Demo as TraitWAssocConst>::A`
|
||||||
|
|
|
|
||||||
|
= note: expected constant `32`
|
||||||
|
found constant `<Demo as TraitWAssocConst>::A`
|
||||||
note: required by a bound in `foo`
|
note: required by a bound in `foo`
|
||||||
--> $DIR/issue-105330.rs:11:28
|
--> $DIR/issue-105330.rs:11:28
|
||||||
|
|
|
|
||||||
|
@ -89,8 +91,10 @@ error[E0271]: type mismatch resolving `<Demo as TraitWAssocConst>::A == 32`
|
||||||
--> $DIR/issue-105330.rs:19:11
|
--> $DIR/issue-105330.rs:19:11
|
||||||
|
|
|
|
||||||
LL | foo::<Demo>();
|
LL | foo::<Demo>();
|
||||||
| ^^^^ types differ
|
| ^^^^ expected `32`, found `<Demo as TraitWAssocConst>::A`
|
||||||
|
|
|
|
||||||
|
= note: expected constant `32`
|
||||||
|
found constant `<Demo as TraitWAssocConst>::A`
|
||||||
note: required by a bound in `foo`
|
note: required by a bound in `foo`
|
||||||
--> $DIR/issue-105330.rs:11:28
|
--> $DIR/issue-105330.rs:11:28
|
||||||
|
|
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue