Auto merge of #106916 - lukas-code:overlapping-substs, r=estebank
Remove overlapping parts of multipart suggestions This PR adds a debug assertion that the parts of a single substitution cannot overlap, fixes a overlapping substitution from the testsuite, and fixes https://github.com/rust-lang/rust/issues/106870. Note that a single suggestion can still have multiple overlapping substitutions / possible edits, we just don't suggest overlapping replacements in a single edit anymore. I've also included a fix for an unrelated bug where rustfix for `explicit_outlives_requirements` would produce multiple trailing commas for a where clause.
This commit is contained in:
commit
d8da513668
13 changed files with 214 additions and 62 deletions
|
@ -629,19 +629,27 @@ impl Diagnostic {
|
||||||
applicability: Applicability,
|
applicability: Applicability,
|
||||||
style: SuggestionStyle,
|
style: SuggestionStyle,
|
||||||
) -> &mut Self {
|
) -> &mut Self {
|
||||||
assert!(!suggestion.is_empty());
|
let mut parts = suggestion
|
||||||
debug_assert!(
|
.into_iter()
|
||||||
!(suggestion.iter().any(|(sp, text)| sp.is_empty() && text.is_empty())),
|
.map(|(span, snippet)| SubstitutionPart { snippet, span })
|
||||||
"Span must not be empty and have no suggestion"
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
parts.sort_unstable_by_key(|part| part.span);
|
||||||
|
|
||||||
|
assert!(!parts.is_empty());
|
||||||
|
debug_assert_eq!(
|
||||||
|
parts.iter().find(|part| part.span.is_empty() && part.snippet.is_empty()),
|
||||||
|
None,
|
||||||
|
"Span must not be empty and have no suggestion",
|
||||||
|
);
|
||||||
|
debug_assert_eq!(
|
||||||
|
parts.array_windows().find(|[a, b]| a.span.overlaps(b.span)),
|
||||||
|
None,
|
||||||
|
"suggestion must not have overlapping parts",
|
||||||
);
|
);
|
||||||
|
|
||||||
self.push_suggestion(CodeSuggestion {
|
self.push_suggestion(CodeSuggestion {
|
||||||
substitutions: vec![Substitution {
|
substitutions: vec![Substitution { parts }],
|
||||||
parts: suggestion
|
|
||||||
.into_iter()
|
|
||||||
.map(|(span, snippet)| SubstitutionPart { snippet, span })
|
|
||||||
.collect(),
|
|
||||||
}],
|
|
||||||
msg: self.subdiagnostic_message_to_diagnostic_message(msg),
|
msg: self.subdiagnostic_message_to_diagnostic_message(msg),
|
||||||
style,
|
style,
|
||||||
applicability,
|
applicability,
|
||||||
|
@ -802,25 +810,34 @@ impl Diagnostic {
|
||||||
suggestions: impl IntoIterator<Item = Vec<(Span, String)>>,
|
suggestions: impl IntoIterator<Item = Vec<(Span, String)>>,
|
||||||
applicability: Applicability,
|
applicability: Applicability,
|
||||||
) -> &mut Self {
|
) -> &mut Self {
|
||||||
let suggestions: Vec<_> = suggestions.into_iter().collect();
|
let substitutions = suggestions
|
||||||
debug_assert!(
|
.into_iter()
|
||||||
!(suggestions
|
.map(|sugg| {
|
||||||
.iter()
|
let mut parts = sugg
|
||||||
.flatten()
|
.into_iter()
|
||||||
.any(|(sp, suggestion)| sp.is_empty() && suggestion.is_empty())),
|
.map(|(span, snippet)| SubstitutionPart { snippet, span })
|
||||||
"Span must not be empty and have no suggestion"
|
.collect::<Vec<_>>();
|
||||||
);
|
|
||||||
|
parts.sort_unstable_by_key(|part| part.span);
|
||||||
|
|
||||||
|
assert!(!parts.is_empty());
|
||||||
|
debug_assert_eq!(
|
||||||
|
parts.iter().find(|part| part.span.is_empty() && part.snippet.is_empty()),
|
||||||
|
None,
|
||||||
|
"Span must not be empty and have no suggestion",
|
||||||
|
);
|
||||||
|
debug_assert_eq!(
|
||||||
|
parts.array_windows().find(|[a, b]| a.span.overlaps(b.span)),
|
||||||
|
None,
|
||||||
|
"suggestion must not have overlapping parts",
|
||||||
|
);
|
||||||
|
|
||||||
|
Substitution { parts }
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
self.push_suggestion(CodeSuggestion {
|
self.push_suggestion(CodeSuggestion {
|
||||||
substitutions: suggestions
|
substitutions,
|
||||||
.into_iter()
|
|
||||||
.map(|sugg| Substitution {
|
|
||||||
parts: sugg
|
|
||||||
.into_iter()
|
|
||||||
.map(|(span, snippet)| SubstitutionPart { snippet, span })
|
|
||||||
.collect(),
|
|
||||||
})
|
|
||||||
.collect(),
|
|
||||||
msg: self.subdiagnostic_message_to_diagnostic_message(msg),
|
msg: self.subdiagnostic_message_to_diagnostic_message(msg),
|
||||||
style: SuggestionStyle::ShowCode,
|
style: SuggestionStyle::ShowCode,
|
||||||
applicability,
|
applicability,
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
//! This module contains the code for creating and emitting diagnostics.
|
//! This module contains the code for creating and emitting diagnostics.
|
||||||
|
|
||||||
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
|
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
|
||||||
|
#![feature(array_windows)]
|
||||||
#![feature(drain_filter)]
|
#![feature(drain_filter)]
|
||||||
#![feature(if_let_guard)]
|
#![feature(if_let_guard)]
|
||||||
#![feature(is_terminal)]
|
#![feature(is_terminal)]
|
||||||
|
|
|
@ -10,7 +10,7 @@ use crate::mbe::transcribe::transcribe;
|
||||||
|
|
||||||
use rustc_ast as ast;
|
use rustc_ast as ast;
|
||||||
use rustc_ast::token::{self, Delimiter, NonterminalKind, Token, TokenKind, TokenKind::*};
|
use rustc_ast::token::{self, Delimiter, NonterminalKind, Token, TokenKind, TokenKind::*};
|
||||||
use rustc_ast::tokenstream::{DelimSpan, TokenStream};
|
use rustc_ast::tokenstream::{DelimSpan, TokenStream, TokenTree};
|
||||||
use rustc_ast::{NodeId, DUMMY_NODE_ID};
|
use rustc_ast::{NodeId, DUMMY_NODE_ID};
|
||||||
use rustc_ast_pretty::pprust;
|
use rustc_ast_pretty::pprust;
|
||||||
use rustc_attr::{self as attr, TransparencyError};
|
use rustc_attr::{self as attr, TransparencyError};
|
||||||
|
@ -212,7 +212,6 @@ fn expand_macro<'cx>(
|
||||||
};
|
};
|
||||||
let arm_span = rhses[i].span();
|
let arm_span = rhses[i].span();
|
||||||
|
|
||||||
let rhs_spans = rhs.tts.iter().map(|t| t.span()).collect::<Vec<_>>();
|
|
||||||
// rhs has holes ( `$id` and `$(...)` that need filled)
|
// rhs has holes ( `$id` and `$(...)` that need filled)
|
||||||
let mut tts = match transcribe(cx, &named_matches, &rhs, rhs_span, transparency) {
|
let mut tts = match transcribe(cx, &named_matches, &rhs, rhs_span, transparency) {
|
||||||
Ok(tts) => tts,
|
Ok(tts) => tts,
|
||||||
|
@ -224,12 +223,25 @@ fn expand_macro<'cx>(
|
||||||
|
|
||||||
// Replace all the tokens for the corresponding positions in the macro, to maintain
|
// Replace all the tokens for the corresponding positions in the macro, to maintain
|
||||||
// proper positions in error reporting, while maintaining the macro_backtrace.
|
// proper positions in error reporting, while maintaining the macro_backtrace.
|
||||||
if rhs_spans.len() == tts.len() {
|
if tts.len() == rhs.tts.len() {
|
||||||
tts = tts.map_enumerated(|i, tt| {
|
tts = tts.map_enumerated(|i, tt| {
|
||||||
let mut tt = tt.clone();
|
let mut tt = tt.clone();
|
||||||
let mut sp = rhs_spans[i];
|
let rhs_tt = &rhs.tts[i];
|
||||||
sp = sp.with_ctxt(tt.span().ctxt());
|
let ctxt = tt.span().ctxt();
|
||||||
tt.set_span(sp);
|
match (&mut tt, rhs_tt) {
|
||||||
|
// preserve the delim spans if able
|
||||||
|
(
|
||||||
|
TokenTree::Delimited(target_sp, ..),
|
||||||
|
mbe::TokenTree::Delimited(source_sp, ..),
|
||||||
|
) => {
|
||||||
|
target_sp.open = source_sp.open.with_ctxt(ctxt);
|
||||||
|
target_sp.close = source_sp.close.with_ctxt(ctxt);
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
let sp = rhs_tt.span().with_ctxt(ctxt);
|
||||||
|
tt.set_span(sp);
|
||||||
|
}
|
||||||
|
}
|
||||||
tt
|
tt
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -2175,13 +2175,31 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements {
|
||||||
dropped_predicate_count += 1;
|
dropped_predicate_count += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if drop_predicate && !in_where_clause {
|
if drop_predicate {
|
||||||
lint_spans.push(predicate_span);
|
if !in_where_clause {
|
||||||
} else if drop_predicate && i + 1 < num_predicates {
|
lint_spans.push(predicate_span);
|
||||||
// If all the bounds on a predicate were inferable and there are
|
} else if predicate_span.from_expansion() {
|
||||||
// further predicates, we want to eat the trailing comma.
|
// Don't try to extend the span if it comes from a macro expansion.
|
||||||
let next_predicate_span = hir_generics.predicates[i + 1].span();
|
where_lint_spans.push(predicate_span);
|
||||||
where_lint_spans.push(predicate_span.to(next_predicate_span.shrink_to_lo()));
|
} else if 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();
|
||||||
|
if next_predicate_span.from_expansion() {
|
||||||
|
where_lint_spans.push(predicate_span);
|
||||||
|
} else {
|
||||||
|
where_lint_spans
|
||||||
|
.push(predicate_span.to(next_predicate_span.shrink_to_lo()));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Eat the optional trailing comma after the last predicate.
|
||||||
|
let where_span = hir_generics.where_clause_span;
|
||||||
|
if where_span.from_expansion() {
|
||||||
|
where_lint_spans.push(predicate_span);
|
||||||
|
} else {
|
||||||
|
where_lint_spans.push(predicate_span.to(where_span.shrink_to_hi()));
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
where_lint_spans.extend(self.consolidate_outlives_bound_spans(
|
where_lint_spans.extend(self.consolidate_outlives_bound_spans(
|
||||||
predicate_span.shrink_to_lo(),
|
predicate_span.shrink_to_lo(),
|
||||||
|
@ -2225,6 +2243,11 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements {
|
||||||
Applicability::MaybeIncorrect
|
Applicability::MaybeIncorrect
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Due to macros, there might be several predicates with the same span
|
||||||
|
// and we only want to suggest removing them once.
|
||||||
|
lint_spans.sort_unstable();
|
||||||
|
lint_spans.dedup();
|
||||||
|
|
||||||
cx.emit_spanned_lint(
|
cx.emit_spanned_lint(
|
||||||
EXPLICIT_OUTLIVES_REQUIREMENTS,
|
EXPLICIT_OUTLIVES_REQUIREMENTS,
|
||||||
lint_spans.clone(),
|
lint_spans.clone(),
|
||||||
|
|
|
@ -311,6 +311,10 @@ fn check_uninlined_args(
|
||||||
// in those cases, make the code suggestion hidden
|
// in those cases, make the code suggestion hidden
|
||||||
let multiline_fix = fixes.iter().any(|(span, _)| cx.sess().source_map().is_multiline(*span));
|
let multiline_fix = fixes.iter().any(|(span, _)| cx.sess().source_map().is_multiline(*span));
|
||||||
|
|
||||||
|
// Suggest removing each argument only once, for example in `format!("{0} {0}", arg)`.
|
||||||
|
fixes.sort_unstable_by_key(|(span, _)| *span);
|
||||||
|
fixes.dedup_by_key(|(span, _)| *span);
|
||||||
|
|
||||||
span_lint_and_then(
|
span_lint_and_then(
|
||||||
cx,
|
cx,
|
||||||
UNINLINED_FORMAT_ARGS,
|
UNINLINED_FORMAT_ARGS,
|
||||||
|
|
|
@ -8,7 +8,7 @@ LL | fn make_marker() -> impl Marker<gimme_a_const!(marker)> {
|
||||||
| in this macro invocation
|
| in this macro invocation
|
||||||
...
|
...
|
||||||
LL | ($rusty: ident) => {{ let $rusty = 3; *&$rusty }}
|
LL | ($rusty: ident) => {{ let $rusty = 3; *&$rusty }}
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected type
|
| ^ expected type
|
||||||
|
|
|
|
||||||
= note: this error originates in the macro `gimme_a_const` (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in the macro `gimme_a_const` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
|
@ -22,26 +22,21 @@ LL | Example::<gimme_a_const!(marker)>
|
||||||
| in this macro invocation
|
| in this macro invocation
|
||||||
...
|
...
|
||||||
LL | ($rusty: ident) => {{ let $rusty = 3; *&$rusty }}
|
LL | ($rusty: ident) => {{ let $rusty = 3; *&$rusty }}
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected type
|
| ^ expected type
|
||||||
|
|
|
|
||||||
= note: this error originates in the macro `gimme_a_const` (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in the macro `gimme_a_const` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
error: expected type, found `{`
|
error: expected type, found `{`
|
||||||
--> $DIR/macro-fail.rs:4:10
|
--> $DIR/macro-fail.rs:4:10
|
||||||
|
|
|
|
||||||
LL | () => {{
|
LL | () => {{
|
||||||
| __________^
|
| ^ expected type
|
||||||
LL | |
|
|
||||||
LL | | const X: usize = 1337;
|
|
||||||
LL | | X
|
|
||||||
LL | | }}
|
|
||||||
| |___^ expected type
|
|
||||||
...
|
...
|
||||||
LL | let _fail = Example::<external_macro!()>;
|
LL | let _fail = Example::<external_macro!()>;
|
||||||
| -----------------
|
| -----------------
|
||||||
| |
|
| |
|
||||||
| this macro call doesn't expand to a type
|
| this macro call doesn't expand to a type
|
||||||
| in this macro invocation
|
| in this macro invocation
|
||||||
|
|
|
|
||||||
= note: this error originates in the macro `external_macro` (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in the macro `external_macro` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ error: expected one of `::`, `;`, or `as`, found `{`
|
||||||
--> $DIR/import-prefix-macro-1.rs:11:27
|
--> $DIR/import-prefix-macro-1.rs:11:27
|
||||||
|
|
|
|
||||||
LL | ($p: path) => (use $p {S, Z});
|
LL | ($p: path) => (use $p {S, Z});
|
||||||
| ^^^^^^ expected one of `::`, `;`, or `as`
|
| ^ expected one of `::`, `;`, or `as`
|
||||||
...
|
...
|
||||||
LL | import! { a::b::c }
|
LL | import! { a::b::c }
|
||||||
| ------------------- in this macro invocation
|
| ------------------- in this macro invocation
|
||||||
|
|
|
@ -21,8 +21,8 @@ LL | foo!(true);
|
||||||
= note: this error originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
help: if `bar` is a struct, use braces as delimiters
|
help: if `bar` is a struct, use braces as delimiters
|
||||||
|
|
|
|
||||||
LL | bar { }
|
LL | bar { baz: $rest }
|
||||||
| ~
|
| ~ ~
|
||||||
help: if `bar` is a function, use the arguments directly
|
help: if `bar` is a function, use the arguments directly
|
||||||
|
|
|
|
||||||
LL - bar(baz: $rest)
|
LL - bar(baz: $rest)
|
||||||
|
|
|
@ -365,4 +365,24 @@ mod unions {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://github.com/rust-lang/rust/issues/106870
|
||||||
|
mod multiple_predicates_with_same_span {
|
||||||
|
macro_rules! m {
|
||||||
|
($($name:ident)+) => {
|
||||||
|
struct Inline<'a, $($name: 'a,)+>(&'a ($($name,)+));
|
||||||
|
//~^ ERROR: outlives requirements can be inferred
|
||||||
|
struct FullWhere<'a, $($name,)+>(&'a ($($name,)+)) where $($name: 'a,)+;
|
||||||
|
//~^ ERROR: outlives requirements can be inferred
|
||||||
|
struct PartialWhere<'a, $($name,)+>(&'a ($($name,)+)) where (): Sized, $($name: 'a,)+;
|
||||||
|
//~^ ERROR: outlives requirements can be inferred
|
||||||
|
struct Interleaved<'a, $($name,)+>(&'a ($($name,)+))
|
||||||
|
where
|
||||||
|
(): Sized,
|
||||||
|
$($name: 'a, $name: 'a, )+ //~ ERROR: outlives requirements can be inferred
|
||||||
|
$($name: 'a, $name: 'a, )+;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m!(T0 T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12 T13 T14 T15);
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -819,5 +819,61 @@ LL - union BeeWhereAyTeeYooWhereOutlivesAyIsDebugBee<'a, 'b, T, U> where U:
|
||||||
LL + union BeeWhereAyTeeYooWhereOutlivesAyIsDebugBee<'a, 'b, T, U> where U: Debug, {
|
LL + union BeeWhereAyTeeYooWhereOutlivesAyIsDebugBee<'a, 'b, T, U> where U: Debug, {
|
||||||
|
|
|
|
||||||
|
|
||||||
error: aborting due to 68 previous errors
|
error: outlives requirements can be inferred
|
||||||
|
--> $DIR/edition-lint-infer-outlives-multispan.rs:372:38
|
||||||
|
|
|
||||||
|
LL | struct Inline<'a, $($name: 'a,)+>(&'a ($($name,)+));
|
||||||
|
| ^^^^ help: remove these bounds
|
||||||
|
...
|
||||||
|
LL | m!(T0 T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12 T13 T14 T15);
|
||||||
|
| --------------------------------------------------------- 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-multispan.rs:374:64
|
||||||
|
|
|
||||||
|
LL | struct FullWhere<'a, $($name,)+>(&'a ($($name,)+)) where $($name: 'a,)+;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^ help: remove these bounds
|
||||||
|
...
|
||||||
|
LL | m!(T0 T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12 T13 T14 T15);
|
||||||
|
| --------------------------------------------------------- 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-multispan.rs:376:86
|
||||||
|
|
|
||||||
|
LL | struct PartialWhere<'a, $($name,)+>(&'a ($($name,)+)) where (): Sized, $($name: 'a,)+;
|
||||||
|
| ^^^^^^^^^ help: remove these bounds
|
||||||
|
...
|
||||||
|
LL | m!(T0 T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12 T13 T14 T15);
|
||||||
|
| --------------------------------------------------------- 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-multispan.rs:381:19
|
||||||
|
|
|
||||||
|
LL | $($name: 'a, $name: 'a, )+
|
||||||
|
| ^^^^^^^^^ ^^^^^^^^^
|
||||||
|
LL | $($name: 'a, $name: 'a, )+;
|
||||||
|
| ^^^^^^^^^ ^^^^^^^^^
|
||||||
|
...
|
||||||
|
LL | m!(T0 T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12 T13 T14 T15);
|
||||||
|
| ---------------------------------------------------------
|
||||||
|
| |
|
||||||
|
| in this macro invocation
|
||||||
|
| in this macro invocation
|
||||||
|
| in this macro invocation
|
||||||
|
| in this macro invocation
|
||||||
|
|
|
||||||
|
= note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
help: remove these bounds
|
||||||
|
|
|
||||||
|
LL ~ $(, , )+
|
||||||
|
LL ~ $(, , )+;
|
||||||
|
|
|
||||||
|
|
||||||
|
error: aborting due to 72 previous errors
|
||||||
|
|
||||||
|
|
|
@ -791,5 +791,14 @@ struct StaticRef<T: 'static> {
|
||||||
field: &'static T
|
field: &'static T
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct TrailingCommaInWhereClause<'a, T, U>
|
||||||
|
where
|
||||||
|
T: 'a,
|
||||||
|
|
||||||
|
//~^ ERROR outlives requirements can be inferred
|
||||||
|
{
|
||||||
|
tee: T,
|
||||||
|
yoo: &'a U
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -791,5 +791,14 @@ struct StaticRef<T: 'static> {
|
||||||
field: &'static T
|
field: &'static T
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct TrailingCommaInWhereClause<'a, T, U>
|
||||||
|
where
|
||||||
|
T: 'a,
|
||||||
|
U: 'a,
|
||||||
|
//~^ ERROR outlives requirements can be inferred
|
||||||
|
{
|
||||||
|
tee: T,
|
||||||
|
yoo: &'a U
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error: outlives requirements can be inferred
|
error: outlives requirements can be inferred
|
||||||
--> $DIR/edition-lint-infer-outlives.rs:26:31
|
--> $DIR/edition-lint-infer-outlives.rs:797:5
|
||||||
|
|
|
|
||||||
LL | struct TeeOutlivesAy<'a, T: 'a> {
|
LL | U: 'a,
|
||||||
| ^^^^ help: remove this bound
|
| ^^^^^^ help: remove this bound
|
||||||
|
|
|
|
||||||
note: the lint level is defined here
|
note: the lint level is defined here
|
||||||
--> $DIR/edition-lint-infer-outlives.rs:4:9
|
--> $DIR/edition-lint-infer-outlives.rs:4:9
|
||||||
|
@ -10,6 +10,12 @@ note: the lint level is defined here
|
||||||
LL | #![deny(explicit_outlives_requirements)]
|
LL | #![deny(explicit_outlives_requirements)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: outlives requirements can be inferred
|
||||||
|
--> $DIR/edition-lint-infer-outlives.rs:26:31
|
||||||
|
|
|
||||||
|
LL | struct TeeOutlivesAy<'a, T: 'a> {
|
||||||
|
| ^^^^ help: remove this bound
|
||||||
|
|
||||||
error: outlives requirements can be inferred
|
error: outlives requirements can be inferred
|
||||||
--> $DIR/edition-lint-infer-outlives.rs:31:40
|
--> $DIR/edition-lint-infer-outlives.rs:31:40
|
||||||
|
|
|
|
||||||
|
@ -916,5 +922,5 @@ error: outlives requirements can be inferred
|
||||||
LL | union BeeWhereOutlivesAyTeeWhereDebug<'a, 'b, T> where 'b: 'a, T: Debug {
|
LL | union BeeWhereOutlivesAyTeeWhereDebug<'a, 'b, T> where 'b: 'a, T: Debug {
|
||||||
| ^^^^^^^^ help: remove this bound
|
| ^^^^^^^^ help: remove this bound
|
||||||
|
|
||||||
error: aborting due to 152 previous errors
|
error: aborting due to 153 previous errors
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue