Auto merge of #113188 - matthiaskrgr:rollup-j3abaks, r=matthiaskrgr
Rollup of 6 pull requests Successful merges: - #107624 (Stabilize `const_cstr_methods`) - #111403 (suggest `slice::swap` for `mem::swap(&mut x[0], &mut x[1])` borrowck error) - #113071 (Account for late-bound vars from parent arg-position impl trait) - #113165 (Encode item bounds for `DefKind::ImplTraitPlaceholder`) - #113171 (Properly implement variances_of for RPITIT GAT) - #113177 (Use structured suggestion when telling user about `for<'a>`) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
b4591cb04c
32 changed files with 327 additions and 99 deletions
|
@ -982,7 +982,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
&msg_borrow,
|
||||
None,
|
||||
);
|
||||
self.suggest_split_at_mut_if_applicable(
|
||||
self.suggest_slice_method_if_applicable(
|
||||
&mut err,
|
||||
place,
|
||||
issued_borrow.borrowed_place,
|
||||
|
@ -1262,7 +1262,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
);
|
||||
}
|
||||
|
||||
fn suggest_split_at_mut_if_applicable(
|
||||
fn suggest_slice_method_if_applicable(
|
||||
&self,
|
||||
err: &mut Diagnostic,
|
||||
place: Place<'tcx>,
|
||||
|
@ -1274,7 +1274,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
err.help(
|
||||
"consider using `.split_at_mut(position)` or similar method to obtain \
|
||||
two mutable non-overlapping sub-slices",
|
||||
);
|
||||
)
|
||||
.help("consider using `.swap(index_1, index_2)` to swap elements at the specified indices");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -99,6 +99,15 @@ hir_analysis_invalid_union_field =
|
|||
hir_analysis_invalid_union_field_sugg =
|
||||
wrap the field type in `ManuallyDrop<...>`
|
||||
|
||||
hir_analysis_late_bound_const_in_apit = `impl Trait` can only mention const parameters from an fn or impl
|
||||
.label = const parameter declared here
|
||||
|
||||
hir_analysis_late_bound_lifetime_in_apit = `impl Trait` can only mention lifetimes from an fn or impl
|
||||
.label = lifetime declared here
|
||||
|
||||
hir_analysis_late_bound_type_in_apit = `impl Trait` can only mention type parameters from an fn or impl
|
||||
.label = type parameter declared here
|
||||
|
||||
hir_analysis_lifetimes_or_bounds_mismatch_on_trait =
|
||||
lifetime parameters or bounds on {$item_kind} `{$ident}` do not match the trait declaration
|
||||
.label = lifetimes do not match {$item_kind} in trait
|
||||
|
|
|
@ -1344,12 +1344,10 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
|
|||
Scope::Binder {
|
||||
where_bound_origin: Some(hir::PredicateOrigin::ImplTrait), ..
|
||||
} => {
|
||||
let mut err = self.tcx.sess.struct_span_err(
|
||||
lifetime_ref.ident.span,
|
||||
"`impl Trait` can only mention lifetimes bound at the fn or impl level",
|
||||
);
|
||||
err.span_note(self.tcx.def_span(region_def_id), "lifetime declared here");
|
||||
err.emit();
|
||||
self.tcx.sess.emit_err(errors::LateBoundInApit::Lifetime {
|
||||
span: lifetime_ref.ident.span,
|
||||
param_span: self.tcx.def_span(region_def_id),
|
||||
});
|
||||
return;
|
||||
}
|
||||
Scope::Root { .. } => break,
|
||||
|
@ -1379,6 +1377,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
|
|||
let mut late_depth = 0;
|
||||
let mut scope = self.scope;
|
||||
let mut crossed_anon_const = false;
|
||||
|
||||
let result = loop {
|
||||
match *scope {
|
||||
Scope::Body { s, .. } => {
|
||||
|
@ -1446,6 +1445,50 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
|
|||
return;
|
||||
}
|
||||
|
||||
// We may fail to resolve higher-ranked ty/const vars that are mentioned by APIT.
|
||||
// AST-based resolution does not care for impl-trait desugaring, which are the
|
||||
// responsibility of lowering. This may create a mismatch between the resolution
|
||||
// AST found (`param_def_id`) which points to HRTB, and what HIR allows.
|
||||
// ```
|
||||
// fn foo(x: impl for<T> Trait<Assoc = impl Trait2<T>>) {}
|
||||
// ```
|
||||
//
|
||||
// In such case, walk back the binders to diagnose it properly.
|
||||
let mut scope = self.scope;
|
||||
loop {
|
||||
match *scope {
|
||||
Scope::Binder {
|
||||
where_bound_origin: Some(hir::PredicateOrigin::ImplTrait), ..
|
||||
} => {
|
||||
let guar = self.tcx.sess.emit_err(match self.tcx.def_kind(param_def_id) {
|
||||
DefKind::TyParam => errors::LateBoundInApit::Type {
|
||||
span: self.tcx.hir().span(hir_id),
|
||||
param_span: self.tcx.def_span(param_def_id),
|
||||
},
|
||||
DefKind::ConstParam => errors::LateBoundInApit::Const {
|
||||
span: self.tcx.hir().span(hir_id),
|
||||
param_span: self.tcx.def_span(param_def_id),
|
||||
},
|
||||
kind => {
|
||||
bug!("unexpected def-kind: {}", kind.descr(param_def_id.to_def_id()))
|
||||
}
|
||||
});
|
||||
self.map.defs.insert(hir_id, ResolvedArg::Error(guar));
|
||||
return;
|
||||
}
|
||||
Scope::Root { .. } => break,
|
||||
Scope::Binder { s, .. }
|
||||
| Scope::Body { s, .. }
|
||||
| Scope::Elision { s, .. }
|
||||
| Scope::ObjectLifetimeDefault { s, .. }
|
||||
| Scope::Supertrait { s, .. }
|
||||
| Scope::TraitRefBoundary { s, .. }
|
||||
| Scope::AnonConstBoundary { s } => {
|
||||
scope = s;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.tcx.sess.delay_span_bug(
|
||||
self.tcx.hir().span(hir_id),
|
||||
format!("could not resolve {param_def_id:?}"),
|
||||
|
|
|
@ -875,3 +875,28 @@ pub(crate) enum ReturnTypeNotationIllegalParam {
|
|||
param_span: Span,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
pub(crate) enum LateBoundInApit {
|
||||
#[diag(hir_analysis_late_bound_type_in_apit)]
|
||||
Type {
|
||||
#[primary_span]
|
||||
span: Span,
|
||||
#[label]
|
||||
param_span: Span,
|
||||
},
|
||||
#[diag(hir_analysis_late_bound_const_in_apit)]
|
||||
Const {
|
||||
#[primary_span]
|
||||
span: Span,
|
||||
#[label]
|
||||
param_span: Span,
|
||||
},
|
||||
#[diag(hir_analysis_late_bound_lifetime_in_apit)]
|
||||
Lifetime {
|
||||
#[primary_span]
|
||||
span: Span,
|
||||
#[label]
|
||||
param_span: Span,
|
||||
},
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ use rustc_arena::DroplessArena;
|
|||
use rustc_hir::def::DefKind;
|
||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||
use rustc_middle::query::Providers;
|
||||
use rustc_middle::ty::{self, CrateVariancesMap, SubstsRef, Ty, TyCtxt};
|
||||
use rustc_middle::ty::{self, CrateVariancesMap, ImplTraitInTraitData, SubstsRef, Ty, TyCtxt};
|
||||
use rustc_middle::ty::{TypeSuperVisitable, TypeVisitable};
|
||||
use std::ops::ControlFlow;
|
||||
|
||||
|
@ -51,20 +51,26 @@ fn variances_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Variance] {
|
|||
| DefKind::Struct
|
||||
| DefKind::Union
|
||||
| DefKind::Variant
|
||||
| DefKind::Ctor(..) => {}
|
||||
| DefKind::Ctor(..) => {
|
||||
// These are inferred.
|
||||
let crate_map = tcx.crate_variances(());
|
||||
return crate_map.variances.get(&item_def_id.to_def_id()).copied().unwrap_or(&[]);
|
||||
}
|
||||
DefKind::OpaqueTy | DefKind::ImplTraitPlaceholder => {
|
||||
return variance_of_opaque(tcx, item_def_id);
|
||||
}
|
||||
_ => {
|
||||
// Variance not relevant.
|
||||
span_bug!(tcx.def_span(item_def_id), "asked to compute variance for wrong kind of item")
|
||||
DefKind::AssocTy => {
|
||||
if let Some(ImplTraitInTraitData::Trait { .. }) =
|
||||
tcx.opt_rpitit_info(item_def_id.to_def_id())
|
||||
{
|
||||
return variance_of_opaque(tcx, item_def_id);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
// Everything else must be inferred.
|
||||
|
||||
let crate_map = tcx.crate_variances(());
|
||||
crate_map.variances.get(&item_def_id.to_def_id()).copied().unwrap_or(&[])
|
||||
// Variance not relevant.
|
||||
span_bug!(tcx.def_span(item_def_id), "asked to compute variance for wrong kind of item");
|
||||
}
|
||||
|
||||
#[instrument(level = "trace", skip(tcx), ret)]
|
||||
|
|
|
@ -1447,6 +1447,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
|||
.is_type_alias_impl_trait
|
||||
.set(def_id.index, self.tcx.is_type_alias_impl_trait(def_id));
|
||||
}
|
||||
if let DefKind::ImplTraitPlaceholder = def_kind {
|
||||
self.encode_explicit_item_bounds(def_id);
|
||||
}
|
||||
if tcx.impl_method_has_trait_impl_trait_tys(def_id)
|
||||
&& let Ok(table) = self.tcx.collect_return_position_impl_trait_in_trait_tys(def_id)
|
||||
{
|
||||
|
|
|
@ -1632,9 +1632,13 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
|
|||
..
|
||||
} = &rib.kind
|
||||
{
|
||||
diag.span_help(
|
||||
*span,
|
||||
"consider introducing a higher-ranked lifetime here with `for<'a>`",
|
||||
diag.multipart_suggestion(
|
||||
"consider introducing a higher-ranked lifetime here",
|
||||
vec![
|
||||
(span.shrink_to_lo(), "for<'a> ".into()),
|
||||
(lifetime.ident.span.shrink_to_hi(), "'a ".into()),
|
||||
],
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -241,7 +241,7 @@ impl CStr {
|
|||
/// ```
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(const_cstr_methods)]
|
||||
/// #![feature(const_cstr_from_ptr)]
|
||||
///
|
||||
/// use std::ffi::{c_char, CStr};
|
||||
///
|
||||
|
@ -256,7 +256,7 @@ impl CStr {
|
|||
#[inline]
|
||||
#[must_use]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_const_unstable(feature = "const_cstr_methods", issue = "101719")]
|
||||
#[rustc_const_unstable(feature = "const_cstr_from_ptr", issue = "101719")]
|
||||
pub const unsafe fn from_ptr<'a>(ptr: *const c_char) -> &'a CStr {
|
||||
// SAFETY: The caller has provided a pointer that points to a valid C
|
||||
// string with a NUL terminator of size less than `isize::MAX`, whose
|
||||
|
@ -377,7 +377,7 @@ impl CStr {
|
|||
/// assert!(cstr.is_err());
|
||||
/// ```
|
||||
#[stable(feature = "cstr_from_bytes", since = "1.10.0")]
|
||||
#[rustc_const_unstable(feature = "const_cstr_methods", issue = "101719")]
|
||||
#[rustc_const_stable(feature = "const_cstr_methods", since = "CURRENT_RUSTC_VERSION")]
|
||||
pub const fn from_bytes_with_nul(bytes: &[u8]) -> Result<&Self, FromBytesWithNulError> {
|
||||
let nul_pos = memchr::memchr(0, bytes);
|
||||
match nul_pos {
|
||||
|
@ -561,10 +561,12 @@ impl CStr {
|
|||
#[must_use = "this returns the result of the operation, \
|
||||
without modifying the original"]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn to_bytes(&self) -> &[u8] {
|
||||
#[rustc_const_stable(feature = "const_cstr_methods", since = "CURRENT_RUSTC_VERSION")]
|
||||
pub const fn to_bytes(&self) -> &[u8] {
|
||||
let bytes = self.to_bytes_with_nul();
|
||||
// FIXME(const-hack) replace with range index
|
||||
// SAFETY: to_bytes_with_nul returns slice with length at least 1
|
||||
unsafe { bytes.get_unchecked(..bytes.len() - 1) }
|
||||
unsafe { slice::from_raw_parts(bytes.as_ptr(), bytes.len() - 1) }
|
||||
}
|
||||
|
||||
/// Converts this C string to a byte slice containing the trailing 0 byte.
|
||||
|
@ -588,7 +590,7 @@ impl CStr {
|
|||
#[must_use = "this returns the result of the operation, \
|
||||
without modifying the original"]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_const_unstable(feature = "const_cstr_methods", issue = "101719")]
|
||||
#[rustc_const_stable(feature = "const_cstr_methods", since = "CURRENT_RUSTC_VERSION")]
|
||||
pub const fn to_bytes_with_nul(&self) -> &[u8] {
|
||||
// SAFETY: Transmuting a slice of `c_char`s to a slice of `u8`s
|
||||
// is safe on all supported targets.
|
||||
|
@ -612,7 +614,8 @@ impl CStr {
|
|||
/// assert_eq!(cstr.to_str(), Ok("foo"));
|
||||
/// ```
|
||||
#[stable(feature = "cstr_to_str", since = "1.4.0")]
|
||||
pub fn to_str(&self) -> Result<&str, str::Utf8Error> {
|
||||
#[rustc_const_stable(feature = "const_cstr_methods", since = "CURRENT_RUSTC_VERSION")]
|
||||
pub const fn to_str(&self) -> Result<&str, str::Utf8Error> {
|
||||
// N.B., when `CStr` is changed to perform the length check in `.to_bytes()`
|
||||
// instead of in `from_ptr()`, it may be worth considering if this should
|
||||
// be rewritten to do the UTF-8 check inline with the length calculation
|
||||
|
|
|
@ -113,7 +113,6 @@
|
|||
#![feature(const_caller_location)]
|
||||
#![feature(const_cell_into_inner)]
|
||||
#![feature(const_char_from_u32_unchecked)]
|
||||
#![feature(const_cstr_methods)]
|
||||
#![feature(const_discriminant)]
|
||||
#![feature(const_eval_select)]
|
||||
#![feature(const_exact_div)]
|
||||
|
|
|
@ -22,11 +22,10 @@ error[E0637]: `&` without an explicit lifetime name cannot be used here
|
|||
LL | T: Into<&u32>,
|
||||
| ^ explicit lifetime name needed here
|
||||
|
|
||||
help: consider introducing a higher-ranked lifetime here with `for<'a>`
|
||||
--> $DIR/E0637.rs:13:8
|
||||
help: consider introducing a higher-ranked lifetime here
|
||||
|
|
||||
LL | T: Into<&u32>,
|
||||
| ^
|
||||
LL | T: for<'a> Into<&'a u32>,
|
||||
| +++++++ ++
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
|
|
|
@ -4,11 +4,10 @@ error[E0637]: `&` without an explicit lifetime name cannot be used here
|
|||
LL | fn should_error<T>() where T : Into<&u32> {}
|
||||
| ^ explicit lifetime name needed here
|
||||
|
|
||||
help: consider introducing a higher-ranked lifetime here with `for<'a>`
|
||||
--> $DIR/issue-65285-incorrect-explicit-lifetime-name-needed.rs:5:32
|
||||
help: consider introducing a higher-ranked lifetime here
|
||||
|
|
||||
LL | fn should_error<T>() where T : Into<&u32> {}
|
||||
| ^
|
||||
LL | fn should_error<T>() where T : for<'a> Into<&'a u32> {}
|
||||
| +++++++ ++
|
||||
|
||||
error[E0106]: missing lifetime specifier
|
||||
--> $DIR/issue-65285-incorrect-explicit-lifetime-name-needed.rs:9:20
|
||||
|
|
|
@ -14,6 +14,10 @@ impl Foo for Local {
|
|||
fn bar(self) -> Arc<String> { Arc::new(String::new()) }
|
||||
}
|
||||
|
||||
fn generic(f: impl Foo) {
|
||||
let x = &*f.bar();
|
||||
}
|
||||
|
||||
fn main() {
|
||||
// Witness an RPITIT from another crate.
|
||||
let &() = Foreign.bar();
|
||||
|
|
19
tests/ui/impl-trait/in-trait/variances-of-gat.rs
Normal file
19
tests/ui/impl-trait/in-trait/variances-of-gat.rs
Normal file
|
@ -0,0 +1,19 @@
|
|||
// check-pass
|
||||
// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
|
||||
// revisions: current next
|
||||
|
||||
#![feature(return_position_impl_trait_in_trait)]
|
||||
|
||||
trait Foo {}
|
||||
|
||||
impl Foo for () {}
|
||||
|
||||
trait ThreeCellFragment {
|
||||
fn ext_cells<'a>(&'a self) -> impl Foo + 'a {
|
||||
self.ext_adjacent_cells()
|
||||
}
|
||||
|
||||
fn ext_adjacent_cells<'a>(&'a self) -> impl Foo + 'a;
|
||||
}
|
||||
|
||||
fn main() {}
|
|
@ -3,6 +3,6 @@ trait Trait<'a> {
|
|||
}
|
||||
|
||||
fn test_argument_position(x: impl for<'a> Trait<'a, Assoc = impl Copy + 'a>) {}
|
||||
//~^ ERROR `impl Trait` can only mention lifetimes bound at the fn or impl level
|
||||
//~^ ERROR `impl Trait` can only mention lifetimes from an fn or impl
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -1,14 +1,8 @@
|
|||
error: `impl Trait` can only mention lifetimes bound at the fn or impl level
|
||||
error: `impl Trait` can only mention lifetimes from an fn or impl
|
||||
--> $DIR/universal_wrong_hrtb.rs:5:73
|
||||
|
|
||||
LL | fn test_argument_position(x: impl for<'a> Trait<'a, Assoc = impl Copy + 'a>) {}
|
||||
| ^^
|
||||
|
|
||||
note: lifetime declared here
|
||||
--> $DIR/universal_wrong_hrtb.rs:5:39
|
||||
|
|
||||
LL | fn test_argument_position(x: impl for<'a> Trait<'a, Assoc = impl Copy + 'a>) {}
|
||||
| ^^
|
||||
| -- lifetime declared here ^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ LL | *a = 5;
|
|||
| ------ first borrow later used here
|
||||
|
|
||||
= help: consider using `.split_at_mut(position)` or similar method to obtain two mutable non-overlapping sub-slices
|
||||
= help: consider using `.swap(index_1, index_2)` to swap elements at the specified indices
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
#![feature(non_lifetime_binders)]
|
||||
//~^ WARN the feature `non_lifetime_binders` is incomplete
|
||||
|
||||
trait Trait<Input> {
|
||||
type Assoc;
|
||||
}
|
||||
|
||||
fn uwu(_: impl for<T> Trait<(), Assoc = impl Trait<T>>) {}
|
||||
//~^ ERROR `impl Trait` can only mention type parameters from an fn or impl
|
||||
|
||||
fn main() {}
|
|
@ -0,0 +1,17 @@
|
|||
warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/nested-apit-mentioning-outer-bound-var.rs:1:12
|
||||
|
|
||||
LL | #![feature(non_lifetime_binders)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
|
||||
error: `impl Trait` can only mention type parameters from an fn or impl
|
||||
--> $DIR/nested-apit-mentioning-outer-bound-var.rs:8:52
|
||||
|
|
||||
LL | fn uwu(_: impl for<T> Trait<(), Assoc = impl Trait<T>>) {}
|
||||
| - type parameter declared here ^
|
||||
|
||||
error: aborting due to previous error; 1 warning emitted
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
// run-rustfix
|
||||
|
||||
trait WithType<T> {}
|
||||
trait WithRegion<'a> { }
|
||||
|
||||
#[allow(dead_code)]
|
||||
struct Foo<T> {
|
||||
t: T
|
||||
}
|
||||
|
||||
impl<T> Foo<T>
|
||||
where
|
||||
T: for<'a> WithType<&'a u32>
|
||||
//~^ ERROR `&` without an explicit lifetime name cannot be used here
|
||||
{ }
|
||||
|
||||
fn main() {}
|
|
@ -0,0 +1,17 @@
|
|||
// run-rustfix
|
||||
|
||||
trait WithType<T> {}
|
||||
trait WithRegion<'a> { }
|
||||
|
||||
#[allow(dead_code)]
|
||||
struct Foo<T> {
|
||||
t: T
|
||||
}
|
||||
|
||||
impl<T> Foo<T>
|
||||
where
|
||||
T: WithType<&u32>
|
||||
//~^ ERROR `&` without an explicit lifetime name cannot be used here
|
||||
{ }
|
||||
|
||||
fn main() {}
|
|
@ -1,14 +1,13 @@
|
|||
error[E0637]: `&` without an explicit lifetime name cannot be used here
|
||||
--> $DIR/where-clause-trait-impl-region.rs:11:17
|
||||
--> $DIR/where-clause-inherent-impl-ampersand-rust2015.rs:13:17
|
||||
|
|
||||
LL | T: WithType<&u32>
|
||||
| ^ explicit lifetime name needed here
|
||||
|
|
||||
help: consider introducing a higher-ranked lifetime here with `for<'a>`
|
||||
--> $DIR/where-clause-trait-impl-region.rs:11:8
|
||||
help: consider introducing a higher-ranked lifetime here
|
||||
|
|
||||
LL | T: WithType<&u32>
|
||||
| ^
|
||||
LL | T: for<'a> WithType<&'a u32>
|
||||
| +++++++ ++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
// edition:2018
|
||||
// run-rustfix
|
||||
|
||||
trait WithType<T> {}
|
||||
trait WithRegion<'a> { }
|
||||
|
||||
#[allow(dead_code)]
|
||||
struct Foo<T> {
|
||||
t: T
|
||||
}
|
||||
|
||||
impl<T> Foo<T>
|
||||
where
|
||||
T: for<'a> WithType<&'a u32>
|
||||
//~^ ERROR `&` without an explicit lifetime name cannot be used here
|
||||
{ }
|
||||
|
||||
fn main() {}
|
|
@ -0,0 +1,18 @@
|
|||
// edition:2018
|
||||
// run-rustfix
|
||||
|
||||
trait WithType<T> {}
|
||||
trait WithRegion<'a> { }
|
||||
|
||||
#[allow(dead_code)]
|
||||
struct Foo<T> {
|
||||
t: T
|
||||
}
|
||||
|
||||
impl<T> Foo<T>
|
||||
where
|
||||
T: WithType<&u32>
|
||||
//~^ ERROR `&` without an explicit lifetime name cannot be used here
|
||||
{ }
|
||||
|
||||
fn main() {}
|
|
@ -1,14 +1,13 @@
|
|||
error[E0637]: `&` without an explicit lifetime name cannot be used here
|
||||
--> $DIR/where-clause-trait-impl-region.rs:11:17
|
||||
--> $DIR/where-clause-inherent-impl-ampersand-rust2018.rs:14:17
|
||||
|
|
||||
LL | T: WithType<&u32>
|
||||
| ^ explicit lifetime name needed here
|
||||
|
|
||||
help: consider introducing a higher-ranked lifetime here with `for<'a>`
|
||||
--> $DIR/where-clause-trait-impl-region.rs:11:8
|
||||
help: consider introducing a higher-ranked lifetime here
|
||||
|
|
||||
LL | T: WithType<&u32>
|
||||
| ^
|
||||
LL | T: for<'a> WithType<&'a u32>
|
||||
| +++++++ ++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
// 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 `&` without an explicit lifetime name cannot be used here
|
||||
//[rust2018]~^^ ERROR `&` without an explicit lifetime name cannot be used here
|
||||
{ }
|
||||
|
||||
fn main() {}
|
|
@ -0,0 +1,14 @@
|
|||
// run-rustfix
|
||||
|
||||
trait WithType<T> {}
|
||||
trait WithRegion<'a> { }
|
||||
|
||||
trait Foo { }
|
||||
|
||||
impl<T> Foo for Vec<T>
|
||||
where
|
||||
T: for<'a> WithType<&'a u32>
|
||||
//~^ ERROR `&` without an explicit lifetime name cannot be used here
|
||||
{ }
|
||||
|
||||
fn main() {}
|
|
@ -0,0 +1,14 @@
|
|||
// run-rustfix
|
||||
|
||||
trait WithType<T> {}
|
||||
trait WithRegion<'a> { }
|
||||
|
||||
trait Foo { }
|
||||
|
||||
impl<T> Foo for Vec<T>
|
||||
where
|
||||
T: WithType<&u32>
|
||||
//~^ ERROR `&` without an explicit lifetime name cannot be used here
|
||||
{ }
|
||||
|
||||
fn main() {}
|
|
@ -1,14 +1,13 @@
|
|||
error[E0637]: `&` without an explicit lifetime name cannot be used here
|
||||
--> $DIR/where-clause-inherent-impl-ampersand.rs:13:17
|
||||
--> $DIR/where-clause-trait-impl-region-2015.rs:10:17
|
||||
|
|
||||
LL | T: WithType<&u32>
|
||||
| ^ explicit lifetime name needed here
|
||||
|
|
||||
help: consider introducing a higher-ranked lifetime here with `for<'a>`
|
||||
--> $DIR/where-clause-inherent-impl-ampersand.rs:13:8
|
||||
help: consider introducing a higher-ranked lifetime here
|
||||
|
|
||||
LL | T: WithType<&u32>
|
||||
| ^
|
||||
LL | T: for<'a> WithType<&'a u32>
|
||||
| +++++++ ++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
// run-rustfix
|
||||
// edition:2018
|
||||
|
||||
trait WithType<T> {}
|
||||
trait WithRegion<'a> { }
|
||||
|
||||
trait Foo { }
|
||||
|
||||
impl<T> Foo for Vec<T>
|
||||
where
|
||||
T: for<'a> WithType<&'a u32>
|
||||
//~^ ERROR `&` without an explicit lifetime name cannot be used here
|
||||
{ }
|
||||
|
||||
fn main() {}
|
|
@ -0,0 +1,15 @@
|
|||
// run-rustfix
|
||||
// edition:2018
|
||||
|
||||
trait WithType<T> {}
|
||||
trait WithRegion<'a> { }
|
||||
|
||||
trait Foo { }
|
||||
|
||||
impl<T> Foo for Vec<T>
|
||||
where
|
||||
T: WithType<&u32>
|
||||
//~^ ERROR `&` without an explicit lifetime name cannot be used here
|
||||
{ }
|
||||
|
||||
fn main() {}
|
|
@ -1,14 +1,13 @@
|
|||
error[E0637]: `&` without an explicit lifetime name cannot be used here
|
||||
--> $DIR/where-clause-inherent-impl-ampersand.rs:13:17
|
||||
--> $DIR/where-clause-trait-impl-region-2018.rs:11:17
|
||||
|
|
||||
LL | T: WithType<&u32>
|
||||
| ^ explicit lifetime name needed here
|
||||
|
|
||||
help: consider introducing a higher-ranked lifetime here with `for<'a>`
|
||||
--> $DIR/where-clause-inherent-impl-ampersand.rs:13:8
|
||||
help: consider introducing a higher-ranked lifetime here
|
||||
|
|
||||
LL | T: WithType<&u32>
|
||||
| ^
|
||||
LL | T: for<'a> WithType<&'a u32>
|
||||
| +++++++ ++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
// 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,rust2018]~^ ERROR `&` without an explicit lifetime name cannot be used here
|
||||
{ }
|
||||
|
||||
fn main() {}
|
Loading…
Add table
Reference in a new issue