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,
|
&msg_borrow,
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
self.suggest_split_at_mut_if_applicable(
|
self.suggest_slice_method_if_applicable(
|
||||||
&mut err,
|
&mut err,
|
||||||
place,
|
place,
|
||||||
issued_borrow.borrowed_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,
|
&self,
|
||||||
err: &mut Diagnostic,
|
err: &mut Diagnostic,
|
||||||
place: Place<'tcx>,
|
place: Place<'tcx>,
|
||||||
|
@ -1274,7 +1274,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
err.help(
|
err.help(
|
||||||
"consider using `.split_at_mut(position)` or similar method to obtain \
|
"consider using `.split_at_mut(position)` or similar method to obtain \
|
||||||
two mutable non-overlapping sub-slices",
|
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 =
|
hir_analysis_invalid_union_field_sugg =
|
||||||
wrap the field type in `ManuallyDrop<...>`
|
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 =
|
hir_analysis_lifetimes_or_bounds_mismatch_on_trait =
|
||||||
lifetime parameters or bounds on {$item_kind} `{$ident}` do not match the trait declaration
|
lifetime parameters or bounds on {$item_kind} `{$ident}` do not match the trait declaration
|
||||||
.label = lifetimes do not match {$item_kind} in trait
|
.label = lifetimes do not match {$item_kind} in trait
|
||||||
|
|
|
@ -1344,12 +1344,10 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
|
||||||
Scope::Binder {
|
Scope::Binder {
|
||||||
where_bound_origin: Some(hir::PredicateOrigin::ImplTrait), ..
|
where_bound_origin: Some(hir::PredicateOrigin::ImplTrait), ..
|
||||||
} => {
|
} => {
|
||||||
let mut err = self.tcx.sess.struct_span_err(
|
self.tcx.sess.emit_err(errors::LateBoundInApit::Lifetime {
|
||||||
lifetime_ref.ident.span,
|
span: lifetime_ref.ident.span,
|
||||||
"`impl Trait` can only mention lifetimes bound at the fn or impl level",
|
param_span: self.tcx.def_span(region_def_id),
|
||||||
);
|
});
|
||||||
err.span_note(self.tcx.def_span(region_def_id), "lifetime declared here");
|
|
||||||
err.emit();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Scope::Root { .. } => break,
|
Scope::Root { .. } => break,
|
||||||
|
@ -1379,6 +1377,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
|
||||||
let mut late_depth = 0;
|
let mut late_depth = 0;
|
||||||
let mut scope = self.scope;
|
let mut scope = self.scope;
|
||||||
let mut crossed_anon_const = false;
|
let mut crossed_anon_const = false;
|
||||||
|
|
||||||
let result = loop {
|
let result = loop {
|
||||||
match *scope {
|
match *scope {
|
||||||
Scope::Body { s, .. } => {
|
Scope::Body { s, .. } => {
|
||||||
|
@ -1446,6 +1445,50 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
|
||||||
return;
|
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.sess.delay_span_bug(
|
||||||
self.tcx.hir().span(hir_id),
|
self.tcx.hir().span(hir_id),
|
||||||
format!("could not resolve {param_def_id:?}"),
|
format!("could not resolve {param_def_id:?}"),
|
||||||
|
|
|
@ -875,3 +875,28 @@ pub(crate) enum ReturnTypeNotationIllegalParam {
|
||||||
param_span: Span,
|
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::DefKind;
|
||||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||||
use rustc_middle::query::Providers;
|
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 rustc_middle::ty::{TypeSuperVisitable, TypeVisitable};
|
||||||
use std::ops::ControlFlow;
|
use std::ops::ControlFlow;
|
||||||
|
|
||||||
|
@ -51,20 +51,26 @@ fn variances_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Variance] {
|
||||||
| DefKind::Struct
|
| DefKind::Struct
|
||||||
| DefKind::Union
|
| DefKind::Union
|
||||||
| DefKind::Variant
|
| 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 => {
|
DefKind::OpaqueTy | DefKind::ImplTraitPlaceholder => {
|
||||||
return variance_of_opaque(tcx, item_def_id);
|
return variance_of_opaque(tcx, item_def_id);
|
||||||
}
|
}
|
||||||
_ => {
|
DefKind::AssocTy => {
|
||||||
// Variance not relevant.
|
if let Some(ImplTraitInTraitData::Trait { .. }) =
|
||||||
span_bug!(tcx.def_span(item_def_id), "asked to compute variance for wrong kind of item")
|
tcx.opt_rpitit_info(item_def_id.to_def_id())
|
||||||
|
{
|
||||||
|
return variance_of_opaque(tcx, item_def_id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Everything else must be inferred.
|
// Variance not relevant.
|
||||||
|
span_bug!(tcx.def_span(item_def_id), "asked to compute variance for wrong kind of item");
|
||||||
let crate_map = tcx.crate_variances(());
|
|
||||||
crate_map.variances.get(&item_def_id.to_def_id()).copied().unwrap_or(&[])
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(level = "trace", skip(tcx), ret)]
|
#[instrument(level = "trace", skip(tcx), ret)]
|
||||||
|
|
|
@ -1447,6 +1447,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
||||||
.is_type_alias_impl_trait
|
.is_type_alias_impl_trait
|
||||||
.set(def_id.index, self.tcx.is_type_alias_impl_trait(def_id));
|
.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)
|
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)
|
&& 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
|
} = &rib.kind
|
||||||
{
|
{
|
||||||
diag.span_help(
|
diag.multipart_suggestion(
|
||||||
*span,
|
"consider introducing a higher-ranked lifetime here",
|
||||||
"consider introducing a higher-ranked lifetime here with `for<'a>`",
|
vec![
|
||||||
|
(span.shrink_to_lo(), "for<'a> ".into()),
|
||||||
|
(lifetime.ident.span.shrink_to_hi(), "'a ".into()),
|
||||||
|
],
|
||||||
|
Applicability::MachineApplicable,
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -241,7 +241,7 @@ impl CStr {
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// #![feature(const_cstr_methods)]
|
/// #![feature(const_cstr_from_ptr)]
|
||||||
///
|
///
|
||||||
/// use std::ffi::{c_char, CStr};
|
/// use std::ffi::{c_char, CStr};
|
||||||
///
|
///
|
||||||
|
@ -256,7 +256,7 @@ impl CStr {
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[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 {
|
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
|
// 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
|
// string with a NUL terminator of size less than `isize::MAX`, whose
|
||||||
|
@ -377,7 +377,7 @@ impl CStr {
|
||||||
/// assert!(cstr.is_err());
|
/// assert!(cstr.is_err());
|
||||||
/// ```
|
/// ```
|
||||||
#[stable(feature = "cstr_from_bytes", since = "1.10.0")]
|
#[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> {
|
pub const fn from_bytes_with_nul(bytes: &[u8]) -> Result<&Self, FromBytesWithNulError> {
|
||||||
let nul_pos = memchr::memchr(0, bytes);
|
let nul_pos = memchr::memchr(0, bytes);
|
||||||
match nul_pos {
|
match nul_pos {
|
||||||
|
@ -561,10 +561,12 @@ impl CStr {
|
||||||
#[must_use = "this returns the result of the operation, \
|
#[must_use = "this returns the result of the operation, \
|
||||||
without modifying the original"]
|
without modifying the original"]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[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();
|
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
|
// 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.
|
/// 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, \
|
#[must_use = "this returns the result of the operation, \
|
||||||
without modifying the original"]
|
without modifying the original"]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[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] {
|
pub const fn to_bytes_with_nul(&self) -> &[u8] {
|
||||||
// SAFETY: Transmuting a slice of `c_char`s to a slice of `u8`s
|
// SAFETY: Transmuting a slice of `c_char`s to a slice of `u8`s
|
||||||
// is safe on all supported targets.
|
// is safe on all supported targets.
|
||||||
|
@ -612,7 +614,8 @@ impl CStr {
|
||||||
/// assert_eq!(cstr.to_str(), Ok("foo"));
|
/// assert_eq!(cstr.to_str(), Ok("foo"));
|
||||||
/// ```
|
/// ```
|
||||||
#[stable(feature = "cstr_to_str", since = "1.4.0")]
|
#[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()`
|
// 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
|
// 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
|
// be rewritten to do the UTF-8 check inline with the length calculation
|
||||||
|
|
|
@ -113,7 +113,6 @@
|
||||||
#![feature(const_caller_location)]
|
#![feature(const_caller_location)]
|
||||||
#![feature(const_cell_into_inner)]
|
#![feature(const_cell_into_inner)]
|
||||||
#![feature(const_char_from_u32_unchecked)]
|
#![feature(const_char_from_u32_unchecked)]
|
||||||
#![feature(const_cstr_methods)]
|
|
||||||
#![feature(const_discriminant)]
|
#![feature(const_discriminant)]
|
||||||
#![feature(const_eval_select)]
|
#![feature(const_eval_select)]
|
||||||
#![feature(const_exact_div)]
|
#![feature(const_exact_div)]
|
||||||
|
|
|
@ -22,11 +22,10 @@ error[E0637]: `&` without an explicit lifetime name cannot be used here
|
||||||
LL | T: Into<&u32>,
|
LL | T: Into<&u32>,
|
||||||
| ^ explicit lifetime name needed here
|
| ^ explicit lifetime name needed here
|
||||||
|
|
|
|
||||||
help: consider introducing a higher-ranked lifetime here with `for<'a>`
|
help: consider introducing a higher-ranked lifetime here
|
||||||
--> $DIR/E0637.rs:13:8
|
|
||||||
|
|
|
|
||||||
LL | T: Into<&u32>,
|
LL | T: for<'a> Into<&'a u32>,
|
||||||
| ^
|
| +++++++ ++
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
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> {}
|
LL | fn should_error<T>() where T : Into<&u32> {}
|
||||||
| ^ explicit lifetime name needed here
|
| ^ explicit lifetime name needed here
|
||||||
|
|
|
|
||||||
help: consider introducing a higher-ranked lifetime here with `for<'a>`
|
help: consider introducing a higher-ranked lifetime here
|
||||||
--> $DIR/issue-65285-incorrect-explicit-lifetime-name-needed.rs:5:32
|
|
||||||
|
|
|
|
||||||
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
|
error[E0106]: missing lifetime specifier
|
||||||
--> $DIR/issue-65285-incorrect-explicit-lifetime-name-needed.rs:9:20
|
--> $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 bar(self) -> Arc<String> { Arc::new(String::new()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn generic(f: impl Foo) {
|
||||||
|
let x = &*f.bar();
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
// Witness an RPITIT from another crate.
|
// Witness an RPITIT from another crate.
|
||||||
let &() = Foreign.bar();
|
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>) {}
|
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() {}
|
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
|
--> $DIR/universal_wrong_hrtb.rs:5:73
|
||||||
|
|
|
|
||||||
LL | fn test_argument_position(x: impl for<'a> Trait<'a, Assoc = impl Copy + 'a>) {}
|
LL | fn test_argument_position(x: impl for<'a> Trait<'a, Assoc = impl Copy + 'a>) {}
|
||||||
| ^^
|
| -- lifetime declared here ^^
|
||||||
|
|
|
||||||
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>) {}
|
|
||||||
| ^^
|
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ LL | *a = 5;
|
||||||
| ------ first borrow later used here
|
| ------ 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 `.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
|
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
|
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>
|
LL | T: WithType<&u32>
|
||||||
| ^ explicit lifetime name needed here
|
| ^ explicit lifetime name needed here
|
||||||
|
|
|
|
||||||
help: consider introducing a higher-ranked lifetime here with `for<'a>`
|
help: consider introducing a higher-ranked lifetime here
|
||||||
--> $DIR/where-clause-trait-impl-region.rs:11:8
|
|
||||||
|
|
|
|
||||||
LL | T: WithType<&u32>
|
LL | T: for<'a> WithType<&'a u32>
|
||||||
| ^
|
| +++++++ ++
|
||||||
|
|
||||||
error: aborting due to previous error
|
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
|
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>
|
LL | T: WithType<&u32>
|
||||||
| ^ explicit lifetime name needed here
|
| ^ explicit lifetime name needed here
|
||||||
|
|
|
|
||||||
help: consider introducing a higher-ranked lifetime here with `for<'a>`
|
help: consider introducing a higher-ranked lifetime here
|
||||||
--> $DIR/where-clause-trait-impl-region.rs:11:8
|
|
||||||
|
|
|
|
||||||
LL | T: WithType<&u32>
|
LL | T: for<'a> WithType<&'a u32>
|
||||||
| ^
|
| +++++++ ++
|
||||||
|
|
||||||
error: aborting due to previous error
|
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
|
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>
|
LL | T: WithType<&u32>
|
||||||
| ^ explicit lifetime name needed here
|
| ^ explicit lifetime name needed here
|
||||||
|
|
|
|
||||||
help: consider introducing a higher-ranked lifetime here with `for<'a>`
|
help: consider introducing a higher-ranked lifetime here
|
||||||
--> $DIR/where-clause-inherent-impl-ampersand.rs:13:8
|
|
||||||
|
|
|
|
||||||
LL | T: WithType<&u32>
|
LL | T: for<'a> WithType<&'a u32>
|
||||||
| ^
|
| +++++++ ++
|
||||||
|
|
||||||
error: aborting due to previous error
|
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
|
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>
|
LL | T: WithType<&u32>
|
||||||
| ^ explicit lifetime name needed here
|
| ^ explicit lifetime name needed here
|
||||||
|
|
|
|
||||||
help: consider introducing a higher-ranked lifetime here with `for<'a>`
|
help: consider introducing a higher-ranked lifetime here
|
||||||
--> $DIR/where-clause-inherent-impl-ampersand.rs:13:8
|
|
||||||
|
|
|
|
||||||
LL | T: WithType<&u32>
|
LL | T: for<'a> WithType<&'a u32>
|
||||||
| ^
|
| +++++++ ++
|
||||||
|
|
||||||
error: aborting due to previous error
|
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
Add a link
Reference in a new issue