From 7401e3def59452e795468d4d5e4f30c7ef100fec Mon Sep 17 00:00:00 2001 From: scalexm Date: Fri, 2 Nov 2018 15:08:51 +0100 Subject: [PATCH 01/11] Distinguish between placeholder kinds --- src/librustc/infer/canonical/mod.rs | 6 +++--- src/librustc/infer/higher_ranked/mod.rs | 2 +- src/librustc/infer/mod.rs | 2 +- src/librustc/infer/nll_relate/mod.rs | 4 ++-- src/librustc/ty/mod.rs | 21 ++++++++++++++++--- src/librustc/ty/sty.rs | 2 +- src/librustc/util/ppaux.rs | 2 +- .../borrow_check/error_reporting.rs | 4 ++-- .../borrow_check/nll/region_infer/mod.rs | 2 +- .../borrow_check/nll/region_infer/values.rs | 18 ++++++++-------- .../borrow_check/nll/type_check/mod.rs | 2 +- .../borrow_check/nll/type_check/relate_tys.rs | 5 ++++- 12 files changed, 44 insertions(+), 26 deletions(-) diff --git a/src/librustc/infer/canonical/mod.rs b/src/librustc/infer/canonical/mod.rs index f7eb7118f412f..41839d61d3260 100644 --- a/src/librustc/infer/canonical/mod.rs +++ b/src/librustc/infer/canonical/mod.rs @@ -142,7 +142,7 @@ pub enum CanonicalVarKind { /// A "placeholder" that represents "any region". Created when you /// are solving a goal like `for<'a> T: Foo<'a>` to represent the /// bound region `'a`. - PlaceholderRegion(ty::Placeholder), + PlaceholderRegion(ty::PlaceholderRegion), } impl CanonicalVarKind { @@ -374,9 +374,9 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> { universe_map(ui), ).into(), - CanonicalVarKind::PlaceholderRegion(ty::Placeholder { universe, name }) => { + CanonicalVarKind::PlaceholderRegion(ty::PlaceholderRegion { universe, name }) => { let universe_mapped = universe_map(universe); - let placeholder_mapped = ty::Placeholder { + let placeholder_mapped = ty::PlaceholderRegion { universe: universe_mapped, name, }; diff --git a/src/librustc/infer/higher_ranked/mod.rs b/src/librustc/infer/higher_ranked/mod.rs index 8172f620c3646..ddf46b18ef730 100644 --- a/src/librustc/infer/higher_ranked/mod.rs +++ b/src/librustc/infer/higher_ranked/mod.rs @@ -340,7 +340,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { let next_universe = self.create_next_universe(); let (result, map) = self.tcx.replace_late_bound_regions(binder, |br| { - self.tcx.mk_region(ty::RePlaceholder(ty::Placeholder { + self.tcx.mk_region(ty::RePlaceholder(ty::PlaceholderRegion { universe: next_universe, name: br, })) diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index 87e32be1a1759..dfe6aa160b3ad 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -411,7 +411,7 @@ pub enum NLLRegionVariableOrigin { /// "Universal" instantiation of a higher-ranked region (e.g., /// from a `for<'a> T` binder). Meant to represent "any region". - Placeholder(ty::Placeholder), + Placeholder(ty::PlaceholderRegion), Existential, } diff --git a/src/librustc/infer/nll_relate/mod.rs b/src/librustc/infer/nll_relate/mod.rs index e003c1989e096..9bdbf77fee0a9 100644 --- a/src/librustc/infer/nll_relate/mod.rs +++ b/src/librustc/infer/nll_relate/mod.rs @@ -95,7 +95,7 @@ pub trait TypeRelatingDelegate<'tcx> { /// So e.g. if you have `for<'a> fn(..) <: for<'b> fn(..)`, then /// we will invoke this method to instantiate `'b` with a /// placeholder region. - fn next_placeholder_region(&mut self, placeholder: ty::Placeholder) -> ty::Region<'tcx>; + fn next_placeholder_region(&mut self, placeholder: ty::PlaceholderRegion) -> ty::Region<'tcx>; /// Creates a new existential region in the given universe. This /// is used when handling subtyping and type variables -- if we @@ -176,7 +176,7 @@ where universe }); - let placeholder = ty::Placeholder { universe, name: br }; + let placeholder = ty::PlaceholderRegion { universe, name: br }; delegate.next_placeholder_region(placeholder) } else { delegate.next_existential_region_var() diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index ad200449f8907..4372beafa6488 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -1587,12 +1587,27 @@ impl UniverseIndex { /// universe are just two regions with an unknown relationship to one /// another. #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, PartialOrd, Ord)] -pub struct Placeholder { +pub struct Placeholder { pub universe: UniverseIndex, - pub name: BoundRegion, + pub name: T, } -impl_stable_hash_for!(struct Placeholder { universe, name }); +impl<'a, 'gcx, T> HashStable> for Placeholder + where T: HashStable> +{ + fn hash_stable( + &self, + hcx: &mut StableHashingContext<'a>, + hasher: &mut StableHasher + ) { + self.universe.hash_stable(hcx, hasher); + self.name.hash_stable(hcx, hasher); + } +} + +pub type PlaceholderRegion = Placeholder; + +pub type PlaceholderType = Placeholder; /// When type checking, we use the `ParamEnv` to track /// details about the set of where-clauses that are in scope at this diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index bd3a34cae90f4..5c01f1cc3e4d7 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -1165,7 +1165,7 @@ pub enum RegionKind { /// A placeholder region - basically the higher-ranked version of ReFree. /// Should not exist after typeck. - RePlaceholder(ty::Placeholder), + RePlaceholder(ty::PlaceholderRegion), /// Empty lifetime is for data that is never accessed. /// Bottom in the region lattice. We treat ReEmpty somewhat diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index d53370d242bd9..613a0dbc61f42 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -792,7 +792,7 @@ define_print! { } ty::ReLateBound(_, br) | ty::ReFree(ty::FreeRegion { bound_region: br, .. }) | - ty::RePlaceholder(ty::Placeholder { name: br, .. }) => { + ty::RePlaceholder(ty::PlaceholderRegion { name: br, .. }) => { write!(f, "{}", br) } ty::ReScope(scope) if cx.identify_regions => { diff --git a/src/librustc_mir/borrow_check/error_reporting.rs b/src/librustc_mir/borrow_check/error_reporting.rs index 3c4d8e09fc166..4ccd26bee8b88 100644 --- a/src/librustc_mir/borrow_check/error_reporting.rs +++ b/src/librustc_mir/borrow_check/error_reporting.rs @@ -2193,7 +2193,7 @@ impl<'tcx> AnnotatedBorrowFnSignature<'tcx> { match ty.sty { ty::TyKind::Ref(ty::RegionKind::ReLateBound(_, br), _, _) | ty::TyKind::Ref( - ty::RegionKind::RePlaceholder(ty::Placeholder { name: br, .. }), + ty::RegionKind::RePlaceholder(ty::PlaceholderRegion { name: br, .. }), _, _, ) => with_highlight_region_for_bound_region(*br, counter, || ty.to_string()), @@ -2207,7 +2207,7 @@ impl<'tcx> AnnotatedBorrowFnSignature<'tcx> { match ty.sty { ty::TyKind::Ref(region, _, _) => match region { ty::RegionKind::ReLateBound(_, br) - | ty::RegionKind::RePlaceholder(ty::Placeholder { name: br, .. }) => { + | ty::RegionKind::RePlaceholder(ty::PlaceholderRegion { name: br, .. }) => { with_highlight_region_for_bound_region(*br, counter, || region.to_string()) } _ => region.to_string(), diff --git a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs index 376f445924270..6a1dc50c67a09 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs @@ -1230,7 +1230,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { mir: &Mir<'tcx>, _mir_def_id: DefId, longer_fr: RegionVid, - placeholder: ty::Placeholder, + placeholder: ty::PlaceholderRegion, ) { debug!( "check_bound_universal_region(fr={:?}, placeholder={:?})", diff --git a/src/librustc_mir/borrow_check/nll/region_infer/values.rs b/src/librustc_mir/borrow_check/nll/region_infer/values.rs index 2b7ef38d3edf9..69e2c896d33e5 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/values.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/values.rs @@ -150,7 +150,7 @@ crate enum RegionElement { /// A placeholder (e.g., instantiated from a `for<'a> fn(&'a u32)` /// type). - PlaceholderRegion(ty::Placeholder), + PlaceholderRegion(ty::PlaceholderRegion), } /// When we initially compute liveness, we use a bit matrix storing @@ -219,17 +219,17 @@ impl LivenessValues { } } -/// Maps from `ty::Placeholder` values that are used in the rest of +/// Maps from `ty::PlaceholderRegion` values that are used in the rest of /// rustc to the internal `PlaceholderIndex` values that are used in /// NLL. #[derive(Default)] crate struct PlaceholderIndices { - to_index: FxHashMap, - from_index: IndexVec, + to_index: FxHashMap, + from_index: IndexVec, } impl PlaceholderIndices { - crate fn insert(&mut self, placeholder: ty::Placeholder) -> PlaceholderIndex { + crate fn insert(&mut self, placeholder: ty::PlaceholderRegion) -> PlaceholderIndex { let PlaceholderIndices { to_index, from_index, @@ -239,11 +239,11 @@ impl PlaceholderIndices { .or_insert_with(|| from_index.push(placeholder)) } - crate fn lookup_index(&self, placeholder: ty::Placeholder) -> PlaceholderIndex { + crate fn lookup_index(&self, placeholder: ty::PlaceholderRegion) -> PlaceholderIndex { self.to_index[&placeholder] } - crate fn lookup_placeholder(&self, placeholder: PlaceholderIndex) -> ty::Placeholder { + crate fn lookup_placeholder(&self, placeholder: PlaceholderIndex) -> ty::PlaceholderRegion { self.from_index[placeholder] } @@ -375,7 +375,7 @@ impl RegionValues { crate fn placeholders_contained_in<'a>( &'a self, r: N, - ) -> impl Iterator + 'a { + ) -> impl Iterator + 'a { self.placeholders .row(r) .into_iter() @@ -432,7 +432,7 @@ impl ToElementIndex for RegionVid { } } -impl ToElementIndex for ty::Placeholder { +impl ToElementIndex for ty::PlaceholderRegion { fn add_to_row(self, values: &mut RegionValues, row: N) -> bool { let index = values.placeholder_indices.lookup_index(self); values.placeholders.insert(row, index) diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs index 06dfd4bc2cc1f..6f4d8c2bef934 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs @@ -777,7 +777,7 @@ impl MirTypeckRegionConstraints<'tcx> { fn placeholder_region( &mut self, infcx: &InferCtxt<'_, '_, 'tcx>, - placeholder: ty::Placeholder, + placeholder: ty::PlaceholderRegion, ) -> ty::Region<'tcx> { let placeholder_index = self.placeholder_indices.insert(placeholder); match self.placeholder_index_to_region.get(placeholder_index) { diff --git a/src/librustc_mir/borrow_check/nll/type_check/relate_tys.rs b/src/librustc_mir/borrow_check/nll/type_check/relate_tys.rs index b82efb29f6e56..cf4f913080783 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/relate_tys.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/relate_tys.rs @@ -84,7 +84,10 @@ impl TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, '_, 'tcx> { } } - fn next_placeholder_region(&mut self, placeholder: ty::Placeholder) -> ty::Region<'tcx> { + fn next_placeholder_region( + &mut self, + placeholder: ty::PlaceholderRegion + ) -> ty::Region<'tcx> { if let Some(borrowck_context) = &mut self.borrowck_context { borrowck_context.constraints.placeholder_region(self.infcx, placeholder) } else { From 05995a85221cde573b81ab918b0f3686452dca3b Mon Sep 17 00:00:00 2001 From: scalexm Date: Fri, 2 Nov 2018 18:48:24 +0100 Subject: [PATCH 02/11] Introduce `TyKind::Placeholder` variant --- src/librustc/ich/impls_ty.rs | 3 +++ src/librustc/infer/canonical/canonicalizer.rs | 1 + src/librustc/infer/freshen.rs | 6 +++--- src/librustc/traits/coherence.rs | 2 +- src/librustc/traits/error_reporting.rs | 2 +- src/librustc/traits/query/dropck_outlives.rs | 1 + src/librustc/traits/select.rs | 3 +++ src/librustc/ty/context.rs | 2 +- src/librustc/ty/error.rs | 1 + src/librustc/ty/fast_reject.rs | 2 +- src/librustc/ty/flags.rs | 1 + src/librustc/ty/item_path.rs | 1 + src/librustc/ty/layout.rs | 4 +++- src/librustc/ty/mod.rs | 1 + src/librustc/ty/outlives.rs | 1 + src/librustc/ty/structural_impls.rs | 2 ++ src/librustc/ty/sty.rs | 5 +++++ src/librustc/ty/util.rs | 2 +- src/librustc/ty/walk.rs | 2 +- src/librustc/ty/wf.rs | 1 + src/librustc/util/ppaux.rs | 5 ++++- src/librustc_codegen_llvm/debuginfo/type_names.rs | 1 + src/librustc_lint/types.rs | 1 + src/librustc_mir/monomorphize/item.rs | 1 + src/librustc_traits/chalk_context/program_clauses.rs | 1 + src/librustc_traits/dropck_outlives.rs | 2 +- src/librustc_traits/lowering/environment.rs | 1 + src/librustc_typeck/check/cast.rs | 2 +- src/librustc_typeck/variance/constraints.rs | 1 + src/librustdoc/clean/mod.rs | 1 + 30 files changed, 46 insertions(+), 13 deletions(-) diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs index 679107160a6fc..4b465c7ad54a9 100644 --- a/src/librustc/ich/impls_ty.rs +++ b/src/librustc/ich/impls_ty.rs @@ -687,6 +687,9 @@ for ty::TyKind<'gcx> Bound(bound_ty) => { bound_ty.hash_stable(hcx, hasher); } + ty::Placeholder(placeholder_ty) => { + placeholder_ty.hash_stable(hcx, hasher); + } Foreign(def_id) => { def_id.hash_stable(hcx, hasher); } diff --git a/src/librustc/infer/canonical/canonicalizer.rs b/src/librustc/infer/canonical/canonicalizer.rs index a787eeae663fd..a3cbae2ff71c1 100644 --- a/src/librustc/infer/canonical/canonicalizer.rs +++ b/src/librustc/infer/canonical/canonicalizer.rs @@ -380,6 +380,7 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for Canonicalizer<'cx, 'gcx, 'tcx> | ty::Never | ty::Tuple(..) | ty::Projection(..) + | ty::Placeholder(..) | ty::UnnormalizedProjection(..) | ty::Foreign(..) | ty::Param(..) diff --git a/src/librustc/infer/freshen.rs b/src/librustc/infer/freshen.rs index b53444992fa21..d17cf0c7b47a4 100644 --- a/src/librustc/infer/freshen.rs +++ b/src/librustc/infer/freshen.rs @@ -170,9 +170,6 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for TypeFreshener<'a, 'gcx, 'tcx> { t } - ty::Bound(..) => - bug!("encountered bound ty during freshening"), - ty::Generator(..) | ty::Bool | ty::Char | @@ -200,6 +197,9 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for TypeFreshener<'a, 'gcx, 'tcx> { ty::Opaque(..) => { t.super_fold_with(self) } + + ty::Placeholder(..) | + ty::Bound(..) => bug!("unexpected type {:?}", t), } } } diff --git a/src/librustc/traits/coherence.rs b/src/librustc/traits/coherence.rs index 71b77909b82a8..b7a84c99308f8 100644 --- a/src/librustc/traits/coherence.rs +++ b/src/librustc/traits/coherence.rs @@ -455,7 +455,7 @@ fn ty_is_local_constructor(ty: Ty<'_>, in_crate: InCrate) -> bool { false } - ty::Bound(..) | ty::Infer(..) => match in_crate { + ty::Placeholder(..) | ty::Bound(..) | ty::Infer(..) => match in_crate { InCrate::Local => false, // The inference variable might be unified with a local // type in that remote crate. diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 48b2b25d6adf9..7e97dc3c84a79 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -281,7 +281,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { ty::Generator(..) => Some(18), ty::Foreign(..) => Some(19), ty::GeneratorWitness(..) => Some(20), - ty::Bound(..) | ty::Infer(..) | ty::Error => None, + ty::Placeholder(..) | ty::Bound(..) | ty::Infer(..) | ty::Error => None, ty::UnnormalizedProjection(..) => bug!("only used with chalk-engine"), } } diff --git a/src/librustc/traits/query/dropck_outlives.rs b/src/librustc/traits/query/dropck_outlives.rs index 99dc099d57738..b8bf0fcc15307 100644 --- a/src/librustc/traits/query/dropck_outlives.rs +++ b/src/librustc/traits/query/dropck_outlives.rs @@ -251,6 +251,7 @@ pub fn trivial_dropck_outlives<'tcx>(tcx: TyCtxt<'_, '_, 'tcx>, ty: Ty<'tcx>) -> | ty::Projection(..) | ty::Param(_) | ty::Opaque(..) + | ty::Placeholder(..) | ty::Infer(_) | ty::Bound(..) | ty::Generator(..) => false, diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index 550c27ca0ab8b..6a91ad59d98e4 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -2470,6 +2470,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { ty::Infer(ty::TyVar(_)) => Ambiguous, ty::UnnormalizedProjection(..) + | ty::Placeholder(..) | ty::Bound(_) | ty::Infer(ty::FreshTy(_)) | ty::Infer(ty::FreshIntTy(_)) @@ -2555,6 +2556,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { } ty::UnnormalizedProjection(..) + | ty::Placeholder(..) | ty::Bound(_) | ty::Infer(ty::FreshTy(_)) | ty::Infer(ty::FreshIntTy(_)) @@ -2594,6 +2596,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { | ty::Char => Vec::new(), ty::UnnormalizedProjection(..) + | ty::Placeholder(..) | ty::Dynamic(..) | ty::Param(..) | ty::Foreign(..) diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index a8ce52a8e156c..d9d1b81fd8fe0 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -2250,7 +2250,7 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> { pub fn print_debug_stats(self) { sty_debug_print!( self, - Adt, Array, Slice, RawPtr, Ref, FnDef, FnPtr, + Adt, Array, Slice, RawPtr, Ref, FnDef, FnPtr, Placeholder, Generator, GeneratorWitness, Dynamic, Closure, Tuple, Bound, Param, Infer, UnnormalizedProjection, Projection, Opaque, Foreign); diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs index 4737c72b1ef0f..e78759e3e7961 100644 --- a/src/librustc/ty/error.rs +++ b/src/librustc/ty/error.rs @@ -212,6 +212,7 @@ impl<'a, 'gcx, 'lcx, 'tcx> ty::TyS<'tcx> { ty::Infer(ty::TyVar(_)) => "inferred type".into(), ty::Infer(ty::IntVar(_)) => "integral variable".into(), ty::Infer(ty::FloatVar(_)) => "floating-point variable".into(), + ty::Placeholder(..) => "placeholder type".into(), ty::Bound(_) | ty::Infer(ty::FreshTy(_)) => "fresh type".into(), ty::Infer(ty::FreshIntTy(_)) => "fresh integral type".into(), diff --git a/src/librustc/ty/fast_reject.rs b/src/librustc/ty/fast_reject.rs index 380f95993f8fb..8304e36381572 100644 --- a/src/librustc/ty/fast_reject.rs +++ b/src/librustc/ty/fast_reject.rs @@ -122,7 +122,7 @@ pub fn simplify_type<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, ty::Foreign(def_id) => { Some(ForeignSimplifiedType(def_id)) } - ty::Bound(..) | ty::Infer(_) | ty::Error => None, + ty::Placeholder(..) | ty::Bound(..) | ty::Infer(_) | ty::Error => None, } } diff --git a/src/librustc/ty/flags.rs b/src/librustc/ty/flags.rs index 0764f363250dd..9cdeb300393b9 100644 --- a/src/librustc/ty/flags.rs +++ b/src/librustc/ty/flags.rs @@ -74,6 +74,7 @@ impl FlagComputation { &ty::Uint(_) | &ty::Never | &ty::Str | + &ty::Placeholder(..) | &ty::Foreign(..) => { } diff --git a/src/librustc/ty/item_path.rs b/src/librustc/ty/item_path.rs index d44ba03084159..f6c90ab0a1ad2 100644 --- a/src/librustc/ty/item_path.rs +++ b/src/librustc/ty/item_path.rs @@ -515,6 +515,7 @@ pub fn characteristic_def_id_of_type(ty: Ty<'_>) -> Option { ty::Str | ty::FnPtr(_) | ty::Projection(_) | + ty::Placeholder(..) | ty::UnnormalizedProjection(..) | ty::Param(_) | ty::Opaque(..) | diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs index da0a9acede20e..5406495226d79 100644 --- a/src/librustc/ty/layout.rs +++ b/src/librustc/ty/layout.rs @@ -1159,6 +1159,7 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> { } ty::Bound(..) | + ty::Placeholder(..) | ty::UnnormalizedProjection(..) | ty::GeneratorWitness(..) | ty::Infer(_) => { @@ -1743,7 +1744,8 @@ impl<'a, 'tcx, C> TyLayoutMethods<'tcx, C> for Ty<'tcx> } ty::Projection(_) | ty::UnnormalizedProjection(..) | ty::Bound(..) | - ty::Opaque(..) | ty::Param(_) | ty::Infer(_) | ty::Error => { + ty::Placeholder(..) | ty::Opaque(..) | ty::Param(_) | ty::Infer(_) | + ty::Error => { bug!("TyLayout::field_type: unexpected type `{}`", this.ty) } }) diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 4372beafa6488..baedbc8214976 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -2445,6 +2445,7 @@ impl<'a, 'gcx, 'tcx> AdtDef { } } + Placeholder(..) | Bound(..) | Infer(..) => { bug!("unexpected type `{:?}` in sized_constraint_for_ty", diff --git a/src/librustc/ty/outlives.rs b/src/librustc/ty/outlives.rs index 7fac88a3d78f1..0e3fc62e4ca9a 100644 --- a/src/librustc/ty/outlives.rs +++ b/src/librustc/ty/outlives.rs @@ -155,6 +155,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { ty::FnDef(..) | // OutlivesFunction (*) ty::FnPtr(_) | // OutlivesFunction (*) ty::Dynamic(..) | // OutlivesObject, OutlivesFragment (*) + ty::Placeholder(..) | ty::Bound(..) | ty::Error => { // (*) Bare functions and traits are both binders. In the diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index e92f92dce63d0..d6aeb288b5cdc 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -746,6 +746,7 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> { ty::Infer(_) | ty::Param(..) | ty::Bound(..) | + ty::Placeholder(..) | ty::Never | ty::Foreign(..) => return self }; @@ -792,6 +793,7 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> { ty::Error | ty::Infer(_) | ty::Bound(..) | + ty::Placeholder(..) | ty::Param(..) | ty::Never | ty::Foreign(..) => false, diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index 5c01f1cc3e4d7..7e6673a3dcdc1 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -203,6 +203,9 @@ pub enum TyKind<'tcx> { /// Bound type variable, used only when preparing a trait query. Bound(BoundTy), + /// A placeholder type - universally quantified higher-ranked type. + Placeholder(ty::PlaceholderType), + /// A type variable used during type checking. Infer(InferTy), @@ -1890,6 +1893,7 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> { Foreign(..) | Param(_) | Bound(..) | + Placeholder(..) | Infer(_) | Error => {} } @@ -1954,6 +1958,7 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> { ty::Infer(ty::TyVar(_)) => false, ty::Bound(_) | + ty::Placeholder(..) | ty::Infer(ty::FreshTy(_)) | ty::Infer(ty::FreshIntTy(_)) | ty::Infer(ty::FreshFloatTy(_)) => diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index 3d0c54d6b0a5b..f0885f960516d 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -952,7 +952,7 @@ fn needs_drop_raw<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // Can refer to a type which may drop. // FIXME(eddyb) check this against a ParamEnv. ty::Dynamic(..) | ty::Projection(..) | ty::Param(_) | ty::Bound(..) | - ty::Opaque(..) | ty::Infer(_) | ty::Error => true, + ty::Placeholder(..) | ty::Opaque(..) | ty::Infer(_) | ty::Error => true, ty::UnnormalizedProjection(..) => bug!("only used with chalk-engine"), diff --git a/src/librustc/ty/walk.rs b/src/librustc/ty/walk.rs index 284c595ee2d96..82b95b9df6031 100644 --- a/src/librustc/ty/walk.rs +++ b/src/librustc/ty/walk.rs @@ -82,7 +82,7 @@ fn push_subtypes<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent_ty: Ty<'tcx>) { match parent_ty.sty { ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Str | ty::Infer(_) | ty::Param(_) | ty::Never | ty::Error | - ty::Bound(..) | ty::Foreign(..) => { + ty::Placeholder(..) | ty::Bound(..) | ty::Foreign(..) => { } ty::Array(ty, len) => { push_const(stack, len); diff --git a/src/librustc/ty/wf.rs b/src/librustc/ty/wf.rs index 1336eac63f880..6ae0793d92471 100644 --- a/src/librustc/ty/wf.rs +++ b/src/librustc/ty/wf.rs @@ -259,6 +259,7 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> { ty::Never | ty::Param(_) | ty::Bound(..) | + ty::Placeholder(..) | ty::Foreign(..) => { // WfScalar, WfParameter, etc } diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 613a0dbc61f42..0c424b344159d 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -18,7 +18,7 @@ use ty::{Bool, Char, Adt}; use ty::{Error, Str, Array, Slice, Float, FnDef, FnPtr}; use ty::{Param, Bound, RawPtr, Ref, Never, Tuple}; use ty::{Closure, Generator, GeneratorWitness, Foreign, Projection, Opaque}; -use ty::{UnnormalizedProjection, Dynamic, Int, Uint, Infer}; +use ty::{Placeholder, UnnormalizedProjection, Dynamic, Int, Uint, Infer}; use ty::{self, RegionVid, Ty, TyCtxt, TypeFoldable, GenericParamCount, GenericParamDefKind}; use util::nodemap::FxHashSet; @@ -1144,6 +1144,9 @@ define_print! { data.print(f, cx)?; write!(f, ")") } + Placeholder(placeholder) => { + write!(f, "Placeholder({:?})", placeholder) + } Opaque(def_id, substs) => { if cx.is_verbose { return write!(f, "Opaque({:?}, {:?})", def_id, substs); diff --git a/src/librustc_codegen_llvm/debuginfo/type_names.rs b/src/librustc_codegen_llvm/debuginfo/type_names.rs index c3a15ccca0a9d..60545f9e193d1 100644 --- a/src/librustc_codegen_llvm/debuginfo/type_names.rs +++ b/src/librustc_codegen_llvm/debuginfo/type_names.rs @@ -172,6 +172,7 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, } ty::Error | ty::Infer(_) | + ty::Placeholder(..) | ty::UnnormalizedProjection(..) | ty::Projection(..) | ty::Bound(..) | diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs index 0e2d041b1ffdb..82ace620c8ab2 100644 --- a/src/librustc_lint/types.rs +++ b/src/librustc_lint/types.rs @@ -727,6 +727,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { ty::Closure(..) | ty::Generator(..) | ty::GeneratorWitness(..) | + ty::Placeholder(..) | ty::UnnormalizedProjection(..) | ty::Projection(..) | ty::Opaque(..) | diff --git a/src/librustc_mir/monomorphize/item.rs b/src/librustc_mir/monomorphize/item.rs index 9c90e5ffd3c78..24de92e79f0e4 100644 --- a/src/librustc_mir/monomorphize/item.rs +++ b/src/librustc_mir/monomorphize/item.rs @@ -378,6 +378,7 @@ impl<'a, 'tcx> DefPathBasedNames<'a, 'tcx> { ty::Error | ty::Bound(..) | ty::Infer(_) | + ty::Placeholder(..) | ty::UnnormalizedProjection(..) | ty::Projection(..) | ty::Param(_) | diff --git a/src/librustc_traits/chalk_context/program_clauses.rs b/src/librustc_traits/chalk_context/program_clauses.rs index 31f97b72e1927..5592d2a583cfb 100644 --- a/src/librustc_traits/chalk_context/program_clauses.rs +++ b/src/librustc_traits/chalk_context/program_clauses.rs @@ -418,6 +418,7 @@ impl ChalkInferenceContext<'cx, 'gcx, 'tcx> { } ty::GeneratorWitness(..) | + ty::Placeholder(..) | ty::UnnormalizedProjection(..) | ty::Infer(..) | ty::Bound(..) | diff --git a/src/librustc_traits/dropck_outlives.rs b/src/librustc_traits/dropck_outlives.rs index af64522f18398..9ab86daf65449 100644 --- a/src/librustc_traits/dropck_outlives.rs +++ b/src/librustc_traits/dropck_outlives.rs @@ -274,7 +274,7 @@ fn dtorck_constraint_for_ty<'a, 'gcx, 'tcx>( ty::UnnormalizedProjection(..) => bug!("only used with chalk-engine"), - ty::Bound(..) | ty::Infer(..) | ty::Error => { + ty::Placeholder(..) | ty::Bound(..) | ty::Infer(..) | ty::Error => { // By the time this code runs, all type variables ought to // be fully resolved. Err(NoSolution) diff --git a/src/librustc_traits/lowering/environment.rs b/src/librustc_traits/lowering/environment.rs index 54f0c6e8da78a..c3573f47cebfe 100644 --- a/src/librustc_traits/lowering/environment.rs +++ b/src/librustc_traits/lowering/environment.rs @@ -114,6 +114,7 @@ impl ClauseVisitor<'set, 'a, 'tcx> { ty::Tuple(..) | ty::Never | ty::Infer(..) | + ty::Placeholder(..) | ty::Bound(..) => (), ty::GeneratorWitness(..) | diff --git a/src/librustc_typeck/check/cast.rs b/src/librustc_typeck/check/cast.rs index 3f0a353124442..c35aee7883f49 100644 --- a/src/librustc_typeck/check/cast.rs +++ b/src/librustc_typeck/check/cast.rs @@ -128,7 +128,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { ty::Opaque(def_id, substs) => Some(PointerKind::OfOpaque(def_id, substs)), ty::Param(ref p) => Some(PointerKind::OfParam(p)), // Insufficient type information. - ty::Bound(..) | ty::Infer(_) => None, + ty::Placeholder(..) | ty::Bound(..) | ty::Infer(_) => None, ty::Bool | ty::Char | ty::Int(..) | ty::Uint(..) | ty::Float(_) | ty::Array(..) | ty::GeneratorWitness(..) | diff --git a/src/librustc_typeck/variance/constraints.rs b/src/librustc_typeck/variance/constraints.rs index 47d34c909961e..ed32e5a8d9b38 100644 --- a/src/librustc_typeck/variance/constraints.rs +++ b/src/librustc_typeck/variance/constraints.rs @@ -336,6 +336,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { // types, where we use Error as the Self type } + ty::Placeholder(..) | ty::UnnormalizedProjection(..) | ty::GeneratorWitness(..) | ty::Bound(..) | diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 0518d73e1e30f..fd8f70b19e7ec 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -2744,6 +2744,7 @@ impl<'tcx> Clean for Ty<'tcx> { ty::Closure(..) | ty::Generator(..) => Tuple(vec![]), // FIXME(pcwalton) ty::Bound(..) => panic!("Bound"), + ty::Placeholder(..) => panic!("Placeholder"), ty::UnnormalizedProjection(..) => panic!("UnnormalizedProjection"), ty::GeneratorWitness(..) => panic!("GeneratorWitness"), ty::Infer(..) => panic!("Infer"), From da3def3ebffaefc4e8abbdba99981141ab74e4e4 Mon Sep 17 00:00:00 2001 From: scalexm Date: Fri, 2 Nov 2018 18:56:30 +0100 Subject: [PATCH 03/11] Rename some occurences of `skol` to `placeholder` --- src/librustc/traits/project.rs | 4 ++-- src/librustc/traits/query/normalize.rs | 2 +- src/librustc/ty/fold.rs | 8 ++++---- src/librustc/ty/mod.rs | 6 +++--- src/librustc/ty/sty.rs | 2 +- src/librustc_typeck/check/method/probe.rs | 2 +- src/librustc_typeck/check/writeback.rs | 4 ++-- 7 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/librustc/traits/project.rs b/src/librustc/traits/project.rs index b59bd0e238873..0aabb7ad713f1 100644 --- a/src/librustc/traits/project.rs +++ b/src/librustc/traits/project.rs @@ -424,7 +424,7 @@ impl<'a, 'b, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for AssociatedTypeNormalizer<'a, if let ConstValue::Unevaluated(def_id, substs) = constant.val { let tcx = self.selcx.tcx().global_tcx(); if let Some(param_env) = self.tcx().lift_to_global(&self.param_env) { - if substs.needs_infer() || substs.has_skol() { + if substs.needs_infer() || substs.has_placeholders() { let identity_substs = Substs::identity_for_item(tcx, def_id); let instance = ty::Instance::resolve(tcx, param_env, def_id, identity_substs); if let Some(instance) = instance { @@ -1656,7 +1656,7 @@ impl<'tcx> ProjectionCache<'tcx> { } pub fn rollback_placeholder(&mut self, snapshot: &ProjectionCacheSnapshot) { - self.map.partial_rollback(&snapshot.snapshot, &|k| k.ty.has_re_skol()); + self.map.partial_rollback(&snapshot.snapshot, &|k| k.ty.has_re_placeholders()); } pub fn commit(&mut self, snapshot: &ProjectionCacheSnapshot) { diff --git a/src/librustc/traits/query/normalize.rs b/src/librustc/traits/query/normalize.rs index 59b086e35de31..91b2ba301c312 100644 --- a/src/librustc/traits/query/normalize.rs +++ b/src/librustc/traits/query/normalize.rs @@ -202,7 +202,7 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for QueryNormalizer<'cx, 'gcx, 'tcx if let ConstValue::Unevaluated(def_id, substs) = constant.val { let tcx = self.infcx.tcx.global_tcx(); if let Some(param_env) = self.tcx().lift_to_global(&self.param_env) { - if substs.needs_infer() || substs.has_skol() { + if substs.needs_infer() || substs.has_placeholders() { let identity_substs = Substs::identity_for_item(tcx, def_id); let instance = ty::Instance::resolve(tcx, param_env, def_id, identity_substs); if let Some(instance) = instance { diff --git a/src/librustc/ty/fold.rs b/src/librustc/ty/fold.rs index 2c7814831450c..9abc84e2a258a 100644 --- a/src/librustc/ty/fold.rs +++ b/src/librustc/ty/fold.rs @@ -102,14 +102,14 @@ pub trait TypeFoldable<'tcx>: fmt::Debug + Clone { fn needs_infer(&self) -> bool { self.has_type_flags(TypeFlags::HAS_TY_INFER | TypeFlags::HAS_RE_INFER) } - fn has_skol(&self) -> bool { - self.has_type_flags(TypeFlags::HAS_RE_SKOL) + fn has_placeholders(&self) -> bool { + self.has_type_flags(TypeFlags::HAS_RE_PLACEHOLDER) } fn needs_subst(&self) -> bool { self.has_type_flags(TypeFlags::NEEDS_SUBST) } - fn has_re_skol(&self) -> bool { - self.has_type_flags(TypeFlags::HAS_RE_SKOL) + fn has_re_placeholders(&self) -> bool { + self.has_type_flags(TypeFlags::HAS_RE_PLACEHOLDER) } fn has_closure_types(&self) -> bool { self.has_type_flags(TypeFlags::HAS_TY_CLOSURE) diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index baedbc8214976..183aaadf6e6be 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -432,7 +432,7 @@ bitflags! { const HAS_SELF = 1 << 1; const HAS_TY_INFER = 1 << 2; const HAS_RE_INFER = 1 << 3; - const HAS_RE_SKOL = 1 << 4; + const HAS_RE_PLACEHOLDER = 1 << 4; /// Does this have any `ReEarlyBound` regions? Used to /// determine whether substitition is required, since those @@ -478,7 +478,7 @@ bitflags! { TypeFlags::HAS_SELF.bits | TypeFlags::HAS_TY_INFER.bits | TypeFlags::HAS_RE_INFER.bits | - TypeFlags::HAS_RE_SKOL.bits | + TypeFlags::HAS_RE_PLACEHOLDER.bits | TypeFlags::HAS_RE_EARLY_BOUND.bits | TypeFlags::HAS_FREE_REGIONS.bits | TypeFlags::HAS_TY_ERR.bits | @@ -1689,7 +1689,7 @@ impl<'tcx> ParamEnv<'tcx> { } Reveal::All => { - if value.has_skol() + if value.has_placeholders() || value.needs_infer() || value.has_param_types() || value.has_self_ty() diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index 7e6673a3dcdc1..cd69d31a00458 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -1465,7 +1465,7 @@ impl RegionKind { } ty::RePlaceholder(..) => { flags = flags | TypeFlags::HAS_FREE_REGIONS; - flags = flags | TypeFlags::HAS_RE_SKOL; + flags = flags | TypeFlags::HAS_RE_PLACEHOLDER; } ty::ReLateBound(..) => { flags = flags | TypeFlags::HAS_RE_LATE_BOUND; diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index 0373bf4e7522d..5b67116cb511e 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -1494,7 +1494,7 @@ impl<'tcx> Candidate<'tcx> { // `WhereClausePick`. assert!( !trait_ref.skip_binder().substs.needs_infer() - && !trait_ref.skip_binder().substs.has_skol() + && !trait_ref.skip_binder().substs.has_placeholders() ); WhereClausePick(trait_ref.clone()) diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs index 50f54bba3fd20..669f2bcb77c4d 100644 --- a/src/librustc_typeck/check/writeback.rs +++ b/src/librustc_typeck/check/writeback.rs @@ -115,7 +115,7 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> { fn write_ty_to_tables(&mut self, hir_id: hir::HirId, ty: Ty<'gcx>) { debug!("write_ty_to_tables({:?}, {:?})", hir_id, ty); - assert!(!ty.needs_infer() && !ty.has_skol()); + assert!(!ty.needs_infer() && !ty.has_placeholders()); self.tables.node_types_mut().insert(hir_id, ty); } @@ -580,7 +580,7 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> { if let Some(substs) = self.fcx.tables.borrow().node_substs_opt(hir_id) { let substs = self.resolve(&substs, &span); debug!("write_substs_to_tcx({:?}, {:?})", hir_id, substs); - assert!(!substs.needs_infer() && !substs.has_skol()); + assert!(!substs.needs_infer() && !substs.has_placeholders()); self.tables.node_substs_mut().insert(hir_id, substs); } From 91623ca6405b5e3c7736bcacb244718906d4aa69 Mon Sep 17 00:00:00 2001 From: scalexm Date: Fri, 2 Nov 2018 19:25:20 +0100 Subject: [PATCH 04/11] Add `HAS_TY_PLACEHOLDER` flag --- src/librustc/infer/canonical/canonicalizer.rs | 8 ++++++-- src/librustc/ty/flags.rs | 5 ++++- src/librustc/ty/fold.rs | 2 +- src/librustc/ty/mod.rs | 5 ++++- 4 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/librustc/infer/canonical/canonicalizer.rs b/src/librustc/infer/canonical/canonicalizer.rs index a3cbae2ff71c1..a9c6c3b50853d 100644 --- a/src/librustc/infer/canonical/canonicalizer.rs +++ b/src/librustc/infer/canonical/canonicalizer.rs @@ -409,9 +409,13 @@ impl<'cx, 'gcx, 'tcx> Canonicalizer<'cx, 'gcx, 'tcx> { V: TypeFoldable<'tcx> + Lift<'gcx>, { let needs_canonical_flags = if canonicalize_region_mode.any() { - TypeFlags::HAS_FREE_REGIONS | TypeFlags::KEEP_IN_LOCAL_TCX + TypeFlags::KEEP_IN_LOCAL_TCX | + TypeFlags::HAS_FREE_REGIONS | // `HAS_RE_PLACEHOLDER` implies `HAS_FREE_REGIONS` + TypeFlags::HAS_TY_PLACEHOLDER } else { - TypeFlags::KEEP_IN_LOCAL_TCX + TypeFlags::KEEP_IN_LOCAL_TCX | + TypeFlags::HAS_RE_PLACEHOLDER | + TypeFlags::HAS_TY_PLACEHOLDER }; let gcx = tcx.global_tcx(); diff --git a/src/librustc/ty/flags.rs b/src/librustc/ty/flags.rs index 9cdeb300393b9..3b84e7b54bdf3 100644 --- a/src/librustc/ty/flags.rs +++ b/src/librustc/ty/flags.rs @@ -74,7 +74,6 @@ impl FlagComputation { &ty::Uint(_) | &ty::Never | &ty::Str | - &ty::Placeholder(..) | &ty::Foreign(..) => { } @@ -120,6 +119,10 @@ impl FlagComputation { self.add_binder(bound_ty.index); } + &ty::Placeholder(..) => { + self.add_flags(TypeFlags::HAS_TY_PLACEHOLDER); + } + &ty::Infer(infer) => { self.add_flags(TypeFlags::HAS_FREE_LOCAL_NAMES); // it might, right? self.add_flags(TypeFlags::HAS_TY_INFER); diff --git a/src/librustc/ty/fold.rs b/src/librustc/ty/fold.rs index 9abc84e2a258a..16de146cf4e4f 100644 --- a/src/librustc/ty/fold.rs +++ b/src/librustc/ty/fold.rs @@ -103,7 +103,7 @@ pub trait TypeFoldable<'tcx>: fmt::Debug + Clone { self.has_type_flags(TypeFlags::HAS_TY_INFER | TypeFlags::HAS_RE_INFER) } fn has_placeholders(&self) -> bool { - self.has_type_flags(TypeFlags::HAS_RE_PLACEHOLDER) + self.has_type_flags(TypeFlags::HAS_RE_PLACEHOLDER | TypeFlags::HAS_TY_PLACEHOLDER) } fn needs_subst(&self) -> bool { self.has_type_flags(TypeFlags::NEEDS_SUBST) diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 183aaadf6e6be..b371f4532e5fa 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -467,6 +467,8 @@ bitflags! { /// if a global bound is safe to evaluate. const HAS_RE_LATE_BOUND = 1 << 13; + const HAS_TY_PLACEHOLDER = 1 << 14; + const NEEDS_SUBST = TypeFlags::HAS_PARAMS.bits | TypeFlags::HAS_SELF.bits | TypeFlags::HAS_RE_EARLY_BOUND.bits; @@ -486,7 +488,8 @@ bitflags! { TypeFlags::HAS_TY_CLOSURE.bits | TypeFlags::HAS_FREE_LOCAL_NAMES.bits | TypeFlags::KEEP_IN_LOCAL_TCX.bits | - TypeFlags::HAS_RE_LATE_BOUND.bits; + TypeFlags::HAS_RE_LATE_BOUND.bits | + TypeFlags::HAS_TY_PLACEHOLDER.bits; } } From cdb96be11e178a82ac6b16f37ef2a9c2b7189d6b Mon Sep 17 00:00:00 2001 From: scalexm Date: Fri, 2 Nov 2018 19:46:30 +0100 Subject: [PATCH 05/11] Handle placeholder types in canonicalization --- src/librustc/ich/impls_ty.rs | 3 +- src/librustc/infer/canonical/canonicalizer.rs | 43 +++++++++++++++---- src/librustc/infer/canonical/mod.rs | 36 +++++++++++----- src/librustc/infer/mod.rs | 22 ++++++++++ src/librustc/infer/type_variable.rs | 2 +- 5 files changed, 85 insertions(+), 21 deletions(-) diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs index 4b465c7ad54a9..e9fac5b923961 100644 --- a/src/librustc/ich/impls_ty.rs +++ b/src/librustc/ich/impls_ty.rs @@ -1099,12 +1099,13 @@ impl_stable_hash_for!(struct infer::canonical::CanonicalVarInfo { impl_stable_hash_for!(enum infer::canonical::CanonicalVarKind { Ty(k), + PlaceholderTy(placeholder), Region(ui), PlaceholderRegion(placeholder), }); impl_stable_hash_for!(enum infer::canonical::CanonicalTyVarKind { - General, + General(ui), Int, Float }); diff --git a/src/librustc/infer/canonical/canonicalizer.rs b/src/librustc/infer/canonical/canonicalizer.rs index a9c6c3b50853d..7a9527573c7d6 100644 --- a/src/librustc/infer/canonical/canonicalizer.rs +++ b/src/librustc/infer/canonical/canonicalizer.rs @@ -339,11 +339,35 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for Canonicalizer<'cx, 'gcx, 'tcx> fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { match t.sty { - ty::Infer(ty::TyVar(_)) => self.canonicalize_ty_var(CanonicalTyVarKind::General, t), + ty::Infer(ty::TyVar(vid)) => { + match self.infcx.unwrap().probe_ty_var(vid) { + // `t` could be a float / int variable: canonicalize that instead + Ok(t) => self.fold_ty(t), + + // `TyVar(vid)` is unresolved, track its universe index in the canonicalized + // result + Err(ui) => self.canonicalize_ty_var( + CanonicalVarInfo { + kind: CanonicalVarKind::Ty(CanonicalTyVarKind::General(ui)) + }, + t + ) + } + } - ty::Infer(ty::IntVar(_)) => self.canonicalize_ty_var(CanonicalTyVarKind::Int, t), + ty::Infer(ty::IntVar(_)) => self.canonicalize_ty_var( + CanonicalVarInfo { + kind: CanonicalVarKind::Ty(CanonicalTyVarKind::Int) + }, + t + ), - ty::Infer(ty::FloatVar(_)) => self.canonicalize_ty_var(CanonicalTyVarKind::Float, t), + ty::Infer(ty::FloatVar(_)) => self.canonicalize_ty_var( + CanonicalVarInfo { + kind: CanonicalVarKind::Ty(CanonicalTyVarKind::Float) + }, + t + ), ty::Infer(ty::FreshTy(_)) | ty::Infer(ty::FreshIntTy(_)) @@ -351,6 +375,13 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for Canonicalizer<'cx, 'gcx, 'tcx> bug!("encountered a fresh type during canonicalization") } + ty::Placeholder(placeholder) => self.canonicalize_ty_var( + CanonicalVarInfo { + kind: CanonicalVarKind::PlaceholderTy(placeholder) + }, + t + ), + ty::Bound(bound_ty) => { if bound_ty.index >= self.binder_index { bug!("escaping bound type during canonicalization") @@ -380,7 +411,6 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for Canonicalizer<'cx, 'gcx, 'tcx> | ty::Never | ty::Tuple(..) | ty::Projection(..) - | ty::Placeholder(..) | ty::UnnormalizedProjection(..) | ty::Foreign(..) | ty::Param(..) @@ -579,15 +609,12 @@ impl<'cx, 'gcx, 'tcx> Canonicalizer<'cx, 'gcx, 'tcx> { /// if `ty_var` is bound to anything; if so, canonicalize /// *that*. Otherwise, create a new canonical variable for /// `ty_var`. - fn canonicalize_ty_var(&mut self, ty_kind: CanonicalTyVarKind, ty_var: Ty<'tcx>) -> Ty<'tcx> { + fn canonicalize_ty_var(&mut self, info: CanonicalVarInfo, ty_var: Ty<'tcx>) -> Ty<'tcx> { let infcx = self.infcx.expect("encountered ty-var without infcx"); let bound_to = infcx.shallow_resolve(ty_var); if bound_to != ty_var { self.fold_ty(bound_to) } else { - let info = CanonicalVarInfo { - kind: CanonicalVarKind::Ty(ty_kind), - }; let var = self.canonical_var(info, ty_var.into()); self.tcx().mk_ty(ty::Bound(BoundTy::new(self.binder_index, var))) } diff --git a/src/librustc/infer/canonical/mod.rs b/src/librustc/infer/canonical/mod.rs index 41839d61d3260..230f8958b3385 100644 --- a/src/librustc/infer/canonical/mod.rs +++ b/src/librustc/infer/canonical/mod.rs @@ -122,6 +122,7 @@ impl CanonicalVarInfo { pub fn is_existential(&self) -> bool { match self.kind { CanonicalVarKind::Ty(_) => true, + CanonicalVarKind::PlaceholderTy(_) => false, CanonicalVarKind::Region(_) => true, CanonicalVarKind::PlaceholderRegion(..) => false, } @@ -136,6 +137,9 @@ pub enum CanonicalVarKind { /// Some kind of type inference variable. Ty(CanonicalTyVarKind), + /// A "placeholder" that represents "any type". + PlaceholderTy(ty::PlaceholderType), + /// Region variable `'?R`. Region(ty::UniverseIndex), @@ -148,12 +152,12 @@ pub enum CanonicalVarKind { impl CanonicalVarKind { pub fn universe(self) -> ty::UniverseIndex { match self { - // At present, we don't support higher-ranked - // quantification over types, so all type variables are in - // the root universe. - CanonicalVarKind::Ty(_) => ty::UniverseIndex::ROOT, + CanonicalVarKind::Ty(kind) => match kind { + CanonicalTyVarKind::General(ui) => ui, + CanonicalTyVarKind::Float | CanonicalTyVarKind::Int => ty::UniverseIndex::ROOT, + } - // Region variables can be created in sub-universes. + CanonicalVarKind::PlaceholderTy(placeholder) => placeholder.universe, CanonicalVarKind::Region(ui) => ui, CanonicalVarKind::PlaceholderRegion(placeholder) => placeholder.universe, } @@ -168,7 +172,7 @@ impl CanonicalVarKind { #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcDecodable, RustcEncodable)] pub enum CanonicalTyVarKind { /// General type variable `?T` that can be unified with arbitrary types. - General, + General(ty::UniverseIndex), /// Integral type variable `?I` (that can only be unified with integral types). Int, @@ -358,8 +362,11 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> { match cv_info.kind { CanonicalVarKind::Ty(ty_kind) => { let ty = match ty_kind { - CanonicalTyVarKind::General => { - self.next_ty_var(TypeVariableOrigin::MiscVariable(span)) + CanonicalTyVarKind::General(ui) => { + self.next_ty_var_in_universe( + TypeVariableOrigin::MiscVariable(span), + universe_map(ui) + ) } CanonicalTyVarKind::Int => self.tcx.mk_int_var(self.next_int_var_id()), @@ -369,6 +376,15 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> { ty.into() } + CanonicalVarKind::PlaceholderTy(ty::PlaceholderType { universe, name }) => { + let universe_mapped = universe_map(universe); + let placeholder_mapped = ty::PlaceholderType { + universe: universe_mapped, + name, + }; + self.tcx.mk_ty(ty::Placeholder(placeholder_mapped)).into() + } + CanonicalVarKind::Region(ui) => self.next_region_var_in_universe( RegionVariableOrigin::MiscVariable(span), universe_map(ui), @@ -380,9 +396,7 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> { universe: universe_mapped, name, }; - self.tcx - .mk_region(ty::RePlaceholder(placeholder_mapped)) - .into() + self.tcx.mk_region(ty::RePlaceholder(placeholder_mapped)).into() } } } diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index dfe6aa160b3ad..6f041fdfb0ac4 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -972,6 +972,17 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { self.tcx.mk_var(self.next_ty_var_id(false, origin)) } + pub fn next_ty_var_in_universe( + &self, + origin: TypeVariableOrigin, + universe: ty::UniverseIndex + ) -> Ty<'tcx> { + let vid = self.type_variables + .borrow_mut() + .new_var(universe, false, origin); + self.tcx.mk_var(vid) + } + pub fn next_diverging_ty_var(&self, origin: TypeVariableOrigin) -> Ty<'tcx> { self.tcx.mk_var(self.next_ty_var_id(true, origin)) } @@ -1227,6 +1238,17 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { } } + /// If `TyVar(vid)` resolves to a type, return that type. Else, return the + /// universe index of `TyVar(vid)`. + pub fn probe_ty_var(&self, vid: TyVid) -> Result, ty::UniverseIndex> { + use self::type_variable::TypeVariableValue; + + match self.type_variables.borrow_mut().probe(vid) { + TypeVariableValue::Known { value } => Ok(value), + TypeVariableValue::Unknown { universe } => Err(universe), + } + } + pub fn shallow_resolve(&self, typ: Ty<'tcx>) -> Ty<'tcx> { self.inlined_shallow_resolve(typ) } diff --git a/src/librustc/infer/type_variable.rs b/src/librustc/infer/type_variable.rs index bec19ba9099dc..5624961ea6e67 100644 --- a/src/librustc/infer/type_variable.rs +++ b/src/librustc/infer/type_variable.rs @@ -72,7 +72,7 @@ pub type TypeVariableMap = FxHashMap; struct TypeVariableData { origin: TypeVariableOrigin, - diverging: bool + diverging: bool, } #[derive(Copy, Clone, Debug)] From 6bf17d249b1dc515eeafcdd04e30723120cb7899 Mon Sep 17 00:00:00 2001 From: scalexm Date: Sat, 3 Nov 2018 14:52:37 +0100 Subject: [PATCH 06/11] Instantiate all bound vars universally --- src/librustc/infer/higher_ranked/mod.rs | 43 ++++++++++++++++--------- src/librustc/infer/mod.rs | 6 ++-- src/librustc/traits/project.rs | 2 +- src/librustc/traits/select.rs | 10 +++--- 4 files changed, 36 insertions(+), 25 deletions(-) diff --git a/src/librustc/infer/higher_ranked/mod.rs b/src/librustc/infer/higher_ranked/mod.rs index ddf46b18ef730..5218aa36facc1 100644 --- a/src/librustc/infer/higher_ranked/mod.rs +++ b/src/librustc/infer/higher_ranked/mod.rs @@ -53,7 +53,7 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> { // First, we instantiate each bound region in the supertype with a // fresh placeholder region. let (b_prime, placeholder_map) = - self.infcx.replace_late_bound_regions_with_placeholders(b); + self.infcx.replace_bound_vars_with_placeholders(b); // Next, we instantiate each bound region in the subtype // with a fresh region variable. These region variables -- @@ -115,7 +115,7 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> { // First, we instantiate each bound region in the matcher // with a placeholder region. let ((a_match, a_value), placeholder_map) = - self.infcx.replace_late_bound_regions_with_placeholders(a_pair); + self.infcx.replace_bound_vars_with_placeholders(a_pair); debug!("higher_ranked_match: a_match={:?}", a_match); debug!("higher_ranked_match: placeholder_map={:?}", placeholder_map); @@ -314,10 +314,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { region_vars } - /// Replace all regions bound by `binder` with placeholder regions and - /// return a map indicating which bound-region was replaced with what - /// placeholder region. This is the first step of checking subtyping - /// when higher-ranked things are involved. + /// Replace all regions (resp. types) bound by `binder` with placeholder + /// regions (resp. types) and return a map indicating which bound-region + /// was replaced with what placeholder region. This is the first step of + /// checking subtyping when higher-ranked things are involved. /// /// **Important:** you must call this function from within a snapshot. /// Moreover, before committing the snapshot, you must eventually call @@ -330,26 +330,37 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { /// the [rustc guide]. /// /// [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/traits/hrtb.html - pub fn replace_late_bound_regions_with_placeholders( + pub fn replace_bound_vars_with_placeholders( &self, - binder: &ty::Binder, + binder: &ty::Binder ) -> (T, PlaceholderMap<'tcx>) where - T : TypeFoldable<'tcx>, + T: TypeFoldable<'tcx> { let next_universe = self.create_next_universe(); - let (result, map) = self.tcx.replace_late_bound_regions(binder, |br| { + let fld_r = |br| { self.tcx.mk_region(ty::RePlaceholder(ty::PlaceholderRegion { universe: next_universe, name: br, })) - }); + }; + + let fld_t = |bound_ty: ty::BoundTy| { + self.tcx.mk_ty(ty::Placeholder(ty::PlaceholderType { + universe: next_universe, + name: bound_ty.var, + })) + }; + + let (result, map) = self.tcx.replace_bound_vars(binder, fld_r, fld_t); - debug!("replace_late_bound_regions_with_placeholders(binder={:?}, result={:?}, map={:?})", - binder, - result, - map); + debug!( + "replace_bound_vars_with_placeholders(binder={:?}, result={:?}, map={:?})", + binder, + result, + map + ); (result, map) } @@ -530,7 +541,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { /// Pops the placeholder regions found in `placeholder_map` from the region /// inference context. Whenever you create placeholder regions via - /// `replace_late_bound_regions_with_placeholders`, they must be popped before you + /// `replace_bound_vars_with_placeholders`, they must be popped before you /// commit the enclosing snapshot (if you do not commit, e.g. within a /// probe or as a result of an error, then this is not necessary, as /// popping happens as part of the rollback). diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index 6f041fdfb0ac4..a29c85bd2b1c5 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -227,7 +227,7 @@ pub struct InferCtxt<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> { universe: Cell, } -/// A map returned by `replace_late_bound_regions_with_placeholders()` +/// A map returned by `replace_bound_vars_with_placeholders()` /// indicating the placeholder region that each late-bound region was /// replaced with. pub type PlaceholderMap<'tcx> = BTreeMap>; @@ -935,7 +935,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { b, }, placeholder_map, - ) = self.replace_late_bound_regions_with_placeholders(predicate); + ) = self.replace_bound_vars_with_placeholders(predicate); let cause_span = cause.span; let ok = self.at(cause, param_env).sub_exp(a_is_expected, a, b)?; @@ -952,7 +952,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { ) -> UnitResult<'tcx> { self.commit_if_ok(|snapshot| { let (ty::OutlivesPredicate(r_a, r_b), placeholder_map) = - self.replace_late_bound_regions_with_placeholders(predicate); + self.replace_bound_vars_with_placeholders(predicate); let origin = SubregionOrigin::from_obligation_cause(cause, || { RelateRegionParamBound(cause.span) }); diff --git a/src/librustc/traits/project.rs b/src/librustc/traits/project.rs index 0aabb7ad713f1..e7b5fc3d1ffd7 100644 --- a/src/librustc/traits/project.rs +++ b/src/librustc/traits/project.rs @@ -204,7 +204,7 @@ pub fn poly_project_and_unify_type<'cx, 'gcx, 'tcx>( let infcx = selcx.infcx(); infcx.commit_if_ok(|snapshot| { let (placeholder_predicate, placeholder_map) = - infcx.replace_late_bound_regions_with_placeholders(&obligation.predicate); + infcx.replace_bound_vars_with_placeholders(&obligation.predicate); let skol_obligation = obligation.with(placeholder_predicate); let r = match project_and_unify_type(selcx, &skol_obligation) { diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index 6a91ad59d98e4..0cb071e3196ae 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -1726,7 +1726,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { let poly_trait_predicate = self.infcx() .resolve_type_vars_if_possible(&obligation.predicate); let (skol_trait_predicate, placeholder_map) = self.infcx() - .replace_late_bound_regions_with_placeholders(&poly_trait_predicate); + .replace_bound_vars_with_placeholders(&poly_trait_predicate); debug!( "match_projection_obligation_against_definition_bounds: \ skol_trait_predicate={:?} placeholder_map={:?}", @@ -2685,7 +2685,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { self.in_snapshot(|this, snapshot| { let (skol_ty, placeholder_map) = this.infcx() - .replace_late_bound_regions_with_placeholders(&ty); + .replace_bound_vars_with_placeholders(&ty); let Normalized { value: normalized_ty, mut obligations, @@ -2919,7 +2919,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { let trait_obligations: Vec> = self.in_snapshot(|this, snapshot| { let poly_trait_ref = obligation.predicate.to_poly_trait_ref(); let (trait_ref, placeholder_map) = this.infcx() - .replace_late_bound_regions_with_placeholders(&poly_trait_ref); + .replace_bound_vars_with_placeholders(&poly_trait_ref); let cause = obligation.derived_cause(ImplDerivedObligation); this.impl_or_trait_obligations( cause, @@ -3122,7 +3122,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { self.in_snapshot(|this, snapshot| { let (predicate, placeholder_map) = this.infcx() - .replace_late_bound_regions_with_placeholders(&obligation.predicate); + .replace_bound_vars_with_placeholders(&obligation.predicate); let trait_ref = predicate.trait_ref; let trait_def_id = trait_ref.def_id; let substs = trait_ref.substs; @@ -3585,7 +3585,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { } let (skol_obligation, placeholder_map) = self.infcx() - .replace_late_bound_regions_with_placeholders(&obligation.predicate); + .replace_bound_vars_with_placeholders(&obligation.predicate); let skol_obligation_trait_ref = skol_obligation.trait_ref; let impl_substs = self.infcx From 95861b159072c404ad5ef2951d1f8c323a3878ca Mon Sep 17 00:00:00 2001 From: scalexm Date: Sat, 3 Nov 2018 15:15:33 +0100 Subject: [PATCH 07/11] Move `BoundTy` debruijn index to the `TyKind` enum variant --- src/librustc/ich/impls_ty.rs | 3 ++- src/librustc/infer/canonical/canonicalizer.rs | 8 ++++---- .../infer/canonical/query_response.rs | 8 ++++---- src/librustc/traits/select.rs | 6 +++--- src/librustc/traits/structural_impls.rs | 2 +- src/librustc/ty/error.rs | 2 +- src/librustc/ty/flags.rs | 4 ++-- src/librustc/ty/fold.rs | 19 ++++++++----------- src/librustc/ty/sty.rs | 12 +++++------- src/librustc/ty/subst.rs | 19 ++++++++++--------- src/librustc/util/ppaux.rs | 6 +++--- .../chalk_context/program_clauses.rs | 19 +++++++++++-------- src/librustc_traits/lowering/environment.rs | 2 +- src/librustc_traits/lowering/mod.rs | 3 ++- 14 files changed, 57 insertions(+), 56 deletions(-) diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs index e9fac5b923961..ad317a96590b3 100644 --- a/src/librustc/ich/impls_ty.rs +++ b/src/librustc/ich/impls_ty.rs @@ -684,7 +684,8 @@ for ty::TyKind<'gcx> Param(param_ty) => { param_ty.hash_stable(hcx, hasher); } - Bound(bound_ty) => { + Bound(debruijn, bound_ty) => { + debruijn.hash_stable(hcx, hasher); bound_ty.hash_stable(hcx, hasher); } ty::Placeholder(placeholder_ty) => { diff --git a/src/librustc/infer/canonical/canonicalizer.rs b/src/librustc/infer/canonical/canonicalizer.rs index 7a9527573c7d6..ddb520775da0a 100644 --- a/src/librustc/infer/canonical/canonicalizer.rs +++ b/src/librustc/infer/canonical/canonicalizer.rs @@ -23,7 +23,7 @@ use infer::InferCtxt; use std::sync::atomic::Ordering; use ty::fold::{TypeFoldable, TypeFolder}; use ty::subst::Kind; -use ty::{self, BoundTy, BoundVar, Lift, List, Ty, TyCtxt, TypeFlags}; +use ty::{self, BoundVar, Lift, List, Ty, TyCtxt, TypeFlags}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::indexed_vec::Idx; @@ -382,8 +382,8 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for Canonicalizer<'cx, 'gcx, 'tcx> t ), - ty::Bound(bound_ty) => { - if bound_ty.index >= self.binder_index { + ty::Bound(debruijn, _) => { + if debruijn >= self.binder_index { bug!("escaping bound type during canonicalization") } else { t @@ -616,7 +616,7 @@ impl<'cx, 'gcx, 'tcx> Canonicalizer<'cx, 'gcx, 'tcx> { self.fold_ty(bound_to) } else { let var = self.canonical_var(info, ty_var.into()); - self.tcx().mk_ty(ty::Bound(BoundTy::new(self.binder_index, var))) + self.tcx().mk_ty(ty::Bound(self.binder_index, var.into())) } } } diff --git a/src/librustc/infer/canonical/query_response.rs b/src/librustc/infer/canonical/query_response.rs index 6f3d10268351a..d32594ebdf366 100644 --- a/src/librustc/infer/canonical/query_response.rs +++ b/src/librustc/infer/canonical/query_response.rs @@ -435,21 +435,21 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> { match result_value.unpack() { UnpackedKind::Type(result_value) => { // e.g., here `result_value` might be `?0` in the example above... - if let ty::Bound(b) = result_value.sty { + if let ty::Bound(debruijn, b) = result_value.sty { // ...in which case we would set `canonical_vars[0]` to `Some(?U)`. // We only allow a `ty::INNERMOST` index in substitutions. - assert_eq!(b.index, ty::INNERMOST); + assert_eq!(debruijn, ty::INNERMOST); opt_values[b.var] = Some(*original_value); } } UnpackedKind::Lifetime(result_value) => { // e.g., here `result_value` might be `'?1` in the example above... - if let &ty::RegionKind::ReLateBound(index, br) = result_value { + if let &ty::RegionKind::ReLateBound(debruijn, br) = result_value { // ... in which case we would set `canonical_vars[0]` to `Some('static)`. // We only allow a `ty::INNERMOST` index in substitutions. - assert_eq!(index, ty::INNERMOST); + assert_eq!(debruijn, ty::INNERMOST); opt_values[br.assert_bound_var()] = Some(*original_value); } } diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index 0cb071e3196ae..0f59f478cb415 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -2471,7 +2471,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { ty::UnnormalizedProjection(..) | ty::Placeholder(..) - | ty::Bound(_) + | ty::Bound(..) | ty::Infer(ty::FreshTy(_)) | ty::Infer(ty::FreshIntTy(_)) | ty::Infer(ty::FreshFloatTy(_)) => { @@ -2557,7 +2557,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { ty::UnnormalizedProjection(..) | ty::Placeholder(..) - | ty::Bound(_) + | ty::Bound(..) | ty::Infer(ty::FreshTy(_)) | ty::Infer(ty::FreshIntTy(_)) | ty::Infer(ty::FreshFloatTy(_)) => { @@ -2601,7 +2601,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { | ty::Param(..) | ty::Foreign(..) | ty::Projection(..) - | ty::Bound(_) + | ty::Bound(..) | ty::Infer(ty::TyVar(_)) | ty::Infer(ty::FreshTy(_)) | ty::Infer(ty::FreshIntTy(_)) diff --git a/src/librustc/traits/structural_impls.rs b/src/librustc/traits/structural_impls.rs index 3e417f10c4494..36538ac0889de 100644 --- a/src/librustc/traits/structural_impls.rs +++ b/src/librustc/traits/structural_impls.rs @@ -324,7 +324,7 @@ impl<'tcx> TypeVisitor<'tcx> for BoundNamesCollector { use syntax::symbol::Symbol; match t.sty { - ty::Bound(bound_ty) if bound_ty.index == self.binder_index => { + ty::Bound(debruijn, bound_ty) if debruijn == self.binder_index => { self.types.insert( bound_ty.var.as_u32(), match bound_ty.kind { diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs index e78759e3e7961..90022a770c114 100644 --- a/src/librustc/ty/error.rs +++ b/src/librustc/ty/error.rs @@ -213,7 +213,7 @@ impl<'a, 'gcx, 'lcx, 'tcx> ty::TyS<'tcx> { ty::Infer(ty::IntVar(_)) => "integral variable".into(), ty::Infer(ty::FloatVar(_)) => "floating-point variable".into(), ty::Placeholder(..) => "placeholder type".into(), - ty::Bound(_) | + ty::Bound(..) => "bound type".into(), ty::Infer(ty::FreshTy(_)) => "fresh type".into(), ty::Infer(ty::FreshIntTy(_)) => "fresh integral type".into(), ty::Infer(ty::FreshFloatTy(_)) => "fresh floating-point type".into(), diff --git a/src/librustc/ty/flags.rs b/src/librustc/ty/flags.rs index 3b84e7b54bdf3..1ea7e27c0dcdb 100644 --- a/src/librustc/ty/flags.rs +++ b/src/librustc/ty/flags.rs @@ -115,8 +115,8 @@ impl FlagComputation { self.add_substs(&substs.substs); } - &ty::Bound(bound_ty) => { - self.add_binder(bound_ty.index); + &ty::Bound(debruijn, _) => { + self.add_binder(debruijn); } &ty::Placeholder(..) => { diff --git a/src/librustc/ty/fold.rs b/src/librustc/ty/fold.rs index 16de146cf4e4f..6f0e8d4f02680 100644 --- a/src/librustc/ty/fold.rs +++ b/src/librustc/ty/fold.rs @@ -460,8 +460,8 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for BoundVarReplacer<'a, 'gcx, 'tcx> fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { match t.sty { - ty::Bound(bound_ty) => { - if bound_ty.index == self.current_index { + ty::Bound(debruijn, bound_ty) => { + if debruijn == self.current_index { let fld_t = &mut self.fld_t; let ty = fld_t(bound_ty); ty::fold::shift_vars( @@ -526,7 +526,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { T: TypeFoldable<'tcx> { // identity for bound types - let fld_t = |bound_ty| self.mk_ty(ty::Bound(bound_ty)); + let fld_t = |bound_ty| self.mk_ty(ty::Bound(ty::INNERMOST, bound_ty)); self.replace_escaping_bound_vars(value.skip_binder(), fld_r, fld_t) } @@ -722,16 +722,13 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for Shifter<'a, 'gcx, 'tcx> { fn fold_ty(&mut self, ty: ty::Ty<'tcx>) -> ty::Ty<'tcx> { match ty.sty { - ty::Bound(bound_ty) => { - if self.amount == 0 || bound_ty.index < self.current_index { + ty::Bound(debruijn, bound_ty) => { + if self.amount == 0 || debruijn < self.current_index { ty } else { - let shifted = ty::BoundTy { - index: bound_ty.index.shifted_in(self.amount), - var: bound_ty.var, - kind: bound_ty.kind, - }; - self.tcx.mk_ty(ty::Bound(shifted)) + self.tcx.mk_ty( + ty::Bound(debruijn.shifted_in(self.amount), bound_ty) + ) } } diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index cd69d31a00458..3056abba95626 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -201,7 +201,7 @@ pub enum TyKind<'tcx> { Param(ParamTy), /// Bound type variable, used only when preparing a trait query. - Bound(BoundTy), + Bound(ty::DebruijnIndex, BoundTy), /// A placeholder type - universally quantified higher-ranked type. Placeholder(ty::PlaceholderType), @@ -1245,7 +1245,6 @@ newtype_index! { #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)] pub struct BoundTy { - pub index: DebruijnIndex, pub var: BoundVar, pub kind: BoundTyKind, } @@ -1256,13 +1255,12 @@ pub enum BoundTyKind { Param(InternedString), } -impl_stable_hash_for!(struct BoundTy { index, var, kind }); +impl_stable_hash_for!(struct BoundTy { var, kind }); impl_stable_hash_for!(enum self::BoundTyKind { Anon, Param(a) }); -impl BoundTy { - pub fn new(index: DebruijnIndex, var: BoundVar) -> Self { +impl From for BoundTy { + fn from(var: BoundVar) -> Self { BoundTy { - index, var, kind: BoundTyKind::Anon, } @@ -1957,7 +1955,7 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> { ty::Infer(ty::TyVar(_)) => false, - ty::Bound(_) | + ty::Bound(..) | ty::Placeholder(..) | ty::Infer(ty::FreshTy(_)) | ty::Infer(ty::FreshIntTy(_)) | diff --git a/src/librustc/ty/subst.rs b/src/librustc/ty/subst.rs index b7f1731ba44e5..3425203989891 100644 --- a/src/librustc/ty/subst.rs +++ b/src/librustc/ty/subst.rs @@ -190,11 +190,12 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> { Substs::for_item(tcx, def_id, |param, _| { match param.kind { ty::GenericParamDefKind::Type { .. } => { - tcx.mk_ty(ty::Bound(ty::BoundTy { - index: ty::INNERMOST, - var: ty::BoundVar::from(param.index), - kind: ty::BoundTyKind::Param(param.name), - })).into() + tcx.mk_ty( + ty::Bound(ty::INNERMOST, ty::BoundTy { + var: ty::BoundVar::from(param.index), + kind: ty::BoundTyKind::Param(param.name), + }) + ).into() } ty::GenericParamDefKind::Lifetime => { @@ -584,18 +585,18 @@ impl CanonicalUserSubsts<'tcx> { self.value.substs.iter().zip(BoundVar::new(0)..).all(|(kind, cvar)| { match kind.unpack() { UnpackedKind::Type(ty) => match ty.sty { - ty::Bound(b) => { + ty::Bound(debruijn, b) => { // We only allow a `ty::INNERMOST` index in substitutions. - assert_eq!(b.index, ty::INNERMOST); + assert_eq!(debruijn, ty::INNERMOST); cvar == b.var } _ => false, }, UnpackedKind::Lifetime(r) => match r { - ty::ReLateBound(index, br) => { + ty::ReLateBound(debruijn, br) => { // We only allow a `ty::INNERMOST` index in substitutions. - assert_eq!(*index, ty::INNERMOST); + assert_eq!(*debruijn, ty::INNERMOST); cvar == br.assert_bound_var() } _ => false, diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 0c424b344159d..eea3b54919d52 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -1110,13 +1110,13 @@ define_print! { Infer(infer_ty) => write!(f, "{}", infer_ty), Error => write!(f, "[type error]"), Param(ref param_ty) => write!(f, "{}", param_ty), - Bound(bound_ty) => { + Bound(debruijn, bound_ty) => { match bound_ty.kind { ty::BoundTyKind::Anon => { - if bound_ty.index == ty::INNERMOST { + if debruijn == ty::INNERMOST { write!(f, "^{}", bound_ty.var.index()) } else { - write!(f, "^{}_{}", bound_ty.index.index(), bound_ty.var.index()) + write!(f, "^{}_{}", debruijn.index(), bound_ty.var.index()) } } diff --git a/src/librustc_traits/chalk_context/program_clauses.rs b/src/librustc_traits/chalk_context/program_clauses.rs index 5592d2a583cfb..b8670e5e91436 100644 --- a/src/librustc_traits/chalk_context/program_clauses.rs +++ b/src/librustc_traits/chalk_context/program_clauses.rs @@ -59,7 +59,8 @@ fn assemble_clauses_from_assoc_ty_values<'tcx>( fn program_clauses_for_raw_ptr<'tcx>(tcx: ty::TyCtxt<'_, '_, 'tcx>) -> Clauses<'tcx> { let ty = ty::Bound( - ty::BoundTy::new(ty::INNERMOST, ty::BoundVar::from_u32(0)) + ty::INNERMOST, + ty::BoundVar::from_u32(0).into() ); let ty = tcx.mk_ty(ty); @@ -88,9 +89,9 @@ fn program_clauses_for_fn_ptr<'tcx>( ) -> Clauses<'tcx> { let inputs_and_output = tcx.mk_type_list( (0..arity_and_output).into_iter() + .map(|i| ty::BoundVar::from(i)) // DebruijnIndex(1) because we are going to inject these in a `PolyFnSig` - .map(|i| ty::BoundTy::new(ty::DebruijnIndex::from(1usize), ty::BoundVar::from(i))) - .map(|t| tcx.mk_ty(ty::Bound(t))) + .map(|var| tcx.mk_ty(ty::Bound(ty::DebruijnIndex::from(1usize), var.into()))) ); let fn_sig = ty::Binder::bind(ty::FnSig { @@ -115,7 +116,8 @@ fn program_clauses_for_fn_ptr<'tcx>( fn program_clauses_for_slice<'tcx>(tcx: ty::TyCtxt<'_, '_, 'tcx>) -> Clauses<'tcx> { let ty = ty::Bound( - ty::BoundTy::new(ty::INNERMOST, ty::BoundVar::from_u32(0)) + ty::INNERMOST, + ty::BoundVar::from_u32(0).into() ); let ty = tcx.mk_ty(ty); @@ -151,7 +153,8 @@ fn program_clauses_for_array<'tcx>( length: &'tcx ty::Const<'tcx> ) -> Clauses<'tcx> { let ty = ty::Bound( - ty::BoundTy::new(ty::INNERMOST, ty::BoundVar::from_u32(0)) + ty::INNERMOST, + ty::BoundVar::from_u32(0).into() ); let ty = tcx.mk_ty(ty); @@ -188,8 +191,8 @@ fn program_clauses_for_tuple<'tcx>( ) -> Clauses<'tcx> { let type_list = tcx.mk_type_list( (0..arity).into_iter() - .map(|i| ty::BoundTy::new(ty::INNERMOST, ty::BoundVar::from(i))) - .map(|t| tcx.mk_ty(ty::Bound(t))) + .map(|i| ty::BoundVar::from(i)) + .map(|var| tcx.mk_ty(ty::Bound(ty::INNERMOST, var.into()))) ); let tuple_ty = tcx.mk_ty(ty::Tuple(type_list)); @@ -233,7 +236,7 @@ fn program_clauses_for_ref<'tcx>(tcx: ty::TyCtxt<'_, '_, 'tcx>) -> Clauses<'tcx> ty::ReLateBound(ty::INNERMOST, ty::BoundRegion::BrAnon(0)) ); let ty = tcx.mk_ty( - ty::Bound(ty::BoundTy::new(ty::INNERMOST, ty::BoundVar::from_u32(1))) + ty::Bound(ty::INNERMOST, ty::BoundVar::from_u32(1).into()) ); let ref_ty = tcx.mk_ref(region, ty::TypeAndMut { diff --git a/src/librustc_traits/lowering/environment.rs b/src/librustc_traits/lowering/environment.rs index c3573f47cebfe..519b0ac61058e 100644 --- a/src/librustc_traits/lowering/environment.rs +++ b/src/librustc_traits/lowering/environment.rs @@ -55,7 +55,7 @@ impl ClauseVisitor<'set, 'a, 'tcx> { ty::ReLateBound(ty::INNERMOST, ty::BoundRegion::BrAnon(0)) ); let ty = self.tcx.mk_ty( - ty::Bound(ty::BoundTy::new(ty::INNERMOST, ty::BoundVar::from_u32(1))) + ty::Bound(ty::INNERMOST, ty::BoundVar::from_u32(1).into()) ); let ref_ty = self.tcx.mk_ref(region, ty::TypeAndMut { diff --git a/src/librustc_traits/lowering/mod.rs b/src/librustc_traits/lowering/mod.rs index cf1bc04dd4e01..2d8e5b48aac7b 100644 --- a/src/librustc_traits/lowering/mod.rs +++ b/src/librustc_traits/lowering/mod.rs @@ -515,7 +515,8 @@ pub fn program_clauses_for_associated_type_def<'a, 'tcx>( .unwrap_or(0); // Add a new type param after the existing ones (`U` in the comment above). let ty_var = ty::Bound( - ty::BoundTy::new(ty::INNERMOST, ty::BoundVar::from_u32(offset + 1)) + ty::INNERMOST, + ty::BoundVar::from_u32(offset + 1).into() ); // `ProjectionEq(>::AssocType = U)` From 5b2baa8336ab85f958ac6a8e78e71b490a43e474 Mon Sep 17 00:00:00 2001 From: scalexm Date: Sat, 3 Nov 2018 16:08:50 +0100 Subject: [PATCH 08/11] Implement some instantiate / canonical routines --- src/librustc_traits/chalk_context/mod.rs | 165 ++++++++++++++++------- 1 file changed, 113 insertions(+), 52 deletions(-) diff --git a/src/librustc_traits/chalk_context/mod.rs b/src/librustc_traits/chalk_context/mod.rs index 0fd9f607a5462..14d4be2b1787d 100644 --- a/src/librustc_traits/chalk_context/mod.rs +++ b/src/librustc_traits/chalk_context/mod.rs @@ -11,7 +11,7 @@ mod program_clauses; use chalk_engine::fallible::Fallible as ChalkEngineFallible; -use chalk_engine::{context, hh::HhGoal, DelayedLiteral, ExClause}; +use chalk_engine::{context, hh::HhGoal, DelayedLiteral, Literal, ExClause}; use rustc::infer::canonical::{ Canonical, CanonicalVarValues, OriginalQueryValues, QueryRegionConstraint, QueryResponse, }; @@ -28,7 +28,7 @@ use rustc::traits::{ InEnvironment, }; use rustc::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; -use rustc::ty::subst::Kind; +use rustc::ty::subst::{Kind, UnpackedKind}; use rustc::ty::{self, TyCtxt}; use std::fmt::{self, Debug}; @@ -44,7 +44,7 @@ crate struct ChalkArenas<'gcx> { #[derive(Copy, Clone)] crate struct ChalkContext<'cx, 'gcx: 'cx> { _arenas: ChalkArenas<'gcx>, - _tcx: TyCtxt<'cx, 'gcx, 'gcx>, + tcx: TyCtxt<'cx, 'gcx, 'gcx>, } #[derive(Copy, Clone)] @@ -68,7 +68,7 @@ BraceStructTypeFoldableImpl! { } impl context::Context for ChalkArenas<'tcx> { - type CanonicalExClause = Canonical<'tcx, ExClause>; + type CanonicalExClause = Canonical<'tcx, ChalkExClause<'tcx>>; type CanonicalGoalInEnvironment = Canonical<'tcx, InEnvironment<'tcx, Goal<'tcx>>>; @@ -147,19 +147,29 @@ impl context::ContextOps> for ChalkContext<'cx, 'gcx> { /// - the environment and goal found by substitution `S` into `arg` fn instantiate_ucanonical_goal( &self, - _arg: &Canonical<'gcx, InEnvironment<'gcx, Goal<'gcx>>>, - _op: impl context::WithInstantiatedUCanonicalGoal, Output = R>, + arg: &Canonical<'gcx, InEnvironment<'gcx, Goal<'gcx>>>, + op: impl context::WithInstantiatedUCanonicalGoal, Output = R>, ) -> R { - unimplemented!() + self.tcx.infer_ctxt().enter_with_canonical(DUMMY_SP, arg, |ref infcx, arg, subst| { + let chalk_infcx = &mut ChalkInferenceContext { + infcx, + }; + op.with(chalk_infcx, subst, arg.environment, arg.goal) + }) } fn instantiate_ex_clause( &self, _num_universes: usize, - _canonical_ex_clause: &Canonical<'gcx, ChalkExClause<'gcx>>, - _op: impl context::WithInstantiatedExClause, Output = R>, + arg: &Canonical<'gcx, ChalkExClause<'gcx>>, + op: impl context::WithInstantiatedExClause, Output = R>, ) -> R { - unimplemented!() + self.tcx.infer_ctxt().enter_with_canonical(DUMMY_SP, &arg.upcast(), |ref infcx, arg, _| { + let chalk_infcx = &mut ChalkInferenceContext { + infcx, + }; + op.with(chalk_infcx,arg) + }) } /// True if this solution has no region constraints. @@ -186,14 +196,33 @@ impl context::ContextOps> for ChalkContext<'cx, 'gcx> { } fn is_trivial_substitution( - _u_canon: &Canonical<'gcx, InEnvironment<'gcx, Goal<'gcx>>>, - _canonical_subst: &Canonical<'gcx, ConstrainedSubst<'gcx>>, + u_canon: &Canonical<'gcx, InEnvironment<'gcx, Goal<'gcx>>>, + canonical_subst: &Canonical<'tcx, ConstrainedSubst<'tcx>>, ) -> bool { - unimplemented!() - } - - fn num_universes(_: &Canonical<'gcx, InEnvironment<'gcx, Goal<'gcx>>>) -> usize { - 0 // FIXME + let subst = &canonical_subst.value.subst; + assert_eq!(u_canon.variables.len(), subst.var_values.len()); + subst.var_values + .iter_enumerated() + .all(|(cvar, kind)| match kind.unpack() { + UnpackedKind::Lifetime(r) => match r { + &ty::ReLateBound(debruijn, br) => { + debug_assert_eq!(debruijn, ty::INNERMOST); + cvar == br.assert_bound_var() + } + _ => false, + }, + UnpackedKind::Type(ty) => match ty.sty { + ty::Bound(debruijn, bound_ty) => { + debug_assert_eq!(debruijn, ty::INNERMOST); + cvar == bound_ty.var + } + _ => false, + }, + }) + } + + fn num_universes(canon: &Canonical<'gcx, InEnvironment<'gcx, Goal<'gcx>>>) -> usize { + canon.max_universe.index() + 1 } /// Convert a goal G *from* the canonical universes *into* our @@ -214,39 +243,6 @@ impl context::ContextOps> for ChalkContext<'cx, 'gcx> { } } -//impl context::UCanonicalGoalInEnvironment> -// for Canonical<'gcx, ty::ParamEnvAnd<'gcx, Goal<'gcx>>> -//{ -// fn canonical(&self) -> &Canonical<'gcx, ty::ParamEnvAnd<'gcx, Goal<'gcx>>> { -// self -// } -// -// fn is_trivial_substitution( -// &self, -// canonical_subst: &Canonical<'tcx, ConstrainedSubst<'tcx>>, -// ) -> bool { -// let subst = &canonical_subst.value.subst; -// assert_eq!(self.canonical.variables.len(), subst.var_values.len()); -// subst -// .var_values -// .iter_enumerated() -// .all(|(cvar, kind)| match kind.unpack() { -// Kind::Lifetime(r) => match r { -// ty::ReCanonical(cvar1) => cvar == cvar1, -// _ => false, -// }, -// Kind::Type(ty) => match ty.sty { -// ty::Infer(ty::InferTy::CanonicalTy(cvar1)) => cvar == cvar1, -// _ => false, -// }, -// }) -// } -// -// fn num_universes(&self) -> usize { -// 0 // FIXME -// } -//} - impl context::InferenceTable, ChalkArenas<'tcx>> for ChalkInferenceContext<'cx, 'gcx, 'tcx> { @@ -338,9 +334,9 @@ impl context::UnificationOps, ChalkArenas<'tcx>> fn instantiate_binders_universally( &mut self, - _arg: &ty::Binder>, + arg: &ty::Binder>, ) -> Goal<'tcx> { - panic!("FIXME -- universal instantiation needs sgrif's branch") + self.infcx.replace_bound_vars_with_placeholders(arg).0 } fn instantiate_binders_existentially( @@ -491,3 +487,68 @@ BraceStructLiftImpl! { subst, constraints } } + +trait Upcast<'tcx, 'gcx: 'tcx>: 'gcx { + type Upcasted: 'tcx; + + fn upcast(&self) -> Self::Upcasted; +} + +impl<'tcx, 'gcx: 'tcx> Upcast<'tcx, 'gcx> for DelayedLiteral> { + type Upcasted = DelayedLiteral>; + + fn upcast(&self) -> Self::Upcasted { + match self { + &DelayedLiteral::CannotProve(..) => DelayedLiteral::CannotProve(()), + &DelayedLiteral::Negative(index) => DelayedLiteral::Negative(index), + DelayedLiteral::Positive(index, subst) => DelayedLiteral::Positive( + *index, + subst.clone() + ), + } + } +} + +impl<'tcx, 'gcx: 'tcx> Upcast<'tcx, 'gcx> for Literal> { + type Upcasted = Literal>; + + fn upcast(&self) -> Self::Upcasted { + match self { + &Literal::Negative(goal) => Literal::Negative(goal), + &Literal::Positive(goal) => Literal::Positive(goal), + } + } +} + +impl<'tcx, 'gcx: 'tcx> Upcast<'tcx, 'gcx> for ExClause> { + type Upcasted = ExClause>; + + fn upcast(&self) -> Self::Upcasted { + ExClause { + subst: self.subst.clone(), + delayed_literals: self.delayed_literals + .iter() + .map(|l| l.upcast()) + .collect(), + constraints: self.constraints.clone(), + subgoals: self.subgoals + .iter() + .map(|g| g.upcast()) + .collect(), + } + } +} + +impl<'tcx, 'gcx: 'tcx, T> Upcast<'tcx, 'gcx> for Canonical<'gcx, T> + where T: Upcast<'tcx, 'gcx> +{ + type Upcasted = Canonical<'tcx, T::Upcasted>; + + fn upcast(&self) -> Self::Upcasted { + Canonical { + max_universe: self.max_universe, + value: self.value.upcast(), + variables: self.variables, + } + } +} From c0f98e83906453e0f563a6f925f5c6e14f93a0ba Mon Sep 17 00:00:00 2001 From: scalexm Date: Mon, 5 Nov 2018 18:08:47 +0100 Subject: [PATCH 09/11] Fix `ChalkInferenceContext::into_hh_goal` --- src/librustc_traits/chalk_context/mod.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/librustc_traits/chalk_context/mod.rs b/src/librustc_traits/chalk_context/mod.rs index 14d4be2b1787d..25a6af284b572 100644 --- a/src/librustc_traits/chalk_context/mod.rs +++ b/src/librustc_traits/chalk_context/mod.rs @@ -256,7 +256,10 @@ impl context::InferenceTable, ChalkArenas<'tcx>> fn into_hh_goal(&mut self, goal: Goal<'tcx>) -> ChalkHhGoal<'tcx> { match *goal { - GoalKind::Implies(..) => panic!("FIXME rust-lang-nursery/chalk#94"), + GoalKind::Implies(hypotheses, goal) => HhGoal::Implies( + hypotheses.iter().cloned().collect(), + goal + ), GoalKind::And(left, right) => HhGoal::And(left, right), GoalKind::Not(subgoal) => HhGoal::Not(subgoal), GoalKind::DomainGoal(d) => HhGoal::DomainGoal(d), From 4478dced472dec4f516cc4ef553a1476e40c09b8 Mon Sep 17 00:00:00 2001 From: scalexm Date: Wed, 14 Nov 2018 12:50:26 +0100 Subject: [PATCH 10/11] Fix NLL ui test --- src/test/ui/nll/user-annotations/dump-fn-method.stderr | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/ui/nll/user-annotations/dump-fn-method.stderr b/src/test/ui/nll/user-annotations/dump-fn-method.stderr index 359423d0cfbea..c963625c961e8 100644 --- a/src/test/ui/nll/user-annotations/dump-fn-method.stderr +++ b/src/test/ui/nll/user-annotations/dump-fn-method.stderr @@ -4,7 +4,7 @@ error: user substs: Canonical { max_universe: U0, variables: [], value: UserSubs LL | let x = foo::; //~ ERROR [u32] | ^^^^^^^^^^ -error: user substs: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General) }, CanonicalVarInfo { kind: Ty(General) }], value: UserSubsts { substs: [^0, u32, ^1], user_self_ty: None } } +error: user substs: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }, CanonicalVarInfo { kind: Ty(General(U0)) }], value: UserSubsts { substs: [^0, u32, ^1], user_self_ty: None } } --> $DIR/dump-fn-method.rs:42:13 | LL | let x = <_ as Bazoom>::method::<_>; //~ ERROR [^0, u32, ^1] @@ -16,7 +16,7 @@ error: user substs: Canonical { max_universe: U0, variables: [], value: UserSubs LL | let x = >::method::; //~ ERROR [u8, u16, u32] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: user substs: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General) }, CanonicalVarInfo { kind: Ty(General) }], value: UserSubsts { substs: [^0, ^1, u32], user_self_ty: None } } +error: user substs: Canonical { max_universe: U1, variables: [CanonicalVarInfo { kind: Ty(General(U1)) }, CanonicalVarInfo { kind: Ty(General(U1)) }], value: UserSubsts { substs: [^0, ^1, u32], user_self_ty: None } } --> $DIR/dump-fn-method.rs:54:5 | LL | y.method::(44, 66); //~ ERROR [^0, ^1, u32] From b8a30f04cdd129ab89b85d0eda11f1c65058767a Mon Sep 17 00:00:00 2001 From: scalexm Date: Sat, 24 Nov 2018 23:34:44 +0100 Subject: [PATCH 11/11] Try to work around #53332 in `src/test/run-pass/rustc-rust-log.rs` --- src/test/run-pass/rustc-rust-log.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/run-pass/rustc-rust-log.rs b/src/test/run-pass/rustc-rust-log.rs index 8c3e4b391e995..10e91e71fe284 100644 --- a/src/test/run-pass/rustc-rust-log.rs +++ b/src/test/run-pass/rustc-rust-log.rs @@ -16,6 +16,7 @@ // // dont-check-compiler-stdout // dont-check-compiler-stderr +// compile-flags: --error-format human // rustc-env:RUST_LOG=debug