Skip to content

Commit 2f6babb

Browse files
committed
Remove is_self and has_self_ty methods
1 parent ee36cfa commit 2f6babb

18 files changed

+128
-143
lines changed

src/librustc/infer/error_reporting/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1329,15 +1329,15 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
13291329
let generics = self.tcx.generics_of(did);
13301330
// Account for the case where `did` corresponds to `Self`, which doesn't have
13311331
// the expected type argument.
1332-
if !param.is_self() {
1332+
if !(generics.has_self && param.index == 0) {
13331333
let type_param = generics.type_param(param, self.tcx);
13341334
let hir = &self.tcx.hir();
13351335
hir.as_local_hir_id(type_param.def_id).map(|id| {
13361336
// Get the `hir::Param` to verify whether it already has any bounds.
13371337
// We do this to avoid suggesting code that ends up as `T: 'a'b`,
13381338
// instead we suggest `T: 'a + 'b` in that case.
13391339
let mut has_bounds = false;
1340-
if let Node::GenericParam(ref param) = hir.get(id) {
1340+
if let Node::GenericParam(param) = hir.get(id) {
13411341
has_bounds = !param.bounds.is_empty();
13421342
}
13431343
let sp = hir.span(id);

src/librustc/traits/object_safety.rs

+81-63
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,10 @@ impl<'tcx> TyCtxt<'tcx> {
9191
pub fn astconv_object_safety_violations(self, trait_def_id: DefId)
9292
-> Vec<ObjectSafetyViolation>
9393
{
94+
debug_assert!(self.generics_of(trait_def_id).has_self);
95+
let self_ty = self.mk_self_type();
9496
let violations = traits::supertrait_def_ids(self, trait_def_id)
95-
.filter(|&def_id| self.predicates_reference_self(def_id, true))
97+
.filter(|&def_id| self.predicates_reference_self(def_id, self_ty, true))
9698
.map(|_| ObjectSafetyViolation::SupertraitSelf)
9799
.collect();
98100

@@ -106,21 +108,44 @@ impl<'tcx> TyCtxt<'tcx> {
106108
pub fn object_safety_violations(self, trait_def_id: DefId)
107109
-> Vec<ObjectSafetyViolation>
108110
{
111+
debug_assert!(self.generics_of(trait_def_id).has_self);
112+
let self_ty = self.mk_self_type();
109113
debug!("object_safety_violations: {:?}", trait_def_id);
110114

111115
traits::supertrait_def_ids(self, trait_def_id)
112-
.flat_map(|def_id| self.object_safety_violations_for_trait(def_id))
116+
.flat_map(|def_id| self.object_safety_violations_for_trait(def_id, self_ty))
113117
.collect()
114118
}
115119

116-
fn object_safety_violations_for_trait(self, trait_def_id: DefId)
117-
-> Vec<ObjectSafetyViolation>
118-
{
120+
/// We say a method is *vtable safe* if it can be invoked on a trait
121+
/// object. Note that object-safe traits can have some
122+
/// non-vtable-safe methods, so long as they require `Self:Sized` or
123+
/// otherwise ensure that they cannot be used when `Self=Trait`.
124+
pub fn is_vtable_safe_method(self, trait_def_id: DefId, method: &ty::AssocItem) -> bool {
125+
debug_assert!(self.generics_of(trait_def_id).has_self);
126+
let self_ty = self.mk_self_type();
127+
debug!("is_vtable_safe_method({:?}, {:?})", trait_def_id, method);
128+
// Any method that has a `Self : Sized` requisite can't be called.
129+
if self.generics_require_sized_self(method.def_id, self_ty) {
130+
return false;
131+
}
132+
133+
match self.virtual_call_violation_for_method(trait_def_id, self_ty, method) {
134+
None | Some(MethodViolationCode::WhereClauseReferencesSelf(_)) => true,
135+
Some(_) => false,
136+
}
137+
}
138+
139+
fn object_safety_violations_for_trait(
140+
self,
141+
trait_def_id: DefId,
142+
self_ty: Ty<'tcx>,
143+
) -> Vec<ObjectSafetyViolation> {
119144
// Check methods for violations.
120145
let mut violations: Vec<_> = self.associated_items(trait_def_id)
121146
.filter(|item| item.kind == ty::AssocKind::Method)
122147
.filter_map(|item|
123-
self.object_safety_violation_for_method(trait_def_id, &item)
148+
self.object_safety_violation_for_method(trait_def_id, self_ty, &item)
124149
.map(|code| ObjectSafetyViolation::Method(item.ident.name, code))
125150
).filter(|violation| {
126151
if let ObjectSafetyViolation::Method(_,
@@ -142,10 +167,10 @@ impl<'tcx> TyCtxt<'tcx> {
142167
}).collect();
143168

144169
// Check the trait itself.
145-
if self.trait_has_sized_self(trait_def_id) {
170+
if self.trait_has_sized_self(trait_def_id, self_ty) {
146171
violations.push(ObjectSafetyViolation::SizedSelf);
147172
}
148-
if self.predicates_reference_self(trait_def_id, false) {
173+
if self.predicates_reference_self(trait_def_id, self_ty, false) {
149174
violations.push(ObjectSafetyViolation::SupertraitSelf);
150175
}
151176

@@ -163,14 +188,16 @@ impl<'tcx> TyCtxt<'tcx> {
163188
fn predicates_reference_self(
164189
self,
165190
trait_def_id: DefId,
166-
supertraits_only: bool) -> bool
167-
{
191+
self_ty: Ty<'tcx>,
192+
supertraits_only: bool,
193+
) -> bool {
168194
let trait_ref = ty::Binder::dummy(ty::TraitRef::identity(self, trait_def_id));
169195
let predicates = if supertraits_only {
170196
self.super_predicates_of(trait_def_id)
171197
} else {
172198
self.predicates_of(trait_def_id)
173199
};
200+
let has_self_ty = |t: Ty<'tcx>| t.walk().any(|t| t == self_ty);
174201
predicates
175202
.predicates
176203
.iter()
@@ -179,7 +206,7 @@ impl<'tcx> TyCtxt<'tcx> {
179206
match predicate {
180207
ty::Predicate::Trait(ref data) => {
181208
// In the case of a trait predicate, we can skip the "self" type.
182-
data.skip_binder().input_types().skip(1).any(|t| t.has_self_ty())
209+
data.skip_binder().input_types().skip(1).any(has_self_ty)
183210
}
184211
ty::Predicate::Projection(ref data) => {
185212
// And similarly for projections. This should be redundant with
@@ -199,7 +226,7 @@ impl<'tcx> TyCtxt<'tcx> {
199226
.trait_ref(self)
200227
.input_types()
201228
.skip(1)
202-
.any(|t| t.has_self_ty())
229+
.any(has_self_ty)
203230
}
204231
ty::Predicate::WellFormed(..) |
205232
ty::Predicate::ObjectSafe(..) |
@@ -214,11 +241,11 @@ impl<'tcx> TyCtxt<'tcx> {
214241
})
215242
}
216243

217-
fn trait_has_sized_self(self, trait_def_id: DefId) -> bool {
218-
self.generics_require_sized_self(trait_def_id)
244+
fn trait_has_sized_self(self, trait_def_id: DefId, self_ty: Ty<'tcx>) -> bool {
245+
self.generics_require_sized_self(trait_def_id, self_ty)
219246
}
220247

221-
fn generics_require_sized_self(self, def_id: DefId) -> bool {
248+
fn generics_require_sized_self(self, def_id: DefId, self_ty: Ty<'tcx>) -> bool {
222249
let sized_def_id = match self.lang_items().sized_trait() {
223250
Some(def_id) => def_id,
224251
None => { return false; /* No Sized trait, can't require it! */ }
@@ -229,11 +256,11 @@ impl<'tcx> TyCtxt<'tcx> {
229256
let predicates = predicates.instantiate_identity(self).predicates;
230257
elaborate_predicates(self, predicates)
231258
.any(|predicate| match predicate {
232-
ty::Predicate::Trait(ref trait_pred) if trait_pred.def_id() == sized_def_id => {
233-
trait_pred.skip_binder().self_ty().is_self()
259+
ty::Predicate::Trait(ref trait_pred) => {
260+
trait_pred.def_id() == sized_def_id
261+
&& trait_pred.skip_binder().self_ty() == self_ty
234262
}
235263
ty::Predicate::Projection(..) |
236-
ty::Predicate::Trait(..) |
237264
ty::Predicate::Subtype(..) |
238265
ty::Predicate::RegionOutlives(..) |
239266
ty::Predicate::WellFormed(..) |
@@ -248,51 +275,32 @@ impl<'tcx> TyCtxt<'tcx> {
248275
}
249276

250277
/// Returns `Some(_)` if this method makes the containing trait not object safe.
251-
fn object_safety_violation_for_method(self,
252-
trait_def_id: DefId,
253-
method: &ty::AssocItem)
254-
-> Option<MethodViolationCode>
255-
{
278+
fn object_safety_violation_for_method(
279+
self,
280+
trait_def_id: DefId,
281+
self_ty: Ty<'tcx>,
282+
method: &ty::AssocItem,
283+
) -> Option<MethodViolationCode> {
256284
debug!("object_safety_violation_for_method({:?}, {:?})", trait_def_id, method);
257285
// Any method that has a `Self : Sized` requisite is otherwise
258286
// exempt from the regulations.
259-
if self.generics_require_sized_self(method.def_id) {
287+
if self.generics_require_sized_self(method.def_id, self_ty) {
260288
return None;
261289
}
262290

263-
self.virtual_call_violation_for_method(trait_def_id, method)
264-
}
265-
266-
/// We say a method is *vtable safe* if it can be invoked on a trait
267-
/// object. Note that object-safe traits can have some
268-
/// non-vtable-safe methods, so long as they require `Self:Sized` or
269-
/// otherwise ensure that they cannot be used when `Self=Trait`.
270-
pub fn is_vtable_safe_method(self,
271-
trait_def_id: DefId,
272-
method: &ty::AssocItem)
273-
-> bool
274-
{
275-
debug!("is_vtable_safe_method({:?}, {:?})", trait_def_id, method);
276-
// Any method that has a `Self : Sized` requisite can't be called.
277-
if self.generics_require_sized_self(method.def_id) {
278-
return false;
279-
}
280-
281-
match self.virtual_call_violation_for_method(trait_def_id, method) {
282-
None | Some(MethodViolationCode::WhereClauseReferencesSelf(_)) => true,
283-
Some(_) => false,
284-
}
291+
self.virtual_call_violation_for_method(trait_def_id, self_ty, method)
285292
}
286293

287294
/// Returns `Some(_)` if this method cannot be called on a trait
288295
/// object; this does not necessarily imply that the enclosing trait
289296
/// is not object safe, because the method might have a where clause
290297
/// `Self:Sized`.
291-
fn virtual_call_violation_for_method(self,
292-
trait_def_id: DefId,
293-
method: &ty::AssocItem)
294-
-> Option<MethodViolationCode>
295-
{
298+
fn virtual_call_violation_for_method(
299+
self,
300+
trait_def_id: DefId,
301+
self_ty: Ty<'tcx>,
302+
method: &ty::AssocItem,
303+
) -> Option<MethodViolationCode> {
296304
// The method's first parameter must be named `self`
297305
if !method.method_has_self_argument {
298306
return Some(MethodViolationCode::StaticMethod);
@@ -301,11 +309,15 @@ impl<'tcx> TyCtxt<'tcx> {
301309
let sig = self.fn_sig(method.def_id);
302310

303311
for input_ty in &sig.skip_binder().inputs()[1..] {
304-
if self.contains_illegal_self_type_reference(trait_def_id, input_ty) {
312+
if self.contains_illegal_self_type_reference(trait_def_id, self_ty, input_ty) {
305313
return Some(MethodViolationCode::ReferencesSelf);
306314
}
307315
}
308-
if self.contains_illegal_self_type_reference(trait_def_id, sig.output().skip_binder()) {
316+
if self.contains_illegal_self_type_reference(
317+
trait_def_id,
318+
self_ty,
319+
sig.output().skip_binder(),
320+
) {
309321
return Some(MethodViolationCode::ReferencesSelf);
310322
}
311323

@@ -323,7 +335,9 @@ impl<'tcx> TyCtxt<'tcx> {
323335
.collect::<Vec<_>>()
324336
// Do a shallow visit so that `contains_illegal_self_type_reference`
325337
// may apply it's custom visiting.
326-
.visit_tys_shallow(|t| self.contains_illegal_self_type_reference(trait_def_id, t)) {
338+
.visit_tys_shallow(|t| {
339+
self.contains_illegal_self_type_reference(trait_def_id, self_ty, t)
340+
}) {
327341
let span = self.def_span(method.def_id);
328342
return Some(MethodViolationCode::WhereClauseReferencesSelf(span));
329343
}
@@ -337,7 +351,7 @@ impl<'tcx> TyCtxt<'tcx> {
337351
// However, this is already considered object-safe. We allow it as a special case here.
338352
// FIXME(mikeyhew) get rid of this `if` statement once `receiver_is_dispatchable` allows
339353
// `Receiver: Unsize<Receiver[Self => dyn Trait]>`
340-
if receiver_ty != self.mk_self_type() {
354+
if receiver_ty != self_ty {
341355
if !self.receiver_is_dispatchable(method, receiver_ty) {
342356
return Some(MethodViolationCode::UndispatchableReceiver);
343357
} else {
@@ -404,7 +418,10 @@ impl<'tcx> TyCtxt<'tcx> {
404418
/// Performs a type substitution to produce the version of receiver_ty when `Self = self_ty`
405419
/// e.g., for receiver_ty = `Rc<Self>` and self_ty = `Foo`, returns `Rc<Foo>`.
406420
fn receiver_for_self_ty(
407-
self, receiver_ty: Ty<'tcx>, self_ty: Ty<'tcx>, method_def_id: DefId
421+
self,
422+
receiver_ty: Ty<'tcx>,
423+
self_ty: Ty<'tcx>,
424+
method_def_id: DefId,
408425
) -> Ty<'tcx> {
409426
debug!("receiver_for_self_ty({:?}, {:?}, {:?})", receiver_ty, self_ty, method_def_id);
410427
let substs = InternalSubsts::for_item(self, method_def_id, |param, _| {
@@ -608,11 +625,12 @@ impl<'tcx> TyCtxt<'tcx> {
608625
})
609626
}
610627

611-
fn contains_illegal_self_type_reference(self,
612-
trait_def_id: DefId,
613-
ty: Ty<'tcx>)
614-
-> bool
615-
{
628+
fn contains_illegal_self_type_reference(
629+
self,
630+
trait_def_id: DefId,
631+
self_ty: Ty<'tcx>,
632+
ty: Ty<'tcx>,
633+
) -> bool {
616634
// This is somewhat subtle. In general, we want to forbid
617635
// references to `Self` in the argument and return types,
618636
// since the value of `Self` is erased. However, there is one
@@ -656,8 +674,8 @@ impl<'tcx> TyCtxt<'tcx> {
656674
let mut error = false;
657675
ty.maybe_walk(|ty| {
658676
match ty.sty {
659-
ty::Param(ref param_ty) => {
660-
if param_ty.is_self() {
677+
ty::Param(_) => {
678+
if ty == self_ty {
661679
error = true;
662680
}
663681

src/librustc/ty/error.rs

+1-7
Original file line numberDiff line numberDiff line change
@@ -239,13 +239,7 @@ impl<'tcx> ty::TyS<'tcx> {
239239
ty::Infer(ty::FreshFloatTy(_)) => "fresh floating-point type".into(),
240240
ty::Projection(_) => "associated type".into(),
241241
ty::UnnormalizedProjection(_) => "non-normalized associated type".into(),
242-
ty::Param(ref p) => {
243-
if p.is_self() {
244-
"Self".into()
245-
} else {
246-
"type parameter".into()
247-
}
248-
}
242+
ty::Param(_) => "type parameter".into(),
249243
ty::Opaque(..) => "opaque type".into(),
250244
ty::Error => "type error".into(),
251245
}

src/librustc/ty/flags.rs

+2-6
Original file line numberDiff line numberDiff line change
@@ -86,13 +86,9 @@ impl FlagComputation {
8686
self.add_flags(TypeFlags::HAS_TY_ERR)
8787
}
8888

89-
&ty::Param(ref p) => {
89+
&ty::Param(_) => {
9090
self.add_flags(TypeFlags::HAS_FREE_LOCAL_NAMES);
91-
if p.is_self() {
92-
self.add_flags(TypeFlags::HAS_SELF);
93-
} else {
94-
self.add_flags(TypeFlags::HAS_PARAMS);
95-
}
91+
self.add_flags(TypeFlags::HAS_PARAMS);
9692
}
9793

9894
&ty::Generator(_, ref substs, _) => {

src/librustc/ty/fold.rs

-3
Original file line numberDiff line numberDiff line change
@@ -85,9 +85,6 @@ pub trait TypeFoldable<'tcx>: fmt::Debug + Clone {
8585
fn has_param_types(&self) -> bool {
8686
self.has_type_flags(TypeFlags::HAS_PARAMS)
8787
}
88-
fn has_self_ty(&self) -> bool {
89-
self.has_type_flags(TypeFlags::HAS_SELF)
90-
}
9188
fn has_infer_types(&self) -> bool {
9289
self.has_type_flags(TypeFlags::HAS_TY_INFER)
9390
}

src/librustc/ty/instance.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -298,8 +298,9 @@ impl<'tcx> Instance<'tcx> {
298298
) -> Option<Instance<'tcx>> {
299299
debug!("resolve(def_id={:?}, substs={:?})", def_id, substs);
300300
let fn_sig = tcx.fn_sig(def_id);
301-
let is_vtable_shim =
302-
fn_sig.inputs().skip_binder().len() > 0 && fn_sig.input(0).skip_binder().is_self();
301+
let is_vtable_shim = fn_sig.inputs().skip_binder().len() > 0
302+
&& fn_sig.input(0).skip_binder().is_param(0)
303+
&& tcx.generics_of(def_id).has_self;
303304
if is_vtable_shim {
304305
debug!(" => associated item with unsizeable self: Self");
305306
Some(Instance {

src/librustc/ty/layout.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -1601,7 +1601,6 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
16011601
// resulting from the final codegen session.
16021602
if
16031603
layout.ty.has_param_types() ||
1604-
layout.ty.has_self_ty() ||
16051604
!self.param_env.caller_bounds.is_empty()
16061605
{
16071606
return;
@@ -1767,7 +1766,7 @@ impl<'tcx> SizeSkeleton<'tcx> {
17671766
let tail = tcx.struct_tail_erasing_lifetimes(pointee, param_env);
17681767
match tail.sty {
17691768
ty::Param(_) | ty::Projection(_) => {
1770-
debug_assert!(tail.has_param_types() || tail.has_self_ty());
1769+
debug_assert!(tail.has_param_types());
17711770
Ok(SizeSkeleton::Pointer {
17721771
non_zero,
17731772
tail: tcx.erase_regions(&tail)

0 commit comments

Comments
 (0)