Skip to content

Commit 148a44a

Browse files
authored
Rollup merge of rust-lang#97595 - ouz-a:issue-97381, r=compiler-errors
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` 😅
2 parents 47aee31 + 8f1fff0 commit 148a44a

File tree

6 files changed

+132
-11
lines changed

6 files changed

+132
-11
lines changed

compiler/rustc_trait_selection/src/traits/util.rs

+8-6
Original file line numberDiff line numberDiff line change
@@ -304,22 +304,24 @@ pub fn get_vtable_index_of_object_method<'tcx, N>(
304304
tcx: TyCtxt<'tcx>,
305305
object: &super::ImplSourceObjectData<'tcx, N>,
306306
method_def_id: DefId,
307-
) -> usize {
307+
) -> Option<usize> {
308308
let existential_trait_ref = object
309309
.upcast_trait_ref
310310
.map_bound(|trait_ref| ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref));
311311
let existential_trait_ref = tcx.erase_regions(existential_trait_ref);
312+
312313
// Count number of methods preceding the one we are selecting and
313314
// add them to the total offset.
314-
let index = tcx
315+
if let Some(index) = tcx
315316
.own_existential_vtable_entries(existential_trait_ref)
316317
.iter()
317318
.copied()
318319
.position(|def_id| def_id == method_def_id)
319-
.unwrap_or_else(|| {
320-
bug!("get_vtable_index_of_object_method: {:?} was not found", method_def_id);
321-
});
322-
object.vtable_base + index
320+
{
321+
Some(object.vtable_base + index)
322+
} else {
323+
None
324+
}
323325
}
324326

325327
pub fn closure_trait_ref_and_return_type<'tcx>(

compiler/rustc_ty_utils/src/instance.rs

+9-5
Original file line numberDiff line numberDiff line change
@@ -347,11 +347,15 @@ fn resolve_associated_item<'tcx>(
347347
_ => None,
348348
},
349349
traits::ImplSource::Object(ref data) => {
350-
let index = traits::get_vtable_index_of_object_method(tcx, data, trait_item_id);
351-
Some(Instance {
352-
def: ty::InstanceDef::Virtual(trait_item_id, index),
353-
substs: rcvr_substs,
354-
})
350+
if let Some(index) = traits::get_vtable_index_of_object_method(tcx, data, trait_item_id)
351+
{
352+
Some(Instance {
353+
def: ty::InstanceDef::Virtual(trait_item_id, index),
354+
substs: rcvr_substs,
355+
})
356+
} else {
357+
None
358+
}
355359
}
356360
traits::ImplSource::Builtin(..) => {
357361
if Some(trait_ref.def_id) == tcx.lang_items().clone_trait() {
+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
use std::ops::Deref;
2+
trait MyTrait: Deref<Target = u32> {}
3+
struct MyStruct(u32);
4+
impl MyTrait for MyStruct {}
5+
impl Deref for MyStruct {
6+
type Target = u32;
7+
8+
fn deref(&self) -> &Self::Target {
9+
&self.0
10+
}
11+
}
12+
fn get_concrete_value(i: u32) -> MyStruct {
13+
MyStruct(i)
14+
}
15+
fn get_boxed_value(i: u32) -> Box<dyn MyTrait> {
16+
Box::new(get_concrete_value(i))
17+
}
18+
fn main() {
19+
let v = [1, 2, 3]
20+
.iter()
21+
.map(|i| get_boxed_value(*i))
22+
.collect::<Vec<_>>();
23+
24+
let el = &v[0];
25+
26+
for _ in v {
27+
//~^ ERROR cannot move out of `v` because it is borrowed
28+
println!("{}", ***el > 0);
29+
}
30+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
error[E0505]: cannot move out of `v` because it is borrowed
2+
--> $DIR/issue-97381.rs:26:14
3+
|
4+
LL | let el = &v[0];
5+
| - borrow of `v` occurs here
6+
LL |
7+
LL | for _ in v {
8+
| ^ move out of `v` occurs here
9+
LL |
10+
LL | println!("{}", ***el > 0);
11+
| ---- borrow later used here
12+
13+
error: aborting due to previous error
14+
15+
For more information about this error, try `rustc --explain E0505`.
+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// revisions: lib usage
2+
//[lib] compile-flags: --crate-type=lib
3+
//[lib] build-pass
4+
5+
use std::ops::Sub;
6+
trait Vector2 {
7+
type ScalarType;
8+
9+
fn from_values(x: Self::ScalarType, y: Self::ScalarType) -> Self
10+
where
11+
Self: Sized;
12+
13+
fn x(&self) -> Self::ScalarType;
14+
fn y(&self) -> Self::ScalarType;
15+
}
16+
17+
impl<T> Sub for dyn Vector2<ScalarType = T>
18+
where
19+
T: Sub<Output = T>,
20+
(dyn Vector2<ScalarType = T>): Sized,
21+
{
22+
type Output = dyn Vector2<ScalarType = T>;
23+
24+
fn sub(self, rhs: Self) -> Self::Output {
25+
Self::from_values(self.x() - rhs.x(), self.y() - rhs.y())
26+
}
27+
}
28+
29+
struct Vec2 {
30+
x: i32,
31+
y: i32,
32+
}
33+
34+
impl Vector2 for Vec2 {
35+
type ScalarType = i32;
36+
37+
fn from_values(x: Self::ScalarType, y: Self::ScalarType) -> Self
38+
where
39+
Self: Sized,
40+
{
41+
Self { x, y }
42+
}
43+
44+
fn x(&self) -> Self::ScalarType {
45+
self.x
46+
}
47+
fn y(&self) -> Self::ScalarType {
48+
self.y
49+
}
50+
}
51+
52+
#[cfg(usage)]
53+
fn main() {
54+
let hey: Box<dyn Vector2<ScalarType = i32>> = Box::new(Vec2 { x: 1, y: 2 });
55+
let word: Box<dyn Vector2<ScalarType = i32>> = Box::new(Vec2 { x: 1, y: 2 });
56+
57+
let bar = *hey - *word;
58+
//[usage]~^ ERROR cannot subtract
59+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
error[E0369]: cannot subtract `(dyn Vector2<ScalarType = i32> + 'static)` from `dyn Vector2<ScalarType = i32>`
2+
--> $DIR/type-unsatisfiable.rs:57:20
3+
|
4+
LL | let bar = *hey - *word;
5+
| ---- ^ ----- (dyn Vector2<ScalarType = i32> + 'static)
6+
| |
7+
| dyn Vector2<ScalarType = i32>
8+
9+
error: aborting due to previous error
10+
11+
For more information about this error, try `rustc --explain E0369`.

0 commit comments

Comments
 (0)