From f9bf8270556ea7f89df32c40bd536a26457f8818 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Mon, 12 Mar 2018 16:31:34 -0400 Subject: [PATCH] resolve `'_` in `dyn Trait` just like ordinary elision cc #48468 --- src/librustc/middle/resolve_lifetime.rs | 25 ++++++++++++--- .../dyn-trait-underscore.rs | 32 +++++++++++++++++++ .../dyn-trait-underscore.stderr | 27 ++++++++++++++++ 3 files changed, 80 insertions(+), 4 deletions(-) create mode 100644 src/test/ui/underscore-lifetime/dyn-trait-underscore.rs create mode 100644 src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index f8fb2e5a1c821..0aa750aba0660 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -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` becomes + // `Box`. + self.resolve_object_lifetime_default(lifetime) + } + LifetimeName::Underscore => { + // If the user writes `'_`, we use the *ordinary* elision + // rules. So the `'_` in e.g. `Box` 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) => { diff --git a/src/test/ui/underscore-lifetime/dyn-trait-underscore.rs b/src/test/ui/underscore-lifetime/dyn-trait-underscore.rs new file mode 100644 index 0000000000000..c24762201004b --- /dev/null +++ b/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 or the MIT license +// , 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(items: &[T]) -> Box> { + // ^^^^^^^^^^^^^^^^^^^^^ bound *here* defaults to `'static` + Box::new(items.iter()) //~ ERROR cannot infer an appropriate lifetime +} + +fn b(items: &[T]) -> Box + '_> { + Box::new(items.iter()) // OK, equivalent to c +} + +fn c<'a, T>(items: &'a [T]) -> Box + 'a> { + Box::new(items.iter()) // OK, equivalent to b +} + +fn main() { } diff --git a/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr b/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr new file mode 100644 index 0000000000000..cb3035f42a04a --- /dev/null +++ b/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(items: &[T]) -> Box> { +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 + 'static> + found std::boxed::Box> + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0495`.