Skip to content

Commit ee53d9a

Browse files
committed
Remove query for .pin_type()
1 parent 7a75a66 commit ee53d9a

4 files changed

+47
-36
lines changed

src/librustc/middle/resolve_lifetime.rs

Lines changed: 32 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -2145,46 +2145,44 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
21452145
false
21462146
};
21472147

2148-
let mut self_arg = &inputs[0].node;
2149-
2150-
// Apply `self: &(mut) Self` elision rules even if nested in `Pin`.
2151-
loop {
2152-
if let hir::TyKind::Path(hir::QPath::Resolved(None, ref path)) = *self_arg {
2153-
if let Res::Def(DefKind::Struct, def_id) = path.res {
2154-
if self.tcx.lang_items().pin_type() == Some(def_id) {
2155-
if let Some(args) = path
2156-
.segments
2157-
.last()
2158-
.and_then(|segment| segment.args.as_ref())
2159-
{
2160-
if args.args.len() == 1 {
2161-
if let GenericArg::Type(ty) = &args.args[0] {
2162-
self_arg = &ty.node;
2163-
// Keep dereferencing `self_arg` until we get to non-`Pin`
2164-
// types.
2165-
continue;
2166-
}
2167-
}
2148+
struct SelfVisitor<'a, F: FnMut(Res) -> bool> {
2149+
is_self_ty: F,
2150+
map: &'a NamedRegionMap,
2151+
lifetime: Option<Region>,
2152+
}
2153+
2154+
impl<'a, F: FnMut(Res) -> bool> Visitor<'a> for SelfVisitor<'a, F> {
2155+
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'a> {
2156+
NestedVisitorMap::None
2157+
}
2158+
2159+
fn visit_ty(&mut self, ty: &'a hir::Ty) {
2160+
if let hir::TyKind::Rptr(lifetime_ref, ref mt) = ty.node {
2161+
if let hir::TyKind::Path(hir::QPath::Resolved(None, ref path)) = mt.ty.node
2162+
{
2163+
if (self.is_self_ty)(path.res) {
2164+
self.lifetime = self.map.defs.get(&lifetime_ref.hir_id).copied();
2165+
return;
21682166
}
21692167
}
21702168
}
2169+
intravisit::walk_ty(self, ty)
21712170
}
2172-
break;
21732171
}
21742172

2175-
if let hir::TyKind::Rptr(lifetime_ref, ref mt) = *self_arg {
2176-
if let hir::TyKind::Path(hir::QPath::Resolved(None, ref path)) = mt.ty.node {
2177-
if is_self_ty(path.res) {
2178-
if let Some(&lifetime) = self.map.defs.get(&lifetime_ref.hir_id) {
2179-
let scope = Scope::Elision {
2180-
elide: Elide::Exact(lifetime),
2181-
s: self.scope,
2182-
};
2183-
self.with(scope, |_, this| this.visit_ty(output));
2184-
return;
2185-
}
2186-
}
2187-
}
2173+
let mut visitor = SelfVisitor {
2174+
is_self_ty,
2175+
map: self.map,
2176+
lifetime: None,
2177+
};
2178+
visitor.visit_ty(&inputs[0]);
2179+
if let Some(lifetime) = visitor.lifetime {
2180+
let scope = Scope::Elision {
2181+
elide: Elide::Exact(lifetime),
2182+
s: self.scope,
2183+
};
2184+
self.with(scope, |_, this| this.visit_ty(output));
2185+
return;
21882186
}
21892187
}
21902188

src/test/ui/self/arbitrary_self_types_pin_lifetime.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ impl Foo {
1919

2020
type Alias<T> = Pin<T>;
2121
impl Foo {
22-
fn bar<'a>(self: Alias<&Self>, arg: &'a ()) -> &() { arg }
22+
fn bar<'a>(self: Alias<&Self>, arg: &'a ()) -> Alias<&Self> { self }
2323
}
2424

2525
struct Bar<T: Unpin, U: Unpin> {

src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,9 @@ impl Foo {
1010
fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self, f) } //~ ERROR E0623
1111
}
1212

13+
type Alias<T> = Pin<T>;
14+
impl Foo {
15+
fn bar<'a>(self: Alias<&Self>, arg: &'a ()) -> &() { arg } //~ ERROR E0623
16+
}
17+
1318
fn main() {}

src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch.stderr

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,13 @@ LL | fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self,
1414
| |
1515
| this parameter and the return type are declared with different lifetimes...
1616

17-
error: aborting due to 2 previous errors
17+
error[E0623]: lifetime mismatch
18+
--> $DIR/arbitrary_self_types_pin_lifetime_mismatch.rs:15:58
19+
|
20+
LL | fn bar<'a>(self: Alias<&Self>, arg: &'a ()) -> &() { arg }
21+
| ------ --- ^^^ ...but data from `arg` is returned here
22+
| |
23+
| this parameter and the return type are declared with different lifetimes...
24+
25+
error: aborting due to 3 previous errors
1826

0 commit comments

Comments
 (0)