about summary refs log tree commit diff
diff options
context:
space:
mode:
authorvarkor <github@varkor.com>2018-05-14 19:57:59 +0100
committervarkor <github@varkor.com>2018-05-15 14:22:11 +0100
commit3ae2468261dca097ecfa81a74654fed32b60f8ce (patch)
tree888f15ca0211f0175ac1cc5f744b3a4f8c1c4757
parentd9190da9825b729ce63becf727b2cfdad3e8561a (diff)
downloadrust-3ae2468261dca097ecfa81a74654fed32b60f8ce.tar.gz
rust-3ae2468261dca097ecfa81a74654fed32b60f8ce.zip
Clean up shared subst code
-rw-r--r--src/librustc/infer/mod.rs65
-rw-r--r--src/librustc/ty/context.rs12
-rw-r--r--src/librustc_typeck/astconv.rs14
-rw-r--r--src/librustc_typeck/check/method/confirm.rs50
-rw-r--r--src/librustc_typeck/check/method/mod.rs16
-rw-r--r--src/librustc_typeck/check/method/probe.rs27
-rw-r--r--src/librustc_typeck/check/mod.rs61
7 files changed, 101 insertions, 144 deletions
diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs
index d90ba51fffc..7a1e255dc5d 100644
--- a/src/librustc/infer/mod.rs
+++ b/src/librustc/infer/mod.rs
@@ -905,34 +905,34 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
         self.next_region_var(RegionVariableOrigin::NLL(origin))
     }
 
-    /// Create a region inference variable for the given
-    /// region parameter definition.
-    pub fn region_var_for_def(&self,
-                              span: Span,
-                              def: &ty::GenericParamDef)
-                              -> ty::Region<'tcx> {
-        self.next_region_var(EarlyBoundRegion(span, def.name))
-    }
-
-    /// Create a type inference variable for the given
-    /// type parameter definition. The substitutions are
-    /// for actual parameters that may be referred to by
-    /// the default of this type parameter, if it exists.
-    /// E.g. `struct Foo<A, B, C = (A, B)>(...);` when
-    /// used in a path such as `Foo::<T, U>::new()` will
-    /// use an inference variable for `C` with `[T, U]`
-    /// as the substitutions for the default, `(T, U)`.
-    pub fn type_var_for_def(&self,
-                            span: Span,
-                            def: &ty::GenericParamDef)
-                            -> Ty<'tcx> {
-        let ty_var_id = self.type_variables
-                            .borrow_mut()
-                            .new_var(self.universe(),
-                                     false,
-                                     TypeVariableOrigin::TypeParameterDefinition(span, def.name));
-
-        self.tcx.mk_var(ty_var_id)
+    pub fn var_for_def(&self,
+                       span: Span,
+                       param: &ty::GenericParamDef)
+                       -> UnpackedKind<'tcx> {
+        match param.kind {
+            GenericParamDefKind::Lifetime => {
+                // Create a region inference variable for the given
+                // region parameter definition.
+                UnpackedKind::Lifetime(self.next_region_var(EarlyBoundRegion(span, param.name)))
+            }
+            GenericParamDefKind::Type(_) => {
+                // Create a type inference variable for the given
+                // type parameter definition. The substitutions are
+                // for actual parameters that may be referred to by
+                // the default of this type parameter, if it exists.
+                // E.g. `struct Foo<A, B, C = (A, B)>(...);` when
+                // used in a path such as `Foo::<T, U>::new()` will
+                // use an inference variable for `C` with `[T, U]`
+                // as the substitutions for the default, `(T, U)`.
+                let ty_var_id = self.type_variables
+                                    .borrow_mut()
+                                    .new_var(self.universe(),
+                                             false,
+                                             TypeVariableOrigin::TypeParameterDefinition(span, param.name));
+
+                UnpackedKind::Type(self.tcx.mk_var(ty_var_id))
+            }
+        }
     }
 
     /// Given a set of generics defined on a type or impl, returns a substitution mapping each
@@ -942,14 +942,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
                                  def_id: DefId)
                                  -> &'tcx Substs<'tcx> {
         Substs::for_item(self.tcx, def_id, |param, _| {
-            match param.kind {
-                GenericParamDefKind::Lifetime => {
-                    UnpackedKind::Lifetime(self.region_var_for_def(span, param))
-                }
-                GenericParamDefKind::Type(_) => {
-                    UnpackedKind::Type(self.type_var_for_def(span, param))
-                }
-            }
+            self.var_for_def(span, param)
         })
     }
 
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index 924271ea3d4..66c451e8193 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -2329,18 +2329,12 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
         let substs = Substs::for_item(self, def_id, |param, substs| {
             match param.kind {
                 GenericParamDefKind::Lifetime => bug!(),
-                GenericParamDefKind::Type(_) => {
+                GenericParamDefKind::Type(ty_param) => {
                     if param.index == 0 {
                         UnpackedKind::Type(ty)
                     } else {
-                        match param.kind {
-                            ty::GenericParamDefKind::Type(ty_param) => {
-                                assert!(ty_param.has_default);
-                                UnpackedKind::Type(
-                                    self.type_of(param.def_id).subst(self, substs))
-                            }
-                            _ => unreachable!()
-                        }
+                        assert!(ty_param.has_default);
+                        UnpackedKind::Type(self.type_of(param.def_id).subst(self, substs))
                     }
                 }
             }
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index f60c78702b6..32ea9938ff5 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -276,7 +276,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
                     };
                     UnpackedKind::Lifetime(lt)
                 }
-                GenericParamDefKind::Type(_) => {
+                GenericParamDefKind::Type(ty) => {
                     let i = param.index as usize;
 
                     // Handle Self first, so we can adjust the index to match the AST.
@@ -284,24 +284,18 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
                         return UnpackedKind::Type(ty);
                     }
 
-                    let has_default = match param.kind {
-                        GenericParamDefKind::Type(ty) => ty.has_default,
-                        _ => unreachable!()
-                    };
-
                     let i = i - (lt_accepted + own_self);
                     let ty = if i < ty_provided {
                         // A provided type parameter.
                         self.ast_ty_to_ty(&parameters.types[i])
                     } else if infer_types {
                         // No type parameters were provided, we can infer all.
-                        let ty_var = if !default_needs_object_self(param) {
+                        if !default_needs_object_self(param) {
                             self.ty_infer_for_def(param, span)
                         } else {
                             self.ty_infer(span)
-                        };
-                        ty_var
-                    } else if has_default {
+                        }
+                    } else if ty.has_default {
                         // No type parameter provided, but a default exists.
 
                         // If we are converting an object type, then the
diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs
index c208e0fae64..e2b4380fda2 100644
--- a/src/librustc_typeck/check/method/confirm.rs
+++ b/src/librustc_typeck/check/method/confirm.rs
@@ -318,36 +318,28 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
         let provided = &segment.parameters;
         let own_counts = method_generics.own_counts();
         Substs::for_item(self.tcx, pick.item.def_id, |param, _| {
-            match param.kind {
-                GenericParamDefKind::Lifetime => {
-                    let i = param.index as usize;
-                    let lt = if i < parent_substs.len() {
-                        parent_substs.region_at(i)
-                    } else if let Some(lifetime)
-                            = provided.as_ref().and_then(|p| p.lifetimes.get(i - parent_substs.len())) {
-                        AstConv::ast_region_to_region(self.fcx, lifetime, Some(param))
-                    } else {
-                        self.region_var_for_def(self.span, param)
-                    };
-                    UnpackedKind::Lifetime(lt)
-                }
-                GenericParamDefKind::Type(_) => {
-                    let i = param.index as usize;
-                    let ty = if i < parent_substs.len() {
-                        parent_substs.type_at(i)
-                    } else if let Some(ast_ty)
-                        = provided.as_ref().and_then(|p| {
-                            let idx =
-                                i - parent_substs.len() - own_counts.lifetimes;
-                            p.types.get(idx)
-                        })
-                    {
-                        self.to_ty(ast_ty)
-                    } else {
-                        self.type_var_for_def(self.span, param)
-                    };
-                    UnpackedKind::Type(ty)
+            let i = param.index as usize;
+            if i < parent_substs.len() {
+                parent_substs[i].unpack()
+            } else {
+                match param.kind {
+                    GenericParamDefKind::Lifetime => {
+                        if let Some(lifetime) = provided.as_ref().and_then(|p| {
+                            p.lifetimes.get(i - parent_substs.len())
+                        }) {
+                            return UnpackedKind::Lifetime(
+                                AstConv::ast_region_to_region(self.fcx, lifetime, Some(param)));
+                        }
+                    }
+                    GenericParamDefKind::Type(_) => {
+                        if let Some(ast_ty) = provided.as_ref().and_then(|p| {
+                            p.types.get(i - parent_substs.len() - own_counts.lifetimes)
+                        }) {
+                            return UnpackedKind::Type(self.to_ty(ast_ty));
+                        }
+                    }
                 }
+                self.var_for_def(self.span, param)
             }
         })
     }
diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs
index 298b8548e36..f02f70caef9 100644
--- a/src/librustc_typeck/check/method/mod.rs
+++ b/src/librustc_typeck/check/method/mod.rs
@@ -256,20 +256,16 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
         // Construct a trait-reference `self_ty : Trait<input_tys>`
         let substs = Substs::for_item(self.tcx, trait_def_id, |param, _| {
             match param.kind {
-                GenericParamDefKind::Lifetime => {
-                    UnpackedKind::Lifetime(self.region_var_for_def(span, param))
-                }
+                GenericParamDefKind::Lifetime => {}
                 GenericParamDefKind::Type(_) => {
-                    let ty = if param.index == 0 {
-                        self_ty
+                    if param.index == 0 {
+                        return UnpackedKind::Type(self_ty);
                     } else if let Some(ref input_types) = opt_input_types {
-                        input_types[param.index as usize - 1]
-                    } else {
-                        self.type_var_for_def(span, param)
-                    };
-                    UnpackedKind::Type(ty)
+                        return UnpackedKind::Type(input_types[param.index as usize - 1]);
+                    }
                 }
             }
+            self.var_for_def(span, param)
         });
 
         let trait_ref = ty::TraitRef::new(trait_def_id, substs);
diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs
index a96796bb148..54fea4ab00a 100644
--- a/src/librustc_typeck/check/method/probe.rs
+++ b/src/librustc_typeck/check/method/probe.rs
@@ -1389,26 +1389,17 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
             xform_fn_sig.subst(self.tcx, substs)
         } else {
             let substs = Substs::for_item(self.tcx, method, |param, _| {
-                match param.kind {
-                    GenericParamDefKind::Lifetime => {
-                        let i = param.index as usize;
-                        let lt = if i < substs.len() {
-                            substs.region_at(i)
-                        } else {
+                let i = param.index as usize;
+                if i < substs.len() {
+                    substs[i].unpack()
+                } else {
+                    match param.kind {
+                        GenericParamDefKind::Lifetime => {
                             // In general, during probe we erase regions. See
                             // `impl_self_ty()` for an explanation.
-                            self.tcx.types.re_erased
-                        };
-                        UnpackedKind::Lifetime(lt)
-                    }
-                    GenericParamDefKind::Type(_) => {
-                        let i = param.index as usize;
-                        let ty = if i < substs.len() {
-                            substs.type_at(i)
-                        } else {
-                            self.type_var_for_def(self.span, param)
-                        };
-                        UnpackedKind::Type(ty)
+                            UnpackedKind::Lifetime(self.tcx.types.re_erased)
+                        }
+                        GenericParamDefKind::Type(_) => self.var_for_def(self.span, param),
                     }
                 }
             });
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 99e47f92daf..0b0659729ef 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -1746,7 +1746,11 @@ impl<'a, 'gcx, 'tcx> AstConv<'gcx, 'tcx> for FnCtxt<'a, 'gcx, 'tcx> {
     fn ty_infer_for_def(&self,
                         ty_param_def: &ty::GenericParamDef,
                         span: Span) -> Ty<'tcx> {
-        self.type_var_for_def(span, ty_param_def)
+        if let UnpackedKind::Type(ty) = self.var_for_def(span, ty_param_def) {
+            ty
+        } else {
+            unreachable!()
+        }
     }
 
     fn projected_ty_from_poly_trait_ref(&self,
@@ -4759,17 +4763,26 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
             (None, None) => (0, false)
         };
         let substs = Substs::for_item(self.tcx, def.def_id(), |param, substs| {
+            let mut i = param.index as usize;
+
+            let segment = if i < fn_start {
+                if let GenericParamDefKind::Type(_) = param.kind {
+                    // Handle Self first, so we can adjust the index to match the AST.
+                    if has_self && i == 0 {
+                        return opt_self_ty.map(|ty| UnpackedKind::Type(ty)).unwrap_or_else(|| {
+                            self.var_for_def(span, param)
+                        });
+                    }
+                }
+                i -= has_self as usize;
+                type_segment
+            } else {
+                i -= fn_start;
+                fn_segment
+            };
+
             match param.kind {
                 GenericParamDefKind::Lifetime => {
-                    let mut i = param.index as usize;
-
-                    let segment = if i < fn_start {
-                        i -= has_self as usize;
-                        type_segment
-                    } else {
-                        i -= fn_start;
-                        fn_segment
-                    };
                     let lifetimes = segment.map_or(&[][..], |(s, _)| {
                         s.parameters.as_ref().map_or(&[][..], |p| &p.lifetimes[..])
                     });
@@ -4782,21 +4795,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                     UnpackedKind::Lifetime(lt)
                 }
                 GenericParamDefKind::Type(_) => {
-                    let mut i = param.index as usize;
-
-                    let segment = if i < fn_start {
-                        // Handle Self first, so we can adjust the index to match the AST.
-                        if has_self && i == 0 {
-                            return UnpackedKind::Type(opt_self_ty.unwrap_or_else(|| {
-                                self.type_var_for_def(span, param)
-                            }));
-                        }
-                        i -= has_self as usize;
-                        type_segment
-                    } else {
-                        i -= fn_start;
-                        fn_segment
-                    };
                     let (types, infer_types) = segment.map_or((&[][..], true), |(s, _)| {
                         (s.parameters.as_ref().map_or(&[][..], |p| &p.types[..]), s.infer_types)
                     });
@@ -4811,24 +4809,23 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                         _ => unreachable!()
                     };
 
-                    let ty = if let Some(ast_ty) = types.get(i) {
+                    if let Some(ast_ty) = types.get(i) {
                         // A provided type parameter.
-                        self.to_ty(ast_ty)
+                        UnpackedKind::Type(self.to_ty(ast_ty))
                     } else if !infer_types && has_default {
                         // No type parameter provided, but a default exists.
                         let default = self.tcx.type_of(param.def_id);
-                        self.normalize_ty(
+                        UnpackedKind::Type(self.normalize_ty(
                             span,
                             default.subst_spanned(self.tcx, substs, Some(span))
-                        )
+                        ))
                     } else {
                         // No type parameters were provided, we can infer all.
                         // This can also be reached in some error cases:
                         // We prefer to use inference variables instead of
                         // TyError to let type inference recover somewhat.
-                        self.type_var_for_def(span, param)
-                    };
-                    UnpackedKind::Type(ty)
+                        self.var_for_def(span, param)
+                    }
                 }
             }
         });