address review comments + better tests
This commit is contained in:
parent
83e653920d
commit
1eba6c404f
6 changed files with 415 additions and 108 deletions
|
@ -1316,6 +1316,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
param.id,
|
||||
¶m.kind,
|
||||
¶m.bounds,
|
||||
param.colon_span,
|
||||
generics.span,
|
||||
itctx,
|
||||
PredicateOrigin::GenericParam,
|
||||
)
|
||||
|
@ -1365,6 +1367,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
id: NodeId,
|
||||
kind: &GenericParamKind,
|
||||
bounds: &[GenericBound],
|
||||
colon_span: Option<Span>,
|
||||
parent_span: Span,
|
||||
itctx: &ImplTraitContext,
|
||||
origin: PredicateOrigin,
|
||||
) -> Option<hir::WherePredicate<'hir>> {
|
||||
|
@ -1377,8 +1381,17 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
|
||||
let ident = self.lower_ident(ident);
|
||||
let param_span = ident.span;
|
||||
let span =
|
||||
bounds.iter().fold(param_span.shrink_to_hi(), |span, bound| span.to(bound.span()));
|
||||
|
||||
// Reconstruct the span of the entire predicate from the individual generic bounds.
|
||||
let span_start = colon_span.unwrap_or_else(|| param_span.shrink_to_hi());
|
||||
let span = bounds.iter().fold(span_start, |span_accum, bound| {
|
||||
match bound.span().find_ancestor_inside(parent_span) {
|
||||
Some(bound_span) => span_accum.to(bound_span),
|
||||
None => span_accum,
|
||||
}
|
||||
});
|
||||
let span = self.lower_span(span);
|
||||
|
||||
match kind {
|
||||
GenericParamKind::Const { .. } => None,
|
||||
GenericParamKind::Type { .. } => {
|
||||
|
|
|
@ -2247,6 +2247,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
) -> (hir::GenericParam<'hir>, Option<hir::WherePredicate<'hir>>, hir::TyKind<'hir>) {
|
||||
// Add a definition for the in-band `Param`.
|
||||
let def_id = self.local_def_id(node_id);
|
||||
let span = self.lower_span(span);
|
||||
|
||||
// Set the name to `impl Bound1 + Bound2`.
|
||||
let param = hir::GenericParam {
|
||||
|
@ -2254,7 +2255,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
def_id,
|
||||
name: ParamName::Plain(self.lower_ident(ident)),
|
||||
pure_wrt_drop: false,
|
||||
span: self.lower_span(span),
|
||||
span,
|
||||
kind: hir::GenericParamKind::Type { default: None, synthetic: true },
|
||||
colon_span: None,
|
||||
};
|
||||
|
@ -2264,6 +2265,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
node_id,
|
||||
&GenericParamKind::Type { default: None },
|
||||
bounds,
|
||||
/* colon_span */ None,
|
||||
span,
|
||||
&ImplTraitContext::Universal,
|
||||
hir::PredicateOrigin::ImplTrait,
|
||||
);
|
||||
|
@ -2273,7 +2276,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
let ty = hir::TyKind::Path(hir::QPath::Resolved(
|
||||
None,
|
||||
self.arena.alloc(hir::Path {
|
||||
span: self.lower_span(span),
|
||||
span,
|
||||
res,
|
||||
segments:
|
||||
arena_vec![self; hir::PathSegment::new(self.lower_ident(ident), hir_id, res)],
|
||||
|
|
|
@ -55,7 +55,7 @@ use rustc_session::lint::{BuiltinLintDiagnostics, FutureIncompatibilityReason};
|
|||
use rustc_span::edition::Edition;
|
||||
use rustc_span::source_map::Spanned;
|
||||
use rustc_span::symbol::{kw, sym, Ident, Symbol};
|
||||
use rustc_span::{BytePos, InnerSpan, Span, SyntaxContext};
|
||||
use rustc_span::{BytePos, InnerSpan, Span};
|
||||
use rustc_target::abi::{Abi, VariantIdx};
|
||||
use rustc_trait_selection::infer::{InferCtxtExt, TyCtxtInferExt};
|
||||
use rustc_trait_selection::traits::{self, misc::can_type_implement_copy, EvaluationResult};
|
||||
|
@ -2184,7 +2184,7 @@ impl ExplicitOutlivesRequirements {
|
|||
tcx: TyCtxt<'tcx>,
|
||||
bounds: &hir::GenericBounds<'_>,
|
||||
inferred_outlives: &[ty::Region<'tcx>],
|
||||
span_cx: SyntaxContext,
|
||||
predicate_span: Span,
|
||||
) -> Vec<(usize, Span)> {
|
||||
use rustc_middle::middle::resolve_lifetime::Region;
|
||||
|
||||
|
@ -2207,8 +2207,8 @@ impl ExplicitOutlivesRequirements {
|
|||
return None;
|
||||
}
|
||||
|
||||
let span = bound.span();
|
||||
if span.ctxt() != span_cx || in_external_macro(tcx.sess, span) {
|
||||
let span = bound.span().find_ancestor_inside(predicate_span)?;
|
||||
if in_external_macro(tcx.sess, span) {
|
||||
return None;
|
||||
}
|
||||
|
||||
|
@ -2279,9 +2279,9 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements {
|
|||
use rustc_middle::middle::resolve_lifetime::Region;
|
||||
|
||||
let def_id = item.owner_id.def_id;
|
||||
if let hir::ItemKind::Struct(_, ref hir_generics)
|
||||
| hir::ItemKind::Enum(_, ref hir_generics)
|
||||
| hir::ItemKind::Union(_, ref hir_generics) = item.kind
|
||||
if let hir::ItemKind::Struct(_, hir_generics)
|
||||
| hir::ItemKind::Enum(_, hir_generics)
|
||||
| hir::ItemKind::Union(_, hir_generics) = item.kind
|
||||
{
|
||||
let inferred_outlives = cx.tcx.inferred_outlives_of(def_id);
|
||||
if inferred_outlives.is_empty() {
|
||||
|
@ -2296,47 +2296,48 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements {
|
|||
let mut dropped_predicate_count = 0;
|
||||
let num_predicates = hir_generics.predicates.len();
|
||||
for (i, where_predicate) in hir_generics.predicates.iter().enumerate() {
|
||||
let (relevant_lifetimes, bounds, span, in_where_clause) = match where_predicate {
|
||||
hir::WherePredicate::RegionPredicate(predicate) => {
|
||||
if let Some(Region::EarlyBound(region_def_id)) =
|
||||
cx.tcx.named_region(predicate.lifetime.hir_id)
|
||||
{
|
||||
(
|
||||
Self::lifetimes_outliving_lifetime(
|
||||
inferred_outlives,
|
||||
region_def_id,
|
||||
),
|
||||
&predicate.bounds,
|
||||
predicate.span,
|
||||
predicate.in_where_clause,
|
||||
)
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
hir::WherePredicate::BoundPredicate(predicate) => {
|
||||
// FIXME we can also infer bounds on associated types,
|
||||
// and should check for them here.
|
||||
match predicate.bounded_ty.kind {
|
||||
hir::TyKind::Path(hir::QPath::Resolved(None, path)) => {
|
||||
let Res::Def(DefKind::TyParam, def_id) = path.res else {
|
||||
continue;
|
||||
};
|
||||
let index = ty_generics.param_def_id_to_index[&def_id];
|
||||
let (relevant_lifetimes, bounds, predicate_span, in_where_clause) =
|
||||
match where_predicate {
|
||||
hir::WherePredicate::RegionPredicate(predicate) => {
|
||||
if let Some(Region::EarlyBound(region_def_id)) =
|
||||
cx.tcx.named_region(predicate.lifetime.hir_id)
|
||||
{
|
||||
(
|
||||
Self::lifetimes_outliving_type(inferred_outlives, index),
|
||||
Self::lifetimes_outliving_lifetime(
|
||||
inferred_outlives,
|
||||
region_def_id,
|
||||
),
|
||||
&predicate.bounds,
|
||||
predicate.span,
|
||||
predicate.origin == PredicateOrigin::WhereClause,
|
||||
predicate.in_where_clause,
|
||||
)
|
||||
}
|
||||
_ => {
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => continue,
|
||||
};
|
||||
hir::WherePredicate::BoundPredicate(predicate) => {
|
||||
// FIXME we can also infer bounds on associated types,
|
||||
// and should check for them here.
|
||||
match predicate.bounded_ty.kind {
|
||||
hir::TyKind::Path(hir::QPath::Resolved(None, path)) => {
|
||||
let Res::Def(DefKind::TyParam, def_id) = path.res else {
|
||||
continue;
|
||||
};
|
||||
let index = ty_generics.param_def_id_to_index[&def_id];
|
||||
(
|
||||
Self::lifetimes_outliving_type(inferred_outlives, index),
|
||||
&predicate.bounds,
|
||||
predicate.span,
|
||||
predicate.origin == PredicateOrigin::WhereClause,
|
||||
)
|
||||
}
|
||||
_ => {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => continue,
|
||||
};
|
||||
if relevant_lifetimes.is_empty() {
|
||||
continue;
|
||||
}
|
||||
|
@ -2345,7 +2346,7 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements {
|
|||
cx.tcx,
|
||||
bounds,
|
||||
&relevant_lifetimes,
|
||||
span.ctxt(),
|
||||
predicate_span,
|
||||
);
|
||||
bound_count += bound_spans.len();
|
||||
|
||||
|
@ -2355,15 +2356,15 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements {
|
|||
}
|
||||
|
||||
if drop_predicate && !in_where_clause {
|
||||
lint_spans.push(span);
|
||||
lint_spans.push(predicate_span);
|
||||
} else if drop_predicate && i + 1 < num_predicates {
|
||||
// If all the bounds on a predicate were inferable and there are
|
||||
// further predicates, we want to eat the trailing comma.
|
||||
let next_predicate_span = hir_generics.predicates[i + 1].span();
|
||||
where_lint_spans.push(span.to(next_predicate_span.shrink_to_lo()));
|
||||
where_lint_spans.push(predicate_span.to(next_predicate_span.shrink_to_lo()));
|
||||
} else {
|
||||
where_lint_spans.extend(self.consolidate_outlives_bound_spans(
|
||||
span.shrink_to_lo(),
|
||||
predicate_span.shrink_to_lo(),
|
||||
bounds,
|
||||
bound_spans,
|
||||
));
|
||||
|
@ -2384,12 +2385,26 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements {
|
|||
} else {
|
||||
hir_generics.span.shrink_to_hi().to(where_span)
|
||||
};
|
||||
lint_spans.push(full_where_span);
|
||||
|
||||
// Due to macro expansions, the `full_where_span` might not actually contain all predicates.
|
||||
if where_lint_spans.iter().all(|&sp| full_where_span.contains(sp)) {
|
||||
lint_spans.push(full_where_span);
|
||||
} else {
|
||||
lint_spans.extend(where_lint_spans);
|
||||
}
|
||||
} else {
|
||||
lint_spans.extend(where_lint_spans);
|
||||
}
|
||||
|
||||
if !lint_spans.is_empty() {
|
||||
// Do not automatically delete outlives requirements from macros.
|
||||
let applicability = if lint_spans.iter().all(|sp| sp.can_be_used_for_suggestions())
|
||||
{
|
||||
Applicability::MachineApplicable
|
||||
} else {
|
||||
Applicability::MaybeIncorrect
|
||||
};
|
||||
|
||||
cx.struct_span_lint(
|
||||
EXPLICIT_OUTLIVES_REQUIREMENTS,
|
||||
lint_spans.clone(),
|
||||
|
@ -2397,11 +2412,8 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements {
|
|||
|lint| {
|
||||
lint.set_arg("count", bound_count).multipart_suggestion(
|
||||
fluent::suggestion,
|
||||
lint_spans
|
||||
.into_iter()
|
||||
.map(|span| (span, String::new()))
|
||||
.collect::<Vec<_>>(),
|
||||
Applicability::MachineApplicable,
|
||||
lint_spans.into_iter().map(|span| (span, String::new())).collect(),
|
||||
applicability,
|
||||
)
|
||||
},
|
||||
);
|
||||
|
|
137
src/test/ui/rust-2018/edition-lint-infer-outlives-macro.fixed
Normal file
137
src/test/ui/rust-2018/edition-lint-infer-outlives-macro.fixed
Normal file
|
@ -0,0 +1,137 @@
|
|||
// edition:2018
|
||||
// aux-build:edition-lint-infer-outlives-macro.rs
|
||||
// run-rustfix
|
||||
|
||||
#![deny(explicit_outlives_requirements)]
|
||||
#![allow(dead_code)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate edition_lint_infer_outlives_macro;
|
||||
|
||||
// Test that the lint does not fire if the predicate is from the local crate,
|
||||
// but all the bounds are from an external macro.
|
||||
macro_rules! make_foo {
|
||||
($a:tt) => {
|
||||
struct Foo<$a, 'b: $a> {
|
||||
foo: &$a &'b (),
|
||||
}
|
||||
|
||||
struct FooWhere<$a, 'b> where 'b: $a {
|
||||
foo: &$a &'b (),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gimme_a! {make_foo!}
|
||||
|
||||
struct Bar<'a, 'b> {
|
||||
//~^ ERROR: outlives requirements can be inferred
|
||||
bar: &'a &'b (),
|
||||
}
|
||||
|
||||
struct BarWhere<'a, 'b> {
|
||||
//~^ ERROR: outlives requirements can be inferred
|
||||
bar: &'a &'b (),
|
||||
}
|
||||
|
||||
// Test that the lint *does* fire if the predicate is contained in a local macro.
|
||||
mod everything_inside {
|
||||
macro_rules! m {
|
||||
('b: 'a) => {
|
||||
struct Foo<'a, 'b>(&'a &'b ());
|
||||
//~^ ERROR: outlives requirements can be inferred
|
||||
struct Bar<'a, 'b>(&'a &'b ()) ;
|
||||
//~^ ERROR: outlives requirements can be inferred
|
||||
struct Baz<'a, 'b>(&'a &'b ()) where (): Sized, ;
|
||||
//~^ ERROR: outlives requirements can be inferred
|
||||
};
|
||||
}
|
||||
m!('b: 'a);
|
||||
}
|
||||
|
||||
mod inner_lifetime_outside_colon_inside {
|
||||
macro_rules! m {
|
||||
($b:lifetime: 'a) => {
|
||||
struct Foo<'a, $b>(&'a &$b ());
|
||||
//~^ ERROR: outlives requirements can be inferred
|
||||
struct Bar<'a, $b>(&'a &$b ()) ;
|
||||
//~^ ERROR: outlives requirements can be inferred
|
||||
struct Baz<'a, $b>(&'a &$b ()) where (): Sized, ;
|
||||
//~^ ERROR: outlives requirements can be inferred
|
||||
}
|
||||
}
|
||||
m!('b: 'a);
|
||||
}
|
||||
|
||||
mod outer_lifetime_outside_colon_inside {
|
||||
macro_rules! m {
|
||||
('b: $a:lifetime) => {
|
||||
struct Foo<$a, 'b: $a>(&$a &'b ());
|
||||
struct Bar<$a, 'b>(&$a &'b ()) where 'b: $a;
|
||||
struct Baz<$a, 'b>(&$a &'b ()) where (): Sized, 'b: $a;
|
||||
}
|
||||
}
|
||||
m!('b: 'a);
|
||||
}
|
||||
|
||||
mod both_lifetimes_outside_colon_inside {
|
||||
macro_rules! m {
|
||||
($b:lifetime: $a:lifetime) => {
|
||||
struct Foo<$a, $b: $a>(&$a &$b ());
|
||||
struct Bar<$a, $b>(&$a &$b ()) where $b: $a;
|
||||
struct Baz<$a, $b>(&$a &$b ()) where (): Sized, $b: $a;
|
||||
}
|
||||
}
|
||||
m!('b: 'a);
|
||||
}
|
||||
|
||||
mod everything_outside {
|
||||
macro_rules! m {
|
||||
($b:lifetime $colon:tt $a:lifetime) => {
|
||||
struct Foo<$a, $b $colon $a>(&$a &$b ());
|
||||
struct Bar<$a, $b>(&$a &$b ()) where $b $colon $a;
|
||||
struct Baz<$a, $b>(&$a &$b ()) where (): Sized, $b $colon $a;
|
||||
}
|
||||
}
|
||||
m!('b: 'a);
|
||||
}
|
||||
|
||||
mod everything_outside_with_tt_inner {
|
||||
macro_rules! m {
|
||||
($b:tt $colon:tt $a:lifetime) => {
|
||||
struct Foo<$a, $b $colon $a>(&$a &$b ());
|
||||
struct Bar<$a, $b>(&$a &$b ()) where $b $colon $a;
|
||||
struct Baz<$a, $b>(&$a &$b ()) where (): Sized, $b $colon $a;
|
||||
}
|
||||
}
|
||||
m!('b: 'a);
|
||||
}
|
||||
|
||||
// FIXME: These should be consistent.
|
||||
mod everything_outside_with_tt_outer {
|
||||
macro_rules! m {
|
||||
($b:lifetime $colon:tt $a:tt) => {
|
||||
struct Foo<$a, $b >(&$a &$b ());
|
||||
//~^ ERROR: outlives requirements can be inferred
|
||||
struct Bar<$a, $b>(&$a &$b ()) where $b $colon $a;
|
||||
struct Baz<$a, $b>(&$a &$b ()) where (): Sized, $b $colon $a;
|
||||
}
|
||||
}
|
||||
m!('b: 'a);
|
||||
}
|
||||
|
||||
mod everything_outside_with_tt_both {
|
||||
macro_rules! m {
|
||||
($b:tt $colon:tt $a:tt) => {
|
||||
struct Foo<$a, $b >(&$a &$b ());
|
||||
//~^ ERROR: outlives requirements can be inferred
|
||||
struct Bar<$a, $b>(&$a &$b ()) where ;
|
||||
//~^ ERROR: outlives requirements can be inferred
|
||||
struct Baz<$a, $b>(&$a &$b ()) where (): Sized, ;
|
||||
//~^ ERROR: outlives requirements can be inferred
|
||||
}
|
||||
}
|
||||
m!('b: 'a);
|
||||
}
|
||||
|
||||
fn main() {}
|
|
@ -1,25 +1,25 @@
|
|||
// edition:2018
|
||||
// aux-build:edition-lint-infer-outlives-macro.rs
|
||||
|
||||
// Test that the lint does not fire if the where predicate
|
||||
// is from the local crate, but all the bounds are from an
|
||||
// external macro.
|
||||
// run-rustfix
|
||||
|
||||
#![deny(explicit_outlives_requirements)]
|
||||
#![allow(dead_code)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate edition_lint_infer_outlives_macro;
|
||||
|
||||
// Test that the lint does not fire if the predicate is from the local crate,
|
||||
// but all the bounds are from an external macro.
|
||||
macro_rules! make_foo {
|
||||
($a:tt) => {
|
||||
struct Foo<$a, 'b> where 'b: $a {
|
||||
struct Foo<$a, 'b: $a> {
|
||||
foo: &$a &'b (),
|
||||
}
|
||||
|
||||
struct Foo2<$a, 'b: $a> {
|
||||
struct FooWhere<$a, 'b> where 'b: $a {
|
||||
foo: &$a &'b (),
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
gimme_a! {make_foo!}
|
||||
|
@ -29,41 +29,109 @@ struct Bar<'a, 'b: 'a> {
|
|||
bar: &'a &'b (),
|
||||
}
|
||||
|
||||
macro_rules! make_quux {
|
||||
() => {
|
||||
struct Quux<'a, 'b> where 'b: 'a {
|
||||
//~^ ERROR: outlives requirements can be inferred
|
||||
baz: &'a &'b (),
|
||||
}
|
||||
|
||||
struct Quux2<'a, 'b: 'a> {
|
||||
//~^ ERROR: outlives requirements can be inferred
|
||||
baz: &'a &'b (),
|
||||
}
|
||||
};
|
||||
struct BarWhere<'a, 'b> where 'b: 'a {
|
||||
//~^ ERROR: outlives requirements can be inferred
|
||||
bar: &'a &'b (),
|
||||
}
|
||||
|
||||
make_quux!{}
|
||||
|
||||
macro_rules! make_baz {
|
||||
() => {
|
||||
make_baz!{ 'a }
|
||||
};
|
||||
($a:lifetime) => {
|
||||
struct Baz<$a, 'b> where 'b: $a {
|
||||
baz: &$a &'b (),
|
||||
}
|
||||
|
||||
struct Baz2<$a, 'b: $a> {
|
||||
baz: &$a &'b (),
|
||||
}
|
||||
};
|
||||
// Test that the lint *does* fire if the predicate is contained in a local macro.
|
||||
mod everything_inside {
|
||||
macro_rules! m {
|
||||
('b: 'a) => {
|
||||
struct Foo<'a, 'b: 'a>(&'a &'b ());
|
||||
//~^ ERROR: outlives requirements can be inferred
|
||||
struct Bar<'a, 'b>(&'a &'b ()) where 'b: 'a;
|
||||
//~^ ERROR: outlives requirements can be inferred
|
||||
struct Baz<'a, 'b>(&'a &'b ()) where (): Sized, 'b: 'a;
|
||||
//~^ ERROR: outlives requirements can be inferred
|
||||
};
|
||||
}
|
||||
m!('b: 'a);
|
||||
}
|
||||
|
||||
make_baz!{ 'a }
|
||||
mod inner_lifetime_outside_colon_inside {
|
||||
macro_rules! m {
|
||||
($b:lifetime: 'a) => {
|
||||
struct Foo<'a, $b: 'a>(&'a &$b ());
|
||||
//~^ ERROR: outlives requirements can be inferred
|
||||
struct Bar<'a, $b>(&'a &$b ()) where $b: 'a;
|
||||
//~^ ERROR: outlives requirements can be inferred
|
||||
struct Baz<'a, $b>(&'a &$b ()) where (): Sized, $b: 'a;
|
||||
//~^ ERROR: outlives requirements can be inferred
|
||||
}
|
||||
}
|
||||
m!('b: 'a);
|
||||
}
|
||||
|
||||
mod baz {
|
||||
make_baz!{}
|
||||
mod outer_lifetime_outside_colon_inside {
|
||||
macro_rules! m {
|
||||
('b: $a:lifetime) => {
|
||||
struct Foo<$a, 'b: $a>(&$a &'b ());
|
||||
struct Bar<$a, 'b>(&$a &'b ()) where 'b: $a;
|
||||
struct Baz<$a, 'b>(&$a &'b ()) where (): Sized, 'b: $a;
|
||||
}
|
||||
}
|
||||
m!('b: 'a);
|
||||
}
|
||||
|
||||
mod both_lifetimes_outside_colon_inside {
|
||||
macro_rules! m {
|
||||
($b:lifetime: $a:lifetime) => {
|
||||
struct Foo<$a, $b: $a>(&$a &$b ());
|
||||
struct Bar<$a, $b>(&$a &$b ()) where $b: $a;
|
||||
struct Baz<$a, $b>(&$a &$b ()) where (): Sized, $b: $a;
|
||||
}
|
||||
}
|
||||
m!('b: 'a);
|
||||
}
|
||||
|
||||
mod everything_outside {
|
||||
macro_rules! m {
|
||||
($b:lifetime $colon:tt $a:lifetime) => {
|
||||
struct Foo<$a, $b $colon $a>(&$a &$b ());
|
||||
struct Bar<$a, $b>(&$a &$b ()) where $b $colon $a;
|
||||
struct Baz<$a, $b>(&$a &$b ()) where (): Sized, $b $colon $a;
|
||||
}
|
||||
}
|
||||
m!('b: 'a);
|
||||
}
|
||||
|
||||
mod everything_outside_with_tt_inner {
|
||||
macro_rules! m {
|
||||
($b:tt $colon:tt $a:lifetime) => {
|
||||
struct Foo<$a, $b $colon $a>(&$a &$b ());
|
||||
struct Bar<$a, $b>(&$a &$b ()) where $b $colon $a;
|
||||
struct Baz<$a, $b>(&$a &$b ()) where (): Sized, $b $colon $a;
|
||||
}
|
||||
}
|
||||
m!('b: 'a);
|
||||
}
|
||||
|
||||
// FIXME: These should be consistent.
|
||||
mod everything_outside_with_tt_outer {
|
||||
macro_rules! m {
|
||||
($b:lifetime $colon:tt $a:tt) => {
|
||||
struct Foo<$a, $b $colon $a>(&$a &$b ());
|
||||
//~^ ERROR: outlives requirements can be inferred
|
||||
struct Bar<$a, $b>(&$a &$b ()) where $b $colon $a;
|
||||
struct Baz<$a, $b>(&$a &$b ()) where (): Sized, $b $colon $a;
|
||||
}
|
||||
}
|
||||
m!('b: 'a);
|
||||
}
|
||||
|
||||
mod everything_outside_with_tt_both {
|
||||
macro_rules! m {
|
||||
($b:tt $colon:tt $a:tt) => {
|
||||
struct Foo<$a, $b $colon $a>(&$a &$b ());
|
||||
//~^ ERROR: outlives requirements can be inferred
|
||||
struct Bar<$a, $b>(&$a &$b ()) where $b $colon $a;
|
||||
//~^ ERROR: outlives requirements can be inferred
|
||||
struct Baz<$a, $b>(&$a &$b ()) where (): Sized, $b $colon $a;
|
||||
//~^ ERROR: outlives requirements can be inferred
|
||||
}
|
||||
}
|
||||
m!('b: 'a);
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -5,32 +5,106 @@ LL | struct Bar<'a, 'b: 'a> {
|
|||
| ^^^^ help: remove this bound
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/edition-lint-infer-outlives-macro.rs:8:9
|
||||
--> $DIR/edition-lint-infer-outlives-macro.rs:5:9
|
||||
|
|
||||
LL | #![deny(explicit_outlives_requirements)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: outlives requirements can be inferred
|
||||
--> $DIR/edition-lint-infer-outlives-macro.rs:34:28
|
||||
--> $DIR/edition-lint-infer-outlives-macro.rs:32:24
|
||||
|
|
||||
LL | struct Quux<'a, 'b> where 'b: 'a {
|
||||
| ^^^^^^^^^^^^^ help: remove this bound
|
||||
...
|
||||
LL | make_quux!{}
|
||||
| ------------ in this macro invocation
|
||||
|
|
||||
= note: this error originates in the macro `make_quux` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
LL | struct BarWhere<'a, 'b> where 'b: 'a {
|
||||
| ^^^^^^^^^^^^^ help: remove this bound
|
||||
|
||||
error: outlives requirements can be inferred
|
||||
--> $DIR/edition-lint-infer-outlives-macro.rs:39:28
|
||||
--> $DIR/edition-lint-infer-outlives-macro.rs:41:30
|
||||
|
|
||||
LL | struct Quux2<'a, 'b: 'a> {
|
||||
| ^^^^ help: remove this bound
|
||||
LL | struct Foo<'a, 'b: 'a>(&'a &'b ());
|
||||
| ^^^^ help: remove this bound
|
||||
...
|
||||
LL | make_quux!{}
|
||||
| ------------ in this macro invocation
|
||||
LL | m!('b: 'a);
|
||||
| ---------- in this macro invocation
|
||||
|
|
||||
= note: this error originates in the macro `make_quux` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
= note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
error: outlives requirements can be inferred
|
||||
--> $DIR/edition-lint-infer-outlives-macro.rs:43:44
|
||||
|
|
||||
LL | struct Bar<'a, 'b>(&'a &'b ()) where 'b: 'a;
|
||||
| ^^^^^^^^^^^^ help: remove this bound
|
||||
...
|
||||
LL | m!('b: 'a);
|
||||
| ---------- in this macro invocation
|
||||
|
|
||||
= note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: outlives requirements can be inferred
|
||||
--> $DIR/edition-lint-infer-outlives-macro.rs:45:61
|
||||
|
|
||||
LL | struct Baz<'a, 'b>(&'a &'b ()) where (): Sized, 'b: 'a;
|
||||
| ^^^^^^ help: remove this bound
|
||||
...
|
||||
LL | m!('b: 'a);
|
||||
| ---------- in this macro invocation
|
||||
|
|
||||
= note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: outlives requirements can be inferred
|
||||
--> $DIR/edition-lint-infer-outlives-macro.rs:55:30
|
||||
|
|
||||
LL | struct Foo<'a, $b: 'a>(&'a &$b ());
|
||||
| ^^^^ help: remove this bound
|
||||
...
|
||||
LL | m!('b: 'a);
|
||||
| ---------- in this macro invocation
|
||||
|
|
||||
= note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: outlives requirements can be inferred
|
||||
--> $DIR/edition-lint-infer-outlives-macro.rs:57:44
|
||||
|
|
||||
LL | struct Bar<'a, $b>(&'a &$b ()) where $b: 'a;
|
||||
| ^^^^^^^^^^^^ help: remove this bound
|
||||
...
|
||||
LL | m!('b: 'a);
|
||||
| ---------- in this macro invocation
|
||||
|
|
||||
= note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: outlives requirements can be inferred
|
||||
--> $DIR/edition-lint-infer-outlives-macro.rs:59:61
|
||||
|
|
||||
LL | struct Baz<'a, $b>(&'a &$b ()) where (): Sized, $b: 'a;
|
||||
| ^^^^^^ help: remove this bound
|
||||
...
|
||||
LL | m!('b: 'a);
|
||||
| ---------- in this macro invocation
|
||||
|
|
||||
= note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: outlives requirements can be inferred
|
||||
--> $DIR/edition-lint-infer-outlives-macro.rs:114:31
|
||||
|
|
||||
LL | struct Foo<$a, $b $colon $a>(&$a &$b ());
|
||||
| ^^^^^^^^^ help: remove this bound
|
||||
|
||||
error: outlives requirements can be inferred
|
||||
--> $DIR/edition-lint-infer-outlives-macro.rs:126:31
|
||||
|
|
||||
LL | struct Foo<$a, $b $colon $a>(&$a &$b ());
|
||||
| ^^^^^^^^^ help: remove this bound
|
||||
|
||||
error: outlives requirements can be inferred
|
||||
--> $DIR/edition-lint-infer-outlives-macro.rs:128:50
|
||||
|
|
||||
LL | struct Bar<$a, $b>(&$a &$b ()) where $b $colon $a;
|
||||
| ^^^^^^^^^^^^ help: remove this bound
|
||||
|
||||
error: outlives requirements can be inferred
|
||||
--> $DIR/edition-lint-infer-outlives-macro.rs:130:61
|
||||
|
|
||||
LL | struct Baz<$a, $b>(&$a &$b ()) where (): Sized, $b $colon $a;
|
||||
| ^^^^^^^^^^^^ help: remove this bound
|
||||
|
||||
error: aborting due to 12 previous errors
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue