move E0637 to lowering and improve output, add more tests

This commit is contained in:
Niko Matsakis 2018-10-11 15:51:44 -04:00
parent 68da108d56
commit 1f4d100472
36 changed files with 539 additions and 79 deletions

View File

@ -436,7 +436,9 @@ pub fn walk_lifetime<'v, V: Visitor<'v>>(visitor: &mut V, lifetime: &'v Lifetime
visitor.visit_ident(ident);
}
LifetimeName::Param(ParamName::Fresh(_)) |
LifetimeName::Param(ParamName::Error) |
LifetimeName::Static |
LifetimeName::Error |
LifetimeName::Implicit |
LifetimeName::Underscore => {}
}
@ -747,7 +749,7 @@ pub fn walk_generic_param<'v, V: Visitor<'v>>(visitor: &mut V, param: &'v Generi
walk_list!(visitor, visit_attribute, &param.attrs);
match param.name {
ParamName::Plain(ident) => visitor.visit_ident(ident),
ParamName::Fresh(_) => {}
ParamName::Error | ParamName::Fresh(_) => {}
}
match param.kind {
GenericParamKind::Lifetime { .. } => {}

View File

@ -316,6 +316,11 @@ enum AnonymousLifetimeMode {
/// For **Deprecated** cases, report an error.
CreateParameter,
/// Give a hard error when either `&` or `'_` is written. Used to
/// rule out things like `where T: Foo<'_>`. Does not imply an
/// error on default object bounds (e.g., `Box<dyn Foo>`).
ReportError,
/// Pass responsibility to `resolve_lifetime` code for all cases.
PassThrough,
}
@ -736,6 +741,10 @@ impl<'a> LoweringContext<'a> {
keywords::UnderscoreLifetime.name().as_interned_str(),
hir::LifetimeParamKind::Elided,
),
ParamName::Error => (
keywords::UnderscoreLifetime.name().as_interned_str(),
hir::LifetimeParamKind::Error,
),
};
// Add a definition for the in-band lifetime def
@ -792,7 +801,7 @@ impl<'a> LoweringContext<'a> {
}
/// When we have either an elided or `'_` lifetime in an impl
/// header, we convert it to
/// header, we convert it to an in-band lifetime.
fn collect_fresh_in_band_lifetime(&mut self, span: Span) -> ParamName {
assert!(self.is_collecting_in_band_lifetimes);
let index = self.lifetimes_to_define.len();
@ -1475,7 +1484,7 @@ impl<'a> LoweringContext<'a> {
}
}
hir::LifetimeName::Param(_) => lifetime.name,
hir::LifetimeName::Static => return,
hir::LifetimeName::Error | hir::LifetimeName::Static => return,
};
if !self.currently_bound_lifetimes.contains(&name)
@ -2163,7 +2172,7 @@ impl<'a> LoweringContext<'a> {
}
}
hir::LifetimeName::Param(_) => lifetime.name,
hir::LifetimeName::Static => return,
hir::LifetimeName::Error | hir::LifetimeName::Static => return,
};
if !self.currently_bound_lifetimes.contains(&name) {
@ -2294,17 +2303,15 @@ impl<'a> LoweringContext<'a> {
itctx: ImplTraitContext<'_>,
) -> hir::GenericBound {
match *tpb {
GenericBound::Trait(ref ty, modifier) => hir::GenericBound::Trait(
self.lower_poly_trait_ref(ty, itctx),
self.lower_trait_bound_modifier(modifier),
),
GenericBound::Outlives(ref lifetime) => {
// We don't want to accept `'a: '_`:
self.with_anonymous_lifetime_mode(
AnonymousLifetimeMode::PassThrough,
|this| hir::GenericBound::Outlives(this.lower_lifetime(lifetime)),
GenericBound::Trait(ref ty, modifier) => {
hir::GenericBound::Trait(
self.lower_poly_trait_ref(ty, itctx),
self.lower_trait_bound_modifier(modifier),
)
}
GenericBound::Outlives(ref lifetime) => {
hir::GenericBound::Outlives(self.lower_lifetime(lifetime))
}
}
}
@ -2323,6 +2330,8 @@ impl<'a> LoweringContext<'a> {
AnonymousLifetimeMode::PassThrough => {
self.new_named_lifetime(l.id, span, hir::LifetimeName::Underscore)
}
AnonymousLifetimeMode::ReportError => self.new_error_lifetime(Some(l.id), span),
},
ident => {
self.maybe_collect_in_band_lifetime(ident);
@ -2361,16 +2370,26 @@ impl<'a> LoweringContext<'a> {
add_bounds: &NodeMap<Vec<GenericBound>>,
mut itctx: ImplTraitContext<'_>)
-> hir::GenericParam {
let mut bounds = self.lower_param_bounds(&param.bounds, itctx.reborrow());
let mut bounds = self.with_anonymous_lifetime_mode(
AnonymousLifetimeMode::ReportError,
|this| this.lower_param_bounds(&param.bounds, itctx.reborrow()),
);
match param.kind {
GenericParamKind::Lifetime => {
let was_collecting_in_band = self.is_collecting_in_band_lifetimes;
self.is_collecting_in_band_lifetimes = false;
let lt = self.lower_lifetime(&Lifetime { id: param.id, ident: param.ident });
let lt = self.with_anonymous_lifetime_mode(
AnonymousLifetimeMode::ReportError,
|this| this.lower_lifetime(&Lifetime { id: param.id, ident: param.ident }),
);
let param_name = match lt.name {
hir::LifetimeName::Param(param_name) => param_name,
_ => hir::ParamName::Plain(lt.name.ident()),
hir::LifetimeName::Implicit
| hir::LifetimeName::Underscore
| hir::LifetimeName::Static => hir::ParamName::Plain(lt.name.ident()),
hir::LifetimeName::Error => ParamName::Error,
};
let param = hir::GenericParam {
id: lt.id,
@ -2494,13 +2513,18 @@ impl<'a> LoweringContext<'a> {
}
fn lower_where_clause(&mut self, wc: &WhereClause) -> hir::WhereClause {
hir::WhereClause {
id: self.lower_node_id(wc.id).node_id,
predicates: wc.predicates
.iter()
.map(|predicate| self.lower_where_predicate(predicate))
.collect(),
}
self.with_anonymous_lifetime_mode(
AnonymousLifetimeMode::ReportError,
|this| {
hir::WhereClause {
id: this.lower_node_id(wc.id).node_id,
predicates: wc.predicates
.iter()
.map(|predicate| this.lower_where_predicate(predicate))
.collect(),
}
},
)
}
fn lower_where_predicate(&mut self, pred: &WherePredicate) -> hir::WherePredicate {
@ -4843,10 +4867,38 @@ impl<'a> LoweringContext<'a> {
}
}
AnonymousLifetimeMode::ReportError => self.new_error_lifetime(None, span),
AnonymousLifetimeMode::PassThrough => self.new_implicit_lifetime(span),
}
}
/// Report an error on illegal use of `'_` or a `&T` with no explicit lifetime;
/// return a "error lifetime".
fn new_error_lifetime(&mut self, id: Option<NodeId>, span: Span) -> hir::Lifetime {
let (id, msg, label) = match id {
Some(id) => (id, "`'_` cannot be used here", "`'_` is a reserved lifetime name"),
None => (
self.next_id().node_id,
"`&` without an explicit lifetime name cannot be used here",
"explicit lifetime name needed here",
),
};
let mut err = struct_span_err!(
self.sess,
span,
E0637,
"{}",
msg,
);
err.span_label(span, label);
err.emit();
self.new_named_lifetime(id, span, hir::LifetimeName::Error)
}
/// Invoked to create the lifetime argument(s) for a path like
/// `std::cell::Ref<T>`; note that implicit lifetimes in these
/// sorts of cases are deprecated. This may therefore report a warning or an
@ -4861,6 +4913,12 @@ impl<'a> LoweringContext<'a> {
// impl Foo for std::cell::Ref<u32> // note lack of '_
AnonymousLifetimeMode::CreateParameter => {}
AnonymousLifetimeMode::ReportError => {
return (0..count)
.map(|_| self.new_error_lifetime(None, span))
.collect();
}
// This is the normal case.
AnonymousLifetimeMode::PassThrough => {}
}
@ -4891,6 +4949,10 @@ impl<'a> LoweringContext<'a> {
// `resolve_lifetime` has the code to make that happen.
AnonymousLifetimeMode::CreateParameter => {}
AnonymousLifetimeMode::ReportError => {
// ReportError applies to explicit use of `'_`.
}
// This is the normal case.
AnonymousLifetimeMode::PassThrough => {}
}

View File

@ -208,13 +208,18 @@ pub enum ParamName {
/// where `'f` is something like `Fresh(0)`. The indices are
/// unique per impl, but not necessarily continuous.
Fresh(usize),
/// Indicates an illegal name was given and an error has been
/// repored (so we should squelch other derived errors). Occurs
/// when e.g. `'_` is used in the wrong place.
Error,
}
impl ParamName {
pub fn ident(&self) -> Ident {
match *self {
ParamName::Plain(ident) => ident,
ParamName::Fresh(_) => keywords::UnderscoreLifetime.ident(),
ParamName::Error | ParamName::Fresh(_) => keywords::UnderscoreLifetime.ident(),
}
}
@ -234,6 +239,10 @@ pub enum LifetimeName {
/// User typed nothing. e.g. the lifetime in `&u32`.
Implicit,
/// Indicates an error during lowering (usually `'_` in wrong place)
/// that was already reported.
Error,
/// User typed `'_`.
Underscore,
@ -245,6 +254,7 @@ impl LifetimeName {
pub fn ident(&self) -> Ident {
match *self {
LifetimeName::Implicit => keywords::Invalid.ident(),
LifetimeName::Error => keywords::Invalid.ident(),
LifetimeName::Underscore => keywords::UnderscoreLifetime.ident(),
LifetimeName::Static => keywords::StaticLifetime.ident(),
LifetimeName::Param(param_name) => param_name.ident(),
@ -260,7 +270,7 @@ impl LifetimeName {
// in the compiler is concerned -- `Fresh(_)` variants act
// equivalently to "some fresh name". They correspond to
// early-bound regions on an impl, in other words.
LifetimeName::Param(_) | LifetimeName::Static => false,
LifetimeName::Error | LifetimeName::Param(_) | LifetimeName::Static => false,
}
}
@ -513,6 +523,9 @@ pub enum LifetimeParamKind {
// Indication that the lifetime was elided like both cases here:
// `fn foo(x: &u8) -> &'_ u8 { x }`
Elided,
// Indication that the lifetime name was somehow in error.
Error,
}
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]

View File

@ -144,7 +144,8 @@ impl<'a> HashStable<StableHashingContext<'a>> for hir::ImplItemId {
impl_stable_hash_for!(enum hir::ParamName {
Plain(name),
Fresh(index)
Fresh(index),
Error,
});
impl_stable_hash_for!(enum hir::LifetimeName {
@ -152,6 +153,7 @@ impl_stable_hash_for!(enum hir::LifetimeName {
Implicit,
Underscore,
Static,
Error,
});
impl_stable_hash_for!(struct hir::Label {
@ -210,7 +212,8 @@ impl_stable_hash_for!(struct hir::GenericParam {
impl_stable_hash_for!(enum hir::LifetimeParamKind {
Explicit,
InBand,
Elided
Elided,
Error,
});
impl<'a> HashStable<StableHashingContext<'a>> for hir::GenericParamKind {

View File

@ -755,8 +755,9 @@ for ::middle::resolve_lifetime::Set1<T>
}
impl_stable_hash_for!(enum ::middle::resolve_lifetime::LifetimeDefOrigin {
Explicit,
InBand
ExplicitOrElided,
InBand,
Error,
});
impl_stable_hash_for!(enum ::middle::resolve_lifetime::Region {

View File

@ -43,20 +43,23 @@ use hir::{self, GenericParamKind, LifetimeParamKind};
/// This is used to prevent the usage of in-band lifetimes in `Fn`/`fn` syntax.
#[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Debug)]
pub enum LifetimeDefOrigin {
// Explicit binders like `fn foo<'a>(x: &'a u8)`
Explicit,
// Explicit binders like `fn foo<'a>(x: &'a u8)` or elided like `impl Foo<&u32>`
ExplicitOrElided,
// In-band declarations like `fn foo(x: &'a u8)`
InBand,
// Some kind of erroneous origin
Error,
}
impl LifetimeDefOrigin {
fn from_param(param: &GenericParam) -> Self {
match param.kind {
GenericParamKind::Lifetime { kind } => {
if kind == LifetimeParamKind::InBand {
LifetimeDefOrigin::InBand
} else {
LifetimeDefOrigin::Explicit
match kind {
LifetimeParamKind::InBand => LifetimeDefOrigin::InBand,
LifetimeParamKind::Explicit => LifetimeDefOrigin::ExplicitOrElided,
LifetimeParamKind::Elided => LifetimeDefOrigin::ExplicitOrElided,
LifetimeParamKind::Error => LifetimeDefOrigin::Error,
}
}
_ => bug!("expected a lifetime param"),
@ -612,6 +615,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
// If the user wrote an explicit name, use that.
self.visit_lifetime(lifetime);
}
LifetimeName::Error => { }
}
}
hir::TyKind::Rptr(ref lifetime_ref, ref mt) => {
@ -1631,6 +1635,12 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
fn resolve_lifetime_ref(&mut self, lifetime_ref: &'tcx hir::Lifetime) {
debug!("resolve_lifetime_ref(lifetime_ref={:?})", lifetime_ref);
// If we've already reported an error, just ignore `lifetime_ref`.
if let LifetimeName::Error = lifetime_ref.name {
return;
}
// Walk up the scope chain, tracking the number of fn scopes
// that we pass through, until we find a lifetime with the
// given name or we run out of scopes.
@ -1650,16 +1660,17 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
}
Scope::Binder { ref lifetimes, s, .. } => {
let name = match lifetime_ref.name {
LifetimeName::Param(param_name) => param_name,
match lifetime_ref.name {
LifetimeName::Param(param_name) => {
if let Some(&def) = lifetimes.get(&param_name.modern()) {
break Some(def.shifted(late_depth));
}
}
_ => bug!("expected LifetimeName::Param"),
};
if let Some(&def) = lifetimes.get(&name.modern()) {
break Some(def.shifted(late_depth));
} else {
late_depth += 1;
scope = s;
}
late_depth += 1;
scope = s;
}
Scope::Elision { s, .. } | Scope::ObjectLifetimeDefault { s, .. } => {
@ -1709,8 +1720,10 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
}
Region::Static
| Region::EarlyBound(_, _, LifetimeDefOrigin::Explicit)
| Region::LateBound(_, _, LifetimeDefOrigin::Explicit)
| Region::EarlyBound(_, _, LifetimeDefOrigin::ExplicitOrElided)
| Region::LateBound(_, _, LifetimeDefOrigin::ExplicitOrElided)
| Region::EarlyBound(_, _, LifetimeDefOrigin::Error)
| Region::LateBound(_, _, LifetimeDefOrigin::Error)
| Region::LateBoundAnon(..)
| Region::Free(..) => {}
}
@ -2339,14 +2352,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
match bound {
hir::GenericBound::Outlives(lt) => match lt.name {
hir::LifetimeName::Underscore => {
let mut err = struct_span_err!(
self.tcx.sess,
lt.span,
E0637,
"invalid lifetime bound name: `'_`"
);
err.span_label(lt.span, "`'_` is a reserved lifetime name");
err.emit();
self.tcx.sess.delay_span_bug(lt.span, "use of `'_` in illegal place, but not caught by lowering")
}
hir::LifetimeName::Static => {
self.insert_lifetime(lt, Region::Static);
@ -2364,6 +2370,9 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
hir::LifetimeName::Param(_) | hir::LifetimeName::Implicit => {
self.resolve_lifetime_ref(lt);
}
hir::LifetimeName::Error => {
// No need to do anything, error already reported.
}
}
_ => bug!(),
}

View File

@ -2074,6 +2074,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ExplicitOutlivesRequirements {
hir::GenericParamKind::Type { .. } => {
match param.name {
hir::ParamName::Fresh(_) => { continue; },
hir::ParamName::Error => { continue; },
hir::ParamName::Plain(name) => name.to_string()
}
}

View File

@ -563,6 +563,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
let lifetime = self.try_match_adt_and_generic_args(substs, needle_fr, args, search_stack)?;
match lifetime.name {
hir::LifetimeName::Param(_)
| hir::LifetimeName::Error
| hir::LifetimeName::Static
| hir::LifetimeName::Underscore => {
let region_name = self.synthesize_region_name(counter);

View File

@ -816,7 +816,10 @@ fn check_variances_for_type_defn<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
}
let param = &hir_generics.params[index];
report_bivariance(tcx, param.span, param.name.ident().name);
match param.name {
hir::ParamName::Error => { }
_ => report_bivariance(tcx, param.span, param.name.ident().name),
}
}
}

View File

@ -8,11 +8,11 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
struct Foo<'a: '_>(&'a u8); //~ ERROR invalid lifetime bound name: `'_`
fn foo<'a: '_>(_: &'a u8) {} //~ ERROR invalid lifetime bound name: `'_`
struct Foo<'a: '_>(&'a u8); //~ ERROR cannot be used here
fn foo<'a: '_>(_: &'a u8) {} //~ ERROR cannot be used here
struct Bar<'a>(&'a u8);
impl<'a: '_> Bar<'a> { //~ ERROR invalid lifetime bound name: `'_`
impl<'a: '_> Bar<'a> { //~ ERROR cannot be used here
fn bar() {}
}

View File

@ -1,19 +1,19 @@
error[E0637]: invalid lifetime bound name: `'_`
error[E0637]: `'_` cannot be used here
--> $DIR/E0637.rs:11:16
|
LL | struct Foo<'a: '_>(&'a u8); //~ ERROR invalid lifetime bound name: `'_`
LL | struct Foo<'a: '_>(&'a u8); //~ ERROR cannot be used here
| ^^ `'_` is a reserved lifetime name
error[E0637]: invalid lifetime bound name: `'_`
error[E0637]: `'_` cannot be used here
--> $DIR/E0637.rs:12:12
|
LL | fn foo<'a: '_>(_: &'a u8) {} //~ ERROR invalid lifetime bound name: `'_`
LL | fn foo<'a: '_>(_: &'a u8) {} //~ ERROR cannot be used here
| ^^ `'_` is a reserved lifetime name
error[E0637]: invalid lifetime bound name: `'_`
error[E0637]: `'_` cannot be used here
--> $DIR/E0637.rs:15:10
|
LL | impl<'a: '_> Bar<'a> { //~ ERROR invalid lifetime bound name: `'_`
LL | impl<'a: '_> Bar<'a> { //~ ERROR cannot be used here
| ^^ `'_` is a reserved lifetime name
error: aborting due to 3 previous errors

View File

@ -0,0 +1,46 @@
error[E0637]: `'_` cannot be used here
--> $DIR/in-binder.rs:12:6
|
LL | impl<'_> IceCube<'_> {}
| ^^ `'_` is a reserved lifetime name
error[E0637]: `'_` cannot be used here
--> $DIR/in-binder.rs:17:15
|
LL | struct Struct<'_> {
| ^^ `'_` is a reserved lifetime name
error[E0637]: `'_` cannot be used here
--> $DIR/in-binder.rs:23:11
|
LL | enum Enum<'_> {
| ^^ `'_` is a reserved lifetime name
error[E0637]: `'_` cannot be used here
--> $DIR/in-binder.rs:29:13
|
LL | union Union<'_> {
| ^^ `'_` is a reserved lifetime name
error[E0637]: `'_` cannot be used here
--> $DIR/in-binder.rs:35:13
|
LL | trait Trait<'_> {
| ^^ `'_` is a reserved lifetime name
error[E0637]: `'_` cannot be used here
--> $DIR/in-binder.rs:40:8
|
LL | fn foo<'_>() {
| ^^ `'_` is a reserved lifetime name
error[E0106]: missing lifetime specifier
--> $DIR/in-binder.rs:12:18
|
LL | impl<'_> IceCube<'_> {}
| ^^ expected lifetime parameter
error: aborting due to 7 previous errors
Some errors occurred: E0106, E0637.
For more information about an error, try `rustc --explain E0106`.

View File

@ -0,0 +1,39 @@
error[E0637]: `'_` cannot be used here
--> $DIR/in-binder.rs:12:6
|
LL | impl<'_> IceCube<'_> {}
| ^^ `'_` is a reserved lifetime name
error[E0637]: `'_` cannot be used here
--> $DIR/in-binder.rs:17:15
|
LL | struct Struct<'_> {
| ^^ `'_` is a reserved lifetime name
error[E0637]: `'_` cannot be used here
--> $DIR/in-binder.rs:23:11
|
LL | enum Enum<'_> {
| ^^ `'_` is a reserved lifetime name
error[E0637]: `'_` cannot be used here
--> $DIR/in-binder.rs:29:13
|
LL | union Union<'_> {
| ^^ `'_` is a reserved lifetime name
error[E0637]: `'_` cannot be used here
--> $DIR/in-binder.rs:35:13
|
LL | trait Trait<'_> {
| ^^ `'_` is a reserved lifetime name
error[E0637]: `'_` cannot be used here
--> $DIR/in-binder.rs:40:8
|
LL | fn foo<'_>() {
| ^^ `'_` is a reserved lifetime name
error: aborting due to 6 previous errors
For more information about this error, try `rustc --explain E0637`.

View File

@ -0,0 +1,45 @@
// Check that we error when `'_` appears as the name of a lifetime parameter.
//
// Regression test for #52098.
// revisions: Rust2015 Rust2018
//[Rust2018] edition:2018
struct IceCube<'a> {
v: Vec<&'a char>
}
impl<'_> IceCube<'_> {}
//[Rust2015]~^ ERROR
//[Rust2015]~| ERROR
//[Rust2018]~^^^ ERROR
struct Struct<'_> {
//[Rust2015]~^ ERROR
//[Rust2018]~^^ ERROR
v: Vec<&'static char>
}
enum Enum<'_> {
//[Rust2015]~^ ERROR
//[Rust2018]~^^ ERROR
Variant
}
union Union<'_> {
//[Rust2015]~^ ERROR
//[Rust2018]~^^ ERROR
a: u32
}
trait Trait<'_> {
//[Rust2015]~^ ERROR
//[Rust2018]~^^ ERROR
}
fn foo<'_>() {
//[Rust2015]~^ ERROR
//[Rust2018]~^^ ERROR
}
fn main() {}

View File

@ -0,0 +1,17 @@
// 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 `'_` used in structs/enums gives an error.
use std::fmt::Debug;
fn foo(x: &u32, y: &u32) -> &'_ u32 { loop { } } //~ ERROR
fn main() { }

View File

@ -0,0 +1,11 @@
error[E0106]: missing lifetime specifier
--> $DIR/in-fn-return-illegal.rs:15:30
|
LL | fn foo(x: &u32, y: &u32) -> &'_ u32 { loop { } } //~ ERROR
| ^^ expected lifetime parameter
|
= help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `x` or `y`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0106`.

View File

@ -0,0 +1,23 @@
// 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 `'_` used in structs/enums gives an error.
use std::fmt::Debug;
struct Foo {
x: &'_ u32, //~ ERROR
}
struct Bar {
Variant(&'_ u32), //~ ERROR
}
fn main() { }

View File

@ -0,0 +1,15 @@
error: expected `:`, found `(`
--> $DIR/in-struct.rs:20:12
|
LL | Variant(&'_ u32), //~ ERROR
| ^ expected `:`
error[E0106]: missing lifetime specifier
--> $DIR/in-struct.rs:16:9
|
LL | x: &'_ u32, //~ ERROR
| ^^ expected lifetime parameter
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0106`.

View File

@ -15,13 +15,13 @@ impl Foo<'_> { //~ ERROR missing lifetime specifier
fn x() {}
}
fn foo<'_> //~ ERROR invalid lifetime parameter name: `'_`
fn foo<'_> //~ ERROR cannot be used here
(_: Foo<'_>) {}
trait Meh<'a> {}
impl<'a> Meh<'a> for u8 {}
fn meh() -> Box<for<'_> Meh<'_>> //~ ERROR invalid lifetime parameter name: `'_`
fn meh() -> Box<for<'_> Meh<'_>> //~ ERROR cannot be used here
//~^ ERROR missing lifetime specifier
{
Box::new(5u8)

View File

@ -1,3 +1,15 @@
error[E0637]: `'_` cannot be used here
--> $DIR/underscore-lifetime-binders.rs:18:8
|
LL | fn foo<'_> //~ ERROR cannot be used here
| ^^ `'_` is a reserved lifetime name
error[E0637]: `'_` cannot be used here
--> $DIR/underscore-lifetime-binders.rs:24:21
|
LL | fn meh() -> Box<for<'_> Meh<'_>> //~ ERROR cannot be used here
| ^^ `'_` is a reserved lifetime name
error[E0106]: missing lifetime specifier
--> $DIR/underscore-lifetime-binders.rs:12:17
|
@ -10,22 +22,10 @@ error[E0106]: missing lifetime specifier
LL | impl Foo<'_> { //~ ERROR missing lifetime specifier
| ^^ expected lifetime parameter
error[E0262]: invalid lifetime parameter name: `'_`
--> $DIR/underscore-lifetime-binders.rs:18:8
|
LL | fn foo<'_> //~ ERROR invalid lifetime parameter name: `'_`
| ^^ '_ is a reserved lifetime name
error[E0262]: invalid lifetime parameter name: `'_`
--> $DIR/underscore-lifetime-binders.rs:24:21
|
LL | fn meh() -> Box<for<'_> Meh<'_>> //~ ERROR invalid lifetime parameter name: `'_`
| ^^ '_ is a reserved lifetime name
error[E0106]: missing lifetime specifier
--> $DIR/underscore-lifetime-binders.rs:24:29
|
LL | fn meh() -> Box<for<'_> Meh<'_>> //~ ERROR invalid lifetime parameter name: `'_`
LL | fn meh() -> Box<for<'_> Meh<'_>> //~ ERROR cannot be used here
| ^^ expected lifetime parameter
|
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
@ -41,5 +41,5 @@ LL | fn foo2(_: &'_ u8, y: &'_ u8) -> &'_ u8 { y } //~ ERROR missing lifetime sp
error: aborting due to 6 previous errors
Some errors occurred: E0106, E0262.
Some errors occurred: E0106, E0637.
For more information about an error, try `rustc --explain E0106`.

View File

@ -0,0 +1,8 @@
// Regression test to check that `'b: '_` gets an error, because it's
// basically useless.
//
// #54902
trait Foo<'a> {}
impl<'b: '_> Foo<'b> for i32 {}
fn main() { }

View File

@ -0,0 +1,9 @@
error[E0637]: `'_` cannot be used here
--> $DIR/underscore-outlives-bounds.rs:7:10
|
LL | impl<'b: '_> Foo<'b> for i32 {}
| ^^ `'_` is a reserved lifetime name
error: aborting due to previous error
For more information about this error, try `rustc --explain E0637`.

View File

@ -0,0 +1,18 @@
// revisions: rust2015 rust2018
//[rust2018] edition:2018
trait WithType<T> {}
trait WithRegion<'a> { }
struct Foo<T> {
t: T
}
impl<T> Foo<T>
where
T: WithType<&u32>
//[rust2015]~^ ERROR
//[rust2018]~^^ ERROR
{ }
fn main() {}

View File

@ -0,0 +1,9 @@
error[E0637]: `&` without an explicit lifetime name cannot be used here
--> $DIR/where-clause-inherent-impl-ampersand.rs:13:17
|
LL | T: WithType<&u32>
| ^ explicit lifetime name needed here
error: aborting due to previous error
For more information about this error, try `rustc --explain E0637`.

View File

@ -0,0 +1,9 @@
error[E0637]: `&` without an explicit lifetime name cannot be used here
--> $DIR/where-clause-inherent-impl-ampersand.rs:13:17
|
LL | T: WithType<&u32>
| ^ explicit lifetime name needed here
error: aborting due to previous error
For more information about this error, try `rustc --explain E0637`.

View File

@ -0,0 +1,18 @@
// revisions: rust2015 rust2018
//[rust2018] edition:2018
trait WithType<T> {}
trait WithRegion<'a> { }
struct Foo<T> {
t: T
}
impl<T> Foo<T>
where
T: WithRegion<'_>
//[rust2015]~^ ERROR
//[rust2018]~^^ ERROR
{ }
fn main() {}

View File

@ -0,0 +1,9 @@
error[E0637]: `'_` cannot be used here
--> $DIR/where-clause-inherent-impl-underscore.rs:13:19
|
LL | T: WithRegion<'_>
| ^^ `'_` is a reserved lifetime name
error: aborting due to previous error
For more information about this error, try `rustc --explain E0637`.

View File

@ -0,0 +1,9 @@
error[E0637]: `'_` cannot be used here
--> $DIR/where-clause-inherent-impl-underscore.rs:13:19
|
LL | T: WithRegion<'_>
| ^^ `'_` is a reserved lifetime name
error: aborting due to previous error
For more information about this error, try `rustc --explain E0637`.

View File

@ -0,0 +1,16 @@
// revisions: rust2015 rust2018
//[rust2018] edition:2018
trait WithType<T> {}
trait WithRegion<'a> { }
trait Foo { }
impl<T> Foo for Vec<T>
where
T: WithType<&u32>
//[rust2015]~^ ERROR
//[rust2018]~^^ ERROR
{ }
fn main() {}

View File

@ -0,0 +1,9 @@
error[E0637]: `&` without an explicit lifetime name cannot be used here
--> $DIR/where-clause-trait-impl-region.rs:11:17
|
LL | T: WithType<&u32>
| ^ explicit lifetime name needed here
error: aborting due to previous error
For more information about this error, try `rustc --explain E0637`.

View File

@ -0,0 +1,9 @@
error[E0637]: `&` without an explicit lifetime name cannot be used here
--> $DIR/where-clause-trait-impl-region.rs:11:17
|
LL | T: WithType<&u32>
| ^ explicit lifetime name needed here
error: aborting due to previous error
For more information about this error, try `rustc --explain E0637`.

View File

@ -0,0 +1,16 @@
// revisions: rust2015 rust2018
//[rust2018] edition:2018
trait WithType<T> {}
trait WithRegion<'a> { }
trait Foo { }
impl<T> Foo for Vec<T>
where
T: WithRegion<'_>
//[rust2015]~^ ERROR
//[rust2018]~^^ ERROR
{ }
fn main() {}

View File

@ -0,0 +1,9 @@
error[E0637]: `'_` cannot be used here
--> $DIR/where-clause-trait-impl-underscore.rs:11:19
|
LL | T: WithRegion<'_>
| ^^ `'_` is a reserved lifetime name
error: aborting due to previous error
For more information about this error, try `rustc --explain E0637`.

View File

@ -0,0 +1,9 @@
error[E0637]: `'_` cannot be used here
--> $DIR/where-clause-trait-impl-underscore.rs:11:19
|
LL | T: WithRegion<'_>
| ^^ `'_` is a reserved lifetime name
error: aborting due to previous error
For more information about this error, try `rustc --explain E0637`.

View File

@ -0,0 +1,3 @@
trait Foo<'a> {}
impl<'b: '_> Foo<'b> for i32 {}
fn main() { }

View File

@ -0,0 +1,9 @@
error[E0637]: `'_` cannot be used here
--> $DIR/where-clauses.rs:2:10
|
LL | impl<'b: '_> Foo<'b> for i32 {}
| ^^ `'_` is a reserved lifetime name
error: aborting due to previous error
For more information about this error, try `rustc --explain E0637`.