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 { 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 { 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 { + fn object_safety_violations_for_trait(self, trait_def_id: DefId) -> Vec { // 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 { 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 { // 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 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 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 @@ -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>> = 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 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 {