Fully implement ConstArgHasType
This commit is contained in:
@@ -876,57 +876,25 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(..)) => {
|
||||
// Errors for `ConstEvaluatable` predicates show up as
|
||||
// `SelectionError::ConstEvalFailure`,
|
||||
// not `Unimplemented`.
|
||||
// Errors for `ConstEvaluatable` predicates show up as
|
||||
// `SelectionError::ConstEvalFailure`,
|
||||
// not `Unimplemented`.
|
||||
ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(..))
|
||||
// Errors for `ConstEquate` predicates show up as
|
||||
// `SelectionError::ConstEvalFailure`,
|
||||
// not `Unimplemented`.
|
||||
| ty::PredicateKind::ConstEquate { .. }
|
||||
// Ambiguous predicates should never error
|
||||
| ty::PredicateKind::Ambiguous
|
||||
| ty::PredicateKind::NormalizesTo { .. }
|
||||
| ty::PredicateKind::AliasRelate { .. }
|
||||
| ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType { .. }) => {
|
||||
span_bug!(
|
||||
span,
|
||||
"const-evaluatable requirement gave wrong error: `{:?}`",
|
||||
"Unexpected `Predicate` for `SelectionError`: `{:?}`",
|
||||
obligation
|
||||
)
|
||||
}
|
||||
|
||||
ty::PredicateKind::ConstEquate(..) => {
|
||||
// Errors for `ConstEquate` predicates show up as
|
||||
// `SelectionError::ConstEvalFailure`,
|
||||
// not `Unimplemented`.
|
||||
span_bug!(
|
||||
span,
|
||||
"const-equate requirement gave wrong error: `{:?}`",
|
||||
obligation
|
||||
)
|
||||
}
|
||||
|
||||
ty::PredicateKind::Ambiguous => span_bug!(span, "ambiguous"),
|
||||
|
||||
ty::PredicateKind::NormalizesTo(..) => span_bug!(
|
||||
span,
|
||||
"NormalizesTo predicate should never be the predicate cause of a SelectionError"
|
||||
),
|
||||
|
||||
ty::PredicateKind::AliasRelate(..) => span_bug!(
|
||||
span,
|
||||
"AliasRelate predicate should never be the predicate cause of a SelectionError"
|
||||
),
|
||||
|
||||
ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(ct, ty)) => {
|
||||
let mut diag = self.dcx().struct_span_err(
|
||||
span,
|
||||
format!("the constant `{ct}` is not of type `{ty}`"),
|
||||
);
|
||||
self.note_type_err(
|
||||
&mut diag,
|
||||
&obligation.cause,
|
||||
None,
|
||||
None,
|
||||
// THISPR
|
||||
TypeError::Sorts(ty::error::ExpectedFound::new(true, ty, todo!())),
|
||||
false,
|
||||
false,
|
||||
);
|
||||
diag
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -989,6 +957,24 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||
Overflow(_) => {
|
||||
bug!("overflow should be handled before the `report_selection_error` path");
|
||||
}
|
||||
|
||||
SelectionError::ConstArgHasWrongType { ct, ct_ty, expected_ty } => {
|
||||
let mut diag = self.dcx().struct_span_err(
|
||||
span,
|
||||
format!("the constant `{ct}` is not of type `{expected_ty}`"),
|
||||
);
|
||||
|
||||
self.note_type_err(
|
||||
&mut diag,
|
||||
&obligation.cause,
|
||||
None,
|
||||
None,
|
||||
TypeError::Sorts(ty::error::ExpectedFound::new(true, expected_ty, ct_ty)),
|
||||
false,
|
||||
false,
|
||||
);
|
||||
diag
|
||||
}
|
||||
};
|
||||
|
||||
self.note_obligation_cause(&mut err, &obligation);
|
||||
|
||||
@@ -439,38 +439,50 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
|
||||
// This is because this is not ever a useful obligation to report
|
||||
// as the cause of an overflow.
|
||||
ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(ct, ty)) => {
|
||||
// FIXME(BoxyUwU): Really we should not be calling `ct.ty()` for any variant
|
||||
// other than `ConstKind::Value`. Unfortunately this would require looking in the
|
||||
// env for any `ConstArgHasType` assumptions for parameters and placeholders. I
|
||||
// don't really want to implement this in the old solver so I haven't.
|
||||
//
|
||||
// We do still stall on infer vars though as otherwise a goal like:
|
||||
// `ConstArgHasType(?x: usize, usize)` can succeed even though it might later
|
||||
// get unified with some const that is not of type `usize`.
|
||||
let ct = self.selcx.infcx.shallow_resolve_const(ct);
|
||||
match ct.kind() {
|
||||
ty::ConstKind::Infer(ty::InferConst::Var(vid)) => {
|
||||
let ct = infcx.shallow_resolve_const(ct);
|
||||
let ct_ty = match ct.kind() {
|
||||
ty::ConstKind::Infer(var) => {
|
||||
let var = match var {
|
||||
ty::InferConst::Var(vid) => TyOrConstInferVar::Const(vid),
|
||||
ty::InferConst::EffectVar(vid) => TyOrConstInferVar::Effect(vid),
|
||||
ty::InferConst::Fresh(_) => {
|
||||
bug!("encountered fresh const in fulfill")
|
||||
}
|
||||
};
|
||||
pending_obligation.stalled_on.clear();
|
||||
pending_obligation.stalled_on.extend([TyOrConstInferVar::Const(vid)]);
|
||||
ProcessResult::Unchanged
|
||||
pending_obligation.stalled_on.extend([var]);
|
||||
return ProcessResult::Unchanged;
|
||||
}
|
||||
ty::ConstKind::Error(_) => return ProcessResult::Changed(vec![]),
|
||||
_ => {
|
||||
match self.selcx.infcx.at(&obligation.cause, obligation.param_env).eq(
|
||||
// Only really excercised by generic_const_exprs
|
||||
DefineOpaqueTypes::Yes,
|
||||
// THISPR
|
||||
todo!(),
|
||||
ty,
|
||||
) {
|
||||
Ok(inf_ok) => {
|
||||
ProcessResult::Changed(mk_pending(inf_ok.into_obligations()))
|
||||
}
|
||||
Err(_) => ProcessResult::Error(FulfillmentErrorCode::Select(
|
||||
SelectionError::Unimplemented,
|
||||
)),
|
||||
}
|
||||
ty::ConstKind::Value(ty, _) => ty,
|
||||
ty::ConstKind::Unevaluated(uv) => {
|
||||
infcx.tcx.type_of(uv.def).instantiate(infcx.tcx, uv.args)
|
||||
}
|
||||
// FIXME(generic_const_exprs): we should construct an alias like
|
||||
// `<lhs_ty as Add<rhs_ty>>::Output` when this is an `Expr` representing
|
||||
// `lhs + rhs`.
|
||||
ty::ConstKind::Expr(_) => {
|
||||
return ProcessResult::Changed(mk_pending(vec![]));
|
||||
}
|
||||
ty::ConstKind::Placeholder(_) => {
|
||||
bug!("placeholder const {:?} in old solver", ct)
|
||||
}
|
||||
ty::ConstKind::Bound(_, _) => bug!("escaping bound vars in {:?}", ct),
|
||||
ty::ConstKind::Param(param_ct) => {
|
||||
param_ct.find_ty_from_env(obligation.param_env)
|
||||
}
|
||||
};
|
||||
|
||||
match infcx.at(&obligation.cause, obligation.param_env).eq(
|
||||
// Only really excercised by generic_const_exprs
|
||||
DefineOpaqueTypes::Yes,
|
||||
ct_ty,
|
||||
ty,
|
||||
) {
|
||||
Ok(inf_ok) => ProcessResult::Changed(mk_pending(inf_ok.into_obligations())),
|
||||
Err(_) => ProcessResult::Error(FulfillmentErrorCode::Select(
|
||||
SelectionError::ConstArgHasWrongType { ct, ct_ty, expected_ty: ty },
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -994,23 +994,25 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
}
|
||||
ty::PredicateKind::Ambiguous => Ok(EvaluatedToAmbig),
|
||||
ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(ct, ty)) => {
|
||||
// FIXME(BoxyUwU): Really we should not be calling `ct.ty()` for any variant
|
||||
// other than `ConstKind::Value`. Unfortunately this would require looking in the
|
||||
// env for any `ConstArgHasType` assumptions for parameters and placeholders. I
|
||||
// don't really want to implement this in the old solver so I haven't.
|
||||
//
|
||||
// We do still stall on infer vars though as otherwise a goal like:
|
||||
// `ConstArgHasType(?x: usize, usize)` can succeed even though it might later
|
||||
// get unified with some const that is not of type `usize`.
|
||||
let ct = self.infcx.shallow_resolve_const(ct);
|
||||
let ct_ty = match ct.kind() {
|
||||
ty::ConstKind::Infer(ty::InferConst::Var(_)) => {
|
||||
ty::ConstKind::Infer(_) => {
|
||||
return Ok(EvaluatedToAmbig);
|
||||
}
|
||||
ty::ConstKind::Error(_) => return Ok(EvaluatedToOk),
|
||||
// THISPR
|
||||
_ => todo!(),
|
||||
// _ => ct.ty(),
|
||||
ty::ConstKind::Value(ty, _) => ty,
|
||||
ty::ConstKind::Unevaluated(uv) => {
|
||||
self.tcx().type_of(uv.def).instantiate(self.tcx(), uv.args)
|
||||
}
|
||||
// FIXME(generic_const_exprs): See comment in `fulfill.rs`
|
||||
ty::ConstKind::Expr(_) => return Ok(EvaluatedToOk),
|
||||
ty::ConstKind::Placeholder(_) => {
|
||||
bug!("placeholder const {:?} in old solver", ct)
|
||||
}
|
||||
ty::ConstKind::Bound(_, _) => bug!("escaping bound vars in {:?}", ct),
|
||||
ty::ConstKind::Param(param_ct) => {
|
||||
param_ct.find_ty_from_env(obligation.param_env)
|
||||
}
|
||||
};
|
||||
|
||||
match self.infcx.at(&obligation.cause, obligation.param_env).eq(
|
||||
|
||||
Reference in New Issue
Block a user