Skip to content

Commit f9bf827

Browse files
committed
resolve '_ in dyn Trait just like ordinary elision
cc #48468
1 parent e96e54d commit f9bf827

File tree

3 files changed

+80
-4
lines changed

3 files changed

+80
-4
lines changed

src/librustc/middle/resolve_lifetime.rs

+21-4
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ use hir::map::Map;
1919
use hir::def::Def;
2020
use hir::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE};
2121
use hir::ItemLocalId;
22+
use hir::LifetimeName;
2223
use ty::{self, TyCtxt};
2324

2425
use std::cell::Cell;
@@ -569,10 +570,26 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
569570
for bound in bounds {
570571
self.visit_poly_trait_ref(bound, hir::TraitBoundModifier::None);
571572
}
572-
if lifetime.is_elided() {
573-
self.resolve_object_lifetime_default(lifetime)
574-
} else {
575-
self.visit_lifetime(lifetime);
573+
match lifetime.name {
574+
LifetimeName::Implicit => {
575+
// If the user does not write *anything*, we
576+
// use the object lifetime defaulting
577+
// rules. So e.g. `Box<dyn Debug>` becomes
578+
// `Box<dyn Debug + 'static>`.
579+
self.resolve_object_lifetime_default(lifetime)
580+
}
581+
LifetimeName::Underscore => {
582+
// If the user writes `'_`, we use the *ordinary* elision
583+
// rules. So the `'_` in e.g. `Box<dyn Debug + '_>` will be
584+
// resolved the same as the `'_` in `&'_ Foo`.
585+
//
586+
// cc #48468
587+
self.resolve_elided_lifetimes(slice::from_ref(lifetime), false)
588+
}
589+
LifetimeName::Static | LifetimeName::Name(_) => {
590+
// If the user wrote an explicit name, use that.
591+
self.visit_lifetime(lifetime);
592+
}
576593
}
577594
}
578595
hir::TyRptr(ref lifetime_ref, ref mt) => {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Check that the `'_` in `dyn Trait + '_` acts like ordinary elision,
12+
// and not like an object lifetime default.
13+
//
14+
// cc #48468
15+
16+
#![feature(dyn_trait)]
17+
#![feature(underscore_lifetimes)]
18+
19+
fn a<T>(items: &[T]) -> Box<dyn Iterator<Item=&T>> {
20+
// ^^^^^^^^^^^^^^^^^^^^^ bound *here* defaults to `'static`
21+
Box::new(items.iter()) //~ ERROR cannot infer an appropriate lifetime
22+
}
23+
24+
fn b<T>(items: &[T]) -> Box<dyn Iterator<Item=&T> + '_> {
25+
Box::new(items.iter()) // OK, equivalent to c
26+
}
27+
28+
fn c<'a, T>(items: &'a [T]) -> Box<dyn Iterator<Item=&'a T> + 'a> {
29+
Box::new(items.iter()) // OK, equivalent to b
30+
}
31+
32+
fn main() { }
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
error[E0495]: cannot infer an appropriate lifetime for autoref due to conflicting requirements
2+
--> $DIR/dyn-trait-underscore.rs:21:20
3+
|
4+
LL | Box::new(items.iter()) //~ ERROR cannot infer an appropriate lifetime
5+
| ^^^^
6+
|
7+
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the function body at 19:1...
8+
--> $DIR/dyn-trait-underscore.rs:19:1
9+
|
10+
LL | / fn a<T>(items: &[T]) -> Box<dyn Iterator<Item=&T>> {
11+
LL | | // ^^^^^^^^^^^^^^^^^^^^^ bound *here* defaults to `'static`
12+
LL | | Box::new(items.iter()) //~ ERROR cannot infer an appropriate lifetime
13+
LL | | }
14+
| |_^
15+
note: ...so that reference does not outlive borrowed content
16+
--> $DIR/dyn-trait-underscore.rs:21:14
17+
|
18+
LL | Box::new(items.iter()) //~ ERROR cannot infer an appropriate lifetime
19+
| ^^^^^
20+
= note: but, the lifetime must be valid for the static lifetime...
21+
= note: ...so that the expression is assignable:
22+
expected std::boxed::Box<std::iter::Iterator<Item=&T> + 'static>
23+
found std::boxed::Box<std::iter::Iterator<Item=&T>>
24+
25+
error: aborting due to previous error
26+
27+
For more information about this error, try `rustc --explain E0495`.

0 commit comments

Comments
 (0)