Auto merge of #122206 - matthiaskrgr:rollup-4txx9wx, r=matthiaskrgr
Rollup of 9 pull requests Successful merges: - #121201 (align_offset, align_to: no longer allow implementations to spuriously fail to align) - #122076 (Tweak the way we protect in-place function arguments in interpreters) - #122100 (Better comment for implicit captures in RPITIT) - #122157 (Add the new description field to Target::to_json, and add descriptions for some MSVC targets) - #122164 (Fix misaligned loads when loading UEFI arg pointers) - #122171 (Add some new solver tests) - #122172 (Don't ICE if we collect no RPITITs unless there are no unification errors) - #122197 (inspect formatter: add braces) - #122198 (Remove handling for previously dropped LLVM version) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
46b180ec24
47 changed files with 418 additions and 214 deletions
|
|
@ -260,35 +260,29 @@ pub unsafe fn create_module<'ll>(
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(BranchProtection { bti, pac_ret }) = sess.opts.unstable_opts.branch_protection {
|
if let Some(BranchProtection { bti, pac_ret }) = sess.opts.unstable_opts.branch_protection {
|
||||||
let behavior = if llvm_version >= (15, 0, 0) {
|
|
||||||
llvm::LLVMModFlagBehavior::Min
|
|
||||||
} else {
|
|
||||||
llvm::LLVMModFlagBehavior::Error
|
|
||||||
};
|
|
||||||
|
|
||||||
if sess.target.arch == "aarch64" {
|
if sess.target.arch == "aarch64" {
|
||||||
llvm::LLVMRustAddModuleFlag(
|
llvm::LLVMRustAddModuleFlag(
|
||||||
llmod,
|
llmod,
|
||||||
behavior,
|
llvm::LLVMModFlagBehavior::Min,
|
||||||
c"branch-target-enforcement".as_ptr().cast(),
|
c"branch-target-enforcement".as_ptr().cast(),
|
||||||
bti.into(),
|
bti.into(),
|
||||||
);
|
);
|
||||||
llvm::LLVMRustAddModuleFlag(
|
llvm::LLVMRustAddModuleFlag(
|
||||||
llmod,
|
llmod,
|
||||||
behavior,
|
llvm::LLVMModFlagBehavior::Min,
|
||||||
c"sign-return-address".as_ptr().cast(),
|
c"sign-return-address".as_ptr().cast(),
|
||||||
pac_ret.is_some().into(),
|
pac_ret.is_some().into(),
|
||||||
);
|
);
|
||||||
let pac_opts = pac_ret.unwrap_or(PacRet { leaf: false, key: PAuthKey::A });
|
let pac_opts = pac_ret.unwrap_or(PacRet { leaf: false, key: PAuthKey::A });
|
||||||
llvm::LLVMRustAddModuleFlag(
|
llvm::LLVMRustAddModuleFlag(
|
||||||
llmod,
|
llmod,
|
||||||
behavior,
|
llvm::LLVMModFlagBehavior::Min,
|
||||||
c"sign-return-address-all".as_ptr().cast(),
|
c"sign-return-address-all".as_ptr().cast(),
|
||||||
pac_opts.leaf.into(),
|
pac_opts.leaf.into(),
|
||||||
);
|
);
|
||||||
llvm::LLVMRustAddModuleFlag(
|
llvm::LLVMRustAddModuleFlag(
|
||||||
llmod,
|
llmod,
|
||||||
behavior,
|
llvm::LLVMModFlagBehavior::Min,
|
||||||
c"sign-return-address-with-bkey".as_ptr().cast(),
|
c"sign-return-address-with-bkey".as_ptr().cast(),
|
||||||
u32::from(pac_opts.key == PAuthKey::B),
|
u32::from(pac_opts.key == PAuthKey::B),
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -510,11 +510,13 @@ fn get_argc_argv<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
|
||||||
// Params for UEFI
|
// Params for UEFI
|
||||||
let param_handle = bx.get_param(0);
|
let param_handle = bx.get_param(0);
|
||||||
let param_system_table = bx.get_param(1);
|
let param_system_table = bx.get_param(1);
|
||||||
|
let ptr_size = bx.tcx().data_layout.pointer_size;
|
||||||
|
let ptr_align = bx.tcx().data_layout.pointer_align.abi;
|
||||||
let arg_argc = bx.const_int(cx.type_isize(), 2);
|
let arg_argc = bx.const_int(cx.type_isize(), 2);
|
||||||
let arg_argv = bx.alloca(cx.type_array(cx.type_ptr(), 2), Align::ONE);
|
let arg_argv = bx.alloca(cx.type_array(cx.type_ptr(), 2), ptr_align);
|
||||||
bx.store(param_handle, arg_argv, Align::ONE);
|
bx.store(param_handle, arg_argv, ptr_align);
|
||||||
let arg_argv_el1 = bx.gep(cx.type_ptr(), arg_argv, &[bx.const_int(cx.type_int(), 1)]);
|
let arg_argv_el1 = bx.inbounds_ptradd(arg_argv, bx.const_usize(ptr_size.bytes()));
|
||||||
bx.store(param_system_table, arg_argv_el1, Align::ONE);
|
bx.store(param_system_table, arg_argv_el1, ptr_align);
|
||||||
(arg_argc, arg_argv)
|
(arg_argc, arg_argv)
|
||||||
} else if cx.sess().target.main_needs_argc_argv {
|
} else if cx.sess().target.main_needs_argc_argv {
|
||||||
// Params from native `main()` used as args for rust start function
|
// Params from native `main()` used as args for rust start function
|
||||||
|
|
|
||||||
|
|
@ -227,7 +227,7 @@ impl<'mir, 'tcx: 'mir> CompileTimeEvalContext<'mir, 'tcx> {
|
||||||
if self.tcx.has_attr(def_id, sym::rustc_const_panic_str)
|
if self.tcx.has_attr(def_id, sym::rustc_const_panic_str)
|
||||||
|| Some(def_id) == self.tcx.lang_items().begin_panic_fn()
|
|| Some(def_id) == self.tcx.lang_items().begin_panic_fn()
|
||||||
{
|
{
|
||||||
let args = self.copy_fn_args(args)?;
|
let args = self.copy_fn_args(args);
|
||||||
// &str or &&str
|
// &str or &&str
|
||||||
assert!(args.len() == 1);
|
assert!(args.len() == 1);
|
||||||
|
|
||||||
|
|
@ -254,7 +254,7 @@ impl<'mir, 'tcx: 'mir> CompileTimeEvalContext<'mir, 'tcx> {
|
||||||
|
|
||||||
return Ok(Some(new_instance));
|
return Ok(Some(new_instance));
|
||||||
} else if Some(def_id) == self.tcx.lang_items().align_offset_fn() {
|
} else if Some(def_id) == self.tcx.lang_items().align_offset_fn() {
|
||||||
let args = self.copy_fn_args(args)?;
|
let args = self.copy_fn_args(args);
|
||||||
// For align_offset, we replace the function call if the pointer has no address.
|
// For align_offset, we replace the function call if the pointer has no address.
|
||||||
match self.align_offset(instance, &args, dest, ret)? {
|
match self.align_offset(instance, &args, dest, ret)? {
|
||||||
ControlFlow::Continue(()) => return Ok(Some(instance)),
|
ControlFlow::Continue(()) => return Ok(Some(instance)),
|
||||||
|
|
|
||||||
|
|
@ -472,11 +472,11 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized {
|
||||||
/// argument/return value was actually copied or passed in-place..
|
/// argument/return value was actually copied or passed in-place..
|
||||||
fn protect_in_place_function_argument(
|
fn protect_in_place_function_argument(
|
||||||
ecx: &mut InterpCx<'mir, 'tcx, Self>,
|
ecx: &mut InterpCx<'mir, 'tcx, Self>,
|
||||||
place: &PlaceTy<'tcx, Self::Provenance>,
|
mplace: &MPlaceTy<'tcx, Self::Provenance>,
|
||||||
) -> InterpResult<'tcx> {
|
) -> InterpResult<'tcx> {
|
||||||
// Without an aliasing model, all we can do is put `Uninit` into the place.
|
// Without an aliasing model, all we can do is put `Uninit` into the place.
|
||||||
// Conveniently this also ensures that the place actually points to suitable memory.
|
// Conveniently this also ensures that the place actually points to suitable memory.
|
||||||
ecx.write_uninit(place)
|
ecx.write_uninit(mplace)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Called immediately before a new stack frame gets pushed.
|
/// Called immediately before a new stack frame gets pushed.
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
|
||||||
|
use either::Either;
|
||||||
|
|
||||||
use rustc_middle::{
|
use rustc_middle::{
|
||||||
mir,
|
mir,
|
||||||
ty::{
|
ty::{
|
||||||
|
|
@ -29,14 +31,14 @@ pub enum FnArg<'tcx, Prov: Provenance = CtfeProvenance> {
|
||||||
Copy(OpTy<'tcx, Prov>),
|
Copy(OpTy<'tcx, Prov>),
|
||||||
/// Allow for the argument to be passed in-place: destroy the value originally stored at that place and
|
/// Allow for the argument to be passed in-place: destroy the value originally stored at that place and
|
||||||
/// make the place inaccessible for the duration of the function call.
|
/// make the place inaccessible for the duration of the function call.
|
||||||
InPlace(PlaceTy<'tcx, Prov>),
|
InPlace(MPlaceTy<'tcx, Prov>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx, Prov: Provenance> FnArg<'tcx, Prov> {
|
impl<'tcx, Prov: Provenance> FnArg<'tcx, Prov> {
|
||||||
pub fn layout(&self) -> &TyAndLayout<'tcx> {
|
pub fn layout(&self) -> &TyAndLayout<'tcx> {
|
||||||
match self {
|
match self {
|
||||||
FnArg::Copy(op) => &op.layout,
|
FnArg::Copy(op) => &op.layout,
|
||||||
FnArg::InPlace(place) => &place.layout,
|
FnArg::InPlace(mplace) => &mplace.layout,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -44,13 +46,10 @@ impl<'tcx, Prov: Provenance> FnArg<'tcx, Prov> {
|
||||||
impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
/// Make a copy of the given fn_arg. Any `InPlace` are degenerated to copies, no protection of the
|
/// Make a copy of the given fn_arg. Any `InPlace` are degenerated to copies, no protection of the
|
||||||
/// original memory occurs.
|
/// original memory occurs.
|
||||||
pub fn copy_fn_arg(
|
pub fn copy_fn_arg(&self, arg: &FnArg<'tcx, M::Provenance>) -> OpTy<'tcx, M::Provenance> {
|
||||||
&self,
|
|
||||||
arg: &FnArg<'tcx, M::Provenance>,
|
|
||||||
) -> InterpResult<'tcx, OpTy<'tcx, M::Provenance>> {
|
|
||||||
match arg {
|
match arg {
|
||||||
FnArg::Copy(op) => Ok(op.clone()),
|
FnArg::Copy(op) => op.clone(),
|
||||||
FnArg::InPlace(place) => self.place_to_op(place),
|
FnArg::InPlace(mplace) => mplace.clone().into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -59,7 +58,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
pub fn copy_fn_args(
|
pub fn copy_fn_args(
|
||||||
&self,
|
&self,
|
||||||
args: &[FnArg<'tcx, M::Provenance>],
|
args: &[FnArg<'tcx, M::Provenance>],
|
||||||
) -> InterpResult<'tcx, Vec<OpTy<'tcx, M::Provenance>>> {
|
) -> Vec<OpTy<'tcx, M::Provenance>> {
|
||||||
args.iter().map(|fn_arg| self.copy_fn_arg(fn_arg)).collect()
|
args.iter().map(|fn_arg| self.copy_fn_arg(fn_arg)).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -70,7 +69,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
) -> InterpResult<'tcx, FnArg<'tcx, M::Provenance>> {
|
) -> InterpResult<'tcx, FnArg<'tcx, M::Provenance>> {
|
||||||
Ok(match arg {
|
Ok(match arg {
|
||||||
FnArg::Copy(op) => FnArg::Copy(self.project_field(op, field)?),
|
FnArg::Copy(op) => FnArg::Copy(self.project_field(op, field)?),
|
||||||
FnArg::InPlace(place) => FnArg::InPlace(self.project_field(place, field)?),
|
FnArg::InPlace(mplace) => FnArg::InPlace(self.project_field(mplace, field)?),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -238,10 +237,36 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
) -> InterpResult<'tcx, Vec<FnArg<'tcx, M::Provenance>>> {
|
) -> InterpResult<'tcx, Vec<FnArg<'tcx, M::Provenance>>> {
|
||||||
ops.iter()
|
ops.iter()
|
||||||
.map(|op| {
|
.map(|op| {
|
||||||
Ok(match &op.node {
|
let arg = match &op.node {
|
||||||
mir::Operand::Move(place) => FnArg::InPlace(self.eval_place(*place)?),
|
mir::Operand::Copy(_) | mir::Operand::Constant(_) => {
|
||||||
_ => FnArg::Copy(self.eval_operand(&op.node, None)?),
|
// Make a regular copy.
|
||||||
})
|
let op = self.eval_operand(&op.node, None)?;
|
||||||
|
FnArg::Copy(op)
|
||||||
|
}
|
||||||
|
mir::Operand::Move(place) => {
|
||||||
|
// If this place lives in memory, preserve its location.
|
||||||
|
// We call `place_to_op` which will be an `MPlaceTy` whenever there exists
|
||||||
|
// an mplace for this place. (This is in contrast to `PlaceTy::as_mplace_or_local`
|
||||||
|
// which can return a local even if that has an mplace.)
|
||||||
|
let place = self.eval_place(*place)?;
|
||||||
|
let op = self.place_to_op(&place)?;
|
||||||
|
|
||||||
|
match op.as_mplace_or_imm() {
|
||||||
|
Either::Left(mplace) => FnArg::InPlace(mplace),
|
||||||
|
Either::Right(_imm) => {
|
||||||
|
// This argument doesn't live in memory, so there's no place
|
||||||
|
// to make inaccessible during the call.
|
||||||
|
// We rely on there not being any stray `PlaceTy` that would let the
|
||||||
|
// caller directly access this local!
|
||||||
|
// This is also crucial for tail calls, where we want the `FnArg` to
|
||||||
|
// stay valid when the old stack frame gets popped.
|
||||||
|
FnArg::Copy(op)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(arg)
|
||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
@ -451,7 +476,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
// We work with a copy of the argument for now; if this is in-place argument passing, we
|
// We work with a copy of the argument for now; if this is in-place argument passing, we
|
||||||
// will later protect the source it comes from. This means the callee cannot observe if we
|
// will later protect the source it comes from. This means the callee cannot observe if we
|
||||||
// did in-place of by-copy argument passing, except for pointer equality tests.
|
// did in-place of by-copy argument passing, except for pointer equality tests.
|
||||||
let caller_arg_copy = self.copy_fn_arg(caller_arg)?;
|
let caller_arg_copy = self.copy_fn_arg(caller_arg);
|
||||||
if !already_live {
|
if !already_live {
|
||||||
let local = callee_arg.as_local().unwrap();
|
let local = callee_arg.as_local().unwrap();
|
||||||
let meta = caller_arg_copy.meta();
|
let meta = caller_arg_copy.meta();
|
||||||
|
|
@ -469,8 +494,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
// specifically.)
|
// specifically.)
|
||||||
self.copy_op_allow_transmute(&caller_arg_copy, &callee_arg)?;
|
self.copy_op_allow_transmute(&caller_arg_copy, &callee_arg)?;
|
||||||
// If this was an in-place pass, protect the place it comes from for the duration of the call.
|
// If this was an in-place pass, protect the place it comes from for the duration of the call.
|
||||||
if let FnArg::InPlace(place) = caller_arg {
|
if let FnArg::InPlace(mplace) = caller_arg {
|
||||||
M::protect_in_place_function_argument(self, place)?;
|
M::protect_in_place_function_argument(self, mplace)?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
@ -517,7 +542,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
M::call_intrinsic(
|
M::call_intrinsic(
|
||||||
self,
|
self,
|
||||||
instance,
|
instance,
|
||||||
&self.copy_fn_args(args)?,
|
&self.copy_fn_args(args),
|
||||||
destination,
|
destination,
|
||||||
target,
|
target,
|
||||||
unwind,
|
unwind,
|
||||||
|
|
@ -594,8 +619,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
.map(|arg| (
|
.map(|arg| (
|
||||||
arg.layout().ty,
|
arg.layout().ty,
|
||||||
match arg {
|
match arg {
|
||||||
FnArg::Copy(op) => format!("copy({:?})", *op),
|
FnArg::Copy(op) => format!("copy({op:?})"),
|
||||||
FnArg::InPlace(place) => format!("in-place({:?})", *place),
|
FnArg::InPlace(mplace) => format!("in-place({mplace:?})"),
|
||||||
}
|
}
|
||||||
))
|
))
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
|
|
@ -717,8 +742,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
callee_ty: callee_fn_abi.ret.layout.ty
|
callee_ty: callee_fn_abi.ret.layout.ty
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Protect return place for in-place return value passing.
|
// Protect return place for in-place return value passing.
|
||||||
M::protect_in_place_function_argument(self, &destination.clone().into())?;
|
M::protect_in_place_function_argument(self, &destination)?;
|
||||||
|
|
||||||
// Don't forget to mark "initially live" locals as live.
|
// Don't forget to mark "initially live" locals as live.
|
||||||
self.storage_live_for_always_live_locals()?;
|
self.storage_live_for_always_live_locals()?;
|
||||||
|
|
@ -741,7 +767,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
// An `InPlace` does nothing here, we keep the original receiver intact. We can't
|
// An `InPlace` does nothing here, we keep the original receiver intact. We can't
|
||||||
// really pass the argument in-place anyway, and we are constructing a new
|
// really pass the argument in-place anyway, and we are constructing a new
|
||||||
// `Immediate` receiver.
|
// `Immediate` receiver.
|
||||||
let mut receiver = self.copy_fn_arg(&args[0])?;
|
let mut receiver = self.copy_fn_arg(&args[0]);
|
||||||
let receiver_place = loop {
|
let receiver_place = loop {
|
||||||
match receiver.layout.ty.kind() {
|
match receiver.layout.ty.kind() {
|
||||||
ty::Ref(..) | ty::RawPtr(..) => {
|
ty::Ref(..) | ty::RawPtr(..) => {
|
||||||
|
|
|
||||||
|
|
@ -1,57 +1,26 @@
|
||||||
A lifetime bound on a trait implementation was captured at an incorrect place.
|
An `impl Trait` captured a higher-ranked lifetime, which is not supported.
|
||||||
|
|
||||||
|
Currently, `impl Trait` types are only allowed to capture lifetimes from
|
||||||
|
their parent items, and not from any `for<'a>` binders in scope.
|
||||||
|
|
||||||
Erroneous code example:
|
Erroneous code example:
|
||||||
|
|
||||||
```compile_fail,E0657
|
```compile_fail,E0657
|
||||||
trait Id<T> {}
|
trait BorrowInto<'a> {
|
||||||
trait Lt<'a> {}
|
type Target;
|
||||||
|
|
||||||
impl<'a> Lt<'a> for () {}
|
fn borrow_into(&'a self) -> Self::Target;
|
||||||
impl<T> Id<T> for T {}
|
|
||||||
|
|
||||||
fn free_fn_capture_hrtb_in_impl_trait()
|
|
||||||
-> Box<for<'a> Id<impl Lt<'a>>> // error!
|
|
||||||
{
|
|
||||||
Box::new(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Foo;
|
impl<'a> BorrowInto<'a> for () {
|
||||||
impl Foo {
|
type Target = &'a ();
|
||||||
fn impl_fn_capture_hrtb_in_impl_trait()
|
|
||||||
-> Box<for<'a> Id<impl Lt<'a>>> // error!
|
fn borrow_into(&'a self) -> Self::Target {
|
||||||
{
|
self
|
||||||
Box::new(())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
|
||||||
|
|
||||||
Here, you have used the inappropriate lifetime in the `impl Trait`,
|
fn opaque() -> impl for<'a> BorrowInto<'a, Target = impl Sized + 'a> {
|
||||||
The `impl Trait` can only capture lifetimes bound at the fn or impl
|
()
|
||||||
level.
|
|
||||||
|
|
||||||
To fix this we have to define the lifetime at the function or impl
|
|
||||||
level and use that lifetime in the `impl Trait`. For example you can
|
|
||||||
define the lifetime at the function:
|
|
||||||
|
|
||||||
```
|
|
||||||
trait Id<T> {}
|
|
||||||
trait Lt<'a> {}
|
|
||||||
|
|
||||||
impl<'a> Lt<'a> for () {}
|
|
||||||
impl<T> Id<T> for T {}
|
|
||||||
|
|
||||||
fn free_fn_capture_hrtb_in_impl_trait<'b>()
|
|
||||||
-> Box<for<'a> Id<impl Lt<'b>>> // ok!
|
|
||||||
{
|
|
||||||
Box::new(())
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Foo;
|
|
||||||
impl Foo {
|
|
||||||
fn impl_fn_capture_hrtb_in_impl_trait<'b>()
|
|
||||||
-> Box<for<'a> Id<impl Lt<'b>>> // ok!
|
|
||||||
{
|
|
||||||
Box::new(())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
|
||||||
|
|
@ -312,6 +312,10 @@ hir_analysis_only_current_traits_primitive = only traits defined in the current
|
||||||
|
|
||||||
hir_analysis_only_current_traits_ty = `{$ty}` is not defined in the current crate
|
hir_analysis_only_current_traits_ty = `{$ty}` is not defined in the current crate
|
||||||
|
|
||||||
|
hir_analysis_opaque_captures_higher_ranked_lifetime = `impl Trait` cannot capture {$bad_place}
|
||||||
|
.label = `impl Trait` implicitly captures all lifetimes in scope
|
||||||
|
.note = lifetime declared here
|
||||||
|
|
||||||
hir_analysis_paren_sugar_attribute = the `#[rustc_paren_sugar]` attribute is a temporary means of controlling which traits can use parenthetical notation
|
hir_analysis_paren_sugar_attribute = the `#[rustc_paren_sugar]` attribute is a temporary means of controlling which traits can use parenthetical notation
|
||||||
.help = add `#![feature(unboxed_closures)]` to the crate attributes to use it
|
.help = add `#![feature(unboxed_closures)]` to the crate attributes to use it
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -521,14 +521,6 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
|
||||||
)
|
)
|
||||||
.fold_with(&mut collector);
|
.fold_with(&mut collector);
|
||||||
|
|
||||||
if !unnormalized_trait_sig.output().references_error() {
|
|
||||||
debug_assert_ne!(
|
|
||||||
collector.types.len(),
|
|
||||||
0,
|
|
||||||
"expect >1 RPITITs in call to `collect_return_position_impl_trait_in_trait_tys`"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
let trait_sig = ocx.normalize(&misc_cause, param_env, unnormalized_trait_sig);
|
let trait_sig = ocx.normalize(&misc_cause, param_env, unnormalized_trait_sig);
|
||||||
trait_sig.error_reported()?;
|
trait_sig.error_reported()?;
|
||||||
let trait_return_ty = trait_sig.output();
|
let trait_return_ty = trait_sig.output();
|
||||||
|
|
@ -647,6 +639,13 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !unnormalized_trait_sig.output().references_error() {
|
||||||
|
debug_assert!(
|
||||||
|
!collector.types.is_empty(),
|
||||||
|
"expect >0 RPITITs in call to `collect_return_position_impl_trait_in_trait_tys`"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// FIXME: This has the same issue as #108544, but since this isn't breaking
|
// FIXME: This has the same issue as #108544, but since this isn't breaking
|
||||||
// existing code, I'm not particularly inclined to do the same hack as above
|
// existing code, I'm not particularly inclined to do the same hack as above
|
||||||
// where we process wf obligations manually. This can be fixed in a forward-
|
// where we process wf obligations manually. This can be fixed in a forward-
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,6 @@
|
||||||
use core::ops::ControlFlow;
|
use core::ops::ControlFlow;
|
||||||
use rustc_ast::visit::walk_list;
|
use rustc_ast::visit::walk_list;
|
||||||
use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
|
use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
|
||||||
use rustc_errors::{codes::*, struct_span_code_err};
|
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::def::{DefKind, Res};
|
use rustc_hir::def::{DefKind, Res};
|
||||||
use rustc_hir::def_id::LocalDefId;
|
use rustc_hir::def_id::LocalDefId;
|
||||||
|
|
@ -669,34 +668,47 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
|
||||||
// and ban them. Type variables instantiated inside binders aren't
|
// and ban them. Type variables instantiated inside binders aren't
|
||||||
// well-supported at the moment, so this doesn't work.
|
// well-supported at the moment, so this doesn't work.
|
||||||
// In the future, this should be fixed and this error should be removed.
|
// In the future, this should be fixed and this error should be removed.
|
||||||
let def = self.map.defs.get(&lifetime.hir_id).cloned();
|
let def = self.map.defs.get(&lifetime.hir_id).copied();
|
||||||
let Some(ResolvedArg::LateBound(_, _, def_id)) = def else { continue };
|
let Some(ResolvedArg::LateBound(_, _, lifetime_def_id)) = def else { continue };
|
||||||
let Some(def_id) = def_id.as_local() else { continue };
|
let Some(lifetime_def_id) = lifetime_def_id.as_local() else { continue };
|
||||||
let hir_id = self.tcx.local_def_id_to_hir_id(def_id);
|
let lifetime_hir_id = self.tcx.local_def_id_to_hir_id(lifetime_def_id);
|
||||||
// Ensure that the parent of the def is an item, not HRTB
|
|
||||||
let parent_id = self.tcx.parent_hir_id(hir_id);
|
let bad_place = match self.tcx.hir_node(self.tcx.parent_hir_id(lifetime_hir_id))
|
||||||
if !parent_id.is_owner() {
|
|
||||||
struct_span_code_err!(
|
|
||||||
self.tcx.dcx(),
|
|
||||||
lifetime.ident.span,
|
|
||||||
E0657,
|
|
||||||
"`impl Trait` can only capture lifetimes bound at the fn or impl level"
|
|
||||||
)
|
|
||||||
.emit();
|
|
||||||
self.uninsert_lifetime_on_error(lifetime, def.unwrap());
|
|
||||||
}
|
|
||||||
if let hir::Node::Item(hir::Item {
|
|
||||||
kind: hir::ItemKind::OpaqueTy { .. }, ..
|
|
||||||
}) = self.tcx.hir_node(parent_id)
|
|
||||||
{
|
{
|
||||||
self.tcx.dcx().struct_span_err(
|
// Opaques do not declare their own lifetimes, so if a lifetime comes from an opaque
|
||||||
lifetime.ident.span,
|
// it must be a reified late-bound lifetime from a trait goal.
|
||||||
"higher kinded lifetime bounds on nested opaque types are not supported yet",
|
hir::Node::Item(hir::Item {
|
||||||
)
|
kind: hir::ItemKind::OpaqueTy { .. }, ..
|
||||||
.with_span_note(self.tcx.def_span(def_id), "lifetime declared here")
|
}) => "higher-ranked lifetime from outer `impl Trait`",
|
||||||
.emit();
|
// Other items are fine.
|
||||||
self.uninsert_lifetime_on_error(lifetime, def.unwrap());
|
hir::Node::Item(_) | hir::Node::TraitItem(_) | hir::Node::ImplItem(_) => {
|
||||||
}
|
continue;
|
||||||
|
}
|
||||||
|
hir::Node::Ty(hir::Ty { kind: hir::TyKind::BareFn(_), .. }) => {
|
||||||
|
"higher-ranked lifetime from function pointer"
|
||||||
|
}
|
||||||
|
hir::Node::Ty(hir::Ty { kind: hir::TyKind::TraitObject(..), .. }) => {
|
||||||
|
"higher-ranked lifetime from `dyn` type"
|
||||||
|
}
|
||||||
|
_ => "higher-ranked lifetime",
|
||||||
|
};
|
||||||
|
|
||||||
|
let (span, label) = if lifetime.ident.span == self.tcx.def_span(lifetime_def_id)
|
||||||
|
{
|
||||||
|
let opaque_span = self.tcx.def_span(item_id.owner_id);
|
||||||
|
(opaque_span, Some(opaque_span))
|
||||||
|
} else {
|
||||||
|
(lifetime.ident.span, None)
|
||||||
|
};
|
||||||
|
|
||||||
|
// Ensure that the parent of the def is an item, not HRTB
|
||||||
|
self.tcx.dcx().emit_err(errors::OpaqueCapturesHigherRankedLifetime {
|
||||||
|
span,
|
||||||
|
label,
|
||||||
|
decl_span: self.tcx.def_span(lifetime_def_id),
|
||||||
|
bad_place,
|
||||||
|
});
|
||||||
|
self.uninsert_lifetime_on_error(lifetime, def.unwrap());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => intravisit::walk_ty(self, ty),
|
_ => intravisit::walk_ty(self, ty),
|
||||||
|
|
|
||||||
|
|
@ -1607,3 +1607,15 @@ pub struct UnnamedFieldsReprFieldDefined {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
#[diag(hir_analysis_opaque_captures_higher_ranked_lifetime, code = E0657)]
|
||||||
|
pub struct OpaqueCapturesHigherRankedLifetime {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
#[label]
|
||||||
|
pub label: Option<Span>,
|
||||||
|
#[note]
|
||||||
|
pub decl_span: Span,
|
||||||
|
pub bad_place: &'static str,
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,22 +4,31 @@ pub(super) struct ProofTreeFormatter<'a, 'b> {
|
||||||
f: &'a mut (dyn Write + 'b),
|
f: &'a mut (dyn Write + 'b),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum IndentorState {
|
||||||
|
StartWithNewline,
|
||||||
|
OnNewline,
|
||||||
|
Inline,
|
||||||
|
}
|
||||||
|
|
||||||
/// A formatter which adds 4 spaces of indentation to its input before
|
/// A formatter which adds 4 spaces of indentation to its input before
|
||||||
/// passing it on to its nested formatter.
|
/// passing it on to its nested formatter.
|
||||||
///
|
///
|
||||||
/// We can use this for arbitrary levels of indentation by nesting it.
|
/// We can use this for arbitrary levels of indentation by nesting it.
|
||||||
struct Indentor<'a, 'b> {
|
struct Indentor<'a, 'b> {
|
||||||
f: &'a mut (dyn Write + 'b),
|
f: &'a mut (dyn Write + 'b),
|
||||||
on_newline: bool,
|
state: IndentorState,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Write for Indentor<'_, '_> {
|
impl Write for Indentor<'_, '_> {
|
||||||
fn write_str(&mut self, s: &str) -> std::fmt::Result {
|
fn write_str(&mut self, s: &str) -> std::fmt::Result {
|
||||||
for line in s.split_inclusive('\n') {
|
for line in s.split_inclusive('\n') {
|
||||||
if self.on_newline {
|
match self.state {
|
||||||
self.f.write_str(" ")?;
|
IndentorState::StartWithNewline => self.f.write_str("\n ")?,
|
||||||
|
IndentorState::OnNewline => self.f.write_str(" ")?,
|
||||||
|
IndentorState::Inline => {}
|
||||||
}
|
}
|
||||||
self.on_newline = line.ends_with('\n');
|
self.state =
|
||||||
|
if line.ends_with('\n') { IndentorState::OnNewline } else { IndentorState::Inline };
|
||||||
self.f.write_str(line)?;
|
self.f.write_str(line)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -32,11 +41,15 @@ impl<'a, 'b> ProofTreeFormatter<'a, 'b> {
|
||||||
ProofTreeFormatter { f }
|
ProofTreeFormatter { f }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn nested<F, R>(&mut self, func: F) -> R
|
fn nested<F>(&mut self, func: F) -> std::fmt::Result
|
||||||
where
|
where
|
||||||
F: FnOnce(&mut ProofTreeFormatter<'_, '_>) -> R,
|
F: FnOnce(&mut ProofTreeFormatter<'_, '_>) -> std::fmt::Result,
|
||||||
{
|
{
|
||||||
func(&mut ProofTreeFormatter { f: &mut Indentor { f: self.f, on_newline: true } })
|
write!(self.f, " {{")?;
|
||||||
|
func(&mut ProofTreeFormatter {
|
||||||
|
f: &mut Indentor { f: self.f, state: IndentorState::StartWithNewline },
|
||||||
|
})?;
|
||||||
|
writeln!(self.f, "}}")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn format_goal_evaluation(&mut self, eval: &GoalEvaluation<'_>) -> std::fmt::Result {
|
pub(super) fn format_goal_evaluation(&mut self, eval: &GoalEvaluation<'_>) -> std::fmt::Result {
|
||||||
|
|
@ -47,7 +60,7 @@ impl<'a, 'b> ProofTreeFormatter<'a, 'b> {
|
||||||
IsNormalizesToHack::Yes => "NORMALIZES-TO HACK GOAL",
|
IsNormalizesToHack::Yes => "NORMALIZES-TO HACK GOAL",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
writeln!(self.f, "{}: {:?}", goal_text, eval.uncanonicalized_goal)?;
|
write!(self.f, "{}: {:?}", goal_text, eval.uncanonicalized_goal)?;
|
||||||
self.nested(|this| this.format_canonical_goal_evaluation(&eval.evaluation))
|
self.nested(|this| this.format_canonical_goal_evaluation(&eval.evaluation))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -69,7 +82,7 @@ impl<'a, 'b> ProofTreeFormatter<'a, 'b> {
|
||||||
}
|
}
|
||||||
CanonicalGoalEvaluationKind::Evaluation { revisions } => {
|
CanonicalGoalEvaluationKind::Evaluation { revisions } => {
|
||||||
for (n, step) in revisions.iter().enumerate() {
|
for (n, step) in revisions.iter().enumerate() {
|
||||||
writeln!(self.f, "REVISION {n}")?;
|
write!(self.f, "REVISION {n}")?;
|
||||||
self.nested(|this| this.format_evaluation_step(step))?;
|
self.nested(|this| this.format_evaluation_step(step))?;
|
||||||
}
|
}
|
||||||
writeln!(self.f, "RESULT: {:?}", eval.result)
|
writeln!(self.f, "RESULT: {:?}", eval.result)
|
||||||
|
|
@ -88,25 +101,25 @@ impl<'a, 'b> ProofTreeFormatter<'a, 'b> {
|
||||||
pub(super) fn format_probe(&mut self, probe: &Probe<'_>) -> std::fmt::Result {
|
pub(super) fn format_probe(&mut self, probe: &Probe<'_>) -> std::fmt::Result {
|
||||||
match &probe.kind {
|
match &probe.kind {
|
||||||
ProbeKind::Root { result } => {
|
ProbeKind::Root { result } => {
|
||||||
writeln!(self.f, "ROOT RESULT: {result:?}")
|
write!(self.f, "ROOT RESULT: {result:?}")
|
||||||
}
|
}
|
||||||
ProbeKind::NormalizedSelfTyAssembly => {
|
ProbeKind::NormalizedSelfTyAssembly => {
|
||||||
writeln!(self.f, "NORMALIZING SELF TY FOR ASSEMBLY:")
|
write!(self.f, "NORMALIZING SELF TY FOR ASSEMBLY:")
|
||||||
}
|
}
|
||||||
ProbeKind::UnsizeAssembly => {
|
ProbeKind::UnsizeAssembly => {
|
||||||
writeln!(self.f, "ASSEMBLING CANDIDATES FOR UNSIZING:")
|
write!(self.f, "ASSEMBLING CANDIDATES FOR UNSIZING:")
|
||||||
}
|
}
|
||||||
ProbeKind::UpcastProjectionCompatibility => {
|
ProbeKind::UpcastProjectionCompatibility => {
|
||||||
writeln!(self.f, "PROBING FOR PROJECTION COMPATIBILITY FOR UPCASTING:")
|
write!(self.f, "PROBING FOR PROJECTION COMPATIBILITY FOR UPCASTING:")
|
||||||
}
|
}
|
||||||
ProbeKind::CommitIfOk => {
|
ProbeKind::CommitIfOk => {
|
||||||
writeln!(self.f, "COMMIT_IF_OK:")
|
write!(self.f, "COMMIT_IF_OK:")
|
||||||
}
|
}
|
||||||
ProbeKind::MiscCandidate { name, result } => {
|
ProbeKind::MiscCandidate { name, result } => {
|
||||||
writeln!(self.f, "CANDIDATE {name}: {result:?}")
|
write!(self.f, "CANDIDATE {name}: {result:?}")
|
||||||
}
|
}
|
||||||
ProbeKind::TraitCandidate { source, result } => {
|
ProbeKind::TraitCandidate { source, result } => {
|
||||||
writeln!(self.f, "CANDIDATE {source:?}: {result:?}")
|
write!(self.f, "CANDIDATE {source:?}: {result:?}")
|
||||||
}
|
}
|
||||||
}?;
|
}?;
|
||||||
|
|
||||||
|
|
@ -137,7 +150,7 @@ impl<'a, 'b> ProofTreeFormatter<'a, 'b> {
|
||||||
writeln!(self.f, "TRY_EVALUATE_ADDED_GOALS: {:?}", added_goals_evaluation.result)?;
|
writeln!(self.f, "TRY_EVALUATE_ADDED_GOALS: {:?}", added_goals_evaluation.result)?;
|
||||||
|
|
||||||
for (n, iterations) in added_goals_evaluation.evaluations.iter().enumerate() {
|
for (n, iterations) in added_goals_evaluation.evaluations.iter().enumerate() {
|
||||||
writeln!(self.f, "ITERATION {n}")?;
|
write!(self.f, "ITERATION {n}")?;
|
||||||
self.nested(|this| {
|
self.nested(|this| {
|
||||||
for goal_evaluation in iterations {
|
for goal_evaluation in iterations {
|
||||||
this.format_goal_evaluation(goal_evaluation)?;
|
this.format_goal_evaluation(goal_evaluation)?;
|
||||||
|
|
|
||||||
|
|
@ -3253,6 +3253,7 @@ impl ToJson for Target {
|
||||||
}
|
}
|
||||||
|
|
||||||
target_val!(llvm_target);
|
target_val!(llvm_target);
|
||||||
|
target_val!(description);
|
||||||
d.insert("target-pointer-width".to_string(), self.pointer_width.to_string().to_json());
|
d.insert("target-pointer-width".to_string(), self.pointer_width.to_string().to_json());
|
||||||
target_val!(arch);
|
target_val!(arch);
|
||||||
target_val!(data_layout);
|
target_val!(data_layout);
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ pub fn target() -> Target {
|
||||||
|
|
||||||
Target {
|
Target {
|
||||||
llvm_target: "aarch64-pc-windows-msvc".into(),
|
llvm_target: "aarch64-pc-windows-msvc".into(),
|
||||||
description: None,
|
description: Some("ARM64 Windows MSVC".into()),
|
||||||
pointer_width: 64,
|
pointer_width: 64,
|
||||||
data_layout: "e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128".into(),
|
data_layout: "e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128".into(),
|
||||||
arch: "aarch64".into(),
|
arch: "aarch64".into(),
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ pub fn target() -> Target {
|
||||||
|
|
||||||
Target {
|
Target {
|
||||||
llvm_target: "i686-pc-windows-msvc".into(),
|
llvm_target: "i686-pc-windows-msvc".into(),
|
||||||
description: None,
|
description: Some("32-bit MSVC (Windows 7+)".into()),
|
||||||
pointer_width: 32,
|
pointer_width: 32,
|
||||||
data_layout: "e-m:x-p:32:32-p270:32:32-p271:32:32-p272:64:64-\
|
data_layout: "e-m:x-p:32:32-p270:32:32-p271:32:32-p272:64:64-\
|
||||||
i64:64-i128:128-f80:128-n8:16:32-a:0:32-S32"
|
i64:64-i128:128-f80:128-n8:16:32-a:0:32-S32"
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ pub fn target() -> Target {
|
||||||
|
|
||||||
Target {
|
Target {
|
||||||
llvm_target: "i686-pc-windows-msvc".into(),
|
llvm_target: "i686-pc-windows-msvc".into(),
|
||||||
description: None,
|
description: Some("32-bit Windows 7 support".into()),
|
||||||
pointer_width: 32,
|
pointer_width: 32,
|
||||||
data_layout: "e-m:x-p:32:32-p270:32:32-p271:32:32-p272:64:64-\
|
data_layout: "e-m:x-p:32:32-p270:32:32-p271:32:32-p272:64:64-\
|
||||||
i64:64-i128:128-f80:128-n8:16:32-a:0:32-S32"
|
i64:64-i128:128-f80:128-n8:16:32-a:0:32-S32"
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ pub fn target() -> Target {
|
||||||
|
|
||||||
Target {
|
Target {
|
||||||
llvm_target: "thumbv7a-pc-windows-msvc".into(),
|
llvm_target: "thumbv7a-pc-windows-msvc".into(),
|
||||||
description: None,
|
description: Some("ARM32 Windows MSVC".into()),
|
||||||
pointer_width: 32,
|
pointer_width: 32,
|
||||||
data_layout: "e-m:w-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(),
|
data_layout: "e-m:w-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(),
|
||||||
arch: "arm".into(),
|
arch: "arm".into(),
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ pub fn target() -> Target {
|
||||||
|
|
||||||
Target {
|
Target {
|
||||||
llvm_target: "x86_64-pc-windows-msvc".into(),
|
llvm_target: "x86_64-pc-windows-msvc".into(),
|
||||||
description: None,
|
description: Some("64-bit MSVC (Windows 7+)".into()),
|
||||||
pointer_width: 64,
|
pointer_width: 64,
|
||||||
data_layout:
|
data_layout:
|
||||||
"e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128".into(),
|
"e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128".into(),
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ pub fn target() -> Target {
|
||||||
|
|
||||||
Target {
|
Target {
|
||||||
llvm_target: "x86_64-win7-windows-msvc".into(),
|
llvm_target: "x86_64-win7-windows-msvc".into(),
|
||||||
description: None,
|
description: Some("64-bit Windows 7 support".into()),
|
||||||
pointer_width: 64,
|
pointer_width: 64,
|
||||||
data_layout:
|
data_layout:
|
||||||
"e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128".into(),
|
"e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128".into(),
|
||||||
|
|
|
||||||
|
|
@ -1326,9 +1326,7 @@ impl<T: ?Sized> *const T {
|
||||||
/// `align`.
|
/// `align`.
|
||||||
///
|
///
|
||||||
/// If it is not possible to align the pointer, the implementation returns
|
/// If it is not possible to align the pointer, the implementation returns
|
||||||
/// `usize::MAX`. It is permissible for the implementation to *always*
|
/// `usize::MAX`.
|
||||||
/// return `usize::MAX`. Only your algorithm's performance can depend
|
|
||||||
/// on getting a usable offset here, not its correctness.
|
|
||||||
///
|
///
|
||||||
/// The offset is expressed in number of `T` elements, and not bytes. The value returned can be
|
/// The offset is expressed in number of `T` elements, and not bytes. The value returned can be
|
||||||
/// used with the `wrapping_add` method.
|
/// used with the `wrapping_add` method.
|
||||||
|
|
@ -1337,6 +1335,15 @@ impl<T: ?Sized> *const T {
|
||||||
/// beyond the allocation that the pointer points into. It is up to the caller to ensure that
|
/// beyond the allocation that the pointer points into. It is up to the caller to ensure that
|
||||||
/// the returned offset is correct in all terms other than alignment.
|
/// the returned offset is correct in all terms other than alignment.
|
||||||
///
|
///
|
||||||
|
/// When this is called during compile-time evaluation (which is unstable), the implementation
|
||||||
|
/// may return `usize::MAX` in cases where that can never happen at runtime. This is because the
|
||||||
|
/// actual alignment of pointers is not known yet during compile-time, so an offset with
|
||||||
|
/// guaranteed alignment can sometimes not be computed. For example, a buffer declared as `[u8;
|
||||||
|
/// N]` might be allocated at an odd or an even address, but at compile-time this is not yet
|
||||||
|
/// known, so the execution has to be correct for either choice. It is therefore impossible to
|
||||||
|
/// find an offset that is guaranteed to be 2-aligned. (This behavior is subject to change, as usual
|
||||||
|
/// for unstable APIs.)
|
||||||
|
///
|
||||||
/// # Panics
|
/// # Panics
|
||||||
///
|
///
|
||||||
/// The function panics if `align` is not a power-of-two.
|
/// The function panics if `align` is not a power-of-two.
|
||||||
|
|
|
||||||
|
|
@ -1589,9 +1589,7 @@ impl<T: ?Sized> *mut T {
|
||||||
/// `align`.
|
/// `align`.
|
||||||
///
|
///
|
||||||
/// If it is not possible to align the pointer, the implementation returns
|
/// If it is not possible to align the pointer, the implementation returns
|
||||||
/// `usize::MAX`. It is permissible for the implementation to *always*
|
/// `usize::MAX`.
|
||||||
/// return `usize::MAX`. Only your algorithm's performance can depend
|
|
||||||
/// on getting a usable offset here, not its correctness.
|
|
||||||
///
|
///
|
||||||
/// The offset is expressed in number of `T` elements, and not bytes. The value returned can be
|
/// The offset is expressed in number of `T` elements, and not bytes. The value returned can be
|
||||||
/// used with the `wrapping_add` method.
|
/// used with the `wrapping_add` method.
|
||||||
|
|
@ -1600,6 +1598,15 @@ impl<T: ?Sized> *mut T {
|
||||||
/// beyond the allocation that the pointer points into. It is up to the caller to ensure that
|
/// beyond the allocation that the pointer points into. It is up to the caller to ensure that
|
||||||
/// the returned offset is correct in all terms other than alignment.
|
/// the returned offset is correct in all terms other than alignment.
|
||||||
///
|
///
|
||||||
|
/// When this is called during compile-time evaluation (which is unstable), the implementation
|
||||||
|
/// may return `usize::MAX` in cases where that can never happen at runtime. This is because the
|
||||||
|
/// actual alignment of pointers is not known yet during compile-time, so an offset with
|
||||||
|
/// guaranteed alignment can sometimes not be computed. For example, a buffer declared as `[u8;
|
||||||
|
/// N]` might be allocated at an odd or an even address, but at compile-time this is not yet
|
||||||
|
/// known, so the execution has to be correct for either choice. It is therefore impossible to
|
||||||
|
/// find an offset that is guaranteed to be 2-aligned. (This behavior is subject to change, as usual
|
||||||
|
/// for unstable APIs.)
|
||||||
|
///
|
||||||
/// # Panics
|
/// # Panics
|
||||||
///
|
///
|
||||||
/// The function panics if `align` is not a power-of-two.
|
/// The function panics if `align` is not a power-of-two.
|
||||||
|
|
|
||||||
|
|
@ -3786,11 +3786,8 @@ impl<T> [T] {
|
||||||
/// maintained.
|
/// maintained.
|
||||||
///
|
///
|
||||||
/// This method splits the slice into three distinct slices: prefix, correctly aligned middle
|
/// This method splits the slice into three distinct slices: prefix, correctly aligned middle
|
||||||
/// slice of a new type, and the suffix slice. How exactly the slice is split up is not
|
/// slice of a new type, and the suffix slice. The middle part will be as big as possible under
|
||||||
/// specified; the middle part may be smaller than necessary. However, if this fails to return a
|
/// the given alignment constraint and element size.
|
||||||
/// maximal middle part, that is because code is running in a context where performance does not
|
|
||||||
/// matter, such as a sanitizer attempting to find alignment bugs. Regular code running
|
|
||||||
/// in a default (debug or release) execution *will* return a maximal middle part.
|
|
||||||
///
|
///
|
||||||
/// This method has no purpose when either input element `T` or output element `U` are
|
/// This method has no purpose when either input element `T` or output element `U` are
|
||||||
/// zero-sized and will return the original slice without splitting anything.
|
/// zero-sized and will return the original slice without splitting anything.
|
||||||
|
|
@ -3854,11 +3851,8 @@ impl<T> [T] {
|
||||||
/// types is maintained.
|
/// types is maintained.
|
||||||
///
|
///
|
||||||
/// This method splits the slice into three distinct slices: prefix, correctly aligned middle
|
/// This method splits the slice into three distinct slices: prefix, correctly aligned middle
|
||||||
/// slice of a new type, and the suffix slice. How exactly the slice is split up is not
|
/// slice of a new type, and the suffix slice. The middle part will be as big as possible under
|
||||||
/// specified; the middle part may be smaller than necessary. However, if this fails to return a
|
/// the given alignment constraint and element size.
|
||||||
/// maximal middle part, that is because code is running in a context where performance does not
|
|
||||||
/// matter, such as a sanitizer attempting to find alignment bugs. Regular code running
|
|
||||||
/// in a default (debug or release) execution *will* return a maximal middle part.
|
|
||||||
///
|
///
|
||||||
/// This method has no purpose when either input element `T` or output element `U` are
|
/// This method has no purpose when either input element `T` or output element `U` are
|
||||||
/// zero-sized and will return the original slice without splitting anything.
|
/// zero-sized and will return the original slice without splitting anything.
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@ use std::fmt;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::process;
|
use std::process;
|
||||||
|
|
||||||
use either::Either;
|
|
||||||
use rand::rngs::StdRng;
|
use rand::rngs::StdRng;
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
use rand::SeedableRng;
|
use rand::SeedableRng;
|
||||||
|
|
@ -962,7 +961,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
|
||||||
// to run extra MIR), and Ok(Some(body)) if we found MIR to run for the
|
// to run extra MIR), and Ok(Some(body)) if we found MIR to run for the
|
||||||
// foreign function
|
// foreign function
|
||||||
// Any needed call to `goto_block` will be performed by `emulate_foreign_item`.
|
// Any needed call to `goto_block` will be performed by `emulate_foreign_item`.
|
||||||
let args = ecx.copy_fn_args(args)?; // FIXME: Should `InPlace` arguments be reset to uninit?
|
let args = ecx.copy_fn_args(args); // FIXME: Should `InPlace` arguments be reset to uninit?
|
||||||
let link_name = ecx.item_link_name(instance.def_id());
|
let link_name = ecx.item_link_name(instance.def_id());
|
||||||
return ecx.emulate_foreign_item(link_name, abi, &args, dest, ret, unwind);
|
return ecx.emulate_foreign_item(link_name, abi, &args, dest, ret, unwind);
|
||||||
}
|
}
|
||||||
|
|
@ -981,7 +980,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
|
||||||
ret: Option<mir::BasicBlock>,
|
ret: Option<mir::BasicBlock>,
|
||||||
unwind: mir::UnwindAction,
|
unwind: mir::UnwindAction,
|
||||||
) -> InterpResult<'tcx> {
|
) -> InterpResult<'tcx> {
|
||||||
let args = ecx.copy_fn_args(args)?; // FIXME: Should `InPlace` arguments be reset to uninit?
|
let args = ecx.copy_fn_args(args); // FIXME: Should `InPlace` arguments be reset to uninit?
|
||||||
ecx.emulate_dyn_sym(fn_val, abi, &args, dest, ret, unwind)
|
ecx.emulate_dyn_sym(fn_val, abi, &args, dest, ret, unwind)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1334,18 +1333,12 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
|
||||||
|
|
||||||
fn protect_in_place_function_argument(
|
fn protect_in_place_function_argument(
|
||||||
ecx: &mut InterpCx<'mir, 'tcx, Self>,
|
ecx: &mut InterpCx<'mir, 'tcx, Self>,
|
||||||
place: &PlaceTy<'tcx, Provenance>,
|
place: &MPlaceTy<'tcx, Provenance>,
|
||||||
) -> InterpResult<'tcx> {
|
) -> InterpResult<'tcx> {
|
||||||
// If we have a borrow tracker, we also have it set up protection so that all reads *and
|
// If we have a borrow tracker, we also have it set up protection so that all reads *and
|
||||||
// writes* during this call are insta-UB.
|
// writes* during this call are insta-UB.
|
||||||
let protected_place = if ecx.machine.borrow_tracker.is_some() {
|
let protected_place = if ecx.machine.borrow_tracker.is_some() {
|
||||||
// Have to do `to_op` first because a `Place::Local` doesn't imply the local doesn't have an address.
|
ecx.protect_place(&place)?.into()
|
||||||
if let Either::Left(place) = ecx.place_to_op(place)?.as_mplace_or_imm() {
|
|
||||||
ecx.protect_place(&place)?.into()
|
|
||||||
} else {
|
|
||||||
// Locals that don't have their address taken are as protected as they can ever be.
|
|
||||||
place.clone()
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// No borrow tracker.
|
// No borrow tracker.
|
||||||
place.clone()
|
place.clone()
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ impl<T> Id<T> for T {}
|
||||||
|
|
||||||
fn free_fn_capture_hrtb_in_impl_trait()
|
fn free_fn_capture_hrtb_in_impl_trait()
|
||||||
-> Box<for<'a> Id<impl Lt<'a>>>
|
-> Box<for<'a> Id<impl Lt<'a>>>
|
||||||
//~^ ERROR `impl Trait` can only capture lifetimes bound at the fn or impl level [E0657]
|
//~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from `dyn` type
|
||||||
{
|
{
|
||||||
Box::new(())
|
Box::new(())
|
||||||
}
|
}
|
||||||
|
|
@ -17,7 +17,7 @@ struct Foo;
|
||||||
impl Foo {
|
impl Foo {
|
||||||
fn impl_fn_capture_hrtb_in_impl_trait()
|
fn impl_fn_capture_hrtb_in_impl_trait()
|
||||||
-> Box<for<'a> Id<impl Lt<'a>>>
|
-> Box<for<'a> Id<impl Lt<'a>>>
|
||||||
//~^ ERROR `impl Trait` can only capture lifetimes bound at the fn or impl level
|
//~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from `dyn` type
|
||||||
{
|
{
|
||||||
Box::new(())
|
Box::new(())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,26 @@
|
||||||
error[E0657]: `impl Trait` can only capture lifetimes bound at the fn or impl level
|
error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from `dyn` type
|
||||||
--> $DIR/E0657.rs:10:31
|
--> $DIR/E0657.rs:10:31
|
||||||
|
|
|
|
||||||
LL | -> Box<for<'a> Id<impl Lt<'a>>>
|
LL | -> Box<for<'a> Id<impl Lt<'a>>>
|
||||||
| ^^
|
| ^^
|
||||||
|
|
|
||||||
|
note: lifetime declared here
|
||||||
|
--> $DIR/E0657.rs:10:16
|
||||||
|
|
|
||||||
|
LL | -> Box<for<'a> Id<impl Lt<'a>>>
|
||||||
|
| ^^
|
||||||
|
|
||||||
error[E0657]: `impl Trait` can only capture lifetimes bound at the fn or impl level
|
error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from `dyn` type
|
||||||
--> $DIR/E0657.rs:19:35
|
--> $DIR/E0657.rs:19:35
|
||||||
|
|
|
|
||||||
LL | -> Box<for<'a> Id<impl Lt<'a>>>
|
LL | -> Box<for<'a> Id<impl Lt<'a>>>
|
||||||
| ^^
|
| ^^
|
||||||
|
|
|
||||||
|
note: lifetime declared here
|
||||||
|
--> $DIR/E0657.rs:19:20
|
||||||
|
|
|
||||||
|
LL | -> Box<for<'a> Id<impl Lt<'a>>>
|
||||||
|
| ^^
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,19 +2,19 @@
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
|
|
||||||
fn a() -> impl Fn(&u8) -> (impl Debug + '_) {
|
fn a() -> impl Fn(&u8) -> (impl Debug + '_) {
|
||||||
//~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet
|
//~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait`
|
||||||
|x| x
|
|x| x
|
||||||
//~^ ERROR lifetime may not live long enough
|
//~^ ERROR lifetime may not live long enough
|
||||||
}
|
}
|
||||||
|
|
||||||
fn b() -> impl for<'a> Fn(&'a u8) -> (impl Debug + 'a) {
|
fn b() -> impl for<'a> Fn(&'a u8) -> (impl Debug + 'a) {
|
||||||
//~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet
|
//~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait`
|
||||||
|x| x
|
|x| x
|
||||||
//~^ ERROR lifetime may not live long enough
|
//~^ ERROR lifetime may not live long enough
|
||||||
}
|
}
|
||||||
|
|
||||||
fn c() -> impl for<'a> Fn(&'a u8) -> (impl Debug + '_) {
|
fn c() -> impl for<'a> Fn(&'a u8) -> (impl Debug + '_) {
|
||||||
//~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet
|
//~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait`
|
||||||
|x| x
|
|x| x
|
||||||
//~^ ERROR lifetime may not live long enough
|
//~^ ERROR lifetime may not live long enough
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ help: consider using the `'static` lifetime, but this is uncommon unless you're
|
||||||
LL | fn d() -> impl Fn() -> (impl Debug + 'static) {
|
LL | fn d() -> impl Fn() -> (impl Debug + 'static) {
|
||||||
| ~~~~~~~
|
| ~~~~~~~
|
||||||
|
|
||||||
error: higher kinded lifetime bounds on nested opaque types are not supported yet
|
error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait`
|
||||||
--> $DIR/impl-fn-hrtb-bounds.rs:4:41
|
--> $DIR/impl-fn-hrtb-bounds.rs:4:41
|
||||||
|
|
|
|
||||||
LL | fn a() -> impl Fn(&u8) -> (impl Debug + '_) {
|
LL | fn a() -> impl Fn(&u8) -> (impl Debug + '_) {
|
||||||
|
|
@ -31,7 +31,7 @@ LL | |x| x
|
||||||
| |return type of closure is impl Debug + '2
|
| |return type of closure is impl Debug + '2
|
||||||
| has type `&'1 u8`
|
| has type `&'1 u8`
|
||||||
|
|
||||||
error: higher kinded lifetime bounds on nested opaque types are not supported yet
|
error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait`
|
||||||
--> $DIR/impl-fn-hrtb-bounds.rs:10:52
|
--> $DIR/impl-fn-hrtb-bounds.rs:10:52
|
||||||
|
|
|
|
||||||
LL | fn b() -> impl for<'a> Fn(&'a u8) -> (impl Debug + 'a) {
|
LL | fn b() -> impl for<'a> Fn(&'a u8) -> (impl Debug + 'a) {
|
||||||
|
|
@ -52,7 +52,7 @@ LL | |x| x
|
||||||
| |return type of closure is impl Debug + '2
|
| |return type of closure is impl Debug + '2
|
||||||
| has type `&'1 u8`
|
| has type `&'1 u8`
|
||||||
|
|
||||||
error: higher kinded lifetime bounds on nested opaque types are not supported yet
|
error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait`
|
||||||
--> $DIR/impl-fn-hrtb-bounds.rs:16:52
|
--> $DIR/impl-fn-hrtb-bounds.rs:16:52
|
||||||
|
|
|
|
||||||
LL | fn c() -> impl for<'a> Fn(&'a u8) -> (impl Debug + '_) {
|
LL | fn c() -> impl for<'a> Fn(&'a u8) -> (impl Debug + '_) {
|
||||||
|
|
@ -75,4 +75,5 @@ LL | |x| x
|
||||||
|
|
||||||
error: aborting due to 7 previous errors
|
error: aborting due to 7 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0106`.
|
Some errors have detailed explanations: E0106, E0657.
|
||||||
|
For more information about an error, try `rustc --explain E0106`.
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ use std::fmt::Debug;
|
||||||
|
|
||||||
fn a() -> impl Fn(&u8) -> impl Debug + '_ {
|
fn a() -> impl Fn(&u8) -> impl Debug + '_ {
|
||||||
//~^ ERROR ambiguous `+` in a type
|
//~^ ERROR ambiguous `+` in a type
|
||||||
//~| ERROR higher kinded lifetime bounds on nested opaque types are not supported yet
|
//~| ERROR cannot capture higher-ranked lifetime from outer `impl Trait`
|
||||||
|x| x
|
|x| x
|
||||||
//~^ ERROR lifetime may not live long enough
|
//~^ ERROR lifetime may not live long enough
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ error: ambiguous `+` in a type
|
||||||
LL | fn b() -> impl Fn() -> impl Debug + Send {
|
LL | fn b() -> impl Fn() -> impl Debug + Send {
|
||||||
| ^^^^^^^^^^^^^^^^^ help: use parentheses to disambiguate: `(impl Debug + Send)`
|
| ^^^^^^^^^^^^^^^^^ help: use parentheses to disambiguate: `(impl Debug + Send)`
|
||||||
|
|
||||||
error: higher kinded lifetime bounds on nested opaque types are not supported yet
|
error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait`
|
||||||
--> $DIR/impl-fn-parsing-ambiguities.rs:4:40
|
--> $DIR/impl-fn-parsing-ambiguities.rs:4:40
|
||||||
|
|
|
|
||||||
LL | fn a() -> impl Fn(&u8) -> impl Debug + '_ {
|
LL | fn a() -> impl Fn(&u8) -> impl Debug + '_ {
|
||||||
|
|
@ -33,3 +33,4 @@ LL | |x| x
|
||||||
|
|
||||||
error: aborting due to 4 previous errors
|
error: aborting due to 4 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0657`.
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,10 @@
|
||||||
error[E0657]: `impl Trait` can only capture lifetimes bound at the fn or impl level
|
error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from `dyn` type
|
||||||
|
--> $DIR/implicit-capture-late.rs:10:55
|
||||||
|
|
|
||||||
|
LL | fn foo(x: Vec<i32>) -> Box<dyn for<'a> Deref<Target = impl ?Sized>> {
|
||||||
|
| ^^^^^^^^^^^ `impl Trait` implicitly captures all lifetimes in scope
|
||||||
|
|
|
||||||
|
note: lifetime declared here
|
||||||
--> $DIR/implicit-capture-late.rs:10:36
|
--> $DIR/implicit-capture-late.rs:10:36
|
||||||
|
|
|
|
||||||
LL | fn foo(x: Vec<i32>) -> Box<dyn for<'a> Deref<Target = impl ?Sized>> {
|
LL | fn foo(x: Vec<i32>) -> Box<dyn for<'a> Deref<Target = impl ?Sized>> {
|
||||||
|
|
|
||||||
18
tests/ui/impl-trait/in-trait/opaque-and-lifetime-mismatch.rs
Normal file
18
tests/ui/impl-trait/in-trait/opaque-and-lifetime-mismatch.rs
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
struct Wrapper<'rom>(T);
|
||||||
|
//~^ ERROR cannot find type `T` in this scope
|
||||||
|
|
||||||
|
trait Foo {
|
||||||
|
fn bar() -> Wrapper<impl Sized>;
|
||||||
|
//~^ ERROR missing lifetime specifier
|
||||||
|
//~| ERROR struct takes 0 generic arguments but 1 generic argument was supplied
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Foo for () {
|
||||||
|
fn bar() -> i32 {
|
||||||
|
//~^ ERROR method `bar` has an incompatible type for trait
|
||||||
|
//~| ERROR method `bar` has an incompatible return type for trait
|
||||||
|
0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
||||||
|
|
@ -0,0 +1,67 @@
|
||||||
|
error[E0106]: missing lifetime specifier
|
||||||
|
--> $DIR/opaque-and-lifetime-mismatch.rs:5:24
|
||||||
|
|
|
||||||
|
LL | fn bar() -> Wrapper<impl Sized>;
|
||||||
|
| ^ expected named lifetime parameter
|
||||||
|
|
|
||||||
|
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
|
||||||
|
help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static`, or if you will only have owned values
|
||||||
|
|
|
||||||
|
LL | fn bar() -> Wrapper<'static, impl Sized>;
|
||||||
|
| ++++++++
|
||||||
|
|
||||||
|
error[E0412]: cannot find type `T` in this scope
|
||||||
|
--> $DIR/opaque-and-lifetime-mismatch.rs:1:22
|
||||||
|
|
|
||||||
|
LL | struct Wrapper<'rom>(T);
|
||||||
|
| ^ not found in this scope
|
||||||
|
|
|
||||||
|
help: you might be missing a type parameter
|
||||||
|
|
|
||||||
|
LL | struct Wrapper<'rom, T>(T);
|
||||||
|
| +++
|
||||||
|
|
||||||
|
error[E0107]: struct takes 0 generic arguments but 1 generic argument was supplied
|
||||||
|
--> $DIR/opaque-and-lifetime-mismatch.rs:5:17
|
||||||
|
|
|
||||||
|
LL | fn bar() -> Wrapper<impl Sized>;
|
||||||
|
| ^^^^^^^ ---------- help: remove this generic argument
|
||||||
|
| |
|
||||||
|
| expected 0 generic arguments
|
||||||
|
|
|
||||||
|
note: struct defined here, with 0 generic parameters
|
||||||
|
--> $DIR/opaque-and-lifetime-mismatch.rs:1:8
|
||||||
|
|
|
||||||
|
LL | struct Wrapper<'rom>(T);
|
||||||
|
| ^^^^^^^
|
||||||
|
|
||||||
|
error[E0053]: method `bar` has an incompatible return type for trait
|
||||||
|
--> $DIR/opaque-and-lifetime-mismatch.rs:11:17
|
||||||
|
|
|
||||||
|
LL | fn bar() -> i32 {
|
||||||
|
| ^^^
|
||||||
|
| |
|
||||||
|
| expected `Wrapper<'static>`, found `i32`
|
||||||
|
| return type in trait
|
||||||
|
|
||||||
|
error[E0053]: method `bar` has an incompatible type for trait
|
||||||
|
--> $DIR/opaque-and-lifetime-mismatch.rs:11:17
|
||||||
|
|
|
||||||
|
LL | fn bar() -> i32 {
|
||||||
|
| ^^^
|
||||||
|
| |
|
||||||
|
| expected `Wrapper<'static>`, found `i32`
|
||||||
|
| help: change the output type to match the trait: `Wrapper<'static>`
|
||||||
|
|
|
||||||
|
note: type in trait
|
||||||
|
--> $DIR/opaque-and-lifetime-mismatch.rs:5:17
|
||||||
|
|
|
||||||
|
LL | fn bar() -> Wrapper<impl Sized>;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^
|
||||||
|
= note: expected signature `fn() -> Wrapper<'static>`
|
||||||
|
found signature `fn() -> i32`
|
||||||
|
|
||||||
|
error: aborting due to 5 previous errors
|
||||||
|
|
||||||
|
Some errors have detailed explanations: E0053, E0106, E0107, E0412.
|
||||||
|
For more information about an error, try `rustc --explain E0053`.
|
||||||
|
|
@ -13,7 +13,7 @@ impl<'a> Trait<'a> for X {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn f() -> impl for<'a> Trait<'a, Out = impl Sized + 'a> {
|
fn f() -> impl for<'a> Trait<'a, Out = impl Sized + 'a> {
|
||||||
//~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet
|
//~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait`
|
||||||
X(())
|
X(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
error: higher kinded lifetime bounds on nested opaque types are not supported yet
|
error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait`
|
||||||
--> $DIR/issue-54895.rs:15:53
|
--> $DIR/issue-54895.rs:15:53
|
||||||
|
|
|
|
||||||
LL | fn f() -> impl for<'a> Trait<'a, Out = impl Sized + 'a> {
|
LL | fn f() -> impl for<'a> Trait<'a, Out = impl Sized + 'a> {
|
||||||
|
|
@ -12,3 +12,4 @@ LL | fn f() -> impl for<'a> Trait<'a, Out = impl Sized + 'a> {
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0657`.
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ where
|
||||||
|
|
||||||
struct A;
|
struct A;
|
||||||
fn test() -> impl for<'a> MyFn<&'a A, Output=impl Iterator + 'a> {
|
fn test() -> impl for<'a> MyFn<&'a A, Output=impl Iterator + 'a> {
|
||||||
//~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet
|
//~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait`
|
||||||
Wrap(|a| Some(a).into_iter())
|
Wrap(|a| Some(a).into_iter())
|
||||||
//~^ ERROR implementation of `FnOnce` is not general enough
|
//~^ ERROR implementation of `FnOnce` is not general enough
|
||||||
//~| ERROR implementation of `FnOnce` is not general enough
|
//~| ERROR implementation of `FnOnce` is not general enough
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
error: higher kinded lifetime bounds on nested opaque types are not supported yet
|
error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait`
|
||||||
--> $DIR/issue-67830.rs:21:62
|
--> $DIR/issue-67830.rs:21:62
|
||||||
|
|
|
|
||||||
LL | fn test() -> impl for<'a> MyFn<&'a A, Output=impl Iterator + 'a> {
|
LL | fn test() -> impl for<'a> MyFn<&'a A, Output=impl Iterator + 'a> {
|
||||||
|
|
@ -31,3 +31,4 @@ LL | Wrap(|a| Some(a).into_iter())
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0657`.
|
||||||
|
|
|
||||||
|
|
@ -13,17 +13,17 @@ impl<'a> Hrtb<'a> for &'a () {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make_impl() -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {}
|
fn make_impl() -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {}
|
||||||
//~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet
|
//~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait`
|
||||||
|
|
||||||
fn make_weird_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {
|
fn make_weird_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {
|
||||||
//~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet
|
//~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait`
|
||||||
&()
|
&()
|
||||||
//~^ ERROR implementation of `Hrtb` is not general enough
|
//~^ ERROR implementation of `Hrtb` is not general enough
|
||||||
//~| ERROR implementation of `Hrtb` is not general enough
|
//~| ERROR implementation of `Hrtb` is not general enough
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make_bad_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {
|
fn make_bad_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {
|
||||||
//~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet
|
//~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait`
|
||||||
x
|
x
|
||||||
//~^ ERROR implementation of `Hrtb` is not general enough
|
//~^ ERROR implementation of `Hrtb` is not general enough
|
||||||
//~| ERROR implementation of `Hrtb` is not general enough
|
//~| ERROR implementation of `Hrtb` is not general enough
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
error: higher kinded lifetime bounds on nested opaque types are not supported yet
|
error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait`
|
||||||
--> $DIR/issue-88236-2.rs:15:61
|
--> $DIR/issue-88236-2.rs:15:61
|
||||||
|
|
|
|
||||||
LL | fn make_impl() -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {}
|
LL | fn make_impl() -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {}
|
||||||
|
|
@ -10,7 +10,7 @@ note: lifetime declared here
|
||||||
LL | fn make_impl() -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {}
|
LL | fn make_impl() -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {}
|
||||||
| ^^
|
| ^^
|
||||||
|
|
||||||
error: higher kinded lifetime bounds on nested opaque types are not supported yet
|
error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait`
|
||||||
--> $DIR/issue-88236-2.rs:18:80
|
--> $DIR/issue-88236-2.rs:18:80
|
||||||
|
|
|
|
||||||
LL | fn make_weird_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {
|
LL | fn make_weird_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {
|
||||||
|
|
@ -40,7 +40,7 @@ LL | &()
|
||||||
= note: `Hrtb<'a>` would have to be implemented for the type `&()`
|
= note: `Hrtb<'a>` would have to be implemented for the type `&()`
|
||||||
= note: ...but `Hrtb<'0>` is actually implemented for the type `&'0 ()`, for some specific lifetime `'0`
|
= note: ...but `Hrtb<'0>` is actually implemented for the type `&'0 ()`, for some specific lifetime `'0`
|
||||||
|
|
||||||
error: higher kinded lifetime bounds on nested opaque types are not supported yet
|
error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait`
|
||||||
--> $DIR/issue-88236-2.rs:25:78
|
--> $DIR/issue-88236-2.rs:25:78
|
||||||
|
|
|
|
||||||
LL | fn make_bad_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {
|
LL | fn make_bad_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {
|
||||||
|
|
@ -90,3 +90,4 @@ LL | x
|
||||||
|
|
||||||
error: aborting due to 8 previous errors
|
error: aborting due to 8 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0657`.
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,6 @@ impl<'a> Hrtb<'a> for &'a () {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make_impl() -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {}
|
fn make_impl() -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {}
|
||||||
//~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet
|
//~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait`
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
error: higher kinded lifetime bounds on nested opaque types are not supported yet
|
error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait`
|
||||||
--> $DIR/issue-88236.rs:15:61
|
--> $DIR/issue-88236.rs:15:61
|
||||||
|
|
|
|
||||||
LL | fn make_impl() -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {}
|
LL | fn make_impl() -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {}
|
||||||
|
|
@ -12,3 +12,4 @@ LL | fn make_impl() -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {}
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0657`.
|
||||||
|
|
|
||||||
|
|
@ -23,18 +23,18 @@ impl Qux<'_> for () {}
|
||||||
|
|
||||||
// This is not supported.
|
// This is not supported.
|
||||||
fn one_hrtb_outlives() -> impl for<'a> Foo<'a, Assoc = impl Sized + 'a> {}
|
fn one_hrtb_outlives() -> impl for<'a> Foo<'a, Assoc = impl Sized + 'a> {}
|
||||||
//~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet
|
//~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait`
|
||||||
|
|
||||||
// This is not supported.
|
// This is not supported.
|
||||||
fn one_hrtb_trait_param() -> impl for<'a> Foo<'a, Assoc = impl Qux<'a>> {}
|
fn one_hrtb_trait_param() -> impl for<'a> Foo<'a, Assoc = impl Qux<'a>> {}
|
||||||
//~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet
|
//~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait`
|
||||||
|
|
||||||
fn one_hrtb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl Sized + 'a> {}
|
fn one_hrtb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl Sized + 'a> {}
|
||||||
//~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet
|
//~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait`
|
||||||
//~| ERROR implementation of `Bar` is not general enough
|
//~| ERROR implementation of `Bar` is not general enough
|
||||||
|
|
||||||
fn one_hrtb_trait_param_uses() -> impl for<'a> Bar<'a, Assoc = impl Qux<'a>> {}
|
fn one_hrtb_trait_param_uses() -> impl for<'a> Bar<'a, Assoc = impl Qux<'a>> {}
|
||||||
//~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet
|
//~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait`
|
||||||
//~| ERROR: the trait bound `for<'a> &'a (): Qux<'_>` is not satisfied
|
//~| ERROR: the trait bound `for<'a> &'a (): Qux<'_>` is not satisfied
|
||||||
|
|
||||||
// This should resolve.
|
// This should resolve.
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ help: consider introducing lifetime `'b` here
|
||||||
LL | fn two_htrb_outlives_uses<'b>() -> impl for<'a> Bar<'a, Assoc = impl for<'b> Sized + 'b> {}
|
LL | fn two_htrb_outlives_uses<'b>() -> impl for<'a> Bar<'a, Assoc = impl for<'b> Sized + 'b> {}
|
||||||
| ++++
|
| ++++
|
||||||
|
|
||||||
error: higher kinded lifetime bounds on nested opaque types are not supported yet
|
error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait`
|
||||||
--> $DIR/nested-rpit-hrtb.rs:25:69
|
--> $DIR/nested-rpit-hrtb.rs:25:69
|
||||||
|
|
|
|
||||||
LL | fn one_hrtb_outlives() -> impl for<'a> Foo<'a, Assoc = impl Sized + 'a> {}
|
LL | fn one_hrtb_outlives() -> impl for<'a> Foo<'a, Assoc = impl Sized + 'a> {}
|
||||||
|
|
@ -41,7 +41,7 @@ note: lifetime declared here
|
||||||
LL | fn one_hrtb_outlives() -> impl for<'a> Foo<'a, Assoc = impl Sized + 'a> {}
|
LL | fn one_hrtb_outlives() -> impl for<'a> Foo<'a, Assoc = impl Sized + 'a> {}
|
||||||
| ^^
|
| ^^
|
||||||
|
|
||||||
error: higher kinded lifetime bounds on nested opaque types are not supported yet
|
error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait`
|
||||||
--> $DIR/nested-rpit-hrtb.rs:29:68
|
--> $DIR/nested-rpit-hrtb.rs:29:68
|
||||||
|
|
|
|
||||||
LL | fn one_hrtb_trait_param() -> impl for<'a> Foo<'a, Assoc = impl Qux<'a>> {}
|
LL | fn one_hrtb_trait_param() -> impl for<'a> Foo<'a, Assoc = impl Qux<'a>> {}
|
||||||
|
|
@ -53,7 +53,7 @@ note: lifetime declared here
|
||||||
LL | fn one_hrtb_trait_param() -> impl for<'a> Foo<'a, Assoc = impl Qux<'a>> {}
|
LL | fn one_hrtb_trait_param() -> impl for<'a> Foo<'a, Assoc = impl Qux<'a>> {}
|
||||||
| ^^
|
| ^^
|
||||||
|
|
||||||
error: higher kinded lifetime bounds on nested opaque types are not supported yet
|
error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait`
|
||||||
--> $DIR/nested-rpit-hrtb.rs:32:74
|
--> $DIR/nested-rpit-hrtb.rs:32:74
|
||||||
|
|
|
|
||||||
LL | fn one_hrtb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl Sized + 'a> {}
|
LL | fn one_hrtb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl Sized + 'a> {}
|
||||||
|
|
@ -74,7 +74,7 @@ LL | fn one_hrtb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl Sized + 'a
|
||||||
= note: `()` must implement `Bar<'a>`
|
= note: `()` must implement `Bar<'a>`
|
||||||
= note: ...but it actually implements `Bar<'0>`, for some specific lifetime `'0`
|
= note: ...but it actually implements `Bar<'0>`, for some specific lifetime `'0`
|
||||||
|
|
||||||
error: higher kinded lifetime bounds on nested opaque types are not supported yet
|
error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait`
|
||||||
--> $DIR/nested-rpit-hrtb.rs:36:73
|
--> $DIR/nested-rpit-hrtb.rs:36:73
|
||||||
|
|
|
|
||||||
LL | fn one_hrtb_trait_param_uses() -> impl for<'a> Bar<'a, Assoc = impl Qux<'a>> {}
|
LL | fn one_hrtb_trait_param_uses() -> impl for<'a> Bar<'a, Assoc = impl Qux<'a>> {}
|
||||||
|
|
@ -133,5 +133,5 @@ LL | fn two_htrb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl for<'b> Si
|
||||||
|
|
||||||
error: aborting due to 12 previous errors
|
error: aborting due to 12 previous errors
|
||||||
|
|
||||||
Some errors have detailed explanations: E0261, E0277.
|
Some errors have detailed explanations: E0261, E0277, E0657.
|
||||||
For more information about an error, try `rustc --explain E0261`.
|
For more information about an error, try `rustc --explain E0261`.
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
//@ compile-flags: -Znext-solver
|
||||||
|
//@ check-pass
|
||||||
|
|
||||||
|
// Regression test for #119607.
|
||||||
|
|
||||||
|
pub trait IntoFoo {
|
||||||
|
type Item;
|
||||||
|
type IntoIter: Foo<Item = Self::Item>;
|
||||||
|
|
||||||
|
fn into_iter(self) -> Self::IntoIter;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait Foo {
|
||||||
|
type Item;
|
||||||
|
|
||||||
|
fn next(self) -> Option<Self::Item>;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn foo<'a, Iter1, Elem1>(a: &'a Iter1)
|
||||||
|
where
|
||||||
|
&'a Iter1: IntoFoo<Item = Elem1>,
|
||||||
|
{
|
||||||
|
a.into_iter().next();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
//@ compile-flags: -Znext-solver
|
||||||
|
//@ check-pass
|
||||||
|
|
||||||
|
// Regression test for #119608.
|
||||||
|
|
||||||
|
pub trait Foo {}
|
||||||
|
|
||||||
|
pub trait Bar {
|
||||||
|
type Assoc;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Foo> Bar for T {
|
||||||
|
type Assoc = T;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn foo<I>(_input: <I as Bar>::Assoc)
|
||||||
|
where
|
||||||
|
I: Bar,
|
||||||
|
<I as Bar>::Assoc: Foo,
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
||||||
|
|
@ -7,7 +7,7 @@ pub trait Trait<'a> {
|
||||||
trait Test<'a> {}
|
trait Test<'a> {}
|
||||||
|
|
||||||
pub type Foo = impl for<'a> Trait<'a, Assoc = impl Test<'a>>;
|
pub type Foo = impl for<'a> Trait<'a, Assoc = impl Test<'a>>;
|
||||||
//~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet
|
//~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait`
|
||||||
|
|
||||||
impl Trait<'_> for () {
|
impl Trait<'_> for () {
|
||||||
type Assoc = ();
|
type Assoc = ();
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
error: higher kinded lifetime bounds on nested opaque types are not supported yet
|
error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait`
|
||||||
--> $DIR/escaping-bound-var.rs:9:25
|
--> $DIR/escaping-bound-var.rs:9:47
|
||||||
|
|
|
|
||||||
LL | pub type Foo = impl for<'a> Trait<'a, Assoc = impl Test<'a>>;
|
LL | pub type Foo = impl for<'a> Trait<'a, Assoc = impl Test<'a>>;
|
||||||
| ^^
|
| ^^^^^^^^^^^^^ `impl Trait` implicitly captures all lifetimes in scope
|
||||||
|
|
|
|
||||||
note: lifetime declared here
|
note: lifetime declared here
|
||||||
--> $DIR/escaping-bound-var.rs:9:25
|
--> $DIR/escaping-bound-var.rs:9:25
|
||||||
|
|
@ -12,3 +12,4 @@ LL | pub type Foo = impl for<'a> Trait<'a, Assoc = impl Test<'a>>;
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0657`.
|
||||||
|
|
|
||||||
|
|
@ -12,11 +12,11 @@ type CapturedEarly<'a> = impl Sized + Captures<'a>; //~ [*, o]
|
||||||
//~^ ERROR: unconstrained opaque type
|
//~^ ERROR: unconstrained opaque type
|
||||||
|
|
||||||
type NotCapturedLate<'a> = dyn for<'b> Iterator<Item = impl Sized>; //~ [*, o, o]
|
type NotCapturedLate<'a> = dyn for<'b> Iterator<Item = impl Sized>; //~ [*, o, o]
|
||||||
//~^ ERROR `impl Trait` can only capture lifetimes bound at the fn or impl level
|
//~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from `dyn` type
|
||||||
//~| ERROR: unconstrained opaque type
|
//~| ERROR: unconstrained opaque type
|
||||||
|
|
||||||
type Captured<'a> = dyn for<'b> Iterator<Item = impl Sized + Captures<'a>>; //~ [*, o, o]
|
type Captured<'a> = dyn for<'b> Iterator<Item = impl Sized + Captures<'a>>; //~ [*, o, o]
|
||||||
//~^ ERROR `impl Trait` can only capture lifetimes bound at the fn or impl level
|
//~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from `dyn` type
|
||||||
//~| ERROR: unconstrained opaque type
|
//~| ERROR: unconstrained opaque type
|
||||||
|
|
||||||
type Bar<'a, 'b: 'b, T> = impl Sized; //~ ERROR [*, *, o, o, o]
|
type Bar<'a, 'b: 'b, T> = impl Sized; //~ ERROR [*, *, o, o, o]
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,22 @@
|
||||||
error[E0657]: `impl Trait` can only capture lifetimes bound at the fn or impl level
|
error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from `dyn` type
|
||||||
|
--> $DIR/variance.rs:14:56
|
||||||
|
|
|
||||||
|
LL | type NotCapturedLate<'a> = dyn for<'b> Iterator<Item = impl Sized>;
|
||||||
|
| ^^^^^^^^^^ `impl Trait` implicitly captures all lifetimes in scope
|
||||||
|
|
|
||||||
|
note: lifetime declared here
|
||||||
--> $DIR/variance.rs:14:36
|
--> $DIR/variance.rs:14:36
|
||||||
|
|
|
|
||||||
LL | type NotCapturedLate<'a> = dyn for<'b> Iterator<Item = impl Sized>;
|
LL | type NotCapturedLate<'a> = dyn for<'b> Iterator<Item = impl Sized>;
|
||||||
| ^^
|
| ^^
|
||||||
|
|
||||||
error[E0657]: `impl Trait` can only capture lifetimes bound at the fn or impl level
|
error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from `dyn` type
|
||||||
|
--> $DIR/variance.rs:18:49
|
||||||
|
|
|
||||||
|
LL | type Captured<'a> = dyn for<'b> Iterator<Item = impl Sized + Captures<'a>>;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^ `impl Trait` implicitly captures all lifetimes in scope
|
||||||
|
|
|
||||||
|
note: lifetime declared here
|
||||||
--> $DIR/variance.rs:18:29
|
--> $DIR/variance.rs:18:29
|
||||||
|
|
|
|
||||||
LL | type Captured<'a> = dyn for<'b> Iterator<Item = impl Sized + Captures<'a>>;
|
LL | type Captured<'a> = dyn for<'b> Iterator<Item = impl Sized + Captures<'a>>;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue