about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorMazdak Farrokhzad <twingoow@gmail.com>2019-10-24 20:20:08 +0200
committerGitHub <noreply@github.com>2019-10-24 20:20:08 +0200
commit7b3896fdf2ebf3f5e466b6d4147c0451bae2909f (patch)
tree0f485d3f9916d018027e3e7400acbf149e31fff5 /src
parent1b0367146a55d245373e135deac6978a1095224e (diff)
parent18d873e8f0d10ad61a6110af28e2d1008e6acd16 (diff)
downloadrust-7b3896fdf2ebf3f5e466b6d4147c0451bae2909f.tar.gz
rust-7b3896fdf2ebf3f5e466b6d4147c0451bae2909f.zip
Rollup merge of #65755 - estebank:icicle, r=davidtwco
Avoid ICE when adjusting bad self ty

Fix #65611.
Diffstat (limited to 'src')
-rw-r--r--src/librustc_typeck/check/method/confirm.rs20
-rw-r--r--src/test/ui/issues/issue-65611.rs63
-rw-r--r--src/test/ui/issues/issue-65611.stderr18
3 files changed, 96 insertions, 5 deletions
diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs
index 9baf06be3f6..59636d32bc0 100644
--- a/src/librustc_typeck/check/method/confirm.rs
+++ b/src/librustc_typeck/check/method/confirm.rs
@@ -141,14 +141,24 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
     ///////////////////////////////////////////////////////////////////////////
     // ADJUSTMENTS
 
-    fn adjust_self_ty(&mut self,
-                      unadjusted_self_ty: Ty<'tcx>,
-                      pick: &probe::Pick<'tcx>)
-                      -> Ty<'tcx> {
+    fn adjust_self_ty(
+        &mut self,
+        unadjusted_self_ty: Ty<'tcx>,
+        pick: &probe::Pick<'tcx>,
+    ) -> Ty<'tcx> {
         // Commit the autoderefs by calling `autoderef` again, but this
         // time writing the results into the various tables.
         let mut autoderef = self.autoderef(self.span, unadjusted_self_ty);
-        let (_, n) = autoderef.nth(pick.autoderefs).unwrap();
+        let (_, n) = match autoderef.nth(pick.autoderefs) {
+            Some(n) => n,
+            None => {
+                self.tcx.sess.delay_span_bug(
+                    syntax_pos::DUMMY_SP,
+                    &format!("failed autoderef {}", pick.autoderefs),
+                );
+                return self.tcx.types.err;
+            }
+        };
         assert_eq!(n, pick.autoderefs);
 
         let mut adjustments = autoderef.adjust_steps(self, Needs::None);
diff --git a/src/test/ui/issues/issue-65611.rs b/src/test/ui/issues/issue-65611.rs
new file mode 100644
index 00000000000..b74ee1b0c6e
--- /dev/null
+++ b/src/test/ui/issues/issue-65611.rs
@@ -0,0 +1,63 @@
+use std::mem::MaybeUninit;
+use std::ops::Deref;
+
+pub unsafe trait Array {
+    /// The array’s element type
+    type Item;
+    #[doc(hidden)]
+    /// The smallest index type that indexes the array.
+    type Index: Index;
+    #[doc(hidden)]
+    fn as_ptr(&self) -> *const Self::Item;
+    #[doc(hidden)]
+    fn as_mut_ptr(&mut self) -> *mut Self::Item;
+    #[doc(hidden)]
+    fn capacity() -> usize;
+}
+
+pub trait Index : PartialEq + Copy {
+    fn to_usize(self) -> usize;
+    fn from(usize) -> Self;
+}
+
+impl Index for usize {
+    fn to_usize(self) -> usize { self }
+    fn from(val: usize) -> Self {
+        val
+    }
+}
+
+unsafe impl<T> Array for [T; 1] {
+    type Item = T;
+    type Index = usize;
+    fn as_ptr(&self) -> *const T { self as *const _ as *const _ }
+    fn as_mut_ptr(&mut self) -> *mut T { self as *mut _ as *mut _}
+    fn capacity() -> usize { 1 }
+}
+
+impl<A: Array> Deref for ArrayVec<A> {
+    type Target = [A::Item];
+    #[inline]
+    fn deref(&self) -> &[A::Item] {
+        panic!()
+    }
+}
+
+pub struct ArrayVec<A: Array> {
+    xs: MaybeUninit<A>,
+    len: usize,
+}
+
+impl<A: Array> ArrayVec<A> {
+    pub fn new() -> ArrayVec<A> {
+        panic!()
+    }
+}
+
+fn main() {
+    let mut buffer = ArrayVec::new();
+    let x = buffer.last().unwrap().0.clone();
+    //~^ ERROR type annotations needed
+    //~| ERROR no field `0` on type `&_`
+    buffer.reverse();
+}
diff --git a/src/test/ui/issues/issue-65611.stderr b/src/test/ui/issues/issue-65611.stderr
new file mode 100644
index 00000000000..cb441c13c6b
--- /dev/null
+++ b/src/test/ui/issues/issue-65611.stderr
@@ -0,0 +1,18 @@
+error[E0282]: type annotations needed
+  --> $DIR/issue-65611.rs:59:20
+   |
+LL |     let x = buffer.last().unwrap().0.clone();
+   |                    ^^^^ cannot infer type for `T`
+   |
+   = note: type must be known at this point
+
+error[E0609]: no field `0` on type `&_`
+  --> $DIR/issue-65611.rs:59:36
+   |
+LL |     let x = buffer.last().unwrap().0.clone();
+   |                                    ^
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0282, E0609.
+For more information about an error, try `rustc --explain E0282`.