about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorMatthew Jasper <mjjasper1@gmail.com>2019-08-12 22:15:12 +0100
committerMatthew Jasper <mjjasper1@gmail.com>2019-08-18 19:25:12 +0100
commit24587d20dfa6ddc2391e6edee81ef090f92858fa (patch)
tree49b7603d91d3e0640256fffea68a81b6d82ea290 /src
parent165e460c923117f88832d9b4baa7e222e46a9a05 (diff)
downloadrust-24587d20dfa6ddc2391e6edee81ef090f92858fa.tar.gz
rust-24587d20dfa6ddc2391e6edee81ef090f92858fa.zip
Pre intern the `Self` parameter type
Use this to simplify the object safety code a bit.
Diffstat (limited to 'src')
-rw-r--r--src/librustc/traits/object_safety.rs55
-rw-r--r--src/librustc/ty/context.rs9
-rw-r--r--src/librustc_mir/shim.rs2
-rw-r--r--src/librustc_typeck/astconv.rs4
-rw-r--r--src/librustc_typeck/check/compare_method.rs2
-rw-r--r--src/librustc_typeck/check/wfcheck.rs2
-rw-r--r--src/librustc_typeck/collect.rs2
-rw-r--r--src/librustc_typeck/outlives/implicit_infer.rs2
-rw-r--r--src/librustdoc/clean/mod.rs2
-rw-r--r--src/librustdoc/clean/simplify.rs2
10 files changed, 35 insertions, 47 deletions
diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs
index 98603edd806..7ea7bf0257c 100644
--- a/src/librustc/traits/object_safety.rs
+++ b/src/librustc/traits/object_safety.rs
@@ -92,9 +92,8 @@ impl<'tcx> TyCtxt<'tcx> {
                                             -> Vec<ObjectSafetyViolation>
     {
         debug_assert!(self.generics_of(trait_def_id).has_self);
-        let self_ty = self.mk_self_type();
         let violations = traits::supertrait_def_ids(self, trait_def_id)
-            .filter(|&def_id| self.predicates_reference_self(def_id, self_ty, true))
+            .filter(|&def_id| self.predicates_reference_self(def_id, true))
             .map(|_| ObjectSafetyViolation::SupertraitSelf)
             .collect();
 
@@ -109,11 +108,10 @@ impl<'tcx> TyCtxt<'tcx> {
                                     -> Vec<ObjectSafetyViolation>
     {
         debug_assert!(self.generics_of(trait_def_id).has_self);
-        let self_ty = self.mk_self_type();
         debug!("object_safety_violations: {:?}", trait_def_id);
 
         traits::supertrait_def_ids(self, trait_def_id)
-            .flat_map(|def_id| self.object_safety_violations_for_trait(def_id, self_ty))
+            .flat_map(|def_id| self.object_safety_violations_for_trait(def_id))
             .collect()
     }
 
@@ -123,29 +121,24 @@ impl<'tcx> TyCtxt<'tcx> {
     /// otherwise ensure that they cannot be used when `Self=Trait`.
     pub fn is_vtable_safe_method(self, trait_def_id: DefId, method: &ty::AssocItem) -> bool {
         debug_assert!(self.generics_of(trait_def_id).has_self);
-        let self_ty = self.mk_self_type();
         debug!("is_vtable_safe_method({:?}, {:?})", trait_def_id, method);
         // Any method that has a `Self : Sized` requisite can't be called.
-        if self.generics_require_sized_self(method.def_id, self_ty) {
+        if self.generics_require_sized_self(method.def_id) {
             return false;
         }
 
-        match self.virtual_call_violation_for_method(trait_def_id, self_ty, method) {
+        match self.virtual_call_violation_for_method(trait_def_id, method) {
             None | Some(MethodViolationCode::WhereClauseReferencesSelf(_)) => true,
             Some(_) => false,
         }
     }
 
-    fn object_safety_violations_for_trait(
-        self,
-        trait_def_id: DefId,
-        self_ty: Ty<'tcx>,
-    ) -> Vec<ObjectSafetyViolation> {
+    fn object_safety_violations_for_trait(self, trait_def_id: DefId) -> Vec<ObjectSafetyViolation> {
         // Check methods for violations.
         let mut violations: Vec<_> = self.associated_items(trait_def_id)
             .filter(|item| item.kind == ty::AssocKind::Method)
             .filter_map(|item|
-                self.object_safety_violation_for_method(trait_def_id, self_ty, &item)
+                self.object_safety_violation_for_method(trait_def_id, &item)
                     .map(|code| ObjectSafetyViolation::Method(item.ident.name, code))
             ).filter(|violation| {
                 if let ObjectSafetyViolation::Method(_,
@@ -167,10 +160,10 @@ impl<'tcx> TyCtxt<'tcx> {
             }).collect();
 
         // Check the trait itself.
-        if self.trait_has_sized_self(trait_def_id, self_ty) {
+        if self.trait_has_sized_self(trait_def_id) {
             violations.push(ObjectSafetyViolation::SizedSelf);
         }
-        if self.predicates_reference_self(trait_def_id, self_ty, false) {
+        if self.predicates_reference_self(trait_def_id, false) {
             violations.push(ObjectSafetyViolation::SupertraitSelf);
         }
 
@@ -188,7 +181,6 @@ impl<'tcx> TyCtxt<'tcx> {
     fn predicates_reference_self(
         self,
         trait_def_id: DefId,
-        self_ty: Ty<'tcx>,
         supertraits_only: bool,
     ) -> bool {
         let trait_ref = ty::Binder::dummy(ty::TraitRef::identity(self, trait_def_id));
@@ -197,6 +189,7 @@ impl<'tcx> TyCtxt<'tcx> {
         } else {
             self.predicates_of(trait_def_id)
         };
+        let self_ty = self.types.self_param;
         let has_self_ty = |t: Ty<'tcx>| t.walk().any(|t| t == self_ty);
         predicates
             .predicates
@@ -241,11 +234,11 @@ impl<'tcx> TyCtxt<'tcx> {
             })
     }
 
-    fn trait_has_sized_self(self, trait_def_id: DefId, self_ty: Ty<'tcx>) -> bool {
-        self.generics_require_sized_self(trait_def_id, self_ty)
+    fn trait_has_sized_self(self, trait_def_id: DefId) -> bool {
+        self.generics_require_sized_self(trait_def_id)
     }
 
-    fn generics_require_sized_self(self, def_id: DefId, self_ty: Ty<'tcx>) -> bool {
+    fn generics_require_sized_self(self, def_id: DefId) -> bool {
         let sized_def_id = match self.lang_items().sized_trait() {
             Some(def_id) => def_id,
             None => { return false; /* No Sized trait, can't require it! */ }
@@ -258,7 +251,7 @@ impl<'tcx> TyCtxt<'tcx> {
             .any(|predicate| match predicate {
                 ty::Predicate::Trait(ref trait_pred) => {
                     trait_pred.def_id() == sized_def_id
-                        && trait_pred.skip_binder().self_ty() == self_ty
+                        && trait_pred.skip_binder().self_ty().is_param(0)
                 }
                 ty::Predicate::Projection(..) |
                 ty::Predicate::Subtype(..) |
@@ -278,17 +271,16 @@ impl<'tcx> TyCtxt<'tcx> {
     fn object_safety_violation_for_method(
         self,
         trait_def_id: DefId,
-        self_ty: Ty<'tcx>,
         method: &ty::AssocItem,
     ) -> Option<MethodViolationCode> {
         debug!("object_safety_violation_for_method({:?}, {:?})", trait_def_id, method);
         // Any method that has a `Self : Sized` requisite is otherwise
         // exempt from the regulations.
-        if self.generics_require_sized_self(method.def_id, self_ty) {
+        if self.generics_require_sized_self(method.def_id) {
             return None;
         }
 
-        self.virtual_call_violation_for_method(trait_def_id, self_ty, method)
+        self.virtual_call_violation_for_method(trait_def_id, method)
     }
 
     /// Returns `Some(_)` if this method cannot be called on a trait
@@ -298,7 +290,6 @@ impl<'tcx> TyCtxt<'tcx> {
     fn virtual_call_violation_for_method(
         self,
         trait_def_id: DefId,
-        self_ty: Ty<'tcx>,
         method: &ty::AssocItem,
     ) -> Option<MethodViolationCode> {
         // The method's first parameter must be named `self`
@@ -309,15 +300,11 @@ impl<'tcx> TyCtxt<'tcx> {
         let sig = self.fn_sig(method.def_id);
 
         for input_ty in &sig.skip_binder().inputs()[1..] {
-            if self.contains_illegal_self_type_reference(trait_def_id, self_ty, input_ty) {
+            if self.contains_illegal_self_type_reference(trait_def_id, input_ty) {
                 return Some(MethodViolationCode::ReferencesSelf);
             }
         }
-        if self.contains_illegal_self_type_reference(
-            trait_def_id,
-            self_ty,
-            sig.output().skip_binder(),
-        ) {
+        if self.contains_illegal_self_type_reference(trait_def_id, sig.output().skip_binder()) {
             return Some(MethodViolationCode::ReferencesSelf);
         }
 
@@ -336,7 +323,7 @@ impl<'tcx> TyCtxt<'tcx> {
                 // Do a shallow visit so that `contains_illegal_self_type_reference`
                 // may apply it's custom visiting.
                 .visit_tys_shallow(|t| {
-                    self.contains_illegal_self_type_reference(trait_def_id, self_ty, t)
+                    self.contains_illegal_self_type_reference(trait_def_id, t)
                 }) {
             let span = self.def_span(method.def_id);
             return Some(MethodViolationCode::WhereClauseReferencesSelf(span));
@@ -351,7 +338,7 @@ impl<'tcx> TyCtxt<'tcx> {
         // However, this is already considered object-safe. We allow it as a special case here.
         // FIXME(mikeyhew) get rid of this `if` statement once `receiver_is_dispatchable` allows
         // `Receiver: Unsize<Receiver[Self => dyn Trait]>`
-        if receiver_ty != self_ty {
+        if receiver_ty != self.types.self_param {
             if !self.receiver_is_dispatchable(method, receiver_ty) {
                 return Some(MethodViolationCode::UndispatchableReceiver);
             } else {
@@ -572,7 +559,7 @@ impl<'tcx> TyCtxt<'tcx> {
             // Self: Unsize<U>
             let unsize_predicate = ty::TraitRef {
                 def_id: unsize_did,
-                substs: self.mk_substs_trait(self.mk_self_type(), &[unsized_self_ty.into()]),
+                substs: self.mk_substs_trait(self.types.self_param, &[unsized_self_ty.into()]),
             }.to_predicate();
 
             // U: Trait<Arg1, ..., ArgN>
@@ -628,7 +615,6 @@ impl<'tcx> TyCtxt<'tcx> {
     fn contains_illegal_self_type_reference(
         self,
         trait_def_id: DefId,
-        self_ty: Ty<'tcx>,
         ty: Ty<'tcx>,
      ) -> bool {
         // This is somewhat subtle. In general, we want to forbid
@@ -672,6 +658,7 @@ impl<'tcx> TyCtxt<'tcx> {
 
         let mut supertraits: Option<Vec<ty::PolyTraitRef<'tcx>>> = None;
         let mut error = false;
+        let self_ty = self.types.self_param;
         ty.maybe_walk(|ty| {
             match ty.sty {
                 ty::Param(_) => {
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index ef74d9e5b28..d7c27afe199 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -173,6 +173,7 @@ pub struct CommonTypes<'tcx> {
     pub f32: Ty<'tcx>,
     pub f64: Ty<'tcx>,
     pub never: Ty<'tcx>,
+    pub self_param: Ty<'tcx>,
     pub err: Ty<'tcx>,
 
     /// Dummy type used for the `Self` of a `TraitRef` created for converting
@@ -915,6 +916,10 @@ impl<'tcx> CommonTypes<'tcx> {
             u128: mk(Uint(ast::UintTy::U128)),
             f32: mk(Float(ast::FloatTy::F32)),
             f64: mk(Float(ast::FloatTy::F64)),
+            self_param: mk(ty::Param(ty::ParamTy {
+                index: 0,
+                name: kw::SelfUpper.as_interned_str(),
+            })),
 
             trait_object_dummy_self: mk(Infer(ty::FreshTy(0))),
         }
@@ -2566,10 +2571,6 @@ impl<'tcx> TyCtxt<'tcx> {
         })
     }
 
-    #[inline]
-    pub fn mk_self_type(self) -> Ty<'tcx> {
-        self.mk_ty_param(0, kw::SelfUpper.as_interned_str())
-    }
 
     pub fn mk_param_from_def(self, param: &ty::GenericParamDef) -> Kind<'tcx> {
         match param.kind {
diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs
index 39deb0fe5d3..d4df0f82eea 100644
--- a/src/librustc_mir/shim.rs
+++ b/src/librustc_mir/shim.rs
@@ -710,7 +710,7 @@ fn build_call_shim<'tcx>(
         Adjustment::DerefMove => {
             // fn(Self, ...) -> fn(*mut Self, ...)
             let arg_ty = local_decls[rcvr_arg].ty;
-            debug_assert!(tcx.generics_of(def_id).has_self && arg_ty == tcx.mk_self_type());
+            debug_assert!(tcx.generics_of(def_id).has_self && arg_ty == tcx.types.self_param);
             local_decls[rcvr_arg].ty = tcx.mk_mut_ptr(arg_ty);
 
             Operand::Move(rcvr_l.deref())
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index e29e412858f..9e52eae88ef 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -636,7 +636,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         let default_needs_object_self = |param: &ty::GenericParamDef| {
             if let GenericParamDefKind::Type { has_default, .. } = param.kind {
                 if is_object && has_default && has_self {
-                    let self_param = tcx.mk_self_type();
+                    let self_param = tcx.types.self_param;
                     if tcx.at(span).type_of(param.def_id).walk().any(|ty| ty == self_param) {
                         // There is no suitable inference default for a type parameter
                         // that references self, in an object type.
@@ -2031,7 +2031,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                 // `Self` in trait or type alias.
                 assert_eq!(opt_self_ty, None);
                 self.prohibit_generics(&path.segments);
-                tcx.mk_self_type()
+                tcx.types.self_param
             }
             Res::SelfTy(_, Some(def_id)) => {
                 // `Self` in impl (we know the concrete type).
diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs
index 946082746f4..8e187b7e05b 100644
--- a/src/librustc_typeck/check/compare_method.rs
+++ b/src/librustc_typeck/check/compare_method.rs
@@ -518,7 +518,7 @@ fn compare_self_type<'tcx>(
     let self_string = |method: &ty::AssocItem| {
         let untransformed_self_ty = match method.container {
             ty::ImplContainer(_) => impl_trait_ref.self_ty(),
-            ty::TraitContainer(_) => tcx.mk_self_type()
+            ty::TraitContainer(_) => tcx.types.self_param
         };
         let self_arg_ty = *tcx.fn_sig(method.def_id).input(0).skip_binder();
         let param_env = ty::ParamEnv::reveal_all();
diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs
index c1d8fde3be1..c02b8c4bfb9 100644
--- a/src/librustc_typeck/check/wfcheck.rs
+++ b/src/librustc_typeck/check/wfcheck.rs
@@ -191,7 +191,7 @@ fn check_associated_item(
         let item = fcx.tcx.associated_item(fcx.tcx.hir().local_def_id(item_id));
 
         let (mut implied_bounds, self_ty) = match item.container {
-            ty::TraitContainer(_) => (vec![], fcx.tcx.mk_self_type()),
+            ty::TraitContainer(_) => (vec![], fcx.tcx.types.self_param),
             ty::ImplContainer(def_id) => (fcx.impl_implied_bounds(def_id, span),
                                           fcx.tcx.type_of(def_id))
         };
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index 7010664722d..214e2a4585b 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -713,7 +713,7 @@ fn super_predicates_of(
     let icx = ItemCtxt::new(tcx, trait_def_id);
 
     // Convert the bounds that follow the colon, e.g., `Bar + Zed` in `trait Foo: Bar + Zed`.
-    let self_param_ty = tcx.mk_self_type();
+    let self_param_ty = tcx.types.self_param;
     let superbounds1 = AstConv::compute_bounds(&icx, self_param_ty, bounds, SizedByDefault::No,
         item.span);
 
diff --git a/src/librustc_typeck/outlives/implicit_infer.rs b/src/librustc_typeck/outlives/implicit_infer.rs
index a70aff1dee6..644d723ded5 100644
--- a/src/librustc_typeck/outlives/implicit_infer.rs
+++ b/src/librustc_typeck/outlives/implicit_infer.rs
@@ -211,7 +211,7 @@ fn insert_required_predicates_to_be_wf<'tcx>(
                         substs,
                         required_predicates,
                         explicit_map,
-                        Some(tcx.mk_self_type()),
+                        Some(tcx.types.self_param),
                     );
                 }
             }
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 6f33bdd7f4d..531d6f26641 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -2303,7 +2303,7 @@ impl Clean<Item> for ty::AssocItem {
                         ty::ImplContainer(def_id) => {
                             cx.tcx.type_of(def_id)
                         }
-                        ty::TraitContainer(_) => cx.tcx.mk_self_type()
+                        ty::TraitContainer(_) => cx.tcx.types.self_param,
                     };
                     let self_arg_ty = *sig.input(0).skip_binder();
                     if self_arg_ty == self_ty {
diff --git a/src/librustdoc/clean/simplify.rs b/src/librustdoc/clean/simplify.rs
index 4075d2af667..3801c42307f 100644
--- a/src/librustdoc/clean/simplify.rs
+++ b/src/librustdoc/clean/simplify.rs
@@ -150,7 +150,7 @@ fn trait_is_same_or_supertrait(cx: &DocContext<'_>, child: DefId,
     }
     let predicates = cx.tcx.super_predicates_of(child);
     debug_assert!(cx.tcx.generics_of(child).has_self);
-    let self_ty = cx.tcx.mk_self_type();
+    let self_ty = cx.tcx.types.self_param;
     predicates.predicates.iter().filter_map(|(pred, _)| {
         if let ty::Predicate::Trait(ref pred) = *pred {
             if pred.skip_binder().trait_ref.self_ty() == self_ty {