Auto merge of #120639 - fee1-dead-contrib:new-effects-desugaring, r=oli-obk

Implement new effects desugaring

cc `@rust-lang/project-const-traits.` Will write down notes once I have finished.

* [x] See if we want `T: Tr` to desugar into `T: Tr, T::Effects: Compat<true>`
* [x] Fix ICEs on `type Assoc: ~const Tr` and `type Assoc<T: ~const Tr>`
* [ ] add types and traits to minicore test
* [ ] update rustc-dev-guide

Fixes #119717
Fixes #123664
Fixes #124857
Fixes #126148
This commit is contained in:
bors 2024-06-29 20:08:10 +00:00
commit ba1d7f4a08
175 changed files with 2234 additions and 1576 deletions

View file

@ -269,6 +269,11 @@ where
ecx: &mut EvalCtxt<'_, D>,
goal: Goal<I, Self>,
) -> Vec<Candidate<I>>;
fn consider_builtin_effects_intersection_candidate(
ecx: &mut EvalCtxt<'_, D>,
goal: Goal<I, Self>,
) -> Result<Candidate<I>, NoSolution>;
}
impl<D, I> EvalCtxt<'_, D>
@ -420,6 +425,8 @@ where
G::consider_builtin_destruct_candidate(self, goal)
} else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::TransmuteTrait) {
G::consider_builtin_transmute_candidate(self, goal)
} else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::EffectsIntersection) {
G::consider_builtin_effects_intersection_candidate(self, goal)
} else {
Err(NoSolution)
};

View file

@ -864,6 +864,68 @@ where
) -> Result<Candidate<I>, NoSolution> {
panic!("`BikeshedIntrinsicFrom` does not have an associated type: {:?}", goal)
}
fn consider_builtin_effects_intersection_candidate(
ecx: &mut EvalCtxt<'_, D>,
goal: Goal<I, Self>,
) -> Result<Candidate<I>, NoSolution> {
let ty::Tuple(types) = goal.predicate.self_ty().kind() else {
return Err(NoSolution);
};
let cx = ecx.cx();
let mut first_non_maybe = None;
let mut non_maybe_count = 0;
for ty in types.iter() {
if !matches!(ty::EffectKind::try_from_ty(cx, ty), Some(ty::EffectKind::Maybe)) {
first_non_maybe.get_or_insert(ty);
non_maybe_count += 1;
}
}
match non_maybe_count {
0 => {
let ty = ty::EffectKind::Maybe.to_ty(cx);
ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| {
ecx.instantiate_normalizes_to_term(goal, ty.into());
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
})
}
1 => {
let ty = first_non_maybe.unwrap();
ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| {
ecx.instantiate_normalizes_to_term(goal, ty.into());
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
})
}
_ => {
let mut min = ty::EffectKind::Maybe;
for ty in types.iter() {
// We can't find the intersection if the types used are generic.
//
// FIXME(effects) do we want to look at where clauses to get some
// clue for the case where generic types are being used?
let Some(kind) = ty::EffectKind::try_from_ty(cx, ty) else {
return Err(NoSolution);
};
let Some(result) = ty::EffectKind::intersection(min, kind) else {
return Err(NoSolution);
};
min = result;
}
let ty = min.to_ty(cx);
ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| {
ecx.instantiate_normalizes_to_term(goal, ty.into());
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
})
}
}
}
}
impl<D, I> EvalCtxt<'_, D>

View file

@ -702,6 +702,47 @@ where
}
})
}
fn consider_builtin_effects_intersection_candidate(
ecx: &mut EvalCtxt<'_, D>,
goal: Goal<I, Self>,
) -> Result<Candidate<I>, NoSolution> {
if goal.predicate.polarity != ty::PredicatePolarity::Positive {
return Err(NoSolution);
}
let ty::Tuple(types) = goal.predicate.self_ty().kind() else {
return Err(NoSolution);
};
let cx = ecx.cx();
let maybe_count = types
.iter()
.filter_map(|ty| ty::EffectKind::try_from_ty(cx, ty))
.filter(|&ty| ty == ty::EffectKind::Maybe)
.count();
// Don't do concrete type check unless there are more than one type that will influence the result.
// This would allow `(Maybe, T): Min` pass even if we know nothing about `T`.
if types.len() - maybe_count > 1 {
let mut min = ty::EffectKind::Maybe;
for ty in types.iter() {
let Some(kind) = ty::EffectKind::try_from_ty(ecx.cx(), ty) else {
return Err(NoSolution);
};
let Some(result) = ty::EffectKind::intersection(min, kind) else {
return Err(NoSolution);
};
min = result;
}
}
ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc)
.enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes))
}
}
impl<D, I> EvalCtxt<'_, D>