From 8c7d0077ab51a076d79ff8e91d7845e745f90b21 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sun, 19 Feb 2017 00:15:30 +0300 Subject: [PATCH] Avoid ICE in Self::Assoc in impl headers --- src/librustc_typeck/astconv.rs | 14 +++++++++++++- src/test/compile-fail/resolve-self-in-impl.rs | 3 +++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index fb6d28448a0..ab1897101eb 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -918,7 +918,19 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { (_, Def::SelfTy(Some(_), Some(impl_def_id))) => { // `Self` in an impl of a trait - we have a concrete self type and a // trait reference. - let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap(); + // FIXME: Self type is not always computed when we are here because type parameter + // bounds may affect Self type and have to be converted before it. + let trait_ref = if impl_def_id.is_local() { + tcx.impl_trait_refs.borrow().get(&impl_def_id).cloned().and_then(|x| x) + } else { + tcx.impl_trait_ref(impl_def_id) + }; + let trait_ref = if let Some(trait_ref) = trait_ref { + trait_ref + } else { + tcx.sess.span_err(span, "`Self` type is used before it's determined"); + return (tcx.types.err, Def::Err); + }; let trait_ref = if let Some(free_substs) = self.get_free_substs() { trait_ref.subst(tcx, free_substs) } else { diff --git a/src/test/compile-fail/resolve-self-in-impl.rs b/src/test/compile-fail/resolve-self-in-impl.rs index 82037b6c9ed..04f98c7ab32 100644 --- a/src/test/compile-fail/resolve-self-in-impl.rs +++ b/src/test/compile-fail/resolve-self-in-impl.rs @@ -18,9 +18,12 @@ impl> Tr for S {} //~ ERROR `Self` type is used before it's deter impl Tr for S {} //~ ERROR `Self` type is used before it's determined impl Tr for S where Self: Copy {} //~ ERROR `Self` type is used before it's determined impl Tr for S where S: Copy {} //~ ERROR `Self` type is used before it's determined +impl Tr for S where Self::Assoc: Copy {} //~ ERROR `Self` type is used before it's determined + //~^ ERROR `Self` type is used before it's determined impl Tr for Self {} //~ ERROR `Self` type is used before it's determined impl Tr for S {} //~ ERROR `Self` type is used before it's determined impl Self {} //~ ERROR `Self` type is used before it's determined impl S {} //~ ERROR `Self` type is used before it's determined +impl Tr for S {} //~ ERROR `Self` type is used before it's determined fn main() {}