Skip to content

Commit

Permalink
resolve '_ in dyn Trait just like ordinary elision
Browse files Browse the repository at this point in the history
  • Loading branch information
nikomatsakis committed Mar 14, 2018
1 parent e96e54d commit f9bf827
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 4 deletions.
25 changes: 21 additions & 4 deletions src/librustc/middle/resolve_lifetime.rs
Expand Up @@ -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;
Expand Down Expand Up @@ -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) => {
Expand Down
32 changes: 32 additions & 0 deletions src/test/ui/underscore-lifetime/dyn-trait-underscore.rs
@@ -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() { }
27 changes: 27 additions & 0 deletions src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr
@@ -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`.

0 comments on commit f9bf827

Please sign in to comment.