Remove query for .pin_type()
This commit is contained in:
parent
e2eb957be0
commit
a1fd4fa848
4 changed files with 46 additions and 35 deletions
|
@ -2174,46 +2174,44 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||||
false
|
false
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut self_arg = &inputs[0].node;
|
struct SelfVisitor<'a, F: FnMut(Res) -> bool> {
|
||||||
|
is_self_ty: F,
|
||||||
|
map: &'a NamedRegionMap,
|
||||||
|
lifetime: Option<Region>,
|
||||||
|
}
|
||||||
|
|
||||||
// Apply `self: &(mut) Self` elision rules even if nested in `Pin`.
|
impl<'a, F: FnMut(Res) -> bool> Visitor<'a> for SelfVisitor<'a, F> {
|
||||||
loop {
|
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'a> {
|
||||||
if let hir::TyKind::Path(hir::QPath::Resolved(None, ref path)) = *self_arg {
|
NestedVisitorMap::None
|
||||||
if let Res::Def(DefKind::Struct, def_id) = path.res {
|
}
|
||||||
if self.tcx.lang_items().pin_type() == Some(def_id) {
|
|
||||||
if let Some(args) = path
|
fn visit_ty(&mut self, ty: &'a hir::Ty) {
|
||||||
.segments
|
if let hir::TyKind::Rptr(lifetime_ref, ref mt) = ty.node {
|
||||||
.last()
|
if let hir::TyKind::Path(hir::QPath::Resolved(None, ref path)) = mt.ty.node
|
||||||
.and_then(|segment| segment.args.as_ref())
|
{
|
||||||
{
|
if (self.is_self_ty)(path.res) {
|
||||||
if args.args.len() == 1 {
|
self.lifetime = self.map.defs.get(&lifetime_ref.hir_id).copied();
|
||||||
if let GenericArg::Type(ty) = &args.args[0] {
|
return;
|
||||||
self_arg = &ty.node;
|
|
||||||
// Keep dereferencing `self_arg` until we get to non-`Pin`
|
|
||||||
// types.
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
intravisit::walk_ty(self, ty)
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if let hir::TyKind::Rptr(lifetime_ref, ref mt) = *self_arg {
|
let mut visitor = SelfVisitor {
|
||||||
if let hir::TyKind::Path(hir::QPath::Resolved(None, ref path)) = mt.ty.node {
|
is_self_ty,
|
||||||
if is_self_ty(path.res) {
|
map: self.map,
|
||||||
if let Some(&lifetime) = self.map.defs.get(&lifetime_ref.hir_id) {
|
lifetime: None,
|
||||||
let scope = Scope::Elision {
|
};
|
||||||
elide: Elide::Exact(lifetime),
|
visitor.visit_ty(&inputs[0]);
|
||||||
s: self.scope,
|
if let Some(lifetime) = visitor.lifetime {
|
||||||
};
|
let scope = Scope::Elision {
|
||||||
self.with(scope, |_, this| this.visit_ty(output));
|
elide: Elide::Exact(lifetime),
|
||||||
return;
|
s: self.scope,
|
||||||
}
|
};
|
||||||
}
|
self.with(scope, |_, this| this.visit_ty(output));
|
||||||
}
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ impl Foo {
|
||||||
|
|
||||||
type Alias<T> = Pin<T>;
|
type Alias<T> = Pin<T>;
|
||||||
impl Foo {
|
impl Foo {
|
||||||
fn bar<'a>(self: Alias<&Self>, arg: &'a ()) -> &() { arg }
|
fn bar<'a>(self: Alias<&Self>, arg: &'a ()) -> Alias<&Self> { self }
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Bar<T: Unpin, U: Unpin> {
|
struct Bar<T: Unpin, U: Unpin> {
|
||||||
|
|
|
@ -10,4 +10,9 @@ impl Foo {
|
||||||
fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self, f) } //~ ERROR E0623
|
fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self, f) } //~ ERROR E0623
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Alias<T> = Pin<T>;
|
||||||
|
impl Foo {
|
||||||
|
fn bar<'a>(self: Alias<&Self>, arg: &'a ()) -> &() { arg } //~ ERROR E0623
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -14,5 +14,13 @@ LL | fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self,
|
||||||
| |
|
| |
|
||||||
| this parameter and the return type are declared with different lifetimes...
|
| this parameter and the return type are declared with different lifetimes...
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error[E0623]: lifetime mismatch
|
||||||
|
--> $DIR/arbitrary_self_types_pin_lifetime_mismatch.rs:15:58
|
||||||
|
|
|
||||||
|
LL | fn bar<'a>(self: Alias<&Self>, arg: &'a ()) -> &() { arg }
|
||||||
|
| ------ --- ^^^ ...but data from `arg` is returned here
|
||||||
|
| |
|
||||||
|
| this parameter and the return type are declared with different lifetimes...
|
||||||
|
|
||||||
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue