about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2019-08-19 01:31:35 +0000
committerbors <bors@rust-lang.org>2019-08-19 01:31:35 +0000
commita807902dd6b4222179776c3f3c33da8dafdd4da1 (patch)
treeb4636f43c056de11dd69130ce47039343a9f52c5
parent0ccbae2f1878380e6c3777b8b172dfef61c3842b (diff)
parent24587d20dfa6ddc2391e6edee81ef090f92858fa (diff)
downloadrust-a807902dd6b4222179776c3f3c33da8dafdd4da1.tar.gz
rust-a807902dd6b4222179776c3f3c33da8dafdd4da1.zip
Auto merge of #63463 - matthewjasper:ty_param_cleanup, r=petrochenkov
Don't special case the `Self` parameter by name

This results in a couple of small diagnostic regressions. They could be avoided by keeping the special case just for diagnostics, but that seems worse.

closes #50125
cc #60869
-rw-r--r--src/librustc/hir/lowering.rs11
-rw-r--r--src/librustc/infer/error_reporting/mod.rs4
-rw-r--r--src/librustc/traits/object_safety.rs109
-rw-r--r--src/librustc/ty/context.rs9
-rw-r--r--src/librustc/ty/error.rs8
-rw-r--r--src/librustc/ty/flags.rs17
-rw-r--r--src/librustc/ty/fold.rs3
-rw-r--r--src/librustc/ty/instance.rs5
-rw-r--r--src/librustc/ty/layout.rs3
-rw-r--r--src/librustc/ty/mod.rs38
-rw-r--r--src/librustc/ty/sty.rs15
-rw-r--r--src/librustc_mir/shim.rs2
-rw-r--r--src/librustc_typeck/astconv.rs7
-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.rs18
-rw-r--r--src/librustc_typeck/outlives/implicit_infer.rs30
-rw-r--r--src/librustdoc/clean/mod.rs2
-rw-r--r--src/librustdoc/clean/simplify.rs4
-rw-r--r--src/test/ui/structs/struct-path-self.rs6
-rw-r--r--src/test/ui/structs/struct-path-self.stderr6
-rw-r--r--src/test/ui/type/type-params-in-different-spaces-1.rs2
-rw-r--r--src/test/ui/type/type-params-in-different-spaces-1.stderr2
-rw-r--r--src/test/ui/type/type-params-in-different-spaces-3.stderr2
24 files changed, 124 insertions, 183 deletions
diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs
index d2ea485b5db..cc2e6137df3 100644
--- a/src/librustc/hir/lowering.rs
+++ b/src/librustc/hir/lowering.rs
@@ -2524,15 +2524,6 @@ impl<'a> LoweringContext<'a> {
                 (param_name, kind)
             }
             GenericParamKind::Type { ref default, .. } => {
-                // Don't expose `Self` (recovered "keyword used as ident" parse error).
-                // `rustc::ty` expects `Self` to be only used for a trait's `Self`.
-                // Instead, use `gensym("Self")` to create a distinct name that looks the same.
-                let ident = if param.ident.name == kw::SelfUpper {
-                    param.ident.gensym()
-                } else {
-                    param.ident
-                };
-
                 let add_bounds = add_bounds.get(&param.id).map_or(&[][..], |x| &x);
                 if !add_bounds.is_empty() {
                     let params = self.lower_param_bounds(add_bounds, itctx.reborrow()).into_iter();
@@ -2551,7 +2542,7 @@ impl<'a> LoweringContext<'a> {
                                           .next(),
                 };
 
-                (hir::ParamName::Plain(ident), kind)
+                (hir::ParamName::Plain(param.ident), kind)
             }
             GenericParamKind::Const { ref ty } => {
                 (hir::ParamName::Plain(param.ident), hir::GenericParamKind::Const {
diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs
index 2ffcd2c4ace..84687b8cab5 100644
--- a/src/librustc/infer/error_reporting/mod.rs
+++ b/src/librustc/infer/error_reporting/mod.rs
@@ -1329,7 +1329,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                     let generics = self.tcx.generics_of(did);
                     // Account for the case where `did` corresponds to `Self`, which doesn't have
                     // the expected type argument.
-                    if !param.is_self() {
+                    if !(generics.has_self && param.index == 0) {
                         let type_param = generics.type_param(param, self.tcx);
                         let hir = &self.tcx.hir();
                         hir.as_local_hir_id(type_param.def_id).map(|id| {
@@ -1337,7 +1337,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                             // We do this to avoid suggesting code that ends up as `T: 'a'b`,
                             // instead we suggest `T: 'a + 'b` in that case.
                             let mut has_bounds = false;
-                            if let Node::GenericParam(ref param) = hir.get(id) {
+                            if let Node::GenericParam(param) = hir.get(id) {
                                 has_bounds = !param.bounds.is_empty();
                             }
                             let sp = hir.span(id);
diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs
index 37eff852abd..7ea7bf0257c 100644
--- a/src/librustc/traits/object_safety.rs
+++ b/src/librustc/traits/object_safety.rs
@@ -91,6 +91,7 @@ impl<'tcx> TyCtxt<'tcx> {
     pub fn astconv_object_safety_violations(self, trait_def_id: DefId)
                                             -> Vec<ObjectSafetyViolation>
     {
+        debug_assert!(self.generics_of(trait_def_id).has_self);
         let violations = traits::supertrait_def_ids(self, trait_def_id)
             .filter(|&def_id| self.predicates_reference_self(def_id, true))
             .map(|_| ObjectSafetyViolation::SupertraitSelf)
@@ -106,6 +107,7 @@ impl<'tcx> TyCtxt<'tcx> {
     pub fn object_safety_violations(self, trait_def_id: DefId)
                                     -> Vec<ObjectSafetyViolation>
     {
+        debug_assert!(self.generics_of(trait_def_id).has_self);
         debug!("object_safety_violations: {:?}", trait_def_id);
 
         traits::supertrait_def_ids(self, trait_def_id)
@@ -113,9 +115,25 @@ impl<'tcx> TyCtxt<'tcx> {
             .collect()
     }
 
-    fn object_safety_violations_for_trait(self, trait_def_id: DefId)
-                                          -> Vec<ObjectSafetyViolation>
-    {
+    /// We say a method is *vtable safe* if it can be invoked on a trait
+    /// object.  Note that object-safe traits can have some
+    /// non-vtable-safe methods, so long as they require `Self:Sized` or
+    /// 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);
+        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) {
+            return false;
+        }
+
+        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) -> Vec<ObjectSafetyViolation> {
         // Check methods for violations.
         let mut violations: Vec<_> = self.associated_items(trait_def_id)
             .filter(|item| item.kind == ty::AssocKind::Method)
@@ -163,14 +181,16 @@ impl<'tcx> TyCtxt<'tcx> {
     fn predicates_reference_self(
         self,
         trait_def_id: DefId,
-        supertraits_only: bool) -> bool
-    {
+        supertraits_only: bool,
+    ) -> bool {
         let trait_ref = ty::Binder::dummy(ty::TraitRef::identity(self, trait_def_id));
         let predicates = if supertraits_only {
             self.super_predicates_of(trait_def_id)
         } 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
             .iter()
@@ -179,7 +199,7 @@ impl<'tcx> TyCtxt<'tcx> {
                 match predicate {
                     ty::Predicate::Trait(ref data) => {
                         // In the case of a trait predicate, we can skip the "self" type.
-                        data.skip_binder().input_types().skip(1).any(|t| t.has_self_ty())
+                        data.skip_binder().input_types().skip(1).any(has_self_ty)
                     }
                     ty::Predicate::Projection(ref data) => {
                         // And similarly for projections. This should be redundant with
@@ -199,7 +219,7 @@ impl<'tcx> TyCtxt<'tcx> {
                             .trait_ref(self)
                             .input_types()
                             .skip(1)
-                            .any(|t| t.has_self_ty())
+                            .any(has_self_ty)
                     }
                     ty::Predicate::WellFormed(..) |
                     ty::Predicate::ObjectSafe(..) |
@@ -229,11 +249,11 @@ impl<'tcx> TyCtxt<'tcx> {
         let predicates = predicates.instantiate_identity(self).predicates;
         elaborate_predicates(self, predicates)
             .any(|predicate| match predicate {
-                ty::Predicate::Trait(ref trait_pred) if trait_pred.def_id() == sized_def_id => {
-                    trait_pred.skip_binder().self_ty().is_self()
+                ty::Predicate::Trait(ref trait_pred) => {
+                    trait_pred.def_id() == sized_def_id
+                        && trait_pred.skip_binder().self_ty().is_param(0)
                 }
                 ty::Predicate::Projection(..) |
-                ty::Predicate::Trait(..) |
                 ty::Predicate::Subtype(..) |
                 ty::Predicate::RegionOutlives(..) |
                 ty::Predicate::WellFormed(..) |
@@ -248,11 +268,11 @@ impl<'tcx> TyCtxt<'tcx> {
     }
 
     /// Returns `Some(_)` if this method makes the containing trait not object safe.
-    fn object_safety_violation_for_method(self,
-                                          trait_def_id: DefId,
-                                          method: &ty::AssocItem)
-                                          -> Option<MethodViolationCode>
-    {
+    fn object_safety_violation_for_method(
+        self,
+        trait_def_id: DefId,
+        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.
@@ -263,36 +283,15 @@ impl<'tcx> TyCtxt<'tcx> {
         self.virtual_call_violation_for_method(trait_def_id, method)
     }
 
-    /// We say a method is *vtable safe* if it can be invoked on a trait
-    /// object.  Note that object-safe traits can have some
-    /// non-vtable-safe methods, so long as they require `Self:Sized` or
-    /// 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!("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) {
-            return false;
-        }
-
-        match self.virtual_call_violation_for_method(trait_def_id, method) {
-            None | Some(MethodViolationCode::WhereClauseReferencesSelf(_)) => true,
-            Some(_) => false,
-        }
-    }
-
     /// Returns `Some(_)` if this method cannot be called on a trait
     /// object; this does not necessarily imply that the enclosing trait
     /// is not object safe, because the method might have a where clause
     /// `Self:Sized`.
-    fn virtual_call_violation_for_method(self,
-                                         trait_def_id: DefId,
-                                         method: &ty::AssocItem)
-                                         -> Option<MethodViolationCode>
-    {
+    fn virtual_call_violation_for_method(
+        self,
+        trait_def_id: DefId,
+        method: &ty::AssocItem,
+    ) -> Option<MethodViolationCode> {
         // The method's first parameter must be named `self`
         if !method.method_has_self_argument {
             return Some(MethodViolationCode::StaticMethod);
@@ -323,7 +322,9 @@ impl<'tcx> TyCtxt<'tcx> {
                 .collect::<Vec<_>>()
                 // 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, t)) {
+                .visit_tys_shallow(|t| {
+                    self.contains_illegal_self_type_reference(trait_def_id, t)
+                }) {
             let span = self.def_span(method.def_id);
             return Some(MethodViolationCode::WhereClauseReferencesSelf(span));
         }
@@ -337,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.mk_self_type() {
+        if receiver_ty != self.types.self_param {
             if !self.receiver_is_dispatchable(method, receiver_ty) {
                 return Some(MethodViolationCode::UndispatchableReceiver);
             } else {
@@ -404,7 +405,10 @@ impl<'tcx> TyCtxt<'tcx> {
     /// Performs a type substitution to produce the version of receiver_ty when `Self = self_ty`
     /// e.g., for receiver_ty = `Rc<Self>` and self_ty = `Foo`, returns `Rc<Foo>`.
     fn receiver_for_self_ty(
-        self, receiver_ty: Ty<'tcx>, self_ty: Ty<'tcx>, method_def_id: DefId
+        self,
+        receiver_ty: Ty<'tcx>,
+        self_ty: Ty<'tcx>,
+        method_def_id: DefId,
     ) -> Ty<'tcx> {
         debug!("receiver_for_self_ty({:?}, {:?}, {:?})", receiver_ty, self_ty, method_def_id);
         let substs = InternalSubsts::for_item(self, method_def_id, |param, _| {
@@ -555,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>
@@ -608,11 +612,11 @@ impl<'tcx> TyCtxt<'tcx> {
         })
     }
 
-    fn contains_illegal_self_type_reference(self,
-                                            trait_def_id: DefId,
-                                            ty: Ty<'tcx>)
-                                            -> bool
-    {
+    fn contains_illegal_self_type_reference(
+        self,
+        trait_def_id: DefId,
+        ty: Ty<'tcx>,
+     ) -> bool {
         // This is somewhat subtle. In general, we want to forbid
         // references to `Self` in the argument and return types,
         // since the value of `Self` is erased. However, there is one
@@ -654,10 +658,11 @@ 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(ref param_ty) => {
-                    if param_ty.is_self() {
+                ty::Param(_) => {
+                    if ty == self_ty {
                         error = true;
                     }
 
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index d504ba4dfe0..e72efdb057a 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/ty/error.rs b/src/librustc/ty/error.rs
index 4a72794b61a..d6d17a67e01 100644
--- a/src/librustc/ty/error.rs
+++ b/src/librustc/ty/error.rs
@@ -239,13 +239,7 @@ impl<'tcx> ty::TyS<'tcx> {
             ty::Infer(ty::FreshFloatTy(_)) => "fresh floating-point type".into(),
             ty::Projection(_) => "associated type".into(),
             ty::UnnormalizedProjection(_) => "non-normalized associated type".into(),
-            ty::Param(ref p) => {
-                if p.is_self() {
-                    "Self".into()
-                } else {
-                    "type parameter".into()
-                }
-            }
+            ty::Param(_) => "type parameter".into(),
             ty::Opaque(..) => "opaque type".into(),
             ty::Error => "type error".into(),
         }
diff --git a/src/librustc/ty/flags.rs b/src/librustc/ty/flags.rs
index 9119505acd1..b2d74f963b0 100644
--- a/src/librustc/ty/flags.rs
+++ b/src/librustc/ty/flags.rs
@@ -1,5 +1,5 @@
 use crate::ty::subst::{SubstsRef, UnpackedKind};
-use crate::ty::{self, Ty, TypeFlags, TypeFoldable, InferConst};
+use crate::ty::{self, Ty, TypeFlags, InferConst};
 use crate::mir::interpret::ConstValue;
 
 #[derive(Debug)]
@@ -86,13 +86,9 @@ impl FlagComputation {
                 self.add_flags(TypeFlags::HAS_TY_ERR)
             }
 
-            &ty::Param(ref p) => {
+            &ty::Param(_) => {
                 self.add_flags(TypeFlags::HAS_FREE_LOCAL_NAMES);
-                if p.is_self() {
-                    self.add_flags(TypeFlags::HAS_SELF);
-                } else {
-                    self.add_flags(TypeFlags::HAS_PARAMS);
-                }
+                self.add_flags(TypeFlags::HAS_PARAMS);
             }
 
             &ty::Generator(_, ref substs, _) => {
@@ -143,11 +139,6 @@ impl FlagComputation {
             }
 
             &ty::Projection(ref data) => {
-                // currently we can't normalize projections that
-                // include bound regions, so track those separately.
-                if !data.has_escaping_bound_vars() {
-                    self.add_flags(TypeFlags::HAS_NORMALIZABLE_PROJECTION);
-                }
                 self.add_flags(TypeFlags::HAS_PROJECTION);
                 self.add_projection_ty(data);
             }
@@ -243,7 +234,7 @@ impl FlagComputation {
         match c.val {
             ConstValue::Unevaluated(_, substs) => {
                 self.add_substs(substs);
-                self.add_flags(TypeFlags::HAS_NORMALIZABLE_PROJECTION | TypeFlags::HAS_PROJECTION);
+                self.add_flags(TypeFlags::HAS_PROJECTION);
             },
             ConstValue::Infer(infer) => {
                 self.add_flags(TypeFlags::HAS_FREE_LOCAL_NAMES | TypeFlags::HAS_CT_INFER);
diff --git a/src/librustc/ty/fold.rs b/src/librustc/ty/fold.rs
index ab7df8e4e84..4b30412b419 100644
--- a/src/librustc/ty/fold.rs
+++ b/src/librustc/ty/fold.rs
@@ -85,9 +85,6 @@ pub trait TypeFoldable<'tcx>: fmt::Debug + Clone {
     fn has_param_types(&self) -> bool {
         self.has_type_flags(TypeFlags::HAS_PARAMS)
     }
-    fn has_self_ty(&self) -> bool {
-        self.has_type_flags(TypeFlags::HAS_SELF)
-    }
     fn has_infer_types(&self) -> bool {
         self.has_type_flags(TypeFlags::HAS_TY_INFER)
     }
diff --git a/src/librustc/ty/instance.rs b/src/librustc/ty/instance.rs
index 457d018f017..c71e1ea4e58 100644
--- a/src/librustc/ty/instance.rs
+++ b/src/librustc/ty/instance.rs
@@ -298,8 +298,9 @@ impl<'tcx> Instance<'tcx> {
     ) -> Option<Instance<'tcx>> {
         debug!("resolve(def_id={:?}, substs={:?})", def_id, substs);
         let fn_sig = tcx.fn_sig(def_id);
-        let is_vtable_shim =
-            fn_sig.inputs().skip_binder().len() > 0 && fn_sig.input(0).skip_binder().is_self();
+        let is_vtable_shim = fn_sig.inputs().skip_binder().len() > 0
+            && fn_sig.input(0).skip_binder().is_param(0)
+            && tcx.generics_of(def_id).has_self;
         if is_vtable_shim {
             debug!(" => associated item with unsizeable self: Self");
             Some(Instance {
diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs
index 19c753bc304..8febcfd0754 100644
--- a/src/librustc/ty/layout.rs
+++ b/src/librustc/ty/layout.rs
@@ -1601,7 +1601,6 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
         // resulting from the final codegen session.
         if
             layout.ty.has_param_types() ||
-            layout.ty.has_self_ty() ||
             !self.param_env.caller_bounds.is_empty()
         {
             return;
@@ -1767,7 +1766,7 @@ impl<'tcx> SizeSkeleton<'tcx> {
                 let tail = tcx.struct_tail_erasing_lifetimes(pointee, param_env);
                 match tail.sty {
                     ty::Param(_) | ty::Projection(_) => {
-                        debug_assert!(tail.has_param_types() || tail.has_self_ty());
+                        debug_assert!(tail.has_param_types());
                         Ok(SizeSkeleton::Pointer {
                             non_zero,
                             tail: tcx.erase_regions(&tail)
diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index a8ff36a3946..0b81f193df4 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -414,61 +414,53 @@ pub struct CReaderCacheKey {
 bitflags! {
     pub struct TypeFlags: u32 {
         const HAS_PARAMS         = 1 << 0;
-        const HAS_SELF           = 1 << 1;
-        const HAS_TY_INFER       = 1 << 2;
-        const HAS_RE_INFER       = 1 << 3;
-        const HAS_RE_PLACEHOLDER = 1 << 4;
+        const HAS_TY_INFER       = 1 << 1;
+        const HAS_RE_INFER       = 1 << 2;
+        const HAS_RE_PLACEHOLDER = 1 << 3;
 
         /// Does this have any `ReEarlyBound` regions? Used to
         /// determine whether substitition is required, since those
         /// represent regions that are bound in a `ty::Generics` and
         /// hence may be substituted.
-        const HAS_RE_EARLY_BOUND = 1 << 5;
+        const HAS_RE_EARLY_BOUND = 1 << 4;
 
         /// Does this have any region that "appears free" in the type?
         /// Basically anything but `ReLateBound` and `ReErased`.
-        const HAS_FREE_REGIONS   = 1 << 6;
+        const HAS_FREE_REGIONS   = 1 << 5;
 
         /// Is an error type reachable?
-        const HAS_TY_ERR         = 1 << 7;
-        const HAS_PROJECTION     = 1 << 8;
+        const HAS_TY_ERR         = 1 << 6;
+        const HAS_PROJECTION     = 1 << 7;
 
         // FIXME: Rename this to the actual property since it's used for generators too
-        const HAS_TY_CLOSURE     = 1 << 9;
+        const HAS_TY_CLOSURE     = 1 << 8;
 
         /// `true` if there are "names" of types and regions and so forth
         /// that are local to a particular fn
-        const HAS_FREE_LOCAL_NAMES    = 1 << 10;
+        const HAS_FREE_LOCAL_NAMES    = 1 << 9;
 
         /// Present if the type belongs in a local type context.
         /// Only set for Infer other than Fresh.
-        const KEEP_IN_LOCAL_TCX  = 1 << 11;
-
-        // Is there a projection that does not involve a bound region?
-        // Currently we can't normalize projections w/ bound regions.
-        const HAS_NORMALIZABLE_PROJECTION = 1 << 12;
+        const KEEP_IN_LOCAL_TCX  = 1 << 10;
 
         /// Does this have any `ReLateBound` regions? Used to check
         /// if a global bound is safe to evaluate.
-        const HAS_RE_LATE_BOUND = 1 << 13;
+        const HAS_RE_LATE_BOUND = 1 << 11;
 
-        const HAS_TY_PLACEHOLDER = 1 << 14;
+        const HAS_TY_PLACEHOLDER = 1 << 12;
 
-        const HAS_CT_INFER = 1 << 15;
-        const HAS_CT_PLACEHOLDER = 1 << 16;
+        const HAS_CT_INFER = 1 << 13;
+        const HAS_CT_PLACEHOLDER = 1 << 14;
 
         const NEEDS_SUBST        = TypeFlags::HAS_PARAMS.bits |
-                                   TypeFlags::HAS_SELF.bits |
                                    TypeFlags::HAS_RE_EARLY_BOUND.bits;
 
         /// Flags representing the nominal content of a type,
         /// computed by FlagsComputation. If you add a new nominal
         /// flag, it should be added here too.
         const NOMINAL_FLAGS     = TypeFlags::HAS_PARAMS.bits |
-                                  TypeFlags::HAS_SELF.bits |
                                   TypeFlags::HAS_TY_INFER.bits |
                                   TypeFlags::HAS_RE_INFER.bits |
-                                  TypeFlags::HAS_CT_INFER.bits |
                                   TypeFlags::HAS_RE_PLACEHOLDER.bits |
                                   TypeFlags::HAS_RE_EARLY_BOUND.bits |
                                   TypeFlags::HAS_FREE_REGIONS.bits |
@@ -479,6 +471,7 @@ bitflags! {
                                   TypeFlags::KEEP_IN_LOCAL_TCX.bits |
                                   TypeFlags::HAS_RE_LATE_BOUND.bits |
                                   TypeFlags::HAS_TY_PLACEHOLDER.bits |
+                                  TypeFlags::HAS_CT_INFER.bits |
                                   TypeFlags::HAS_CT_PLACEHOLDER.bits;
     }
 }
@@ -1734,7 +1727,6 @@ impl<'tcx> ParamEnv<'tcx> {
                 if value.has_placeholders()
                     || value.needs_infer()
                     || value.has_param_types()
-                    || value.has_self_ty()
                 {
                     ParamEnvAnd {
                         param_env: self,
diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs
index 42390c209d6..2b173068b38 100644
--- a/src/librustc/ty/sty.rs
+++ b/src/librustc/ty/sty.rs
@@ -1141,13 +1141,6 @@ impl<'tcx> ParamTy {
     pub fn to_ty(self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
         tcx.mk_ty_param(self.index, self.name)
     }
-
-    pub fn is_self(&self) -> bool {
-        // FIXME(#50125): Ignoring `Self` with `index != 0` might lead to weird behavior elsewhere,
-        // but this should only be possible when using `-Z continue-parse-after-error` like
-        // `compile-fail/issue-36638.rs`.
-        self.name.as_symbol() == kw::SelfUpper && self.index == 0
-    }
 }
 
 #[derive(Copy, Clone, Hash, RustcEncodable, RustcDecodable,
@@ -1790,14 +1783,6 @@ impl<'tcx> TyS<'tcx> {
     }
 
     #[inline]
-    pub fn is_self(&self) -> bool {
-        match self.sty {
-            Param(ref p) => p.is_self(),
-            _ => false,
-        }
-    }
-
-    #[inline]
     pub fn is_slice(&self) -> bool {
         match self.sty {
             RawPtr(TypeAndMut { ty, .. }) | Ref(_, ty, _) => match ty.sty {
diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs
index 063e7796371..3e02f6c3725 100644
--- a/src/librustc_mir/shim.rs
+++ b/src/librustc_mir/shim.rs
@@ -708,7 +708,7 @@ fn build_call_shim<'tcx>(
         Adjustment::DerefMove => {
             // fn(Self, ...) -> fn(*mut Self, ...)
             let arg_ty = local_decls[rcvr_arg].ty;
-            assert!(arg_ty.is_self());
+            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 922afbae2a4..9e52eae88ef 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -635,8 +635,9 @@ 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 {
-                    if tcx.at(span).type_of(param.def_id).has_self_ty() {
+                if is_object && has_default && has_self {
+                    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.
                         return true;
@@ -2030,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 28a1ccda4d8..9c6ea7d30cc 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 5ff64224c5a..e979bc7bf25 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -716,7 +716,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);
 
@@ -1014,13 +1014,6 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::Generics {
                         synthetic,
                         ..
                     } => {
-                        if param.name.ident().name == kw::SelfUpper {
-                            span_bug!(
-                                param.span,
-                                "`Self` should not be the name of a regular parameter"
-                            );
-                        }
-
                         if !allow_defaults && default.is_some() {
                             if !tcx.features().default_type_parameter_fallback {
                                 tcx.lint_hir(
@@ -1044,13 +1037,6 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::Generics {
                         }
                     }
                     GenericParamKind::Const { .. } => {
-                        if param.name.ident().name == kw::SelfUpper {
-                            span_bug!(
-                                param.span,
-                                "`Self` should not be the name of a regular parameter",
-                            );
-                        }
-
                         ty::GenericParamDefKind::Const
                     }
                     _ => return None,
@@ -1567,7 +1553,7 @@ fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
                                     &format!(
                                         "defining opaque type use restricts opaque \
                                          type by using the generic parameter `{}` twice",
-                                        p.name
+                                        p,
                                     ),
                                 );
                                 return;
diff --git a/src/librustc_typeck/outlives/implicit_infer.rs b/src/librustc_typeck/outlives/implicit_infer.rs
index 6b288347ad0..644d723ded5 100644
--- a/src/librustc_typeck/outlives/implicit_infer.rs
+++ b/src/librustc_typeck/outlives/implicit_infer.rs
@@ -3,7 +3,6 @@ use rustc::hir::def_id::DefId;
 use rustc::hir::itemlikevisit::ItemLikeVisitor;
 use rustc::ty::subst::{Kind, Subst, UnpackedKind};
 use rustc::ty::{self, Ty, TyCtxt};
-use rustc::ty::fold::TypeFoldable;
 use rustc::util::nodemap::FxHashMap;
 
 use super::explicit::ExplicitPredicatesMap;
@@ -178,11 +177,11 @@ fn insert_required_predicates_to_be_wf<'tcx>(
                 // let _: () = substs.region_at(0);
                 check_explicit_predicates(
                     tcx,
-                    &def.did,
+                    def.did,
                     substs,
                     required_predicates,
                     explicit_map,
-                    IgnoreSelfTy(false),
+                    None,
                 );
             }
 
@@ -208,11 +207,11 @@ fn insert_required_predicates_to_be_wf<'tcx>(
                         .substs;
                     check_explicit_predicates(
                         tcx,
-                        &ex_trait_ref.skip_binder().def_id,
+                        ex_trait_ref.skip_binder().def_id,
                         substs,
                         required_predicates,
                         explicit_map,
-                        IgnoreSelfTy(true),
+                        Some(tcx.types.self_param),
                     );
                 }
             }
@@ -223,11 +222,11 @@ fn insert_required_predicates_to_be_wf<'tcx>(
                 debug!("Projection");
                 check_explicit_predicates(
                     tcx,
-                    &tcx.associated_item(obj.item_def_id).container.id(),
+                    tcx.associated_item(obj.item_def_id).container.id(),
                     obj.substs,
                     required_predicates,
                     explicit_map,
-                    IgnoreSelfTy(false),
+                    None,
                 );
             }
 
@@ -236,9 +235,6 @@ fn insert_required_predicates_to_be_wf<'tcx>(
     }
 }
 
-#[derive(Debug)]
-pub struct IgnoreSelfTy(bool);
-
 /// We also have to check the explicit predicates
 /// declared on the type.
 ///
@@ -256,25 +252,25 @@ pub struct IgnoreSelfTy(bool);
 /// applying the substitution as above.
 pub fn check_explicit_predicates<'tcx>(
     tcx: TyCtxt<'tcx>,
-    def_id: &DefId,
+    def_id: DefId,
     substs: &[Kind<'tcx>],
     required_predicates: &mut RequiredPredicates<'tcx>,
     explicit_map: &mut ExplicitPredicatesMap<'tcx>,
-    ignore_self_ty: IgnoreSelfTy,
+    ignored_self_ty: Option<Ty<'tcx>>,
 ) {
     debug!(
         "check_explicit_predicates(def_id={:?}, \
          substs={:?}, \
          explicit_map={:?}, \
          required_predicates={:?}, \
-         ignore_self_ty={:?})",
+         ignored_self_ty={:?})",
         def_id,
         substs,
         explicit_map,
         required_predicates,
-        ignore_self_ty,
+        ignored_self_ty,
     );
-    let explicit_predicates = explicit_map.explicit_predicates_of(tcx, *def_id);
+    let explicit_predicates = explicit_map.explicit_predicates_of(tcx, def_id);
 
     for outlives_predicate in explicit_predicates.iter() {
         debug!("outlives_predicate = {:?}", &outlives_predicate);
@@ -313,9 +309,9 @@ pub fn check_explicit_predicates<'tcx>(
         // = X` binding from the object type (there must be such a
         // binding) and thus infer an outlives requirement that `X:
         // 'b`.
-        if ignore_self_ty.0 {
+        if let Some(self_ty) = ignored_self_ty {
             if let UnpackedKind::Type(ty) = outlives_predicate.0.unpack() {
-                if ty.has_self_ty() {
+                if ty.walk().any(|ty| ty == self_ty) {
                     debug!("skipping self ty = {:?}", &ty);
                     continue;
                 }
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 023d22861de..9b4803ce41e 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 e4fba73b820..3801c42307f 100644
--- a/src/librustdoc/clean/simplify.rs
+++ b/src/librustdoc/clean/simplify.rs
@@ -149,9 +149,11 @@ fn trait_is_same_or_supertrait(cx: &DocContext<'_>, child: DefId,
         return true
     }
     let predicates = cx.tcx.super_predicates_of(child);
+    debug_assert!(cx.tcx.generics_of(child).has_self);
+    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().is_self() {
+            if pred.skip_binder().trait_ref.self_ty() == self_ty {
                 Some(pred.def_id())
             } else {
                 None
diff --git a/src/test/ui/structs/struct-path-self.rs b/src/test/ui/structs/struct-path-self.rs
index 77880bfca40..c938ce8dad9 100644
--- a/src/test/ui/structs/struct-path-self.rs
+++ b/src/test/ui/structs/struct-path-self.rs
@@ -3,13 +3,13 @@ struct S;
 trait Tr {
     fn f() {
         let s = Self {};
-        //~^ ERROR expected struct, variant or union type, found Self
+        //~^ ERROR expected struct, variant or union type, found type parameter
         let z = Self::<u8> {};
-        //~^ ERROR expected struct, variant or union type, found Self
+        //~^ ERROR expected struct, variant or union type, found type parameter
         //~| ERROR type arguments are not allowed for this type
         match s {
             Self { .. } => {}
-            //~^ ERROR expected struct, variant or union type, found Self
+            //~^ ERROR expected struct, variant or union type, found type parameter
         }
     }
 }
diff --git a/src/test/ui/structs/struct-path-self.stderr b/src/test/ui/structs/struct-path-self.stderr
index 9eaa1f95bd0..8c88cacc69e 100644
--- a/src/test/ui/structs/struct-path-self.stderr
+++ b/src/test/ui/structs/struct-path-self.stderr
@@ -1,4 +1,4 @@
-error[E0071]: expected struct, variant or union type, found Self
+error[E0071]: expected struct, variant or union type, found type parameter
   --> $DIR/struct-path-self.rs:5:17
    |
 LL |         let s = Self {};
@@ -10,13 +10,13 @@ error[E0109]: type arguments are not allowed for this type
 LL |         let z = Self::<u8> {};
    |                        ^^ type argument not allowed
 
-error[E0071]: expected struct, variant or union type, found Self
+error[E0071]: expected struct, variant or union type, found type parameter
   --> $DIR/struct-path-self.rs:7:17
    |
 LL |         let z = Self::<u8> {};
    |                 ^^^^^^^^^^ not a struct
 
-error[E0071]: expected struct, variant or union type, found Self
+error[E0071]: expected struct, variant or union type, found type parameter
   --> $DIR/struct-path-self.rs:11:13
    |
 LL |             Self { .. } => {}
diff --git a/src/test/ui/type/type-params-in-different-spaces-1.rs b/src/test/ui/type/type-params-in-different-spaces-1.rs
index 449a26e901d..71fb7f380ae 100644
--- a/src/test/ui/type/type-params-in-different-spaces-1.rs
+++ b/src/test/ui/type/type-params-in-different-spaces-1.rs
@@ -5,7 +5,7 @@ trait BrokenAdd: Copy + Add<Output=Self> {
         *self + rhs //~  ERROR mismatched types
                     //~| expected type `Self`
                     //~| found type `T`
-                    //~| expected Self, found type parameter
+                    //~| expected type parameter, found a different type parameter
     }
 }
 
diff --git a/src/test/ui/type/type-params-in-different-spaces-1.stderr b/src/test/ui/type/type-params-in-different-spaces-1.stderr
index b3b78424fd9..0448a28ea8e 100644
--- a/src/test/ui/type/type-params-in-different-spaces-1.stderr
+++ b/src/test/ui/type/type-params-in-different-spaces-1.stderr
@@ -2,7 +2,7 @@ error[E0308]: mismatched types
   --> $DIR/type-params-in-different-spaces-1.rs:5:17
    |
 LL |         *self + rhs
-   |                 ^^^ expected Self, found type parameter
+   |                 ^^^ expected type parameter, found a different type parameter
    |
    = note: expected type `Self`
               found type `T`
diff --git a/src/test/ui/type/type-params-in-different-spaces-3.stderr b/src/test/ui/type/type-params-in-different-spaces-3.stderr
index 4e8134da2dd..e25f79947c7 100644
--- a/src/test/ui/type/type-params-in-different-spaces-3.stderr
+++ b/src/test/ui/type/type-params-in-different-spaces-3.stderr
@@ -4,7 +4,7 @@ error[E0308]: mismatched types
 LL |     fn test<X>(u: X) -> Self {
    |                         ---- expected `Self` because of return type
 LL |         u
-   |         ^ expected Self, found type parameter
+   |         ^ expected type parameter, found a different type parameter
    |
    = note: expected type `Self`
               found type `X`