resolve '_ in dyn Trait just like ordinary elision

cc #48468
This commit is contained in:
Niko Matsakis 2018-03-12 16:31:34 -04:00
parent e96e54d3d4
commit f9bf827055
3 changed files with 80 additions and 4 deletions

View file

@ -19,6 +19,7 @@ use hir::map::Map;
use hir::def::Def;
use hir::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE};
use hir::ItemLocalId;
use hir::LifetimeName;
use ty::{self, TyCtxt};
use std::cell::Cell;
@ -569,10 +570,26 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
for bound in bounds {
self.visit_poly_trait_ref(bound, hir::TraitBoundModifier::None);
}
if lifetime.is_elided() {
self.resolve_object_lifetime_default(lifetime)
} else {
self.visit_lifetime(lifetime);
match lifetime.name {
LifetimeName::Implicit => {
// If the user does not write *anything*, we
// use the object lifetime defaulting
// rules. So e.g. `Box<dyn Debug>` becomes
// `Box<dyn Debug + 'static>`.
self.resolve_object_lifetime_default(lifetime)
}
LifetimeName::Underscore => {
// If the user writes `'_`, we use the *ordinary* elision
// rules. So the `'_` in e.g. `Box<dyn Debug + '_>` will be
// resolved the same as the `'_` in `&'_ Foo`.
//
// cc #48468
self.resolve_elided_lifetimes(slice::from_ref(lifetime), false)
}
LifetimeName::Static | LifetimeName::Name(_) => {
// If the user wrote an explicit name, use that.
self.visit_lifetime(lifetime);
}
}
}
hir::TyRptr(ref lifetime_ref, ref mt) => {

View file

@ -0,0 +1,32 @@
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// Check that the `'_` in `dyn Trait + '_` acts like ordinary elision,
// and not like an object lifetime default.
//
// cc #48468
#![feature(dyn_trait)]
#![feature(underscore_lifetimes)]
fn a<T>(items: &[T]) -> Box<dyn Iterator<Item=&T>> {
// ^^^^^^^^^^^^^^^^^^^^^ bound *here* defaults to `'static`
Box::new(items.iter()) //~ ERROR cannot infer an appropriate lifetime
}
fn b<T>(items: &[T]) -> Box<dyn Iterator<Item=&T> + '_> {
Box::new(items.iter()) // OK, equivalent to c
}
fn c<'a, T>(items: &'a [T]) -> Box<dyn Iterator<Item=&'a T> + 'a> {
Box::new(items.iter()) // OK, equivalent to b
}
fn main() { }

View file

@ -0,0 +1,27 @@
error[E0495]: cannot infer an appropriate lifetime for autoref due to conflicting requirements
--> $DIR/dyn-trait-underscore.rs:21:20
|
LL | Box::new(items.iter()) //~ ERROR cannot infer an appropriate lifetime
| ^^^^
|
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the function body at 19:1...
--> $DIR/dyn-trait-underscore.rs:19:1
|
LL | / fn a<T>(items: &[T]) -> Box<dyn Iterator<Item=&T>> {
LL | | // ^^^^^^^^^^^^^^^^^^^^^ bound *here* defaults to `'static`
LL | | Box::new(items.iter()) //~ ERROR cannot infer an appropriate lifetime
LL | | }
| |_^
note: ...so that reference does not outlive borrowed content
--> $DIR/dyn-trait-underscore.rs:21:14
|
LL | Box::new(items.iter()) //~ ERROR cannot infer an appropriate lifetime
| ^^^^^
= note: but, the lifetime must be valid for the static lifetime...
= note: ...so that the expression is assignable:
expected std::boxed::Box<std::iter::Iterator<Item=&T> + 'static>
found std::boxed::Box<std::iter::Iterator<Item=&T>>
error: aborting due to previous error
For more information about this error, try `rustc --explain E0495`.