Rollup merge of #152287 - jakubadamw:issue-137190, r=petrochenkov
Fix an ICE in the vtable iteration for a trait reference in const eval when a supertrait not implemented compiler/rustc_trait_selection/src/traits/vtable.rs@`vtable_entries`: The impossible predicates check in `vtable_entries` used `instantiate_own` which only includes the method's own `where` clauses, without the parent trait's bounds. Replace it with `instantiate_and_check_impossible_predicates` which also checks the trait ref itself, so unsatisfied supertrait bounds are caught and the method is marked `Vacant` instead of ICEing. Closes rust-lang/rust#137190. Closes rust-lang/rust#135470.
This commit is contained in:
commit
8afd63610b
8 changed files with 88 additions and 35 deletions
|
|
@ -12,7 +12,7 @@ use rustc_span::DUMMY_SP;
|
||||||
use smallvec::{SmallVec, smallvec};
|
use smallvec::{SmallVec, smallvec};
|
||||||
use tracing::debug;
|
use tracing::debug;
|
||||||
|
|
||||||
use crate::traits::{impossible_predicates, is_vtable_safe_method};
|
use crate::traits::is_vtable_safe_method;
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum VtblSegment<'tcx> {
|
pub enum VtblSegment<'tcx> {
|
||||||
|
|
@ -271,11 +271,7 @@ fn vtable_entries<'tcx>(
|
||||||
// do not hold for this particular set of type parameters.
|
// do not hold for this particular set of type parameters.
|
||||||
// Note that this method could then never be called, so we
|
// Note that this method could then never be called, so we
|
||||||
// do not want to try and codegen it, in that case (see #23435).
|
// do not want to try and codegen it, in that case (see #23435).
|
||||||
let predicates = tcx.predicates_of(def_id).instantiate_own(tcx, args);
|
if tcx.instantiate_and_check_impossible_predicates((def_id, args)) {
|
||||||
if impossible_predicates(
|
|
||||||
tcx,
|
|
||||||
predicates.map(|(predicate, _)| predicate).collect(),
|
|
||||||
) {
|
|
||||||
debug!("vtable_entries: predicates do not hold");
|
debug!("vtable_entries: predicates do not hold");
|
||||||
return VtblEntry::Vacant;
|
return VtblEntry::Vacant;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,18 +0,0 @@
|
||||||
//@ known-bug: #137190
|
|
||||||
trait Supertrait<T> {
|
|
||||||
fn method(&self) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
trait Trait<P>: Supertrait<()> {}
|
|
||||||
|
|
||||||
impl<P> Trait<P> for () {}
|
|
||||||
|
|
||||||
const fn upcast<P>(x: &dyn Trait<P>) -> &dyn Supertrait<()> {
|
|
||||||
x
|
|
||||||
}
|
|
||||||
|
|
||||||
const fn foo() -> &'static dyn Supertrait<()> {
|
|
||||||
upcast::<()>(&())
|
|
||||||
}
|
|
||||||
|
|
||||||
const _: &'static dyn Supertrait<()> = foo();
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
//@ known-bug: #137190
|
|
||||||
trait Supertrait {
|
|
||||||
fn method(&self) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
trait Trait: Supertrait {}
|
|
||||||
|
|
||||||
impl Trait for () {}
|
|
||||||
|
|
||||||
const _: &dyn Supertrait = &() as &dyn Trait as &dyn Supertrait;
|
|
||||||
|
|
@ -1,4 +1,8 @@
|
||||||
//@ known-bug: #135470
|
// Regression test for #135470.
|
||||||
|
// Verify that we don't ICE when building vtable entries
|
||||||
|
// for a blanket impl involving async and impossible predicates.
|
||||||
|
|
||||||
|
//@ check-pass
|
||||||
//@ compile-flags: -Copt-level=0
|
//@ compile-flags: -Copt-level=0
|
||||||
//@ edition: 2021
|
//@ edition: 2021
|
||||||
|
|
||||||
25
tests/ui/coercion/vtable-unsatisfied-supertrait-generics.rs
Normal file
25
tests/ui/coercion/vtable-unsatisfied-supertrait-generics.rs
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
// Regression test for #137190.
|
||||||
|
// Variant of vtable-unsatisfied-supertrait.rs with generic traits.
|
||||||
|
// Verify that we don't ICE when building vtable entries
|
||||||
|
// for a generic trait whose supertrait is not implemented.
|
||||||
|
|
||||||
|
//@ compile-flags: --crate-type lib
|
||||||
|
|
||||||
|
trait Supertrait<T> {
|
||||||
|
fn method(&self) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
trait Trait<P>: Supertrait<()> {}
|
||||||
|
|
||||||
|
impl<P> Trait<P> for () {}
|
||||||
|
//~^ ERROR the trait bound `(): Supertrait<()>` is not satisfied
|
||||||
|
|
||||||
|
const fn upcast<P>(x: &dyn Trait<P>) -> &dyn Supertrait<()> {
|
||||||
|
x
|
||||||
|
}
|
||||||
|
|
||||||
|
const fn foo() -> &'static dyn Supertrait<()> {
|
||||||
|
upcast::<()>(&())
|
||||||
|
}
|
||||||
|
|
||||||
|
const _: &'static dyn Supertrait<()> = foo();
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
error[E0277]: the trait bound `(): Supertrait<()>` is not satisfied
|
||||||
|
--> $DIR/vtable-unsatisfied-supertrait-generics.rs:14:22
|
||||||
|
|
|
||||||
|
LL | impl<P> Trait<P> for () {}
|
||||||
|
| ^^ the trait `Supertrait<()>` is not implemented for `()`
|
||||||
|
|
|
||||||
|
help: this trait has no implementations, consider adding one
|
||||||
|
--> $DIR/vtable-unsatisfied-supertrait-generics.rs:8:1
|
||||||
|
|
|
||||||
|
LL | trait Supertrait<T> {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^
|
||||||
|
note: required by a bound in `Trait`
|
||||||
|
--> $DIR/vtable-unsatisfied-supertrait-generics.rs:12:17
|
||||||
|
|
|
||||||
|
LL | trait Trait<P>: Supertrait<()> {}
|
||||||
|
| ^^^^^^^^^^^^^^ required by this bound in `Trait`
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
||||||
16
tests/ui/coercion/vtable-unsatisfied-supertrait.rs
Normal file
16
tests/ui/coercion/vtable-unsatisfied-supertrait.rs
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
// Regression test for #137190.
|
||||||
|
// Verify that we don't ICE when building vtable entries
|
||||||
|
// for a trait whose supertrait is not implemented.
|
||||||
|
|
||||||
|
//@ compile-flags: --crate-type lib
|
||||||
|
|
||||||
|
trait Supertrait {
|
||||||
|
fn method(&self) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
trait Trait: Supertrait {}
|
||||||
|
|
||||||
|
impl Trait for () {}
|
||||||
|
//~^ ERROR the trait bound `(): Supertrait` is not satisfied
|
||||||
|
|
||||||
|
const _: &dyn Supertrait = &() as &dyn Trait as &dyn Supertrait;
|
||||||
20
tests/ui/coercion/vtable-unsatisfied-supertrait.stderr
Normal file
20
tests/ui/coercion/vtable-unsatisfied-supertrait.stderr
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
error[E0277]: the trait bound `(): Supertrait` is not satisfied
|
||||||
|
--> $DIR/vtable-unsatisfied-supertrait.rs:13:16
|
||||||
|
|
|
||||||
|
LL | impl Trait for () {}
|
||||||
|
| ^^ the trait `Supertrait` is not implemented for `()`
|
||||||
|
|
|
||||||
|
help: this trait has no implementations, consider adding one
|
||||||
|
--> $DIR/vtable-unsatisfied-supertrait.rs:7:1
|
||||||
|
|
|
||||||
|
LL | trait Supertrait {
|
||||||
|
| ^^^^^^^^^^^^^^^^
|
||||||
|
note: required by a bound in `Trait`
|
||||||
|
--> $DIR/vtable-unsatisfied-supertrait.rs:11:14
|
||||||
|
|
|
||||||
|
LL | trait Trait: Supertrait {}
|
||||||
|
| ^^^^^^^^^^ required by this bound in `Trait`
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
||||||
Loading…
Add table
Add a link
Reference in a new issue