Implement const effect predicate in new solver
This commit is contained in:
parent
a16d491054
commit
cde29b9ec9
127 changed files with 1702 additions and 1170 deletions
|
@ -156,8 +156,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
|||
(leaf_trait_predicate, &obligation)
|
||||
};
|
||||
|
||||
let (main_trait_predicate, leaf_trait_predicate, predicate_constness) = self.get_effects_trait_pred_override(main_trait_predicate, leaf_trait_predicate, span);
|
||||
|
||||
let main_trait_ref = main_trait_predicate.to_poly_trait_ref();
|
||||
let leaf_trait_ref = leaf_trait_predicate.to_poly_trait_ref();
|
||||
|
||||
|
@ -228,7 +226,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
|||
let err_msg = self.get_standard_error_message(
|
||||
main_trait_predicate,
|
||||
message,
|
||||
predicate_constness,
|
||||
None,
|
||||
append_const_msg,
|
||||
post_message,
|
||||
);
|
||||
|
@ -289,13 +287,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
|||
);
|
||||
}
|
||||
|
||||
if tcx.is_lang_item(leaf_trait_ref.def_id(), LangItem::Drop)
|
||||
&& matches!(predicate_constness, Some(ty::BoundConstness::ConstIfConst | ty::BoundConstness::Const))
|
||||
{
|
||||
err.note("`~const Drop` was renamed to `~const Destruct`");
|
||||
err.note("See <https://github.com/rust-lang/rust/pull/94901> for more details");
|
||||
}
|
||||
|
||||
let explanation = get_explanation_based_on_obligation(
|
||||
self.tcx,
|
||||
&obligation,
|
||||
|
@ -541,6 +532,29 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
|||
err
|
||||
}
|
||||
|
||||
ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(predicate)) => {
|
||||
// FIXME(effects): We should recompute the predicate with `~const`
|
||||
// if it's `const`, and if it holds, explain that this bound only
|
||||
// *conditionally* holds. If that fails, we should also do selection
|
||||
// to drill this down to an impl or built-in source, so we can
|
||||
// point at it and explain that while the trait *is* implemented,
|
||||
// that implementation is not const.
|
||||
let err_msg = self.get_standard_error_message(
|
||||
bound_predicate.rebind(ty::TraitPredicate {
|
||||
trait_ref: predicate.trait_ref,
|
||||
polarity: ty::PredicatePolarity::Positive,
|
||||
}),
|
||||
None,
|
||||
Some(match predicate.host {
|
||||
ty::HostPolarity::Maybe => ty::BoundConstness::ConstIfConst,
|
||||
ty::HostPolarity::Const => ty::BoundConstness::Const,
|
||||
}),
|
||||
None,
|
||||
String::new(),
|
||||
);
|
||||
struct_span_code_err!(self.dcx(), span, E0277, "{}", err_msg)
|
||||
}
|
||||
|
||||
ty::PredicateKind::Subtype(predicate) => {
|
||||
// Errors for Subtype predicates show up as
|
||||
// `FulfillmentErrorCode::SubtypeError`,
|
||||
|
@ -2374,16 +2388,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
|||
})
|
||||
}
|
||||
|
||||
// FIXME(effects): Remove this.
|
||||
fn get_effects_trait_pred_override(
|
||||
&self,
|
||||
p: ty::PolyTraitPredicate<'tcx>,
|
||||
leaf: ty::PolyTraitPredicate<'tcx>,
|
||||
_span: Span,
|
||||
) -> (ty::PolyTraitPredicate<'tcx>, ty::PolyTraitPredicate<'tcx>, ty::BoundConstness) {
|
||||
(p, leaf, ty::BoundConstness::NotConst)
|
||||
}
|
||||
|
||||
fn add_tuple_trait_message(
|
||||
&self,
|
||||
obligation_cause_code: &ObligationCauseCode<'tcx>,
|
||||
|
|
|
@ -806,7 +806,8 @@ impl<'tcx> AutoTraitFinder<'tcx> {
|
|||
| ty::PredicateKind::Subtype(..)
|
||||
// FIXME(generic_const_exprs): you can absolutely add this as a where clauses
|
||||
| ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(..))
|
||||
| ty::PredicateKind::Coerce(..) => {}
|
||||
| ty::PredicateKind::Coerce(..)
|
||||
| ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(..)) => {}
|
||||
ty::PredicateKind::Ambiguous => return false,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -245,6 +245,7 @@ fn predicate_references_self<'tcx>(
|
|||
| ty::ClauseKind::RegionOutlives(..)
|
||||
// FIXME(generic_const_exprs): this can mention `Self`
|
||||
| ty::ClauseKind::ConstEvaluatable(..)
|
||||
| ty::ClauseKind::HostEffect(..)
|
||||
=> None,
|
||||
}
|
||||
}
|
||||
|
@ -284,7 +285,8 @@ fn generics_require_sized_self(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
|
|||
| ty::ClauseKind::Projection(_)
|
||||
| ty::ClauseKind::ConstArgHasType(_, _)
|
||||
| ty::ClauseKind::WellFormed(_)
|
||||
| ty::ClauseKind::ConstEvaluatable(_) => false,
|
||||
| ty::ClauseKind::ConstEvaluatable(_)
|
||||
| ty::ClauseKind::HostEffect(..) => false,
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -372,7 +372,11 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
|
|||
| ty::PredicateKind::Subtype(_)
|
||||
| ty::PredicateKind::Coerce(_)
|
||||
| ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(..))
|
||||
| ty::PredicateKind::ConstEquate(..) => {
|
||||
| ty::PredicateKind::ConstEquate(..)
|
||||
// FIXME(effects): We may need to do this using the higher-ranked
|
||||
// pred instead of just instantiating it with placeholders b/c of
|
||||
// higher-ranked implied bound issues in the old solver.
|
||||
| ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(..)) => {
|
||||
let pred = ty::Binder::dummy(infcx.enter_forall_and_leak_universe(binder));
|
||||
let mut obligations = PredicateObligations::with_capacity(1);
|
||||
obligations.push(obligation.with(infcx.tcx, pred));
|
||||
|
@ -398,6 +402,10 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
|
|||
)
|
||||
}
|
||||
|
||||
ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(..)) => {
|
||||
ProcessResult::Changed(Default::default())
|
||||
}
|
||||
|
||||
ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(data)) => {
|
||||
if infcx.considering_regions {
|
||||
infcx.region_outlives_predicate(&obligation.cause, Binder::dummy(data));
|
||||
|
|
|
@ -96,6 +96,7 @@ pub fn compute_implied_outlives_bounds_inner<'tcx>(
|
|||
// FIXME(const_generics): Make sure that `<'a, 'b, const N: &'a &'b u32>` is sound
|
||||
// if we ever support that
|
||||
ty::PredicateKind::Clause(ty::ClauseKind::Trait(..))
|
||||
| ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(..))
|
||||
| ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(..))
|
||||
| ty::PredicateKind::Subtype(..)
|
||||
| ty::PredicateKind::Coerce(..)
|
||||
|
@ -200,6 +201,7 @@ pub fn compute_implied_outlives_bounds_compat_inner<'tcx>(
|
|||
// FIXME(const_generics): Make sure that `<'a, 'b, const N: &'a &'b u32>` is sound
|
||||
// if we ever support that
|
||||
ty::PredicateKind::Clause(ty::ClauseKind::Trait(..))
|
||||
| ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(..))
|
||||
| ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(..))
|
||||
| ty::PredicateKind::Subtype(..)
|
||||
| ty::PredicateKind::Coerce(..)
|
||||
|
|
|
@ -645,6 +645,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
self.evaluate_trait_predicate_recursively(previous_stack, obligation)
|
||||
}
|
||||
|
||||
ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(..)) => {
|
||||
// FIXME(effects): It should be relatively straightforward to implement
|
||||
// old trait solver support for `HostEffect` bounds; or at least basic
|
||||
// support for them.
|
||||
todo!()
|
||||
}
|
||||
|
||||
ty::PredicateKind::Subtype(p) => {
|
||||
let p = bound_predicate.rebind(p);
|
||||
// Does this code ever run?
|
||||
|
|
|
@ -170,6 +170,10 @@ pub fn clause_obligations<'tcx>(
|
|||
ty::ClauseKind::Trait(t) => {
|
||||
wf.compute_trait_pred(t, Elaborate::None);
|
||||
}
|
||||
ty::ClauseKind::HostEffect(..) => {
|
||||
// Technically the well-formedness of this predicate is implied by
|
||||
// the corresponding trait predicate it should've been generated beside.
|
||||
}
|
||||
ty::ClauseKind::RegionOutlives(..) => {}
|
||||
ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(ty, _reg)) => {
|
||||
wf.compute(ty.into());
|
||||
|
@ -1021,6 +1025,7 @@ pub(crate) fn required_region_bounds<'tcx>(
|
|||
}
|
||||
}
|
||||
ty::ClauseKind::Trait(_)
|
||||
| ty::ClauseKind::HostEffect(..)
|
||||
| ty::ClauseKind::RegionOutlives(_)
|
||||
| ty::ClauseKind::Projection(_)
|
||||
| ty::ClauseKind::ConstArgHasType(_, _)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue