Skip to content

Commit

Permalink
Rollup merge of rust-lang#97595 - ouz-a:issue-97381, r=compiler-errors
Browse files Browse the repository at this point in the history
Remove unwrap from get_vtable

This avoids ICE on issue rust-lang#97381 I think the bug is a bit deeper though, it compiles fine when `v` is `&v` which makes me think `Deref` is causing some issue with borrowck but it's fine I guess since this thing crashes since `nightly-2020-09-17` 😅
  • Loading branch information
Dylan-DPC authored Jun 8, 2022
2 parents 47aee31 + 8f1fff0 commit 148a44a
Show file tree
Hide file tree
Showing 6 changed files with 132 additions and 11 deletions.
14 changes: 8 additions & 6 deletions compiler/rustc_trait_selection/src/traits/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -304,22 +304,24 @@ pub fn get_vtable_index_of_object_method<'tcx, N>(
tcx: TyCtxt<'tcx>,
object: &super::ImplSourceObjectData<'tcx, N>,
method_def_id: DefId,
) -> usize {
) -> Option<usize> {
let existential_trait_ref = object
.upcast_trait_ref
.map_bound(|trait_ref| ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref));
let existential_trait_ref = tcx.erase_regions(existential_trait_ref);

// Count number of methods preceding the one we are selecting and
// add them to the total offset.
let index = tcx
if let Some(index) = tcx
.own_existential_vtable_entries(existential_trait_ref)
.iter()
.copied()
.position(|def_id| def_id == method_def_id)
.unwrap_or_else(|| {
bug!("get_vtable_index_of_object_method: {:?} was not found", method_def_id);
});
object.vtable_base + index
{
Some(object.vtable_base + index)
} else {
None
}
}

pub fn closure_trait_ref_and_return_type<'tcx>(
Expand Down
14 changes: 9 additions & 5 deletions compiler/rustc_ty_utils/src/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -347,11 +347,15 @@ fn resolve_associated_item<'tcx>(
_ => None,
},
traits::ImplSource::Object(ref data) => {
let index = traits::get_vtable_index_of_object_method(tcx, data, trait_item_id);
Some(Instance {
def: ty::InstanceDef::Virtual(trait_item_id, index),
substs: rcvr_substs,
})
if let Some(index) = traits::get_vtable_index_of_object_method(tcx, data, trait_item_id)
{
Some(Instance {
def: ty::InstanceDef::Virtual(trait_item_id, index),
substs: rcvr_substs,
})
} else {
None
}
}
traits::ImplSource::Builtin(..) => {
if Some(trait_ref.def_id) == tcx.lang_items().clone_trait() {
Expand Down
30 changes: 30 additions & 0 deletions src/test/ui/traits/vtable/issue-97381.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
use std::ops::Deref;
trait MyTrait: Deref<Target = u32> {}
struct MyStruct(u32);
impl MyTrait for MyStruct {}
impl Deref for MyStruct {
type Target = u32;

fn deref(&self) -> &Self::Target {
&self.0
}
}
fn get_concrete_value(i: u32) -> MyStruct {
MyStruct(i)
}
fn get_boxed_value(i: u32) -> Box<dyn MyTrait> {
Box::new(get_concrete_value(i))
}
fn main() {
let v = [1, 2, 3]
.iter()
.map(|i| get_boxed_value(*i))
.collect::<Vec<_>>();

let el = &v[0];

for _ in v {
//~^ ERROR cannot move out of `v` because it is borrowed
println!("{}", ***el > 0);
}
}
15 changes: 15 additions & 0 deletions src/test/ui/traits/vtable/issue-97381.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
error[E0505]: cannot move out of `v` because it is borrowed
--> $DIR/issue-97381.rs:26:14
|
LL | let el = &v[0];
| - borrow of `v` occurs here
LL |
LL | for _ in v {
| ^ move out of `v` occurs here
LL |
LL | println!("{}", ***el > 0);
| ---- borrow later used here

error: aborting due to previous error

For more information about this error, try `rustc --explain E0505`.
59 changes: 59 additions & 0 deletions src/test/ui/type/type-unsatisfiable.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// revisions: lib usage
//[lib] compile-flags: --crate-type=lib
//[lib] build-pass

use std::ops::Sub;
trait Vector2 {
type ScalarType;

fn from_values(x: Self::ScalarType, y: Self::ScalarType) -> Self
where
Self: Sized;

fn x(&self) -> Self::ScalarType;
fn y(&self) -> Self::ScalarType;
}

impl<T> Sub for dyn Vector2<ScalarType = T>
where
T: Sub<Output = T>,
(dyn Vector2<ScalarType = T>): Sized,
{
type Output = dyn Vector2<ScalarType = T>;

fn sub(self, rhs: Self) -> Self::Output {
Self::from_values(self.x() - rhs.x(), self.y() - rhs.y())
}
}

struct Vec2 {
x: i32,
y: i32,
}

impl Vector2 for Vec2 {
type ScalarType = i32;

fn from_values(x: Self::ScalarType, y: Self::ScalarType) -> Self
where
Self: Sized,
{
Self { x, y }
}

fn x(&self) -> Self::ScalarType {
self.x
}
fn y(&self) -> Self::ScalarType {
self.y
}
}

#[cfg(usage)]
fn main() {
let hey: Box<dyn Vector2<ScalarType = i32>> = Box::new(Vec2 { x: 1, y: 2 });
let word: Box<dyn Vector2<ScalarType = i32>> = Box::new(Vec2 { x: 1, y: 2 });

let bar = *hey - *word;
//[usage]~^ ERROR cannot subtract
}
11 changes: 11 additions & 0 deletions src/test/ui/type/type-unsatisfiable.usage.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
error[E0369]: cannot subtract `(dyn Vector2<ScalarType = i32> + 'static)` from `dyn Vector2<ScalarType = i32>`
--> $DIR/type-unsatisfiable.rs:57:20
|
LL | let bar = *hey - *word;
| ---- ^ ----- (dyn Vector2<ScalarType = i32> + 'static)
| |
| dyn Vector2<ScalarType = i32>

error: aborting due to previous error

For more information about this error, try `rustc --explain E0369`.

0 comments on commit 148a44a

Please sign in to comment.