Skip to content

Commit 9a46196

Browse files
committed
Auto merge of #53677 - eddyb:not-my-self, r=<try>
rustc: remove Ty::{is_self, has_self_ty}. Fixes #50125 by replacing special-casing of `Self` (and the gensym hack) with getting the type for the `Self` parameter from the trait, and comparing types with that, instead. **NOTE**: this is part of #53661, split out to independently check performance impact.
2 parents 61b0072 + d110803 commit 9a46196

32 files changed

+82
-112
lines changed

src/librustc/infer/error_reporting/mod.rs

+14-18
Original file line numberDiff line numberDiff line change
@@ -1117,19 +1117,15 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
11171117
let table = table.borrow();
11181118
table.local_id_root.and_then(|did| {
11191119
let generics = self.tcx.generics_of(did);
1120-
// Account for the case where `did` corresponds to `Self`, which doesn't have
1121-
// the expected type argument.
1122-
if !param.is_self() {
1123-
let type_param = generics.type_param(param, self.tcx);
1124-
let hir = &self.tcx.hir;
1125-
hir.as_local_node_id(type_param.def_id).map(|id| {
1126-
// Get the `hir::Param` to verify whether it already has any bounds.
1127-
// We do this to avoid suggesting code that ends up as `T: 'a'b`,
1128-
// instead we suggest `T: 'a + 'b` in that case.
1129-
let mut has_bounds = false;
1130-
if let hir_map::NodeGenericParam(ref param) = hir.get(id) {
1131-
has_bounds = !param.bounds.is_empty();
1132-
}
1120+
let type_param = generics.type_param(param, self.tcx);
1121+
let hir = &self.tcx.hir;
1122+
hir.as_local_node_id(type_param.def_id).and_then(|id| {
1123+
// Get the `hir::Param` to verify whether it already has any bounds.
1124+
// We do this to avoid suggesting code that ends up as `T: 'a'b`,
1125+
// instead we suggest `T: 'a + 'b` in that case.
1126+
// Also, `Self` isn't in the HIR so we rule it out here.
1127+
if let hir_map::NodeGenericParam(ref hir_param) = hir.get(id) {
1128+
let has_bounds = !hir_param.bounds.is_empty();
11331129
let sp = hir.span(id);
11341130
// `sp` only covers `T`, change it so that it covers
11351131
// `T:` when appropriate
@@ -1141,11 +1137,11 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
11411137
} else {
11421138
sp
11431139
};
1144-
(sp, has_bounds)
1145-
})
1146-
} else {
1147-
None
1148-
}
1140+
Some((sp, has_bounds))
1141+
} else {
1142+
None
1143+
}
1144+
})
11491145
})
11501146
}
11511147
_ => None,

src/librustc/traits/object_safety.rs

+9-4
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
169169
trait_def_id: DefId,
170170
supertraits_only: bool) -> bool
171171
{
172+
let trait_self_ty = self.mk_self_type();
172173
let trait_ref = ty::Binder::dummy(ty::TraitRef::identity(self, trait_def_id));
173174
let predicates = if supertraits_only {
174175
self.super_predicates_of(trait_def_id)
@@ -183,7 +184,9 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
183184
match predicate {
184185
ty::Predicate::Trait(ref data) => {
185186
// In the case of a trait predicate, we can skip the "self" type.
186-
data.skip_binder().input_types().skip(1).any(|t| t.has_self_ty())
187+
data.skip_binder().input_types().skip(1).any(|t| {
188+
t.walk().any(|ty| ty == trait_self_ty)
189+
})
187190
}
188191
ty::Predicate::Projection(..) |
189192
ty::Predicate::WellFormed(..) |
@@ -204,6 +207,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
204207
}
205208

206209
fn generics_require_sized_self(self, def_id: DefId) -> bool {
210+
let trait_self_ty = self.mk_self_type();
207211
let sized_def_id = match self.lang_items().sized_trait() {
208212
Some(def_id) => def_id,
209213
None => { return false; /* No Sized trait, can't require it! */ }
@@ -216,7 +220,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
216220
.any(|predicate| {
217221
match predicate {
218222
ty::Predicate::Trait(ref trait_pred) if trait_pred.def_id() == sized_def_id => {
219-
trait_pred.skip_binder().self_ty().is_self()
223+
trait_pred.skip_binder().self_ty() == trait_self_ty
220224
}
221225
ty::Predicate::Projection(..) |
222226
ty::Predicate::Trait(..) |
@@ -367,12 +371,13 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
367371
// object type, and we cannot resolve `Self as SomeOtherTrait`
368372
// without knowing what `Self` is.
369373

374+
let trait_self_ty = self.mk_self_type();
370375
let mut supertraits: Option<Vec<ty::PolyTraitRef<'tcx>>> = None;
371376
let mut error = false;
372377
ty.maybe_walk(|ty| {
373378
match ty.sty {
374-
ty::Param(ref param_ty) => {
375-
if param_ty.is_self() {
379+
ty::Param(_) => {
380+
if ty == trait_self_ty {
376381
error = true;
377382
}
378383

src/librustc/ty/error.rs

+1-7
Original file line numberDiff line numberDiff line change
@@ -222,13 +222,7 @@ impl<'a, 'gcx, 'lcx, 'tcx> ty::TyS<'tcx> {
222222
ty::Infer(ty::FreshIntTy(_)) => "skolemized integral type".to_string(),
223223
ty::Infer(ty::FreshFloatTy(_)) => "skolemized floating-point type".to_string(),
224224
ty::Projection(_) => "associated type".to_string(),
225-
ty::Param(ref p) => {
226-
if p.is_self() {
227-
"Self".to_string()
228-
} else {
229-
"type parameter".to_string()
230-
}
231-
}
225+
ty::Param(_) => format!("`{}` parameter", self),
232226
ty::Anon(..) => "anonymized type".to_string(),
233227
ty::Error => "type error".to_string(),
234228
}

src/librustc/ty/flags.rs

+2-6
Original file line numberDiff line numberDiff line change
@@ -90,13 +90,9 @@ impl FlagComputation {
9090
self.add_flags(TypeFlags::HAS_TY_ERR)
9191
}
9292

93-
&ty::Param(ref p) => {
93+
&ty::Param(_) => {
9494
self.add_flags(TypeFlags::HAS_FREE_LOCAL_NAMES);
95-
if p.is_self() {
96-
self.add_flags(TypeFlags::HAS_SELF);
97-
} else {
98-
self.add_flags(TypeFlags::HAS_PARAMS);
99-
}
95+
self.add_flags(TypeFlags::HAS_PARAMS);
10096
}
10197

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

src/librustc/ty/fold.rs

-3
Original file line numberDiff line numberDiff line change
@@ -93,9 +93,6 @@ pub trait TypeFoldable<'tcx>: fmt::Debug + Clone {
9393
fn has_param_types(&self) -> bool {
9494
self.has_type_flags(TypeFlags::HAS_PARAMS)
9595
}
96-
fn has_self_ty(&self) -> bool {
97-
self.has_type_flags(TypeFlags::HAS_SELF)
98-
}
9996
fn has_infer_types(&self) -> bool {
10097
self.has_type_flags(TypeFlags::HAS_TY_INFER)
10198
}

src/librustc/ty/layout.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -1130,7 +1130,6 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> {
11301130
if
11311131
!self.tcx.sess.opts.debugging_opts.print_type_sizes ||
11321132
layout.ty.has_param_types() ||
1133-
layout.ty.has_self_ty() ||
11341133
!self.param_env.caller_bounds.is_empty()
11351134
{
11361135
return;
@@ -1300,7 +1299,7 @@ impl<'a, 'tcx> SizeSkeleton<'tcx> {
13001299
let tail = tcx.struct_tail(pointee);
13011300
match tail.sty {
13021301
ty::Param(_) | ty::Projection(_) => {
1303-
debug_assert!(tail.has_param_types() || tail.has_self_ty());
1302+
debug_assert!(tail.has_param_types());
13041303
Ok(SizeSkeleton::Pointer {
13051304
non_zero,
13061305
tail: tcx.erase_regions(&tail)

src/librustc/ty/mod.rs

+13-17
Original file line numberDiff line numberDiff line change
@@ -423,57 +423,54 @@ pub struct CReaderCacheKey {
423423
bitflags! {
424424
pub struct TypeFlags: u32 {
425425
const HAS_PARAMS = 1 << 0;
426-
const HAS_SELF = 1 << 1;
427-
const HAS_TY_INFER = 1 << 2;
428-
const HAS_RE_INFER = 1 << 3;
429-
const HAS_RE_SKOL = 1 << 4;
426+
const HAS_TY_INFER = 1 << 1;
427+
const HAS_RE_INFER = 1 << 2;
428+
const HAS_RE_SKOL = 1 << 3;
430429

431430
/// Does this have any `ReEarlyBound` regions? Used to
432431
/// determine whether substitition is required, since those
433432
/// represent regions that are bound in a `ty::Generics` and
434433
/// hence may be substituted.
435-
const HAS_RE_EARLY_BOUND = 1 << 5;
434+
const HAS_RE_EARLY_BOUND = 1 << 4;
436435

437436
/// Does this have any region that "appears free" in the type?
438437
/// Basically anything but `ReLateBound` and `ReErased`.
439-
const HAS_FREE_REGIONS = 1 << 6;
438+
const HAS_FREE_REGIONS = 1 << 5;
440439

441440
/// Is an error type reachable?
442-
const HAS_TY_ERR = 1 << 7;
443-
const HAS_PROJECTION = 1 << 8;
441+
const HAS_TY_ERR = 1 << 6;
442+
const HAS_PROJECTION = 1 << 7;
444443

445444
// FIXME: Rename this to the actual property since it's used for generators too
446-
const HAS_TY_CLOSURE = 1 << 9;
445+
const HAS_TY_CLOSURE = 1 << 8;
447446

448447
// true if there are "names" of types and regions and so forth
449448
// that are local to a particular fn
450-
const HAS_FREE_LOCAL_NAMES = 1 << 10;
449+
const HAS_FREE_LOCAL_NAMES = 1 << 9;
451450

452451
// Present if the type belongs in a local type context.
453452
// Only set for Infer other than Fresh.
454-
const KEEP_IN_LOCAL_TCX = 1 << 11;
453+
const KEEP_IN_LOCAL_TCX = 1 << 10;
455454

456455
// Is there a projection that does not involve a bound region?
457456
// Currently we can't normalize projections w/ bound regions.
458-
const HAS_NORMALIZABLE_PROJECTION = 1 << 12;
457+
const HAS_NORMALIZABLE_PROJECTION = 1 << 11;
459458

460459
// Set if this includes a "canonical" type or region var --
461460
// ought to be true only for the results of canonicalization.
462-
const HAS_CANONICAL_VARS = 1 << 13;
461+
const HAS_CANONICAL_VARS = 1 << 12;
463462

464463
/// Does this have any `ReLateBound` regions? Used to check
465464
/// if a global bound is safe to evaluate.
466-
const HAS_RE_LATE_BOUND = 1 << 14;
465+
const HAS_RE_LATE_BOUND = 1 << 13;
467466

468467
const NEEDS_SUBST = TypeFlags::HAS_PARAMS.bits |
469-
TypeFlags::HAS_SELF.bits |
470468
TypeFlags::HAS_RE_EARLY_BOUND.bits;
471469

472470
// Flags representing the nominal content of a type,
473471
// computed by FlagsComputation. If you add a new nominal
474472
// flag, it should be added here too.
475473
const NOMINAL_FLAGS = TypeFlags::HAS_PARAMS.bits |
476-
TypeFlags::HAS_SELF.bits |
477474
TypeFlags::HAS_TY_INFER.bits |
478475
TypeFlags::HAS_RE_INFER.bits |
479476
TypeFlags::HAS_RE_SKOL.bits |
@@ -1632,7 +1629,6 @@ impl<'tcx> ParamEnv<'tcx> {
16321629
if value.has_skol()
16331630
|| value.needs_infer()
16341631
|| value.has_param_types()
1635-
|| value.has_self_ty()
16361632
{
16371633
ParamEnvAnd {
16381634
param_env: self,

src/librustc/ty/sty.rs

-18
Original file line numberDiff line numberDiff line change
@@ -982,17 +982,6 @@ impl<'a, 'gcx, 'tcx> ParamTy {
982982
pub fn to_ty(self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Ty<'tcx> {
983983
tcx.mk_ty_param(self.idx, self.name)
984984
}
985-
986-
pub fn is_self(&self) -> bool {
987-
// FIXME(#50125): Ignoring `Self` with `idx != 0` might lead to weird behavior elsewhere,
988-
// but this should only be possible when using `-Z continue-parse-after-error` like
989-
// `compile-fail/issue-36638.rs`.
990-
if self.name == keywords::SelfType.name().as_str() && self.idx == 0 {
991-
true
992-
} else {
993-
false
994-
}
995-
}
996985
}
997986

998987
/// A [De Bruijn index][dbi] is a standard means of representing
@@ -1519,13 +1508,6 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
15191508
}
15201509
}
15211510

1522-
pub fn is_self(&self) -> bool {
1523-
match self.sty {
1524-
Param(ref p) => p.is_self(),
1525-
_ => false,
1526-
}
1527-
}
1528-
15291511
pub fn is_slice(&self) -> bool {
15301512
match self.sty {
15311513
RawPtr(TypeAndMut { ty, .. }) | Ref(_, ty, _) => match ty.sty {

src/librustc_lint/builtin.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1075,6 +1075,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnconditionalRecursion {
10751075
// A trait method, from any number of possible sources.
10761076
// Attempt to select a concrete impl before checking.
10771077
ty::TraitContainer(trait_def_id) => {
1078+
let trait_self_ty = tcx.mk_self_type();
10781079
let trait_ref = ty::TraitRef::from_method(tcx, trait_def_id, callee_substs);
10791080
let trait_ref = ty::Binder::bind(trait_ref);
10801081
let span = tcx.hir.span(expr_id);
@@ -1090,7 +1091,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnconditionalRecursion {
10901091
// If `T` is `Self`, then this call is inside
10911092
// a default method definition.
10921093
Ok(Some(traits::VtableParam(_))) => {
1093-
let on_self = trait_ref.self_ty().is_self();
1094+
let on_self = trait_ref.self_ty() == trait_self_ty;
10941095
// We can only be recurring in a default
10951096
// method if we're being called literally
10961097
// on the `Self` type.

src/librustc_typeck/astconv.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -597,7 +597,9 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
597597
let default_needs_object_self = |param: &ty::GenericParamDef| {
598598
if let GenericParamDefKind::Type { has_default, .. } = param.kind {
599599
if is_object && has_default {
600-
if tcx.at(span).type_of(param.def_id).has_self_ty() {
600+
let trait_self_ty = tcx.mk_self_type();
601+
let default = tcx.at(span).type_of(param.def_id);
602+
if default.walk().any(|ty| ty == trait_self_ty) {
601603
// There is no suitable inference default for a type parameter
602604
// that references self, in an object type.
603605
return true;

src/librustc_typeck/collect.rs

-4
Original file line numberDiff line numberDiff line change
@@ -919,10 +919,6 @@ fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
919919
let mut i = 0;
920920
params.extend(ast_generics.params.iter().filter_map(|param| match param.kind {
921921
GenericParamKind::Type { ref default, synthetic, .. } => {
922-
if param.name.ident().name == keywords::SelfType.name() {
923-
span_bug!(param.span, "`Self` should not be the name of a regular parameter");
924-
}
925-
926922
if !allow_defaults && default.is_some() {
927923
if !tcx.features().default_type_parameter_fallback {
928924
tcx.lint_node(

src/librustc_typeck/outlives/implicit_infer.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,11 @@ pub fn check_explicit_predicates<'tcx>(
267267
debug!("required_predicates = {:?}", required_predicates);
268268
let explicit_predicates = explicit_map.explicit_predicates_of(tcx, *def_id);
269269

270+
let ignore_self_ty = if ignore_self_ty {
271+
Some(tcx.mk_self_type())
272+
} else {
273+
None
274+
};
270275
for outlives_predicate in explicit_predicates.iter() {
271276
debug!("outlives_predicate = {:?}", &outlives_predicate);
272277

@@ -297,7 +302,7 @@ pub fn check_explicit_predicates<'tcx>(
297302
// to apply the substs, and not filter this predicate, we might then falsely
298303
// conclude that e.g. `X: 'x` was a reasonable inferred requirement.
299304
if let UnpackedKind::Type(ty) = outlives_predicate.0.unpack() {
300-
if ty.is_self() && ignore_self_ty {
305+
if Some(ty) == ignore_self_ty {
301306
debug!("skipping self ty = {:?}", &ty);
302307
continue;
303308
}

src/librustdoc/clean/simplify.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -156,10 +156,11 @@ fn trait_is_same_or_supertrait(cx: &DocContext, child: DefId,
156156
if child == trait_ {
157157
return true
158158
}
159+
let trait_self_ty = cx.tcx.mk_self_type();
159160
let predicates = cx.tcx.super_predicates_of(child).predicates;
160161
predicates.iter().filter_map(|pred| {
161162
if let ty::Predicate::Trait(ref pred) = *pred {
162-
if pred.skip_binder().trait_ref.self_ty().is_self() {
163+
if pred.skip_binder().trait_ref.self_ty() == trait_self_ty {
163164
Some(pred.def_id())
164165
} else {
165166
None

src/test/ui/associated-types/associated-types-issue-20346.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error[E0271]: type mismatch resolving `<Adapter<I> as Iterator>::Item == std::op
22
--> $DIR/associated-types-issue-20346.rs:44:5
33
|
44
LL | is_iterator_of::<Option<T>, _>(&adapter); //~ ERROR type mismatch
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected type parameter, found enum `std::option::Option`
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `T` parameter, found enum `std::option::Option`
66
|
77
= note: expected type `T`
88
found type `std::option::Option<T>`

src/test/ui/compare-method/reordered-type-param.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ LL | fn b<C:Clone,D>(&self, x: C) -> C;
55
| - type in trait
66
...
77
LL | fn b<F:Clone,G>(&self, _x: G) -> G { panic!() } //~ ERROR method `b` has an incompatible type
8-
| ^ expected type parameter, found a different type parameter
8+
| ^ expected `F` parameter, found `G` parameter
99
|
1010
= note: expected type `fn(&E, F) -> F`
1111
found type `fn(&E, G) -> G`

src/test/ui/impl-trait/impl-generic-mismatch-ab.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ LL | fn foo<A: Debug>(&self, a: &A, b: &impl Debug);
55
| -- type in trait
66
...
77
LL | fn foo<B: Debug>(&self, a: &impl Debug, b: &B) { }
8-
| ^^^^^^^^^^^ expected type parameter, found a different type parameter
8+
| ^^^^^^^^^^^ expected `B` parameter, found `impl Debug` parameter
99
|
1010
= note: expected type `fn(&(), &B, &impl Debug)`
1111
found type `fn(&(), &impl Debug, &B)`

src/test/ui/impl-trait/universal-mismatched-type.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ error[E0308]: mismatched types
44
LL | fn foo(x: impl Debug) -> String {
55
| ------ expected `std::string::String` because of return type
66
LL | x //~ ERROR mismatched types
7-
| ^ expected struct `std::string::String`, found type parameter
7+
| ^ expected struct `std::string::String`, found `impl Debug` parameter
88
|
99
= note: expected type `std::string::String`
1010
found type `impl Debug`

src/test/ui/impl-trait/universal-two-impl-traits.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@ error[E0308]: mismatched types
22
--> $DIR/universal-two-impl-traits.rs:15:9
33
|
44
LL | a = y; //~ ERROR mismatched
5-
| ^ expected type parameter, found a different type parameter
5+
| ^ expected `impl Debug` parameter, found a different `impl Debug` parameter
66
|
7-
= note: expected type `impl Debug` (type parameter)
8-
found type `impl Debug` (type parameter)
7+
= note: expected type `impl Debug` (`impl Debug` parameter)
8+
found type `impl Debug` (`impl Debug` parameter)
99

1010
error: aborting due to previous error
1111

src/test/ui/issues/issue-13853.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ LL | fn nodes<'a, I: Iterator<Item=&'a N>>(&self) -> I
55
| - expected `I` because of return type
66
...
77
LL | self.iter() //~ ERROR mismatched types
8-
| ^^^^^^^^^^^ expected type parameter, found struct `std::slice::Iter`
8+
| ^^^^^^^^^^^ expected `I` parameter, found struct `std::slice::Iter`
99
|
1010
= note: expected type `I`
1111
found type `std::slice::Iter<'_, N>`

0 commit comments

Comments
 (0)