Skip to content

Commit

Permalink
Rollup merge of rust-lang#65755 - estebank:icicle, r=davidtwco
Browse files Browse the repository at this point in the history
Avoid ICE when adjusting bad self ty

Fix rust-lang#65611.
  • Loading branch information
Centril authored Oct 24, 2019
2 parents 6653c77 + 18d873e commit 3312147
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 5 deletions.
20 changes: 15 additions & 5 deletions src/librustc_typeck/check/method/confirm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
63 changes: 63 additions & 0 deletions src/test/ui/issues/issue-65611.rs
Original file line number Diff line number Diff line change
@@ -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();
}
18 changes: 18 additions & 0 deletions src/test/ui/issues/issue-65611.stderr
Original file line number Diff line number Diff line change
@@ -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`.

0 comments on commit 3312147

Please sign in to comment.