From f02dc74c2cf1afb049f8978c885589a26fb6676b Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 16 Mar 2018 12:45:47 -0400 Subject: [PATCH] extend stable hasher to support `CanonicalTy` --- src/librustc/ich/impls_ty.rs | 50 +++++++++++++++++++- src/librustc/macros.rs | 2 +- src/librustc/traits/query/dropck_outlives.rs | 1 + src/test/incremental/issue-49043.rs | 22 +++++++++ 4 files changed, 72 insertions(+), 3 deletions(-) create mode 100644 src/test/incremental/issue-49043.rs diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs index bb3051b546e64..3d5b65d5ac877 100644 --- a/src/librustc/ich/impls_ty.rs +++ b/src/librustc/ich/impls_ty.rs @@ -902,13 +902,59 @@ for ty::TypeVariants<'gcx> TyForeign(def_id) => { def_id.hash_stable(hcx, hasher); } - TyInfer(..) => { - bug!("ty::TypeVariants::hash_stable() - Unexpected variant {:?}.", *self) + TyInfer(infer_ty) => { + infer_ty.hash_stable(hcx, hasher); } } } } +impl_stable_hash_for!(enum ty::InferTy { + TyVar(a), + IntVar(a), + FloatVar(a), + FreshTy(a), + FreshIntTy(a), + FreshFloatTy(a), + CanonicalTy(a), +}); + +impl<'a, 'gcx> HashStable> +for ty::TyVid +{ + fn hash_stable(&self, + _hcx: &mut StableHashingContext<'a>, + _hasher: &mut StableHasher) { + // TyVid values are confined to an inference context and hence + // should not be hashed. + bug!("ty::TypeVariants::hash_stable() - can't hash a TyVid {:?}.", *self) + } +} + +impl<'a, 'gcx> HashStable> +for ty::IntVid +{ + fn hash_stable(&self, + _hcx: &mut StableHashingContext<'a>, + _hasher: &mut StableHasher) { + // IntVid values are confined to an inference context and hence + // should not be hashed. + bug!("ty::TypeVariants::hash_stable() - can't hash an IntVid {:?}.", *self) + } +} + +impl<'a, 'gcx> HashStable> +for ty::FloatVid +{ + fn hash_stable(&self, + _hcx: &mut StableHashingContext<'a>, + _hasher: &mut StableHasher) { + // FloatVid values are confined to an inference context and hence + // should not be hashed. + bug!("ty::TypeVariants::hash_stable() - can't hash a FloatVid {:?}.", *self) + } +} + impl_stable_hash_for!(struct ty::ParamTy { idx, name diff --git a/src/librustc/macros.rs b/src/librustc/macros.rs index d8a723e184d2c..7dc84b9ca2956 100644 --- a/src/librustc/macros.rs +++ b/src/librustc/macros.rs @@ -72,7 +72,7 @@ macro_rules! __impl_stable_hash_field { #[macro_export] macro_rules! impl_stable_hash_for { - (enum $enum_name:path { $( $variant:ident $( ( $($arg:ident),* ) )* ),* }) => { + (enum $enum_name:path { $( $variant:ident $( ( $($arg:ident),* ) )* ),* $(,)* }) => { impl<'a, 'tcx> ::rustc_data_structures::stable_hasher::HashStable<$crate::ich::StableHashingContext<'a>> for $enum_name { #[inline] fn hash_stable(&self, diff --git a/src/librustc/traits/query/dropck_outlives.rs b/src/librustc/traits/query/dropck_outlives.rs index 1caab6fd89ef9..017c4f5262e25 100644 --- a/src/librustc/traits/query/dropck_outlives.rs +++ b/src/librustc/traits/query/dropck_outlives.rs @@ -51,6 +51,7 @@ impl<'cx, 'gcx, 'tcx> At<'cx, 'gcx, 'tcx> { let gcx = tcx.global_tcx(); let (c_ty, orig_values) = self.infcx.canonicalize_query(&self.param_env.and(ty)); let span = self.cause.span; + debug!("c_ty = {:?}", c_ty); match &gcx.dropck_outlives(c_ty) { Ok(result) if result.is_proven() => { match self.infcx.instantiate_query_result( diff --git a/src/test/incremental/issue-49043.rs b/src/test/incremental/issue-49043.rs new file mode 100644 index 0000000000000..118027b190e29 --- /dev/null +++ b/src/test/incremental/issue-49043.rs @@ -0,0 +1,22 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Regression test for hashing involving canonical variables. In this +// test -- which has an intensional error -- the type of the value +// being dropped winds up including a type variable. Canonicalization +// would then produce a `?0` which -- in turn -- triggered an ICE in +// hashing. + +// revisions:cfail1 + +fn main() { + println!("Hello, world! {}",*thread_rng().choose(&[0, 1, 2, 3]).unwrap()); + //[cfail1]~^ ERROR cannot find function `thread_rng` +}