Skip to content

Commit 4aa1e7a

Browse files
estebankMark-Simulacrum
authored andcommitted
Avoid ICE when adjusting bad self ty
1 parent 4377d2e commit 4aa1e7a

File tree

3 files changed

+96
-5
lines changed

3 files changed

+96
-5
lines changed

src/librustc_typeck/check/method/confirm.rs

+15-5
Original file line numberDiff line numberDiff line change
@@ -141,14 +141,24 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
141141
///////////////////////////////////////////////////////////////////////////
142142
// ADJUSTMENTS
143143

144-
fn adjust_self_ty(&mut self,
145-
unadjusted_self_ty: Ty<'tcx>,
146-
pick: &probe::Pick<'tcx>)
147-
-> Ty<'tcx> {
144+
fn adjust_self_ty(
145+
&mut self,
146+
unadjusted_self_ty: Ty<'tcx>,
147+
pick: &probe::Pick<'tcx>,
148+
) -> Ty<'tcx> {
148149
// Commit the autoderefs by calling `autoderef` again, but this
149150
// time writing the results into the various tables.
150151
let mut autoderef = self.autoderef(self.span, unadjusted_self_ty);
151-
let (_, n) = autoderef.nth(pick.autoderefs).unwrap();
152+
let (_, n) = match autoderef.nth(pick.autoderefs) {
153+
Some(n) => n,
154+
None => {
155+
self.tcx.sess.delay_span_bug(
156+
syntax_pos::DUMMY_SP,
157+
&format!("failed autoderef {}", pick.autoderefs),
158+
);
159+
return self.tcx.types.err;
160+
}
161+
};
152162
assert_eq!(n, pick.autoderefs);
153163

154164
let mut adjustments = autoderef.adjust_steps(self, Needs::None);

src/test/ui/issues/issue-65611.rs

+63
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
use std::mem::MaybeUninit;
2+
use std::ops::Deref;
3+
4+
pub unsafe trait Array {
5+
/// The array’s element type
6+
type Item;
7+
#[doc(hidden)]
8+
/// The smallest index type that indexes the array.
9+
type Index: Index;
10+
#[doc(hidden)]
11+
fn as_ptr(&self) -> *const Self::Item;
12+
#[doc(hidden)]
13+
fn as_mut_ptr(&mut self) -> *mut Self::Item;
14+
#[doc(hidden)]
15+
fn capacity() -> usize;
16+
}
17+
18+
pub trait Index : PartialEq + Copy {
19+
fn to_usize(self) -> usize;
20+
fn from(usize) -> Self;
21+
}
22+
23+
impl Index for usize {
24+
fn to_usize(self) -> usize { self }
25+
fn from(val: usize) -> Self {
26+
val
27+
}
28+
}
29+
30+
unsafe impl<T> Array for [T; 1] {
31+
type Item = T;
32+
type Index = usize;
33+
fn as_ptr(&self) -> *const T { self as *const _ as *const _ }
34+
fn as_mut_ptr(&mut self) -> *mut T { self as *mut _ as *mut _}
35+
fn capacity() -> usize { 1 }
36+
}
37+
38+
impl<A: Array> Deref for ArrayVec<A> {
39+
type Target = [A::Item];
40+
#[inline]
41+
fn deref(&self) -> &[A::Item] {
42+
panic!()
43+
}
44+
}
45+
46+
pub struct ArrayVec<A: Array> {
47+
xs: MaybeUninit<A>,
48+
len: usize,
49+
}
50+
51+
impl<A: Array> ArrayVec<A> {
52+
pub fn new() -> ArrayVec<A> {
53+
panic!()
54+
}
55+
}
56+
57+
fn main() {
58+
let mut buffer = ArrayVec::new();
59+
let x = buffer.last().unwrap().0.clone();
60+
//~^ ERROR type annotations needed
61+
//~| ERROR no field `0` on type `&_`
62+
buffer.reverse();
63+
}

src/test/ui/issues/issue-65611.stderr

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
error[E0282]: type annotations needed
2+
--> $DIR/issue-65611.rs:59:20
3+
|
4+
LL | let x = buffer.last().unwrap().0.clone();
5+
| ^^^^ cannot infer type for `T`
6+
|
7+
= note: type must be known at this point
8+
9+
error[E0609]: no field `0` on type `&_`
10+
--> $DIR/issue-65611.rs:59:36
11+
|
12+
LL | let x = buffer.last().unwrap().0.clone();
13+
| ^
14+
15+
error: aborting due to 2 previous errors
16+
17+
Some errors have detailed explanations: E0282, E0609.
18+
For more information about an error, try `rustc --explain E0282`.

0 commit comments

Comments
 (0)