Rollup merge of #121047 - compiler-errors:default-impls, r=lcnr
Do not assemble candidates for default impls There is no reason (as far as I can tell?) that we should assemble an impl candidate for a default impl. This candidate itself does not prove that the impl holds, and any time that it *does* hold, there will be a more specializing non-default impl that also is assembled. This is because `default impl<T> Foo for T {}` actually expands to `impl<T> Foo for T where T: Foo {}`. The only way to satisfy that where clause (without coinduction) is via *another* implementation that does hold -- precisely an impl that specializes it. This should fix the specialization related regressions for #116494. That should lead to one root crate regression that doesn't have to do with specialization, which I think we can regress. r? lcnr cc ``@rust-lang/types`` cc #31844
This commit is contained in:
commit
ab1fa19d08
9 changed files with 59 additions and 40 deletions
|
@ -337,6 +337,13 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
|||
let mut consider_impls_for_simplified_type = |simp| {
|
||||
if let Some(impls_for_type) = trait_impls.non_blanket_impls().get(&simp) {
|
||||
for &impl_def_id in impls_for_type {
|
||||
// For every `default impl`, there's always a non-default `impl`
|
||||
// that will *also* apply. There's no reason to register a candidate
|
||||
// for this impl, since it is *not* proof that the trait goal holds.
|
||||
if tcx.defaultness(impl_def_id).is_default() {
|
||||
return;
|
||||
}
|
||||
|
||||
match G::consider_impl_candidate(self, goal, impl_def_id) {
|
||||
Ok(candidate) => candidates.push(candidate),
|
||||
Err(NoSolution) => (),
|
||||
|
@ -440,6 +447,13 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
|||
let tcx = self.tcx();
|
||||
let trait_impls = tcx.trait_impls_of(goal.predicate.trait_def_id(tcx));
|
||||
for &impl_def_id in trait_impls.blanket_impls() {
|
||||
// For every `default impl`, there's always a non-default `impl`
|
||||
// that will *also* apply. There's no reason to register a candidate
|
||||
// for this impl, since it is *not* proof that the trait goal holds.
|
||||
if tcx.defaultness(impl_def_id).is_default() {
|
||||
return;
|
||||
}
|
||||
|
||||
match G::consider_impl_candidate(self, goal, impl_def_id) {
|
||||
Ok(candidate) => candidates.push(candidate),
|
||||
Err(NoSolution) => (),
|
||||
|
|
|
@ -566,6 +566,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// For every `default impl`, there's always a non-default `impl`
|
||||
// that will *also* apply. There's no reason to register a candidate
|
||||
// for this impl, since it is *not* proof that the trait goal holds.
|
||||
if self.tcx().defaultness(impl_def_id).is_default() {
|
||||
return;
|
||||
}
|
||||
|
||||
if self.reject_fn_ptr_impls(
|
||||
impl_def_id,
|
||||
obligation,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue