diff options
| author | Niko Matsakis <niko@alum.mit.edu> | 2018-09-26 12:35:24 -0400 |
|---|---|---|
| committer | Niko Matsakis <niko@alum.mit.edu> | 2018-10-27 09:06:01 -0400 |
| commit | 3ef27d82e0623554962e96a9b06921326da861d2 (patch) | |
| tree | d093027b6d8a1832ff8d3d9de3b84d93fa26ce82 | |
| parent | 784746f57e6e9d76f4ecc0415e8ab926a81ce37e (diff) | |
| download | rust-3ef27d82e0623554962e96a9b06921326da861d2.tar.gz rust-3ef27d82e0623554962e96a9b06921326da861d2.zip | |
allow canonicalized regions to carry universe and track max-universe
But.. we don't really use it for anything right now.
| -rw-r--r-- | src/librustc/ich/impls_ty.rs | 4 | ||||
| -rw-r--r-- | src/librustc/infer/canonical/canonicalizer.rs | 15 | ||||
| -rw-r--r-- | src/librustc/infer/canonical/mod.rs | 35 | ||||
| -rw-r--r-- | src/librustc/traits/query/type_op/implied_outlives_bounds.rs | 20 | ||||
| -rw-r--r-- | src/librustc/traits/query/type_op/outlives.rs | 16 | ||||
| -rw-r--r-- | src/test/mir-opt/basic_assignment.rs | 2 | ||||
| -rw-r--r-- | src/test/ui/nll/user-annotations/dump-adt-brace-struct.stderr | 2 | ||||
| -rw-r--r-- | src/test/ui/nll/user-annotations/dump-fn-method.stderr | 8 |
8 files changed, 61 insertions, 41 deletions
diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs index 7e5d19850f4..16a7f1425ab 100644 --- a/src/librustc/ich/impls_ty.rs +++ b/src/librustc/ich/impls_ty.rs @@ -1268,7 +1268,7 @@ for traits::VtableGeneratorData<'gcx, N> where N: HashStable<StableHashingContex impl_stable_hash_for!( impl<'tcx, V> for struct infer::canonical::Canonical<'tcx, V> { - variables, value + max_universe, variables, value } ); @@ -1284,7 +1284,7 @@ impl_stable_hash_for!(struct infer::canonical::CanonicalVarInfo { impl_stable_hash_for!(enum infer::canonical::CanonicalVarKind { Ty(k), - Region + Region(ui), }); impl_stable_hash_for!(enum infer::canonical::CanonicalTyVarKind { diff --git a/src/librustc/infer/canonical/canonicalizer.rs b/src/librustc/infer/canonical/canonicalizer.rs index 2b085a3407c..536da55adc4 100644 --- a/src/librustc/infer/canonical/canonicalizer.rs +++ b/src/librustc/infer/canonical/canonicalizer.rs @@ -261,7 +261,8 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for Canonicalizer<'cx, 'gcx, 'tcx> | ty::ReScope(_) | ty::RePlaceholder(..) | ty::ReEmpty - | ty::ReErased => self.canonicalize_region_mode.canonicalize_free_region(self, r), + | ty::ReErased => self.canonicalize_region_mode + .canonicalize_free_region(self, r), ty::ReClosureBound(..) | ty::ReCanonical(_) => { bug!("canonical region encountered during canonicalization") @@ -353,6 +354,7 @@ impl<'cx, 'gcx, 'tcx> Canonicalizer<'cx, 'gcx, 'tcx> { if !value.has_type_flags(needs_canonical_flags) { let out_value = gcx.lift(value).unwrap(); let canon_value = Canonical { + max_universe: ty::UniverseIndex::ROOT, variables: List::empty(), value: out_value, }; @@ -383,7 +385,14 @@ impl<'cx, 'gcx, 'tcx> Canonicalizer<'cx, 'gcx, 'tcx> { let canonical_variables = tcx.intern_canonical_var_infos(&canonicalizer.variables); + let max_universe = canonical_variables + .iter() + .map(|cvar| cvar.universe()) + .max() + .unwrap_or(ty::UniverseIndex::ROOT); + Canonical { + max_universe, variables: canonical_variables, value: out_value, } @@ -451,8 +460,10 @@ impl<'cx, 'gcx, 'tcx> Canonicalizer<'cx, 'gcx, 'tcx> { } fn canonical_var_for_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { + // TODO: root is not always what we want here, but we'll + // address that in a later commit. let info = CanonicalVarInfo { - kind: CanonicalVarKind::Region, + kind: CanonicalVarKind::Region(ty::UniverseIndex::ROOT), }; let b = self.canonical_var(info, r.into()); debug_assert_eq!(ty::INNERMOST, b.level); diff --git a/src/librustc/infer/canonical/mod.rs b/src/librustc/infer/canonical/mod.rs index e3bd407d17a..24864d77927 100644 --- a/src/librustc/infer/canonical/mod.rs +++ b/src/librustc/infer/canonical/mod.rs @@ -53,6 +53,7 @@ mod substitute; /// numbered starting from 0 in order of first appearance. #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcDecodable, RustcEncodable)] pub struct Canonical<'gcx, V> { + pub max_universe: ty::UniverseIndex, pub variables: CanonicalVarInfos<'gcx>, pub value: V, } @@ -95,6 +96,12 @@ pub struct CanonicalVarInfo { pub kind: CanonicalVarKind, } +impl CanonicalVarInfo { + pub fn universe(self) -> ty::UniverseIndex { + self.kind.universe() + } +} + /// Describes the "kind" of the canonical variable. This is a "kind" /// in the type-theory sense of the term -- i.e., a "meta" type system /// that analyzes type-like values. @@ -104,7 +111,22 @@ pub enum CanonicalVarKind { Ty(CanonicalTyVarKind), /// Region variable `'?R`. - Region, + Region(ty::UniverseIndex), +} + + +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, + + // Region variables can be created in sub-universes. + CanonicalVarKind::Region(ui) => ui, + } + } } /// Rust actually has more than one category of type variables; @@ -220,8 +242,8 @@ impl<'gcx, V> Canonical<'gcx, V> { /// let b: Canonical<'tcx, (T, Ty<'tcx>)> = a.unchecked_map(|v| (v, ty)); /// ``` pub fn unchecked_map<W>(self, map_op: impl FnOnce(V) -> W) -> Canonical<'gcx, W> { - let Canonical { variables, value } = self; - Canonical { variables, value: map_op(value) } + let Canonical { max_universe, variables, value } = self; + Canonical { max_universe, variables, value: map_op(value) } } } @@ -293,8 +315,8 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> { ty.into() } - CanonicalVarKind::Region => self - .next_region_var(RegionVariableOrigin::MiscVariable(span)) + CanonicalVarKind::Region(ui) => self + .next_region_var_in_universe(RegionVariableOrigin::MiscVariable(span), ui) .into(), } } @@ -314,6 +336,7 @@ CloneTypeFoldableImpls! { BraceStructTypeFoldableImpl! { impl<'tcx, C> TypeFoldable<'tcx> for Canonical<'tcx, C> { + max_universe, variables, value, } where C: TypeFoldable<'tcx> @@ -322,7 +345,7 @@ BraceStructTypeFoldableImpl! { BraceStructLiftImpl! { impl<'a, 'tcx, T> Lift<'tcx> for Canonical<'a, T> { type Lifted = Canonical<'tcx, T::Lifted>; - variables, value + max_universe, variables, value } where T: Lift<'tcx> } diff --git a/src/librustc/traits/query/type_op/implied_outlives_bounds.rs b/src/librustc/traits/query/type_op/implied_outlives_bounds.rs index b113a322d37..d5233851db8 100644 --- a/src/librustc/traits/query/type_op/implied_outlives_bounds.rs +++ b/src/librustc/traits/query/type_op/implied_outlives_bounds.rs @@ -38,19 +38,13 @@ impl<'gcx: 'tcx, 'tcx> super::QueryTypeOp<'gcx, 'tcx> for ImpliedOutlivesBounds< tcx: TyCtxt<'_, 'gcx, 'tcx>, canonicalized: Canonicalized<'gcx, ParamEnvAnd<'tcx, Self>>, ) -> Fallible<CanonicalizedQueryResponse<'gcx, Self::QueryResponse>> { - // FIXME the query should take a `ImpliedOutlivesBounds` - let Canonical { - variables, - value: - ParamEnvAnd { - param_env, - value: ImpliedOutlivesBounds { ty }, - }, - } = canonicalized; - let canonicalized = Canonical { - variables, - value: param_env.and(ty), - }; + // FIXME this `unchecked_map` is only necessary because the + // query is defined as taking a `ParamEnvAnd<Ty>`; it should + // take a `ImpliedOutlivesBounds` instead + let canonicalized = canonicalized.unchecked_map(|ParamEnvAnd { param_env, value }| { + let ImpliedOutlivesBounds { ty } = value; + param_env.and(ty) + }); tcx.implied_outlives_bounds(canonicalized) } diff --git a/src/librustc/traits/query/type_op/outlives.rs b/src/librustc/traits/query/type_op/outlives.rs index a36c5accd2a..cd7c6d76eab 100644 --- a/src/librustc/traits/query/type_op/outlives.rs +++ b/src/librustc/traits/query/type_op/outlives.rs @@ -59,18 +59,10 @@ where // FIXME convert to the type expected by the `dropck_outlives` // query. This should eventually be fixed by changing the // *underlying query*. - let Canonical { - variables, - value: - ParamEnvAnd { - param_env, - value: DropckOutlives { dropped_ty }, - }, - } = canonicalized; - let canonicalized = Canonical { - variables, - value: param_env.and(dropped_ty), - }; + let canonicalized = canonicalized.unchecked_map(|ParamEnvAnd { param_env, value }| { + let DropckOutlives { dropped_ty } = value; + param_env.and(dropped_ty) + }); tcx.dropck_outlives(canonicalized) } diff --git a/src/test/mir-opt/basic_assignment.rs b/src/test/mir-opt/basic_assignment.rs index 7ca1d01f20b..75f19d133e0 100644 --- a/src/test/mir-opt/basic_assignment.rs +++ b/src/test/mir-opt/basic_assignment.rs @@ -56,7 +56,7 @@ fn main() { // StorageLive(_4); // _4 = std::option::Option<std::boxed::Box<u32>>::None; // FakeRead(ForLet, _4); -// AscribeUserType(_4, o, UserTypeProjection { base: Ty(Canonical { variables: [], value: std::option::Option<std::boxed::Box<u32>> }), projs: [] }); +// AscribeUserType(_4, o, UserTypeProjection { base: Ty(Canonical { max_universe: U0, variables: [], value: std::option::Option<std::boxed::Box<u32>> }), projs: [] }); // StorageLive(_5); // StorageLive(_6); // _6 = move _4; diff --git a/src/test/ui/nll/user-annotations/dump-adt-brace-struct.stderr b/src/test/ui/nll/user-annotations/dump-adt-brace-struct.stderr index 901ace59d33..88383190cbc 100644 --- a/src/test/ui/nll/user-annotations/dump-adt-brace-struct.stderr +++ b/src/test/ui/nll/user-annotations/dump-adt-brace-struct.stderr @@ -1,4 +1,4 @@ -error: user substs: Canonical { variables: [], value: UserSubsts { substs: [u32], user_self_ty: None } } +error: user substs: Canonical { max_universe: U0, variables: [], value: UserSubsts { substs: [u32], user_self_ty: None } } --> $DIR/dump-adt-brace-struct.rs:28:5 | LL | SomeStruct::<u32> { t: 22 }; //~ ERROR [u32] 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 a26be359fc4..3beb994a4e8 100644 --- a/src/test/ui/nll/user-annotations/dump-fn-method.stderr +++ b/src/test/ui/nll/user-annotations/dump-fn-method.stderr @@ -1,22 +1,22 @@ -error: user substs: Canonical { variables: [], value: UserSubsts { substs: [u32], user_self_ty: None } } +error: user substs: Canonical { max_universe: U0, variables: [], value: UserSubsts { substs: [u32], user_self_ty: None } } --> $DIR/dump-fn-method.rs:36:13 | LL | let x = foo::<u32>; //~ ERROR [u32] | ^^^^^^^^^^ -error: user substs: Canonical { 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) }, CanonicalVarInfo { kind: Ty(General) }], value: UserSubsts { substs: [?0, u32, ?1], user_self_ty: None } } --> $DIR/dump-fn-method.rs:42:13 | LL | let x = <_ as Bazoom<u32>>::method::<_>; //~ ERROR [?0, u32, ?1] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: user substs: Canonical { variables: [], value: UserSubsts { substs: [u8, u16, u32], user_self_ty: None } } +error: user substs: Canonical { max_universe: U0, variables: [], value: UserSubsts { substs: [u8, u16, u32], user_self_ty: None } } --> $DIR/dump-fn-method.rs:46:13 | LL | let x = <u8 as Bazoom<u16>>::method::<u32>; //~ ERROR [u8, u16, u32] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: user substs: Canonical { 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: U0, variables: [CanonicalVarInfo { kind: Ty(General) }, CanonicalVarInfo { kind: Ty(General) }], value: UserSubsts { substs: [?0, ?1, u32], user_self_ty: None } } --> $DIR/dump-fn-method.rs:54:5 | LL | y.method::<u32>(44, 66); //~ ERROR [?0, ?1, u32] |
