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:
bors 2024-03-08 20:34:52 +00:00
commit 46b180ec24
47 changed files with 418 additions and 214 deletions

View File

@ -260,35 +260,29 @@ pub unsafe fn create_module<'ll>(
}
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" {
llvm::LLVMRustAddModuleFlag(
llmod,
behavior,
llvm::LLVMModFlagBehavior::Min,
c"branch-target-enforcement".as_ptr().cast(),
bti.into(),
);
llvm::LLVMRustAddModuleFlag(
llmod,
behavior,
llvm::LLVMModFlagBehavior::Min,
c"sign-return-address".as_ptr().cast(),
pac_ret.is_some().into(),
);
let pac_opts = pac_ret.unwrap_or(PacRet { leaf: false, key: PAuthKey::A });
llvm::LLVMRustAddModuleFlag(
llmod,
behavior,
llvm::LLVMModFlagBehavior::Min,
c"sign-return-address-all".as_ptr().cast(),
pac_opts.leaf.into(),
);
llvm::LLVMRustAddModuleFlag(
llmod,
behavior,
llvm::LLVMModFlagBehavior::Min,
c"sign-return-address-with-bkey".as_ptr().cast(),
u32::from(pac_opts.key == PAuthKey::B),
);

View File

@ -510,11 +510,13 @@ fn get_argc_argv<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
// Params for UEFI
let param_handle = bx.get_param(0);
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_argv = bx.alloca(cx.type_array(cx.type_ptr(), 2), Align::ONE);
bx.store(param_handle, arg_argv, Align::ONE);
let arg_argv_el1 = bx.gep(cx.type_ptr(), arg_argv, &[bx.const_int(cx.type_int(), 1)]);
bx.store(param_system_table, arg_argv_el1, Align::ONE);
let arg_argv = bx.alloca(cx.type_array(cx.type_ptr(), 2), ptr_align);
bx.store(param_handle, arg_argv, ptr_align);
let arg_argv_el1 = bx.inbounds_ptradd(arg_argv, bx.const_usize(ptr_size.bytes()));
bx.store(param_system_table, arg_argv_el1, ptr_align);
(arg_argc, arg_argv)
} else if cx.sess().target.main_needs_argc_argv {
// Params from native `main()` used as args for rust start function

View File

@ -227,7 +227,7 @@ impl<'mir, 'tcx: 'mir> CompileTimeEvalContext<'mir, 'tcx> {
if self.tcx.has_attr(def_id, sym::rustc_const_panic_str)
|| 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
assert!(args.len() == 1);
@ -254,7 +254,7 @@ impl<'mir, 'tcx: 'mir> CompileTimeEvalContext<'mir, 'tcx> {
return Ok(Some(new_instance));
} 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.
match self.align_offset(instance, &args, dest, ret)? {
ControlFlow::Continue(()) => return Ok(Some(instance)),

View File

@ -472,11 +472,11 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized {
/// argument/return value was actually copied or passed in-place..
fn protect_in_place_function_argument(
ecx: &mut InterpCx<'mir, 'tcx, Self>,
place: &PlaceTy<'tcx, Self::Provenance>,
mplace: &MPlaceTy<'tcx, Self::Provenance>,
) -> InterpResult<'tcx> {
// 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.
ecx.write_uninit(place)
ecx.write_uninit(mplace)
}
/// Called immediately before a new stack frame gets pushed.

View File

@ -1,5 +1,7 @@
use std::borrow::Cow;
use either::Either;
use rustc_middle::{
mir,
ty::{
@ -29,14 +31,14 @@ pub enum FnArg<'tcx, Prov: Provenance = CtfeProvenance> {
Copy(OpTy<'tcx, Prov>),
/// 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.
InPlace(PlaceTy<'tcx, Prov>),
InPlace(MPlaceTy<'tcx, Prov>),
}
impl<'tcx, Prov: Provenance> FnArg<'tcx, Prov> {
pub fn layout(&self) -> &TyAndLayout<'tcx> {
match self {
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> {
/// Make a copy of the given fn_arg. Any `InPlace` are degenerated to copies, no protection of the
/// original memory occurs.
pub fn copy_fn_arg(
&self,
arg: &FnArg<'tcx, M::Provenance>,
) -> InterpResult<'tcx, OpTy<'tcx, M::Provenance>> {
pub fn copy_fn_arg(&self, arg: &FnArg<'tcx, M::Provenance>) -> OpTy<'tcx, M::Provenance> {
match arg {
FnArg::Copy(op) => Ok(op.clone()),
FnArg::InPlace(place) => self.place_to_op(place),
FnArg::Copy(op) => op.clone(),
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(
&self,
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()
}
@ -70,7 +69,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
) -> InterpResult<'tcx, FnArg<'tcx, M::Provenance>> {
Ok(match arg {
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>>> {
ops.iter()
.map(|op| {
Ok(match &op.node {
mir::Operand::Move(place) => FnArg::InPlace(self.eval_place(*place)?),
_ => FnArg::Copy(self.eval_operand(&op.node, None)?),
})
let arg = match &op.node {
mir::Operand::Copy(_) | mir::Operand::Constant(_) => {
// 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()
}
@ -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
// 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.
let caller_arg_copy = self.copy_fn_arg(caller_arg)?;
let caller_arg_copy = self.copy_fn_arg(caller_arg);
if !already_live {
let local = callee_arg.as_local().unwrap();
let meta = caller_arg_copy.meta();
@ -469,8 +494,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
// specifically.)
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 let FnArg::InPlace(place) = caller_arg {
M::protect_in_place_function_argument(self, place)?;
if let FnArg::InPlace(mplace) = caller_arg {
M::protect_in_place_function_argument(self, mplace)?;
}
Ok(())
}
@ -517,7 +542,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
M::call_intrinsic(
self,
instance,
&self.copy_fn_args(args)?,
&self.copy_fn_args(args),
destination,
target,
unwind,
@ -594,8 +619,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
.map(|arg| (
arg.layout().ty,
match arg {
FnArg::Copy(op) => format!("copy({:?})", *op),
FnArg::InPlace(place) => format!("in-place({:?})", *place),
FnArg::Copy(op) => format!("copy({op:?})"),
FnArg::InPlace(mplace) => format!("in-place({mplace:?})"),
}
))
.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
});
}
// 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.
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
// really pass the argument in-place anyway, and we are constructing a new
// `Immediate` receiver.
let mut receiver = self.copy_fn_arg(&args[0])?;
let mut receiver = self.copy_fn_arg(&args[0]);
let receiver_place = loop {
match receiver.layout.ty.kind() {
ty::Ref(..) | ty::RawPtr(..) => {

View File

@ -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:
```compile_fail,E0657
trait Id<T> {}
trait Lt<'a> {}
trait BorrowInto<'a> {
type Target;
impl<'a> Lt<'a> for () {}
impl<T> Id<T> for T {}
fn free_fn_capture_hrtb_in_impl_trait()
-> Box<for<'a> Id<impl Lt<'a>>> // error!
{
Box::new(())
fn borrow_into(&'a self) -> Self::Target;
}
struct Foo;
impl Foo {
fn impl_fn_capture_hrtb_in_impl_trait()
-> Box<for<'a> Id<impl Lt<'a>>> // error!
{
Box::new(())
impl<'a> BorrowInto<'a> for () {
type Target = &'a ();
fn borrow_into(&'a self) -> Self::Target {
self
}
}
```
Here, you have used the inappropriate lifetime in the `impl Trait`,
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(())
}
fn opaque() -> impl for<'a> BorrowInto<'a, Target = impl Sized + 'a> {
()
}
```

View File

@ -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_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
.help = add `#![feature(unboxed_closures)]` to the crate attributes to use it

View File

@ -521,14 +521,6 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
)
.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);
trait_sig.error_reported()?;
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
// 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-

View File

@ -9,7 +9,6 @@
use core::ops::ControlFlow;
use rustc_ast::visit::walk_list;
use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
use rustc_errors::{codes::*, struct_span_code_err};
use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res};
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
// well-supported at the moment, so this doesn't work.
// In the future, this should be fixed and this error should be removed.
let def = self.map.defs.get(&lifetime.hir_id).cloned();
let Some(ResolvedArg::LateBound(_, _, def_id)) = def else { continue };
let Some(def_id) = def_id.as_local() else { continue };
let hir_id = self.tcx.local_def_id_to_hir_id(def_id);
// Ensure that the parent of the def is an item, not HRTB
let parent_id = self.tcx.parent_hir_id(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)
let def = self.map.defs.get(&lifetime.hir_id).copied();
let Some(ResolvedArg::LateBound(_, _, lifetime_def_id)) = def else { continue };
let Some(lifetime_def_id) = lifetime_def_id.as_local() else { continue };
let lifetime_hir_id = self.tcx.local_def_id_to_hir_id(lifetime_def_id);
let bad_place = match self.tcx.hir_node(self.tcx.parent_hir_id(lifetime_hir_id))
{
self.tcx.dcx().struct_span_err(
lifetime.ident.span,
"higher kinded lifetime bounds on nested opaque types are not supported yet",
)
.with_span_note(self.tcx.def_span(def_id), "lifetime declared here")
.emit();
self.uninsert_lifetime_on_error(lifetime, def.unwrap());
}
// Opaques do not declare their own lifetimes, so if a lifetime comes from an opaque
// it must be a reified late-bound lifetime from a trait goal.
hir::Node::Item(hir::Item {
kind: hir::ItemKind::OpaqueTy { .. }, ..
}) => "higher-ranked lifetime from outer `impl Trait`",
// Other items are fine.
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),

View File

@ -1607,3 +1607,15 @@ pub struct UnnamedFieldsReprFieldDefined {
#[primary_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,
}

View File

@ -4,22 +4,31 @@ pub(super) struct ProofTreeFormatter<'a, 'b> {
f: &'a mut (dyn Write + 'b),
}
enum IndentorState {
StartWithNewline,
OnNewline,
Inline,
}
/// A formatter which adds 4 spaces of indentation to its input before
/// passing it on to its nested formatter.
///
/// We can use this for arbitrary levels of indentation by nesting it.
struct Indentor<'a, 'b> {
f: &'a mut (dyn Write + 'b),
on_newline: bool,
state: IndentorState,
}
impl Write for Indentor<'_, '_> {
fn write_str(&mut self, s: &str) -> std::fmt::Result {
for line in s.split_inclusive('\n') {
if self.on_newline {
self.f.write_str(" ")?;
match self.state {
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)?;
}
@ -32,11 +41,15 @@ impl<'a, 'b> ProofTreeFormatter<'a, 'b> {
ProofTreeFormatter { f }
}
fn nested<F, R>(&mut self, func: F) -> R
fn nested<F>(&mut self, func: F) -> std::fmt::Result
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 {
@ -47,7 +60,7 @@ impl<'a, 'b> ProofTreeFormatter<'a, 'b> {
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))
}
@ -69,7 +82,7 @@ impl<'a, 'b> ProofTreeFormatter<'a, 'b> {
}
CanonicalGoalEvaluationKind::Evaluation { revisions } => {
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))?;
}
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 {
match &probe.kind {
ProbeKind::Root { result } => {
writeln!(self.f, "ROOT RESULT: {result:?}")
write!(self.f, "ROOT RESULT: {result:?}")
}
ProbeKind::NormalizedSelfTyAssembly => {
writeln!(self.f, "NORMALIZING SELF TY FOR ASSEMBLY:")
write!(self.f, "NORMALIZING SELF TY FOR ASSEMBLY:")
}
ProbeKind::UnsizeAssembly => {
writeln!(self.f, "ASSEMBLING CANDIDATES FOR UNSIZING:")
write!(self.f, "ASSEMBLING CANDIDATES FOR UNSIZING:")
}
ProbeKind::UpcastProjectionCompatibility => {
writeln!(self.f, "PROBING FOR PROJECTION COMPATIBILITY FOR UPCASTING:")
write!(self.f, "PROBING FOR PROJECTION COMPATIBILITY FOR UPCASTING:")
}
ProbeKind::CommitIfOk => {
writeln!(self.f, "COMMIT_IF_OK:")
write!(self.f, "COMMIT_IF_OK:")
}
ProbeKind::MiscCandidate { name, result } => {
writeln!(self.f, "CANDIDATE {name}: {result:?}")
write!(self.f, "CANDIDATE {name}: {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)?;
for (n, iterations) in added_goals_evaluation.evaluations.iter().enumerate() {
writeln!(self.f, "ITERATION {n}")?;
write!(self.f, "ITERATION {n}")?;
self.nested(|this| {
for goal_evaluation in iterations {
this.format_goal_evaluation(goal_evaluation)?;

View File

@ -3253,6 +3253,7 @@ impl ToJson for Target {
}
target_val!(llvm_target);
target_val!(description);
d.insert("target-pointer-width".to_string(), self.pointer_width.to_string().to_json());
target_val!(arch);
target_val!(data_layout);

View File

@ -7,7 +7,7 @@ pub fn target() -> Target {
Target {
llvm_target: "aarch64-pc-windows-msvc".into(),
description: None,
description: Some("ARM64 Windows MSVC".into()),
pointer_width: 64,
data_layout: "e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128".into(),
arch: "aarch64".into(),

View File

@ -23,7 +23,7 @@ pub fn target() -> Target {
Target {
llvm_target: "i686-pc-windows-msvc".into(),
description: None,
description: Some("32-bit MSVC (Windows 7+)".into()),
pointer_width: 32,
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"

View File

@ -23,7 +23,7 @@ pub fn target() -> Target {
Target {
llvm_target: "i686-pc-windows-msvc".into(),
description: None,
description: Some("32-bit Windows 7 support".into()),
pointer_width: 32,
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"

View File

@ -13,7 +13,7 @@ pub fn target() -> Target {
Target {
llvm_target: "thumbv7a-pc-windows-msvc".into(),
description: None,
description: Some("ARM32 Windows MSVC".into()),
pointer_width: 32,
data_layout: "e-m:w-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(),
arch: "arm".into(),

View File

@ -10,7 +10,7 @@ pub fn target() -> Target {
Target {
llvm_target: "x86_64-pc-windows-msvc".into(),
description: None,
description: Some("64-bit MSVC (Windows 7+)".into()),
pointer_width: 64,
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(),

View File

@ -9,7 +9,7 @@ pub fn target() -> Target {
Target {
llvm_target: "x86_64-win7-windows-msvc".into(),
description: None,
description: Some("64-bit Windows 7 support".into()),
pointer_width: 64,
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(),

View File

@ -1326,9 +1326,7 @@ impl<T: ?Sized> *const T {
/// `align`.
///
/// If it is not possible to align the pointer, the implementation returns
/// `usize::MAX`. It is permissible for the implementation to *always*
/// return `usize::MAX`. Only your algorithm's performance can depend
/// on getting a usable offset here, not its correctness.
/// `usize::MAX`.
///
/// The offset is expressed in number of `T` elements, and not bytes. The value returned can be
/// 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
/// 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
///
/// The function panics if `align` is not a power-of-two.

View File

@ -1589,9 +1589,7 @@ impl<T: ?Sized> *mut T {
/// `align`.
///
/// If it is not possible to align the pointer, the implementation returns
/// `usize::MAX`. It is permissible for the implementation to *always*
/// return `usize::MAX`. Only your algorithm's performance can depend
/// on getting a usable offset here, not its correctness.
/// `usize::MAX`.
///
/// The offset is expressed in number of `T` elements, and not bytes. The value returned can be
/// 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
/// 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
///
/// The function panics if `align` is not a power-of-two.

View File

@ -3786,11 +3786,8 @@ impl<T> [T] {
/// maintained.
///
/// 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
/// specified; the middle part may be smaller than necessary. However, if this fails to return a
/// 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.
/// slice of a new type, and the suffix slice. The middle part will be as big as possible under
/// the given alignment constraint and element size.
///
/// 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.
@ -3854,11 +3851,8 @@ impl<T> [T] {
/// types is maintained.
///
/// 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
/// specified; the middle part may be smaller than necessary. However, if this fails to return a
/// 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.
/// slice of a new type, and the suffix slice. The middle part will be as big as possible under
/// the given alignment constraint and element size.
///
/// 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.

View File

@ -8,7 +8,6 @@ use std::fmt;
use std::path::Path;
use std::process;
use either::Either;
use rand::rngs::StdRng;
use rand::Rng;
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
// foreign function
// 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());
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>,
unwind: mir::UnwindAction,
) -> 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)
}
@ -1334,18 +1333,12 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
fn protect_in_place_function_argument(
ecx: &mut InterpCx<'mir, 'tcx, Self>,
place: &PlaceTy<'tcx, Provenance>,
place: &MPlaceTy<'tcx, Provenance>,
) -> InterpResult<'tcx> {
// 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.
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.
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()
}
ecx.protect_place(&place)?.into()
} else {
// No borrow tracker.
place.clone()

View File

@ -8,7 +8,7 @@ impl<T> Id<T> for T {}
fn free_fn_capture_hrtb_in_impl_trait()
-> 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(())
}
@ -17,7 +17,7 @@ struct Foo;
impl Foo {
fn impl_fn_capture_hrtb_in_impl_trait()
-> 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(())
}

View File

@ -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
|
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
|
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

View File

@ -2,19 +2,19 @@
use std::fmt::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
//~^ ERROR lifetime may not live long enough
}
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
//~^ ERROR lifetime may not live long enough
}
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
//~^ ERROR lifetime may not live long enough
}

View File

@ -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) {
| ~~~~~~~
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
|
LL | fn a() -> impl Fn(&u8) -> (impl Debug + '_) {
@ -31,7 +31,7 @@ LL | |x| x
| |return type of closure is impl Debug + '2
| 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
|
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
| 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
|
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
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`.

View File

@ -3,7 +3,7 @@ use std::fmt::Debug;
fn a() -> impl Fn(&u8) -> impl Debug + '_ {
//~^ 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
//~^ ERROR lifetime may not live long enough
}

View File

@ -10,7 +10,7 @@ error: ambiguous `+` in a type
LL | fn b() -> impl Fn() -> 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
|
LL | fn a() -> impl Fn(&u8) -> impl Debug + '_ {
@ -33,3 +33,4 @@ LL | |x| x
error: aborting due to 4 previous errors
For more information about this error, try `rustc --explain E0657`.

View File

@ -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
|
LL | fn foo(x: Vec<i32>) -> Box<dyn for<'a> Deref<Target = impl ?Sized>> {

View 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() {}

View File

@ -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`.

View File

@ -13,7 +13,7 @@ impl<'a> Trait<'a> for X {
}
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(())
}

View File

@ -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
|
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
For more information about this error, try `rustc --explain E0657`.

View File

@ -19,7 +19,7 @@ where
struct 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())
//~^ ERROR implementation of `FnOnce` is not general enough
//~| ERROR implementation of `FnOnce` is not general enough

View File

@ -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
|
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
For more information about this error, try `rustc --explain E0657`.

View File

@ -13,17 +13,17 @@ impl<'a> Hrtb<'a> for &'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> {
//~^ 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
}
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
//~^ ERROR implementation of `Hrtb` is not general enough
//~| ERROR implementation of `Hrtb` is not general enough

View File

@ -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
|
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> {}
| ^^
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
|
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: ...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
|
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
For more information about this error, try `rustc --explain E0657`.

View File

@ -13,6 +13,6 @@ impl<'a> Hrtb<'a> for &'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() {}

View File

@ -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
|
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
For more information about this error, try `rustc --explain E0657`.

View File

@ -23,18 +23,18 @@ impl Qux<'_> for () {}
// This is not supported.
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.
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> {}
//~^ 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
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
// This should resolve.

View File

@ -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> {}
| ++++
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
|
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> {}
| ^^
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
|
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>> {}
| ^^
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
|
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: ...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
|
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
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`.

View File

@ -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() {}

View File

@ -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() {}

View File

@ -7,7 +7,7 @@ pub trait Trait<'a> {
trait 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 () {
type Assoc = ();

View File

@ -1,8 +1,8 @@
error: higher kinded lifetime bounds on nested opaque types are not supported yet
--> $DIR/escaping-bound-var.rs:9:25
error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait`
--> $DIR/escaping-bound-var.rs:9:47
|
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
--> $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
For more information about this error, try `rustc --explain E0657`.

View File

@ -12,11 +12,11 @@ type CapturedEarly<'a> = impl Sized + Captures<'a>; //~ [*, o]
//~^ ERROR: unconstrained opaque type
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
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
type Bar<'a, 'b: 'b, T> = impl Sized; //~ ERROR [*, *, o, o, o]

View File

@ -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
|
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
|
LL | type Captured<'a> = dyn for<'b> Iterator<Item = impl Sized + Captures<'a>>;