Auto merge of #99753 - Dylan-DPC:rollup-k046940, r=Dylan-DPC
Rollup of 5 pull requests Successful merges: - #99618 (handle consts with param/infer in `const_eval_resolve` better) - #99666 (Restore `Opaque` behavior to coherence check) - #99692 (interpret, ptr_offset_from: refactor and test too-far-apart check) - #99739 (Remove erroneous E0133 code from an error message.) - #99748 (Use full type name instead of just saying `impl Trait` in "captures lifetime" error) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
2614e437f5
42 changed files with 350 additions and 171 deletions
|
@ -78,6 +78,8 @@ pub(crate) enum RegionErrorKind<'tcx> {
|
||||||
span: Span,
|
span: Span,
|
||||||
/// The hidden type.
|
/// The hidden type.
|
||||||
hidden_ty: Ty<'tcx>,
|
hidden_ty: Ty<'tcx>,
|
||||||
|
/// The opaque type.
|
||||||
|
key: ty::OpaqueTypeKey<'tcx>,
|
||||||
/// The unexpected region.
|
/// The unexpected region.
|
||||||
member_region: ty::Region<'tcx>,
|
member_region: ty::Region<'tcx>,
|
||||||
},
|
},
|
||||||
|
@ -205,14 +207,16 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RegionErrorKind::UnexpectedHiddenRegion { span, hidden_ty, member_region } => {
|
RegionErrorKind::UnexpectedHiddenRegion { span, hidden_ty, key, member_region } => {
|
||||||
let named_ty = self.regioncx.name_regions(self.infcx.tcx, hidden_ty);
|
let named_ty = self.regioncx.name_regions(self.infcx.tcx, hidden_ty);
|
||||||
|
let named_key = self.regioncx.name_regions(self.infcx.tcx, key);
|
||||||
let named_region = self.regioncx.name_regions(self.infcx.tcx, member_region);
|
let named_region = self.regioncx.name_regions(self.infcx.tcx, member_region);
|
||||||
self.buffer_error(unexpected_hidden_region_diagnostic(
|
self.buffer_error(unexpected_hidden_region_diagnostic(
|
||||||
self.infcx.tcx,
|
self.infcx.tcx,
|
||||||
span,
|
span,
|
||||||
named_ty,
|
named_ty,
|
||||||
named_region,
|
named_region,
|
||||||
|
named_key,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,8 @@ pub(crate) struct NllMemberConstraint<'tcx> {
|
||||||
/// The hidden type in which `R0` appears. (Used in error reporting.)
|
/// The hidden type in which `R0` appears. (Used in error reporting.)
|
||||||
pub(crate) hidden_ty: Ty<'tcx>,
|
pub(crate) hidden_ty: Ty<'tcx>,
|
||||||
|
|
||||||
|
pub(crate) key: ty::OpaqueTypeKey<'tcx>,
|
||||||
|
|
||||||
/// The region `R0`.
|
/// The region `R0`.
|
||||||
pub(crate) member_region_vid: ty::RegionVid,
|
pub(crate) member_region_vid: ty::RegionVid,
|
||||||
|
|
||||||
|
@ -90,6 +92,7 @@ impl<'tcx> MemberConstraintSet<'tcx, ty::RegionVid> {
|
||||||
member_region_vid,
|
member_region_vid,
|
||||||
definition_span: m_c.definition_span,
|
definition_span: m_c.definition_span,
|
||||||
hidden_ty: m_c.hidden_ty,
|
hidden_ty: m_c.hidden_ty,
|
||||||
|
key: m_c.key,
|
||||||
start_index,
|
start_index,
|
||||||
end_index,
|
end_index,
|
||||||
});
|
});
|
||||||
|
|
|
@ -1763,6 +1763,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||||
errors_buffer.push(RegionErrorKind::UnexpectedHiddenRegion {
|
errors_buffer.push(RegionErrorKind::UnexpectedHiddenRegion {
|
||||||
span: m_c.definition_span,
|
span: m_c.definition_span,
|
||||||
hidden_ty: m_c.hidden_ty,
|
hidden_ty: m_c.hidden_ty,
|
||||||
|
key: m_c.key,
|
||||||
member_region,
|
member_region,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -246,7 +246,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||||
// after producing an error for each of them.
|
// after producing an error for each of them.
|
||||||
let definition_ty = instantiated_ty.ty.fold_with(&mut ReverseMapper::new(
|
let definition_ty = instantiated_ty.ty.fold_with(&mut ReverseMapper::new(
|
||||||
self.tcx,
|
self.tcx,
|
||||||
def_id,
|
opaque_type_key,
|
||||||
map,
|
map,
|
||||||
instantiated_ty.ty,
|
instantiated_ty.ty,
|
||||||
instantiated_ty.span,
|
instantiated_ty.span,
|
||||||
|
@ -429,7 +429,7 @@ fn check_opaque_type_parameter_valid(
|
||||||
struct ReverseMapper<'tcx> {
|
struct ReverseMapper<'tcx> {
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
|
|
||||||
opaque_type_def_id: LocalDefId,
|
key: ty::OpaqueTypeKey<'tcx>,
|
||||||
map: FxHashMap<GenericArg<'tcx>, GenericArg<'tcx>>,
|
map: FxHashMap<GenericArg<'tcx>, GenericArg<'tcx>>,
|
||||||
map_missing_regions_to_empty: bool,
|
map_missing_regions_to_empty: bool,
|
||||||
|
|
||||||
|
@ -443,14 +443,14 @@ struct ReverseMapper<'tcx> {
|
||||||
impl<'tcx> ReverseMapper<'tcx> {
|
impl<'tcx> ReverseMapper<'tcx> {
|
||||||
fn new(
|
fn new(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
opaque_type_def_id: LocalDefId,
|
key: ty::OpaqueTypeKey<'tcx>,
|
||||||
map: FxHashMap<GenericArg<'tcx>, GenericArg<'tcx>>,
|
map: FxHashMap<GenericArg<'tcx>, GenericArg<'tcx>>,
|
||||||
hidden_ty: Ty<'tcx>,
|
hidden_ty: Ty<'tcx>,
|
||||||
span: Span,
|
span: Span,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
tcx,
|
tcx,
|
||||||
opaque_type_def_id,
|
key,
|
||||||
map,
|
map,
|
||||||
map_missing_regions_to_empty: false,
|
map_missing_regions_to_empty: false,
|
||||||
hidden_ty: Some(hidden_ty),
|
hidden_ty: Some(hidden_ty),
|
||||||
|
@ -504,7 +504,7 @@ impl<'tcx> TypeFolder<'tcx> for ReverseMapper<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let generics = self.tcx().generics_of(self.opaque_type_def_id);
|
let generics = self.tcx().generics_of(self.key.def_id);
|
||||||
match self.map.get(&r.into()).map(|k| k.unpack()) {
|
match self.map.get(&r.into()).map(|k| k.unpack()) {
|
||||||
Some(GenericArgKind::Lifetime(r1)) => r1,
|
Some(GenericArgKind::Lifetime(r1)) => r1,
|
||||||
Some(u) => panic!("region mapped to unexpected kind: {:?}", u),
|
Some(u) => panic!("region mapped to unexpected kind: {:?}", u),
|
||||||
|
@ -513,9 +513,10 @@ impl<'tcx> TypeFolder<'tcx> for ReverseMapper<'tcx> {
|
||||||
if let Some(hidden_ty) = self.hidden_ty.take() {
|
if let Some(hidden_ty) = self.hidden_ty.take() {
|
||||||
unexpected_hidden_region_diagnostic(
|
unexpected_hidden_region_diagnostic(
|
||||||
self.tcx,
|
self.tcx,
|
||||||
self.tcx.def_span(self.opaque_type_def_id),
|
self.tcx.def_span(self.key.def_id),
|
||||||
hidden_ty,
|
hidden_ty,
|
||||||
r,
|
r,
|
||||||
|
self.key,
|
||||||
)
|
)
|
||||||
.emit();
|
.emit();
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ use std::convert::TryFrom;
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_middle::mir::{
|
use rustc_middle::mir::{
|
||||||
self,
|
self,
|
||||||
interpret::{ConstValue, GlobalId, InterpResult, Scalar},
|
interpret::{ConstValue, GlobalId, InterpResult, PointerArithmetic, Scalar},
|
||||||
BinOp,
|
BinOp,
|
||||||
};
|
};
|
||||||
use rustc_middle::ty;
|
use rustc_middle::ty;
|
||||||
|
@ -328,7 +328,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
// We managed to find a valid allocation for one pointer, but not the other.
|
// We managed to find a valid allocation for one pointer, but not the other.
|
||||||
// That means they are definitely not pointing to the same allocation.
|
// That means they are definitely not pointing to the same allocation.
|
||||||
throw_ub_format!(
|
throw_ub_format!(
|
||||||
"{} called on pointers into different allocations",
|
"`{}` called on pointers into different allocations",
|
||||||
intrinsic_name
|
intrinsic_name
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -336,7 +336,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
// Found allocation for both. They must be into the same allocation.
|
// Found allocation for both. They must be into the same allocation.
|
||||||
if a_alloc_id != b_alloc_id {
|
if a_alloc_id != b_alloc_id {
|
||||||
throw_ub_format!(
|
throw_ub_format!(
|
||||||
"{} called on pointers into different allocations",
|
"`{}` called on pointers into different allocations",
|
||||||
intrinsic_name
|
intrinsic_name
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -346,47 +346,71 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Compute distance.
|
// Compute distance.
|
||||||
let distance = {
|
let dist = {
|
||||||
// The subtraction is always done in `isize` to enforce
|
// Addresses are unsigned, so this is a `usize` computation. We have to do the
|
||||||
// the "no more than `isize::MAX` apart" requirement.
|
// overflow check separately anyway.
|
||||||
let a_offset = ImmTy::from_uint(a_offset, isize_layout);
|
let (val, overflowed, _ty) = {
|
||||||
let b_offset = ImmTy::from_uint(b_offset, isize_layout);
|
let a_offset = ImmTy::from_uint(a_offset, usize_layout);
|
||||||
let (val, overflowed, _ty) =
|
let b_offset = ImmTy::from_uint(b_offset, usize_layout);
|
||||||
self.overflowing_binary_op(BinOp::Sub, &a_offset, &b_offset)?;
|
self.overflowing_binary_op(BinOp::Sub, &a_offset, &b_offset)?
|
||||||
|
};
|
||||||
if overflowed {
|
if overflowed {
|
||||||
throw_ub_format!("pointers were too far apart for {}", intrinsic_name);
|
// a < b
|
||||||
|
if intrinsic_name == sym::ptr_offset_from_unsigned {
|
||||||
|
throw_ub_format!(
|
||||||
|
"`{}` called when first pointer has smaller offset than second: {} < {}",
|
||||||
|
intrinsic_name,
|
||||||
|
a_offset,
|
||||||
|
b_offset,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
// The signed form of the intrinsic allows this. If we interpret the
|
||||||
|
// difference as isize, we'll get the proper signed difference. If that
|
||||||
|
// seems *positive*, they were more than isize::MAX apart.
|
||||||
|
let dist = val.to_machine_isize(self)?;
|
||||||
|
if dist >= 0 {
|
||||||
|
throw_ub_format!(
|
||||||
|
"`{}` called when first pointer is too far before second",
|
||||||
|
intrinsic_name
|
||||||
|
);
|
||||||
|
}
|
||||||
|
dist
|
||||||
|
} else {
|
||||||
|
// b >= a
|
||||||
|
let dist = val.to_machine_isize(self)?;
|
||||||
|
// If converting to isize produced a *negative* result, we had an overflow
|
||||||
|
// because they were more than isize::MAX apart.
|
||||||
|
if dist < 0 {
|
||||||
|
throw_ub_format!(
|
||||||
|
"`{}` called when first pointer is too far ahead of second",
|
||||||
|
intrinsic_name
|
||||||
|
);
|
||||||
|
}
|
||||||
|
dist
|
||||||
}
|
}
|
||||||
val.to_machine_isize(self)?
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Check that the range between them is dereferenceable ("in-bounds or one past the
|
// Check that the range between them is dereferenceable ("in-bounds or one past the
|
||||||
// end of the same allocation"). This is like the check in ptr_offset_inbounds.
|
// end of the same allocation"). This is like the check in ptr_offset_inbounds.
|
||||||
let min_ptr = if distance >= 0 { b } else { a };
|
let min_ptr = if dist >= 0 { b } else { a };
|
||||||
self.check_ptr_access_align(
|
self.check_ptr_access_align(
|
||||||
min_ptr,
|
min_ptr,
|
||||||
Size::from_bytes(distance.unsigned_abs()),
|
Size::from_bytes(dist.unsigned_abs()),
|
||||||
Align::ONE,
|
Align::ONE,
|
||||||
CheckInAllocMsg::OffsetFromTest,
|
CheckInAllocMsg::OffsetFromTest,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
if intrinsic_name == sym::ptr_offset_from_unsigned && distance < 0 {
|
|
||||||
throw_ub_format!(
|
|
||||||
"{} called when first pointer has smaller offset than second: {} < {}",
|
|
||||||
intrinsic_name,
|
|
||||||
a_offset,
|
|
||||||
b_offset,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Perform division by size to compute return value.
|
// Perform division by size to compute return value.
|
||||||
let ret_layout = if intrinsic_name == sym::ptr_offset_from_unsigned {
|
let ret_layout = if intrinsic_name == sym::ptr_offset_from_unsigned {
|
||||||
|
assert!(0 <= dist && dist <= self.machine_isize_max());
|
||||||
usize_layout
|
usize_layout
|
||||||
} else {
|
} else {
|
||||||
|
assert!(self.machine_isize_min() <= dist && dist <= self.machine_isize_max());
|
||||||
isize_layout
|
isize_layout
|
||||||
};
|
};
|
||||||
let pointee_layout = self.layout_of(substs.type_at(0))?;
|
let pointee_layout = self.layout_of(substs.type_at(0))?;
|
||||||
// If ret_layout is unsigned, we checked that so is the distance, so we are good.
|
// If ret_layout is unsigned, we checked that so is the distance, so we are good.
|
||||||
let val = ImmTy::from_int(distance, ret_layout);
|
let val = ImmTy::from_int(dist, ret_layout);
|
||||||
let size = ImmTy::from_int(pointee_layout.size.bytes(), ret_layout);
|
let size = ImmTy::from_int(pointee_layout.size.bytes(), ret_layout);
|
||||||
self.exact_div(&val, &size, dest)?;
|
self.exact_div(&val, &size, dest)?;
|
||||||
}
|
}
|
||||||
|
|
|
@ -237,12 +237,14 @@ pub fn unexpected_hidden_region_diagnostic<'tcx>(
|
||||||
span: Span,
|
span: Span,
|
||||||
hidden_ty: Ty<'tcx>,
|
hidden_ty: Ty<'tcx>,
|
||||||
hidden_region: ty::Region<'tcx>,
|
hidden_region: ty::Region<'tcx>,
|
||||||
|
opaque_ty: ty::OpaqueTypeKey<'tcx>,
|
||||||
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
|
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
|
||||||
|
let opaque_ty = tcx.mk_opaque(opaque_ty.def_id.to_def_id(), opaque_ty.substs);
|
||||||
let mut err = struct_span_err!(
|
let mut err = struct_span_err!(
|
||||||
tcx.sess,
|
tcx.sess,
|
||||||
span,
|
span,
|
||||||
E0700,
|
E0700,
|
||||||
"hidden type for `impl Trait` captures lifetime that does not appear in bounds",
|
"hidden type for `{opaque_ty}` captures lifetime that does not appear in bounds",
|
||||||
);
|
);
|
||||||
|
|
||||||
// Explain the region we are capturing.
|
// Explain the region we are capturing.
|
||||||
|
|
|
@ -21,7 +21,7 @@ use rustc_middle::infer::unify_key::{ConstVarValue, ConstVariableValue};
|
||||||
use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind, ToType};
|
use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind, ToType};
|
||||||
use rustc_middle::mir::interpret::{ErrorHandled, EvalToValTreeResult};
|
use rustc_middle::mir::interpret::{ErrorHandled, EvalToValTreeResult};
|
||||||
use rustc_middle::traits::select;
|
use rustc_middle::traits::select;
|
||||||
use rustc_middle::ty::abstract_const::AbstractConst;
|
use rustc_middle::ty::abstract_const::{AbstractConst, FailureKind};
|
||||||
use rustc_middle::ty::error::{ExpectedFound, TypeError};
|
use rustc_middle::ty::error::{ExpectedFound, TypeError};
|
||||||
use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
|
use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
|
||||||
use rustc_middle::ty::relate::RelateResult;
|
use rustc_middle::ty::relate::RelateResult;
|
||||||
|
@ -966,14 +966,14 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||||
#[instrument(skip(self), level = "debug")]
|
#[instrument(skip(self), level = "debug")]
|
||||||
pub fn member_constraint(
|
pub fn member_constraint(
|
||||||
&self,
|
&self,
|
||||||
opaque_type_def_id: LocalDefId,
|
key: ty::OpaqueTypeKey<'tcx>,
|
||||||
definition_span: Span,
|
definition_span: Span,
|
||||||
hidden_ty: Ty<'tcx>,
|
hidden_ty: Ty<'tcx>,
|
||||||
region: ty::Region<'tcx>,
|
region: ty::Region<'tcx>,
|
||||||
in_regions: &Lrc<Vec<ty::Region<'tcx>>>,
|
in_regions: &Lrc<Vec<ty::Region<'tcx>>>,
|
||||||
) {
|
) {
|
||||||
self.inner.borrow_mut().unwrap_region_constraints().member_constraint(
|
self.inner.borrow_mut().unwrap_region_constraints().member_constraint(
|
||||||
opaque_type_def_id,
|
key,
|
||||||
definition_span,
|
definition_span,
|
||||||
hidden_ty,
|
hidden_ty,
|
||||||
region,
|
region,
|
||||||
|
@ -1675,7 +1675,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||||
#[instrument(skip(self), level = "debug")]
|
#[instrument(skip(self), level = "debug")]
|
||||||
pub fn const_eval_resolve(
|
pub fn const_eval_resolve(
|
||||||
&self,
|
&self,
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
mut param_env: ty::ParamEnv<'tcx>,
|
||||||
unevaluated: ty::Unevaluated<'tcx>,
|
unevaluated: ty::Unevaluated<'tcx>,
|
||||||
span: Option<Span>,
|
span: Option<Span>,
|
||||||
) -> EvalToValTreeResult<'tcx> {
|
) -> EvalToValTreeResult<'tcx> {
|
||||||
|
@ -1686,10 +1686,19 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||||
// variables
|
// variables
|
||||||
if substs.has_infer_types_or_consts() {
|
if substs.has_infer_types_or_consts() {
|
||||||
let ac = AbstractConst::new(self.tcx, unevaluated.shrink());
|
let ac = AbstractConst::new(self.tcx, unevaluated.shrink());
|
||||||
if let Ok(None) = ac {
|
match ac {
|
||||||
substs = InternalSubsts::identity_for_item(self.tcx, unevaluated.def.did);
|
Ok(None) => {
|
||||||
} else {
|
substs = InternalSubsts::identity_for_item(self.tcx, unevaluated.def.did);
|
||||||
return Err(ErrorHandled::TooGeneric);
|
param_env = self.tcx.param_env(unevaluated.def.did);
|
||||||
|
}
|
||||||
|
Ok(Some(ct)) => {
|
||||||
|
if ct.unify_failure_kind(self.tcx) == FailureKind::Concrete {
|
||||||
|
substs = replace_param_and_infer_substs_with_placeholder(self.tcx, substs);
|
||||||
|
} else {
|
||||||
|
return Err(ErrorHandled::TooGeneric);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(guar) => return Err(ErrorHandled::Reported(guar)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2000,3 +2009,43 @@ impl<'tcx> fmt::Debug for RegionObligation<'tcx> {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Replaces substs that reference param or infer variables with suitable
|
||||||
|
/// placeholders. This function is meant to remove these param and infer
|
||||||
|
/// substs when they're not actually needed to evaluate a constant.
|
||||||
|
fn replace_param_and_infer_substs_with_placeholder<'tcx>(
|
||||||
|
tcx: TyCtxt<'tcx>,
|
||||||
|
substs: SubstsRef<'tcx>,
|
||||||
|
) -> SubstsRef<'tcx> {
|
||||||
|
tcx.mk_substs(substs.iter().enumerate().map(|(idx, arg)| {
|
||||||
|
match arg.unpack() {
|
||||||
|
GenericArgKind::Type(_)
|
||||||
|
if arg.has_param_types_or_consts() || arg.has_infer_types_or_consts() =>
|
||||||
|
{
|
||||||
|
tcx.mk_ty(ty::Placeholder(ty::PlaceholderType {
|
||||||
|
universe: ty::UniverseIndex::ROOT,
|
||||||
|
name: ty::BoundVar::from_usize(idx),
|
||||||
|
}))
|
||||||
|
.into()
|
||||||
|
}
|
||||||
|
GenericArgKind::Const(ct)
|
||||||
|
if ct.has_infer_types_or_consts() || ct.has_param_types_or_consts() =>
|
||||||
|
{
|
||||||
|
let ty = ct.ty();
|
||||||
|
// If the type references param or infer, replace that too...
|
||||||
|
if ty.has_param_types_or_consts() || ty.has_infer_types_or_consts() {
|
||||||
|
bug!("const `{ct}`'s type should not reference params or types");
|
||||||
|
}
|
||||||
|
tcx.mk_const(ty::ConstS {
|
||||||
|
ty,
|
||||||
|
kind: ty::ConstKind::Placeholder(ty::PlaceholderConst {
|
||||||
|
universe: ty::UniverseIndex::ROOT,
|
||||||
|
name: ty::BoundConst { ty, var: ty::BoundVar::from_usize(idx) },
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
.into()
|
||||||
|
}
|
||||||
|
_ => arg,
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
|
@ -394,15 +394,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||||
);
|
);
|
||||||
|
|
||||||
concrete_ty.visit_with(&mut ConstrainOpaqueTypeRegionVisitor {
|
concrete_ty.visit_with(&mut ConstrainOpaqueTypeRegionVisitor {
|
||||||
op: |r| {
|
op: |r| self.member_constraint(opaque_type_key, span, concrete_ty, r, &choice_regions),
|
||||||
self.member_constraint(
|
|
||||||
opaque_type_key.def_id,
|
|
||||||
span,
|
|
||||||
concrete_ty,
|
|
||||||
r,
|
|
||||||
&choice_regions,
|
|
||||||
)
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,6 @@ use rustc_data_structures::intern::Interned;
|
||||||
use rustc_data_structures::sync::Lrc;
|
use rustc_data_structures::sync::Lrc;
|
||||||
use rustc_data_structures::undo_log::UndoLogs;
|
use rustc_data_structures::undo_log::UndoLogs;
|
||||||
use rustc_data_structures::unify as ut;
|
use rustc_data_structures::unify as ut;
|
||||||
use rustc_hir::def_id::LocalDefId;
|
|
||||||
use rustc_index::vec::IndexVec;
|
use rustc_index::vec::IndexVec;
|
||||||
use rustc_middle::infer::unify_key::{RegionVidKey, UnifiedRegion};
|
use rustc_middle::infer::unify_key::{RegionVidKey, UnifiedRegion};
|
||||||
use rustc_middle::ty::ReStatic;
|
use rustc_middle::ty::ReStatic;
|
||||||
|
@ -533,7 +532,7 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
|
||||||
|
|
||||||
pub fn member_constraint(
|
pub fn member_constraint(
|
||||||
&mut self,
|
&mut self,
|
||||||
opaque_type_def_id: LocalDefId,
|
key: ty::OpaqueTypeKey<'tcx>,
|
||||||
definition_span: Span,
|
definition_span: Span,
|
||||||
hidden_ty: Ty<'tcx>,
|
hidden_ty: Ty<'tcx>,
|
||||||
member_region: ty::Region<'tcx>,
|
member_region: ty::Region<'tcx>,
|
||||||
|
@ -546,7 +545,7 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
self.data.member_constraints.push(MemberConstraint {
|
self.data.member_constraints.push(MemberConstraint {
|
||||||
opaque_type_def_id,
|
key,
|
||||||
definition_span,
|
definition_span,
|
||||||
hidden_ty,
|
hidden_ty,
|
||||||
member_region,
|
member_region,
|
||||||
|
|
|
@ -2,9 +2,8 @@ pub mod canonical;
|
||||||
pub mod unify_key;
|
pub mod unify_key;
|
||||||
|
|
||||||
use crate::ty::Region;
|
use crate::ty::Region;
|
||||||
use crate::ty::Ty;
|
use crate::ty::{OpaqueTypeKey, Ty};
|
||||||
use rustc_data_structures::sync::Lrc;
|
use rustc_data_structures::sync::Lrc;
|
||||||
use rustc_hir::def_id::LocalDefId;
|
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
|
|
||||||
/// Requires that `region` must be equal to one of the regions in `choice_regions`.
|
/// Requires that `region` must be equal to one of the regions in `choice_regions`.
|
||||||
|
@ -15,8 +14,9 @@ use rustc_span::Span;
|
||||||
/// ```
|
/// ```
|
||||||
#[derive(Debug, Clone, HashStable, TypeFoldable, TypeVisitable, Lift)]
|
#[derive(Debug, Clone, HashStable, TypeFoldable, TypeVisitable, Lift)]
|
||||||
pub struct MemberConstraint<'tcx> {
|
pub struct MemberConstraint<'tcx> {
|
||||||
/// The `DefId` of the opaque type causing this constraint: used for error reporting.
|
/// The `DefId` and substs of the opaque type causing this constraint.
|
||||||
pub opaque_type_def_id: LocalDefId,
|
/// Used for error reporting.
|
||||||
|
pub key: OpaqueTypeKey<'tcx>,
|
||||||
|
|
||||||
/// The span where the hidden type was instantiated.
|
/// The span where the hidden type was instantiated.
|
||||||
pub definition_span: Span,
|
pub definition_span: Span,
|
||||||
|
|
|
@ -42,7 +42,7 @@ fn unsafe_derive_on_repr_packed(tcx: TyCtxt<'_>, def_id: LocalDefId) {
|
||||||
"that does not derive `Copy`"
|
"that does not derive `Copy`"
|
||||||
};
|
};
|
||||||
let message = format!(
|
let message = format!(
|
||||||
"`{}` can't be derived on this `#[repr(packed)]` struct {} (error E0133)",
|
"`{}` can't be derived on this `#[repr(packed)]` struct {}",
|
||||||
tcx.item_name(tcx.trait_id_of_impl(def_id.to_def_id()).expect("derived trait name")),
|
tcx.item_name(tcx.trait_id_of_impl(def_id.to_def_id()).expect("derived trait name")),
|
||||||
extra
|
extra
|
||||||
);
|
);
|
||||||
|
|
|
@ -703,13 +703,42 @@ impl<'tcx> TypeVisitor<'tcx> for OrphanChecker<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ty::Error(_) => ControlFlow::Break(OrphanCheckEarlyExit::LocalTy(ty)),
|
ty::Error(_) => ControlFlow::Break(OrphanCheckEarlyExit::LocalTy(ty)),
|
||||||
ty::Opaque(..) | ty::Closure(..) | ty::Generator(..) | ty::GeneratorWitness(..) => {
|
ty::Closure(..) | ty::Generator(..) | ty::GeneratorWitness(..) => {
|
||||||
self.tcx.sess.delay_span_bug(
|
self.tcx.sess.delay_span_bug(
|
||||||
DUMMY_SP,
|
DUMMY_SP,
|
||||||
format!("ty_is_local invoked on closure or generator: {:?}", ty),
|
format!("ty_is_local invoked on closure or generator: {:?}", ty),
|
||||||
);
|
);
|
||||||
ControlFlow::Break(OrphanCheckEarlyExit::LocalTy(ty))
|
ControlFlow::Break(OrphanCheckEarlyExit::LocalTy(ty))
|
||||||
}
|
}
|
||||||
|
ty::Opaque(..) => {
|
||||||
|
// This merits some explanation.
|
||||||
|
// Normally, opaque types are not involved when performing
|
||||||
|
// coherence checking, since it is illegal to directly
|
||||||
|
// implement a trait on an opaque type. However, we might
|
||||||
|
// end up looking at an opaque type during coherence checking
|
||||||
|
// if an opaque type gets used within another type (e.g. as
|
||||||
|
// the type of a field) when checking for auto trait or `Sized`
|
||||||
|
// impls. This requires us to decide whether or not an opaque
|
||||||
|
// type should be considered 'local' or not.
|
||||||
|
//
|
||||||
|
// We choose to treat all opaque types as non-local, even
|
||||||
|
// those that appear within the same crate. This seems
|
||||||
|
// somewhat surprising at first, but makes sense when
|
||||||
|
// you consider that opaque types are supposed to hide
|
||||||
|
// the underlying type *within the same crate*. When an
|
||||||
|
// opaque type is used from outside the module
|
||||||
|
// where it is declared, it should be impossible to observe
|
||||||
|
// anything about it other than the traits that it implements.
|
||||||
|
//
|
||||||
|
// The alternative would be to look at the underlying type
|
||||||
|
// to determine whether or not the opaque type itself should
|
||||||
|
// be considered local. However, this could make it a breaking change
|
||||||
|
// to switch the underlying ('defining') type from a local type
|
||||||
|
// to a remote type. This would violate the rule that opaque
|
||||||
|
// types should be completely opaque apart from the traits
|
||||||
|
// that they implement, so we don't use this behavior.
|
||||||
|
self.found_non_local_ty(ty)
|
||||||
|
}
|
||||||
};
|
};
|
||||||
// A bit of a hack, the `OrphanChecker` is only used to visit a `TraitRef`, so
|
// A bit of a hack, the `OrphanChecker` is only used to visit a `TraitRef`, so
|
||||||
// the first type we visit is always the self type.
|
// the first type we visit is always the self type.
|
||||||
|
|
|
@ -185,21 +185,12 @@ pub fn is_const_evaluatable<'cx, 'tcx>(
|
||||||
}
|
}
|
||||||
let concrete = infcx.const_eval_resolve(param_env, uv.expand(), Some(span));
|
let concrete = infcx.const_eval_resolve(param_env, uv.expand(), Some(span));
|
||||||
match concrete {
|
match concrete {
|
||||||
Err(ErrorHandled::TooGeneric) => Err(if uv.has_infer_types_or_consts() {
|
Err(ErrorHandled::TooGeneric) => {
|
||||||
NotConstEvaluatable::MentionsInfer
|
Err(NotConstEvaluatable::Error(infcx.tcx.sess.delay_span_bug(
|
||||||
} else if uv.has_param_types_or_consts() {
|
|
||||||
infcx
|
|
||||||
.tcx
|
|
||||||
.sess
|
|
||||||
.delay_span_bug(span, &format!("unexpected `TooGeneric` for {:?}", uv));
|
|
||||||
NotConstEvaluatable::MentionsParam
|
|
||||||
} else {
|
|
||||||
let guar = infcx.tcx.sess.delay_span_bug(
|
|
||||||
span,
|
span,
|
||||||
format!("Missing value for constant, but no error reported?"),
|
format!("Missing value for constant, but no error reported?"),
|
||||||
);
|
)))
|
||||||
NotConstEvaluatable::Error(guar)
|
}
|
||||||
}),
|
|
||||||
Err(ErrorHandled::Linted) => {
|
Err(ErrorHandled::Linted) => {
|
||||||
let reported = infcx
|
let reported = infcx
|
||||||
.tcx
|
.tcx
|
||||||
|
|
|
@ -730,7 +730,7 @@ impl<T: ?Sized> *const T {
|
||||||
/// }
|
/// }
|
||||||
///
|
///
|
||||||
/// // This would be incorrect, as the pointers are not correctly ordered:
|
/// // This would be incorrect, as the pointers are not correctly ordered:
|
||||||
/// // ptr1.offset_from(ptr2)
|
/// // ptr1.sub_ptr(ptr2)
|
||||||
/// ```
|
/// ```
|
||||||
#[unstable(feature = "ptr_sub_ptr", issue = "95892")]
|
#[unstable(feature = "ptr_sub_ptr", issue = "95892")]
|
||||||
#[rustc_const_unstable(feature = "const_ptr_sub_ptr", issue = "95892")]
|
#[rustc_const_unstable(feature = "const_ptr_sub_ptr", issue = "95892")]
|
||||||
|
|
|
@ -13,7 +13,7 @@ LL | | }
|
||||||
|
|
|
|
||||||
= help: consider adding the following bound: `'a: 'b`
|
= help: consider adding the following bound: `'a: 'b`
|
||||||
|
|
||||||
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
|
error[E0700]: hidden type for `impl Trait<'a>` captures lifetime that does not appear in bounds
|
||||||
--> $DIR/ret-impl-trait-one.rs:16:80
|
--> $DIR/ret-impl-trait-one.rs:16:80
|
||||||
|
|
|
|
||||||
LL | async fn async_ret_impl_trait1<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a> {
|
LL | async fn async_ret_impl_trait1<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a> {
|
||||||
|
|
22
src/test/ui/coherence/issue-99663-2.rs
Normal file
22
src/test/ui/coherence/issue-99663-2.rs
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
// check-pass
|
||||||
|
|
||||||
|
#![feature(type_alias_impl_trait)]
|
||||||
|
|
||||||
|
struct Outer<T: ?Sized> {
|
||||||
|
i: InnerSend<T>,
|
||||||
|
}
|
||||||
|
|
||||||
|
type InnerSend<T: ?Sized> = impl Send;
|
||||||
|
|
||||||
|
fn constrain<T: ?Sized>() -> InnerSend<T> {
|
||||||
|
()
|
||||||
|
}
|
||||||
|
|
||||||
|
trait SendMustNotImplDrop {}
|
||||||
|
|
||||||
|
#[allow(drop_bounds)]
|
||||||
|
impl<T: ?Sized + Send + Drop> SendMustNotImplDrop for T {}
|
||||||
|
|
||||||
|
impl<T: ?Sized> SendMustNotImplDrop for Outer<T> {}
|
||||||
|
|
||||||
|
fn main() {}
|
22
src/test/ui/coherence/issue-99663.rs
Normal file
22
src/test/ui/coherence/issue-99663.rs
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
// check-pass
|
||||||
|
|
||||||
|
#![feature(type_alias_impl_trait)]
|
||||||
|
|
||||||
|
struct Send<T> {
|
||||||
|
i: InnerSend<T>,
|
||||||
|
}
|
||||||
|
|
||||||
|
type InnerSend<T> = impl Sized;
|
||||||
|
|
||||||
|
fn constrain<T>() -> InnerSend<T> {
|
||||||
|
()
|
||||||
|
}
|
||||||
|
|
||||||
|
trait SendMustNotImplDrop {}
|
||||||
|
|
||||||
|
#[allow(drop_bounds)]
|
||||||
|
impl<T: Drop> SendMustNotImplDrop for T {}
|
||||||
|
|
||||||
|
impl<T> SendMustNotImplDrop for Send<T> {}
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -1,3 +1,5 @@
|
||||||
|
// check-pass
|
||||||
|
|
||||||
#![feature(generic_const_exprs)]
|
#![feature(generic_const_exprs)]
|
||||||
#![allow(incomplete_features)]
|
#![allow(incomplete_features)]
|
||||||
|
|
||||||
|
@ -21,11 +23,6 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
// FIXME(generic_const_exprs): We can't correctly infer `T` which requires
|
|
||||||
// evaluating `{ N + 1 }` which has substs containing an inference var
|
|
||||||
let mut _q = Default::default();
|
let mut _q = Default::default();
|
||||||
//~^ ERROR type annotations needed
|
|
||||||
|
|
||||||
_q = foo::<_, 2>(_q);
|
_q = foo::<_, 2>(_q);
|
||||||
//~^ ERROR type annotations needed
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,38 +0,0 @@
|
||||||
error[E0282]: type annotations needed
|
|
||||||
--> $DIR/const_eval_resolve_canonical.rs:26:9
|
|
||||||
|
|
|
||||||
LL | let mut _q = Default::default();
|
|
||||||
| ^^^^^^
|
|
||||||
|
|
|
||||||
help: consider giving `_q` an explicit type
|
|
||||||
|
|
|
||||||
LL | let mut _q: _ = Default::default();
|
|
||||||
| +++
|
|
||||||
|
|
||||||
error[E0283]: type annotations needed
|
|
||||||
--> $DIR/const_eval_resolve_canonical.rs:29:10
|
|
||||||
|
|
|
||||||
LL | _q = foo::<_, 2>(_q);
|
|
||||||
| ^^^^^^^^^^^ cannot infer the value of the constant `{ N + 1 }`
|
|
||||||
|
|
|
||||||
note: multiple `impl`s satisfying `(): Foo<{ N + 1 }>` found
|
|
||||||
--> $DIR/const_eval_resolve_canonical.rs:8:1
|
|
||||||
|
|
|
||||||
LL | impl Foo<0> for () {
|
|
||||||
| ^^^^^^^^^^^^^^^^^^
|
|
||||||
...
|
|
||||||
LL | impl Foo<3> for () {
|
|
||||||
| ^^^^^^^^^^^^^^^^^^
|
|
||||||
note: required by a bound in `foo`
|
|
||||||
--> $DIR/const_eval_resolve_canonical.rs:18:9
|
|
||||||
|
|
|
||||||
LL | fn foo<T, const N: usize>(_: T) -> <() as Foo<{ N + 1 }>>::Assoc
|
|
||||||
| --- required by a bound in this
|
|
||||||
LL | where
|
|
||||||
LL | (): Foo<{ N + 1 }>,
|
|
||||||
| ^^^^^^^^^^^^^^ required by this bound in `foo`
|
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
|
||||||
|
|
||||||
Some errors have detailed explanations: E0282, E0283.
|
|
||||||
For more information about an error, try `rustc --explain E0282`.
|
|
|
@ -222,7 +222,7 @@ error[E0080]: could not evaluate static initializer
|
||||||
LL | unsafe { intrinsics::ptr_offset_from_unsigned(self, origin) }
|
LL | unsafe { intrinsics::ptr_offset_from_unsigned(self, origin) }
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
| |
|
| |
|
||||||
| ptr_offset_from_unsigned called on pointers into different allocations
|
| `ptr_offset_from_unsigned` called on pointers into different allocations
|
||||||
| inside `ptr::const_ptr::<impl *const u32>::sub_ptr` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
| inside `ptr::const_ptr::<impl *const u32>::sub_ptr` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
||||||
|
|
|
|
||||||
::: $SRC_DIR/core/src/slice/raw.rs:LL:COL
|
::: $SRC_DIR/core/src/slice/raw.rs:LL:COL
|
||||||
|
@ -241,7 +241,7 @@ error[E0080]: could not evaluate static initializer
|
||||||
LL | unsafe { intrinsics::ptr_offset_from_unsigned(self, origin) }
|
LL | unsafe { intrinsics::ptr_offset_from_unsigned(self, origin) }
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
| |
|
| |
|
||||||
| ptr_offset_from_unsigned called on pointers into different allocations
|
| `ptr_offset_from_unsigned` called on pointers into different allocations
|
||||||
| inside `ptr::const_ptr::<impl *const u32>::sub_ptr` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
| inside `ptr::const_ptr::<impl *const u32>::sub_ptr` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
||||||
|
|
|
|
||||||
::: $SRC_DIR/core/src/slice/raw.rs:LL:COL
|
::: $SRC_DIR/core/src/slice/raw.rs:LL:COL
|
||||||
|
|
|
@ -222,7 +222,7 @@ error[E0080]: could not evaluate static initializer
|
||||||
LL | unsafe { intrinsics::ptr_offset_from_unsigned(self, origin) }
|
LL | unsafe { intrinsics::ptr_offset_from_unsigned(self, origin) }
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
| |
|
| |
|
||||||
| ptr_offset_from_unsigned called on pointers into different allocations
|
| `ptr_offset_from_unsigned` called on pointers into different allocations
|
||||||
| inside `ptr::const_ptr::<impl *const u32>::sub_ptr` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
| inside `ptr::const_ptr::<impl *const u32>::sub_ptr` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
||||||
|
|
|
|
||||||
::: $SRC_DIR/core/src/slice/raw.rs:LL:COL
|
::: $SRC_DIR/core/src/slice/raw.rs:LL:COL
|
||||||
|
@ -241,7 +241,7 @@ error[E0080]: could not evaluate static initializer
|
||||||
LL | unsafe { intrinsics::ptr_offset_from_unsigned(self, origin) }
|
LL | unsafe { intrinsics::ptr_offset_from_unsigned(self, origin) }
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
| |
|
| |
|
||||||
| ptr_offset_from_unsigned called on pointers into different allocations
|
| `ptr_offset_from_unsigned` called on pointers into different allocations
|
||||||
| inside `ptr::const_ptr::<impl *const u32>::sub_ptr` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
| inside `ptr::const_ptr::<impl *const u32>::sub_ptr` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
||||||
|
|
|
|
||||||
::: $SRC_DIR/core/src/slice/raw.rs:LL:COL
|
::: $SRC_DIR/core/src/slice/raw.rs:LL:COL
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#![feature(core_intrinsics)]
|
#![feature(core_intrinsics)]
|
||||||
|
|
||||||
use std::intrinsics::{ptr_offset_from, ptr_offset_from_unsigned};
|
use std::intrinsics::{ptr_offset_from, ptr_offset_from_unsigned};
|
||||||
|
use std::ptr;
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
struct Struct {
|
struct Struct {
|
||||||
|
@ -75,9 +76,21 @@ pub const DIFFERENT_ALLOC_UNSIGNED: usize = {
|
||||||
let base_ptr: *const Struct = &uninit as *const _ as *const Struct;
|
let base_ptr: *const Struct = &uninit as *const _ as *const Struct;
|
||||||
let uninit2 = std::mem::MaybeUninit::<Struct>::uninit();
|
let uninit2 = std::mem::MaybeUninit::<Struct>::uninit();
|
||||||
let field_ptr: *const Struct = &uninit2 as *const _ as *const Struct;
|
let field_ptr: *const Struct = &uninit2 as *const _ as *const Struct;
|
||||||
let offset = unsafe { ptr_offset_from_unsigned(field_ptr, base_ptr) }; //~ERROR evaluation of constant value failed
|
unsafe { ptr_offset_from_unsigned(field_ptr, base_ptr) } //~ERROR evaluation of constant value failed
|
||||||
//~| pointers into different allocations
|
//~| pointers into different allocations
|
||||||
offset as usize
|
};
|
||||||
|
|
||||||
|
pub const TOO_FAR_APART1: isize = {
|
||||||
|
let ptr1 = ptr::null::<u8>();
|
||||||
|
let ptr2 = ptr1.wrapping_add(isize::MAX as usize + 42);
|
||||||
|
unsafe { ptr_offset_from(ptr2, ptr1) } //~ERROR evaluation of constant value failed
|
||||||
|
//~| too far ahead
|
||||||
|
};
|
||||||
|
pub const TOO_FAR_APART2: isize = {
|
||||||
|
let ptr1 = ptr::null::<u8>();
|
||||||
|
let ptr2 = ptr1.wrapping_add(isize::MAX as usize + 42);
|
||||||
|
unsafe { ptr_offset_from(ptr1, ptr2) } //~ERROR evaluation of constant value failed
|
||||||
|
//~| too far before
|
||||||
};
|
};
|
||||||
|
|
||||||
const WRONG_ORDER_UNSIGNED: usize = {
|
const WRONG_ORDER_UNSIGNED: usize = {
|
||||||
|
@ -86,5 +99,27 @@ const WRONG_ORDER_UNSIGNED: usize = {
|
||||||
unsafe { ptr_offset_from_unsigned(p, p.add(2) ) } //~ERROR evaluation of constant value failed
|
unsafe { ptr_offset_from_unsigned(p, p.add(2) ) } //~ERROR evaluation of constant value failed
|
||||||
//~| first pointer has smaller offset than second: 0 < 8
|
//~| first pointer has smaller offset than second: 0 < 8
|
||||||
};
|
};
|
||||||
|
pub const TOO_FAR_APART_UNSIGNED: usize = {
|
||||||
|
let ptr1 = ptr::null::<u8>();
|
||||||
|
let ptr2 = ptr1.wrapping_add(isize::MAX as usize + 42);
|
||||||
|
// This would fit into a `usize` but we still don't allow it.
|
||||||
|
unsafe { ptr_offset_from_unsigned(ptr2, ptr1) } //~ERROR evaluation of constant value failed
|
||||||
|
//~| too far ahead
|
||||||
|
};
|
||||||
|
|
||||||
|
// These do NOT complain that pointers are too far apart; they pass that check (to then fail the
|
||||||
|
// next one).
|
||||||
|
pub const OFFSET_VERY_FAR1: isize = {
|
||||||
|
let ptr1 = ptr::null::<u8>();
|
||||||
|
let ptr2 = ptr1.wrapping_offset(isize::MAX);
|
||||||
|
unsafe { ptr2.offset_from(ptr1) }
|
||||||
|
//~^ inside
|
||||||
|
};
|
||||||
|
pub const OFFSET_VERY_FAR2: isize = {
|
||||||
|
let ptr1 = ptr::null::<u8>();
|
||||||
|
let ptr2 = ptr1.wrapping_offset(isize::MAX);
|
||||||
|
unsafe { ptr1.offset_from(ptr2.wrapping_offset(1)) }
|
||||||
|
//~^ inside
|
||||||
|
};
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error[E0080]: evaluation of constant value failed
|
error[E0080]: evaluation of constant value failed
|
||||||
--> $DIR/offset_from_ub.rs:17:27
|
--> $DIR/offset_from_ub.rs:18:27
|
||||||
|
|
|
|
||||||
LL | let offset = unsafe { ptr_offset_from(field_ptr, base_ptr) };
|
LL | let offset = unsafe { ptr_offset_from(field_ptr, base_ptr) };
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ptr_offset_from called on pointers into different allocations
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from` called on pointers into different allocations
|
||||||
|
|
||||||
error[E0080]: evaluation of constant value failed
|
error[E0080]: evaluation of constant value failed
|
||||||
--> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
--> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
||||||
|
@ -10,62 +10,108 @@ error[E0080]: evaluation of constant value failed
|
||||||
LL | unsafe { intrinsics::ptr_offset_from(self, origin) }
|
LL | unsafe { intrinsics::ptr_offset_from(self, origin) }
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
| |
|
| |
|
||||||
| ptr_offset_from called on pointers into different allocations
|
| `ptr_offset_from` called on pointers into different allocations
|
||||||
| inside `ptr::const_ptr::<impl *const u8>::offset_from` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
| inside `ptr::const_ptr::<impl *const u8>::offset_from` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
||||||
|
|
|
|
||||||
::: $DIR/offset_from_ub.rs:23:14
|
::: $DIR/offset_from_ub.rs:24:14
|
||||||
|
|
|
|
||||||
LL | unsafe { (42 as *const u8).offset_from(&5u8) as usize }
|
LL | unsafe { (42 as *const u8).offset_from(&5u8) as usize }
|
||||||
| ----------------------------------- inside `NOT_PTR` at $DIR/offset_from_ub.rs:23:14
|
| ----------------------------------- inside `NOT_PTR` at $DIR/offset_from_ub.rs:24:14
|
||||||
|
|
||||||
error[E0080]: evaluation of constant value failed
|
error[E0080]: evaluation of constant value failed
|
||||||
--> $DIR/offset_from_ub.rs:30:14
|
--> $DIR/offset_from_ub.rs:31:14
|
||||||
|
|
|
|
||||||
LL | unsafe { ptr_offset_from(field_ptr, base_ptr as *const u16) }
|
LL | unsafe { ptr_offset_from(field_ptr, base_ptr as *const u16) }
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ exact_div: 1_isize cannot be divided by 2_isize without remainder
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ exact_div: 1_isize cannot be divided by 2_isize without remainder
|
||||||
|
|
||||||
error[E0080]: evaluation of constant value failed
|
error[E0080]: evaluation of constant value failed
|
||||||
--> $DIR/offset_from_ub.rs:36:14
|
--> $DIR/offset_from_ub.rs:37:14
|
||||||
|
|
|
|
||||||
LL | unsafe { ptr_offset_from(ptr, ptr) }
|
LL | unsafe { ptr_offset_from(ptr, ptr) }
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds offset_from: null pointer is a dangling pointer (it has no provenance)
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds offset_from: null pointer is a dangling pointer (it has no provenance)
|
||||||
|
|
||||||
error[E0080]: evaluation of constant value failed
|
error[E0080]: evaluation of constant value failed
|
||||||
--> $DIR/offset_from_ub.rs:43:14
|
--> $DIR/offset_from_ub.rs:44:14
|
||||||
|
|
|
|
||||||
LL | unsafe { ptr_offset_from(ptr2, ptr1) }
|
LL | unsafe { ptr_offset_from(ptr2, ptr1) }
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds offset_from: 0x8[noalloc] is a dangling pointer (it has no provenance)
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds offset_from: 0x8[noalloc] is a dangling pointer (it has no provenance)
|
||||||
|
|
||||||
error[E0080]: evaluation of constant value failed
|
error[E0080]: evaluation of constant value failed
|
||||||
--> $DIR/offset_from_ub.rs:52:14
|
--> $DIR/offset_from_ub.rs:53:14
|
||||||
|
|
|
|
||||||
LL | unsafe { ptr_offset_from(end_ptr, start_ptr) }
|
LL | unsafe { ptr_offset_from(end_ptr, start_ptr) }
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds offset_from: alloc18 has size 4, so pointer to 10 bytes starting at offset 0 is out-of-bounds
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds offset_from: alloc18 has size 4, so pointer to 10 bytes starting at offset 0 is out-of-bounds
|
||||||
|
|
||||||
error[E0080]: evaluation of constant value failed
|
error[E0080]: evaluation of constant value failed
|
||||||
--> $DIR/offset_from_ub.rs:61:14
|
--> $DIR/offset_from_ub.rs:62:14
|
||||||
|
|
|
|
||||||
LL | unsafe { ptr_offset_from(start_ptr, end_ptr) }
|
LL | unsafe { ptr_offset_from(start_ptr, end_ptr) }
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds offset_from: alloc21 has size 4, so pointer to 10 bytes starting at offset 0 is out-of-bounds
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds offset_from: alloc21 has size 4, so pointer to 10 bytes starting at offset 0 is out-of-bounds
|
||||||
|
|
||||||
error[E0080]: evaluation of constant value failed
|
error[E0080]: evaluation of constant value failed
|
||||||
--> $DIR/offset_from_ub.rs:69:14
|
--> $DIR/offset_from_ub.rs:70:14
|
||||||
|
|
|
|
||||||
LL | unsafe { ptr_offset_from(end_ptr, end_ptr) }
|
LL | unsafe { ptr_offset_from(end_ptr, end_ptr) }
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds offset_from: alloc24 has size 4, so pointer at offset 10 is out-of-bounds
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds offset_from: alloc24 has size 4, so pointer at offset 10 is out-of-bounds
|
||||||
|
|
||||||
error[E0080]: evaluation of constant value failed
|
error[E0080]: evaluation of constant value failed
|
||||||
--> $DIR/offset_from_ub.rs:78:27
|
--> $DIR/offset_from_ub.rs:79:14
|
||||||
|
|
|
|
||||||
LL | let offset = unsafe { ptr_offset_from_unsigned(field_ptr, base_ptr) };
|
LL | unsafe { ptr_offset_from_unsigned(field_ptr, base_ptr) }
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ptr_offset_from_unsigned called on pointers into different allocations
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from_unsigned` called on pointers into different allocations
|
||||||
|
|
||||||
error[E0080]: evaluation of constant value failed
|
error[E0080]: evaluation of constant value failed
|
||||||
--> $DIR/offset_from_ub.rs:86:14
|
--> $DIR/offset_from_ub.rs:86:14
|
||||||
|
|
|
|
||||||
LL | unsafe { ptr_offset_from_unsigned(p, p.add(2) ) }
|
LL | unsafe { ptr_offset_from(ptr2, ptr1) }
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ptr_offset_from_unsigned called when first pointer has smaller offset than second: 0 < 8
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from` called when first pointer is too far ahead of second
|
||||||
|
|
||||||
error: aborting due to 10 previous errors
|
error[E0080]: evaluation of constant value failed
|
||||||
|
--> $DIR/offset_from_ub.rs:92:14
|
||||||
|
|
|
||||||
|
LL | unsafe { ptr_offset_from(ptr1, ptr2) }
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from` called when first pointer is too far before second
|
||||||
|
|
||||||
|
error[E0080]: evaluation of constant value failed
|
||||||
|
--> $DIR/offset_from_ub.rs:99:14
|
||||||
|
|
|
||||||
|
LL | unsafe { ptr_offset_from_unsigned(p, p.add(2) ) }
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from_unsigned` called when first pointer has smaller offset than second: 0 < 8
|
||||||
|
|
||||||
|
error[E0080]: evaluation of constant value failed
|
||||||
|
--> $DIR/offset_from_ub.rs:106:14
|
||||||
|
|
|
||||||
|
LL | unsafe { ptr_offset_from_unsigned(ptr2, ptr1) }
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from_unsigned` called when first pointer is too far ahead of second
|
||||||
|
|
||||||
|
error[E0080]: evaluation of constant value failed
|
||||||
|
--> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
||||||
|
|
|
||||||
|
LL | unsafe { intrinsics::ptr_offset_from(self, origin) }
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
| |
|
||||||
|
| out-of-bounds offset_from: null pointer is a dangling pointer (it has no provenance)
|
||||||
|
| inside `ptr::const_ptr::<impl *const u8>::offset_from` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
||||||
|
|
|
||||||
|
::: $DIR/offset_from_ub.rs:115:14
|
||||||
|
|
|
||||||
|
LL | unsafe { ptr2.offset_from(ptr1) }
|
||||||
|
| ---------------------- inside `OFFSET_VERY_FAR1` at $DIR/offset_from_ub.rs:115:14
|
||||||
|
|
||||||
|
error[E0080]: evaluation of constant value failed
|
||||||
|
--> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
||||||
|
|
|
||||||
|
LL | unsafe { intrinsics::ptr_offset_from(self, origin) }
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
| |
|
||||||
|
| out-of-bounds offset_from: null pointer is a dangling pointer (it has no provenance)
|
||||||
|
| inside `ptr::const_ptr::<impl *const u8>::offset_from` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
||||||
|
|
|
||||||
|
::: $DIR/offset_from_ub.rs:121:14
|
||||||
|
|
|
||||||
|
LL | unsafe { ptr1.offset_from(ptr2.wrapping_offset(1)) }
|
||||||
|
| ----------------------------------------- inside `OFFSET_VERY_FAR2` at $DIR/offset_from_ub.rs:121:14
|
||||||
|
|
||||||
|
error: aborting due to 15 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0080`.
|
For more information about this error, try `rustc --explain E0080`.
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
error: `Clone` can't be derived on this `#[repr(packed)]` struct with type or const parameters (error E0133)
|
error: `Clone` can't be derived on this `#[repr(packed)]` struct with type or const parameters
|
||||||
--> $DIR/deriving-with-repr-packed.rs:11:16
|
--> $DIR/deriving-with-repr-packed.rs:11:16
|
||||||
|
|
|
|
||||||
LL | #[derive(Copy, Clone, Default, PartialEq, Eq)]
|
LL | #[derive(Copy, Clone, Default, PartialEq, Eq)]
|
||||||
|
@ -13,7 +13,7 @@ LL | #![deny(unaligned_references)]
|
||||||
= note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
|
= note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
|
||||||
= note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
error: `PartialEq` can't be derived on this `#[repr(packed)]` struct with type or const parameters (error E0133)
|
error: `PartialEq` can't be derived on this `#[repr(packed)]` struct with type or const parameters
|
||||||
--> $DIR/deriving-with-repr-packed.rs:11:32
|
--> $DIR/deriving-with-repr-packed.rs:11:32
|
||||||
|
|
|
|
||||||
LL | #[derive(Copy, Clone, Default, PartialEq, Eq)]
|
LL | #[derive(Copy, Clone, Default, PartialEq, Eq)]
|
||||||
|
@ -23,7 +23,7 @@ LL | #[derive(Copy, Clone, Default, PartialEq, Eq)]
|
||||||
= note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
|
= note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
|
||||||
= note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
error: `Hash` can't be derived on this `#[repr(packed)]` struct that does not derive `Copy` (error E0133)
|
error: `Hash` can't be derived on this `#[repr(packed)]` struct that does not derive `Copy`
|
||||||
--> $DIR/deriving-with-repr-packed.rs:19:19
|
--> $DIR/deriving-with-repr-packed.rs:19:19
|
||||||
|
|
|
|
||||||
LL | #[derive(Default, Hash)]
|
LL | #[derive(Default, Hash)]
|
||||||
|
@ -33,7 +33,7 @@ LL | #[derive(Default, Hash)]
|
||||||
= note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
|
= note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
|
||||||
= note: this error originates in the derive macro `Hash` (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in the derive macro `Hash` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
error: `Debug` can't be derived on this `#[repr(packed)]` struct that does not derive `Copy` (error E0133)
|
error: `Debug` can't be derived on this `#[repr(packed)]` struct that does not derive `Copy`
|
||||||
--> $DIR/deriving-with-repr-packed.rs:39:10
|
--> $DIR/deriving-with-repr-packed.rs:39:10
|
||||||
|
|
|
|
||||||
LL | #[derive(Debug, Default)]
|
LL | #[derive(Debug, Default)]
|
||||||
|
@ -46,7 +46,7 @@ LL | #[derive(Debug, Default)]
|
||||||
error: aborting due to 4 previous errors
|
error: aborting due to 4 previous errors
|
||||||
|
|
||||||
Future incompatibility report: Future breakage diagnostic:
|
Future incompatibility report: Future breakage diagnostic:
|
||||||
error: `Clone` can't be derived on this `#[repr(packed)]` struct with type or const parameters (error E0133)
|
error: `Clone` can't be derived on this `#[repr(packed)]` struct with type or const parameters
|
||||||
--> $DIR/deriving-with-repr-packed.rs:11:16
|
--> $DIR/deriving-with-repr-packed.rs:11:16
|
||||||
|
|
|
|
||||||
LL | #[derive(Copy, Clone, Default, PartialEq, Eq)]
|
LL | #[derive(Copy, Clone, Default, PartialEq, Eq)]
|
||||||
|
@ -62,7 +62,7 @@ LL | #![deny(unaligned_references)]
|
||||||
= note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
Future breakage diagnostic:
|
Future breakage diagnostic:
|
||||||
error: `PartialEq` can't be derived on this `#[repr(packed)]` struct with type or const parameters (error E0133)
|
error: `PartialEq` can't be derived on this `#[repr(packed)]` struct with type or const parameters
|
||||||
--> $DIR/deriving-with-repr-packed.rs:11:32
|
--> $DIR/deriving-with-repr-packed.rs:11:32
|
||||||
|
|
|
|
||||||
LL | #[derive(Copy, Clone, Default, PartialEq, Eq)]
|
LL | #[derive(Copy, Clone, Default, PartialEq, Eq)]
|
||||||
|
@ -78,7 +78,7 @@ LL | #![deny(unaligned_references)]
|
||||||
= note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
Future breakage diagnostic:
|
Future breakage diagnostic:
|
||||||
error: `Hash` can't be derived on this `#[repr(packed)]` struct that does not derive `Copy` (error E0133)
|
error: `Hash` can't be derived on this `#[repr(packed)]` struct that does not derive `Copy`
|
||||||
--> $DIR/deriving-with-repr-packed.rs:19:19
|
--> $DIR/deriving-with-repr-packed.rs:19:19
|
||||||
|
|
|
|
||||||
LL | #[derive(Default, Hash)]
|
LL | #[derive(Default, Hash)]
|
||||||
|
@ -94,7 +94,7 @@ LL | #![deny(unaligned_references)]
|
||||||
= note: this error originates in the derive macro `Hash` (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in the derive macro `Hash` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
Future breakage diagnostic:
|
Future breakage diagnostic:
|
||||||
error: `Debug` can't be derived on this `#[repr(packed)]` struct that does not derive `Copy` (error E0133)
|
error: `Debug` can't be derived on this `#[repr(packed)]` struct that does not derive `Copy`
|
||||||
--> $DIR/deriving-with-repr-packed.rs:39:10
|
--> $DIR/deriving-with-repr-packed.rs:39:10
|
||||||
|
|
|
|
||||||
LL | #[derive(Debug, Default)]
|
LL | #[derive(Debug, Default)]
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
|
error[E0700]: hidden type for `impl Swap` captures lifetime that does not appear in bounds
|
||||||
--> $DIR/hidden-lifetimes.rs:29:5
|
--> $DIR/hidden-lifetimes.rs:29:5
|
||||||
|
|
|
|
||||||
LL | fn hide_ref<'a, 'b, T: 'static>(x: &'a mut &'b T) -> impl Swap + 'a {
|
LL | fn hide_ref<'a, 'b, T: 'static>(x: &'a mut &'b T) -> impl Swap + 'a {
|
||||||
|
@ -11,7 +11,7 @@ help: to declare that the `impl Trait` captures `'b`, you can add an explicit `'
|
||||||
LL | fn hide_ref<'a, 'b, T: 'static>(x: &'a mut &'b T) -> impl Swap + 'a + 'b {
|
LL | fn hide_ref<'a, 'b, T: 'static>(x: &'a mut &'b T) -> impl Swap + 'a + 'b {
|
||||||
| ++++
|
| ++++
|
||||||
|
|
||||||
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
|
error[E0700]: hidden type for `impl Swap` captures lifetime that does not appear in bounds
|
||||||
--> $DIR/hidden-lifetimes.rs:46:5
|
--> $DIR/hidden-lifetimes.rs:46:5
|
||||||
|
|
|
|
||||||
LL | fn hide_rc_refcell<'a, 'b: 'a, T: 'static>(x: Rc<RefCell<&'b T>>) -> impl Swap + 'a {
|
LL | fn hide_rc_refcell<'a, 'b: 'a, T: 'static>(x: Rc<RefCell<&'b T>>) -> impl Swap + 'a {
|
||||||
|
|
|
@ -20,7 +20,7 @@ fn foo<'a: 'b, 'b, 'c>(x: &'static i32, mut y: &'a i32) -> E<'b, 'c> {
|
||||||
let _: &'b i32 = *u.0;
|
let _: &'b i32 = *u.0;
|
||||||
}
|
}
|
||||||
u.0
|
u.0
|
||||||
//~^ ERROR hidden type for `impl Trait` captures lifetime that does not appear in bounds
|
//~^ ERROR hidden type for `E<'b, 'c>` captures lifetime that does not appear in bounds
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
|
error[E0700]: hidden type for `E<'b, 'c>` captures lifetime that does not appear in bounds
|
||||||
--> $DIR/error-handling-2.rs:22:5
|
--> $DIR/error-handling-2.rs:22:5
|
||||||
|
|
|
|
||||||
LL | fn foo<'a: 'b, 'b, 'c>(x: &'static i32, mut y: &'a i32) -> E<'b, 'c> {
|
LL | fn foo<'a: 'b, 'b, 'c>(x: &'static i32, mut y: &'a i32) -> E<'b, 'c> {
|
||||||
|
|
|
@ -26,7 +26,7 @@ where
|
||||||
// 'a in ['d, 'e]
|
// 'a in ['d, 'e]
|
||||||
// ```
|
// ```
|
||||||
if condition() { a } else { b }
|
if condition() { a } else { b }
|
||||||
//~^ ERROR hidden type for `impl Trait` captures lifetime that does not appear in bounds
|
//~^ ERROR hidden type for `impl Trait<'d, 'e>` captures lifetime that does not appear in bounds
|
||||||
}
|
}
|
||||||
|
|
||||||
fn condition() -> bool {
|
fn condition() -> bool {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
|
error[E0700]: hidden type for `impl Trait<'d, 'e>` captures lifetime that does not appear in bounds
|
||||||
--> $DIR/ordinary-bounds-unrelated.rs:28:33
|
--> $DIR/ordinary-bounds-unrelated.rs:28:33
|
||||||
|
|
|
|
||||||
LL | fn upper_bounds<'a, 'b, 'c, 'd, 'e>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'d, 'e>
|
LL | fn upper_bounds<'a, 'b, 'c, 'd, 'e>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'d, 'e>
|
||||||
|
|
|
@ -29,7 +29,7 @@ fn upper_bounds<'a, 'b>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'a, 'b>
|
||||||
//
|
//
|
||||||
// We are forced to pick that '0 = 'e, because only 'e is outlived by *both* 'a and 'b.
|
// We are forced to pick that '0 = 'e, because only 'e is outlived by *both* 'a and 'b.
|
||||||
if condition() { a } else { b }
|
if condition() { a } else { b }
|
||||||
//~^ ERROR hidden type for `impl Trait` captures lifetime that does not appear in bounds
|
//~^ ERROR hidden type for `impl Trait<'a, 'b>` captures lifetime that does not appear in bounds
|
||||||
}
|
}
|
||||||
|
|
||||||
fn condition() -> bool {
|
fn condition() -> bool {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
|
error[E0700]: hidden type for `impl Trait<'a, 'b>` captures lifetime that does not appear in bounds
|
||||||
--> $DIR/ordinary-bounds-unsuited.rs:31:33
|
--> $DIR/ordinary-bounds-unsuited.rs:31:33
|
||||||
|
|
|
|
||||||
LL | fn upper_bounds<'a, 'b>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'a, 'b>
|
LL | fn upper_bounds<'a, 'b>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'a, 'b>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
|
error[E0700]: hidden type for `impl Copy` captures lifetime that does not appear in bounds
|
||||||
--> $DIR/must_outlive_least_region_or_bound.rs:3:35
|
--> $DIR/must_outlive_least_region_or_bound.rs:3:35
|
||||||
|
|
|
|
||||||
LL | fn elided(x: &i32) -> impl Copy { x }
|
LL | fn elided(x: &i32) -> impl Copy { x }
|
||||||
|
@ -11,7 +11,7 @@ help: to declare that the `impl Trait` captures `'_`, you can add an explicit `'
|
||||||
LL | fn elided(x: &i32) -> impl Copy + '_ { x }
|
LL | fn elided(x: &i32) -> impl Copy + '_ { x }
|
||||||
| ++++
|
| ++++
|
||||||
|
|
||||||
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
|
error[E0700]: hidden type for `impl Copy` captures lifetime that does not appear in bounds
|
||||||
--> $DIR/must_outlive_least_region_or_bound.rs:6:44
|
--> $DIR/must_outlive_least_region_or_bound.rs:6:44
|
||||||
|
|
|
|
||||||
LL | fn explicit<'a>(x: &'a i32) -> impl Copy { x }
|
LL | fn explicit<'a>(x: &'a i32) -> impl Copy { x }
|
||||||
|
@ -96,7 +96,7 @@ help: alternatively, add an explicit `'static` bound to this reference
|
||||||
LL | fn with_bound<'a>(x: &'static i32) -> impl LifetimeTrait<'a> + 'static { x }
|
LL | fn with_bound<'a>(x: &'static i32) -> impl LifetimeTrait<'a> + 'static { x }
|
||||||
| ~~~~~~~~~~~~
|
| ~~~~~~~~~~~~
|
||||||
|
|
||||||
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
|
error[E0700]: hidden type for `impl Fn(&'a u32)` captures lifetime that does not appear in bounds
|
||||||
--> $DIR/must_outlive_least_region_or_bound.rs:38:5
|
--> $DIR/must_outlive_least_region_or_bound.rs:38:5
|
||||||
|
|
|
|
||||||
LL | fn move_lifetime_into_fn<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Fn(&'a u32) {
|
LL | fn move_lifetime_into_fn<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Fn(&'a u32) {
|
||||||
|
|
|
@ -7,7 +7,7 @@ LL | impl<T: std::fmt::Debug> AnotherTrait for T {}
|
||||||
LL | impl AnotherTrait for D<OpaqueType> {
|
LL | impl AnotherTrait for D<OpaqueType> {
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `D<OpaqueType>`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `D<OpaqueType>`
|
||||||
|
|
|
|
||||||
= note: downstream crates may implement trait `std::fmt::Debug` for type `OpaqueType`
|
= note: upstream crates may add a new impl of trait `std::fmt::Debug` for type `OpaqueType` in future versions
|
||||||
|
|
||||||
error: cannot implement trait on type alias impl trait
|
error: cannot implement trait on type alias impl trait
|
||||||
--> $DIR/negative-reasoning.rs:19:25
|
--> $DIR/negative-reasoning.rs:19:25
|
||||||
|
|
|
@ -15,7 +15,7 @@ fn foo<'x, 'y>(x: Cell<&'x u32>) -> impl Trait<'y>
|
||||||
where 'x: 'y
|
where 'x: 'y
|
||||||
{
|
{
|
||||||
x
|
x
|
||||||
//~^ ERROR hidden type for `impl Trait` captures lifetime that does not appear in bounds [E0700]
|
//~^ ERROR hidden type for `impl Trait<'y>` captures lifetime that does not appear in bounds [E0700]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() { }
|
fn main() { }
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
|
error[E0700]: hidden type for `impl Trait<'y>` captures lifetime that does not appear in bounds
|
||||||
--> $DIR/region-escape-via-bound.rs:17:5
|
--> $DIR/region-escape-via-bound.rs:17:5
|
||||||
|
|
|
|
||||||
LL | fn foo<'x, 'y>(x: Cell<&'x u32>) -> impl Trait<'y>
|
LL | fn foo<'x, 'y>(x: Cell<&'x u32>) -> impl Trait<'y>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
|
error[E0700]: hidden type for `impl Iterator<Item = u32>` captures lifetime that does not appear in bounds
|
||||||
--> $DIR/static-return-lifetime-infered.rs:7:9
|
--> $DIR/static-return-lifetime-infered.rs:7:9
|
||||||
|
|
|
|
||||||
LL | fn iter_values_anon(&self) -> impl Iterator<Item=u32> {
|
LL | fn iter_values_anon(&self) -> impl Iterator<Item=u32> {
|
||||||
|
@ -11,7 +11,7 @@ help: to declare that the `impl Trait` captures `'_`, you can add an explicit `'
|
||||||
LL | fn iter_values_anon(&self) -> impl Iterator<Item=u32> + '_ {
|
LL | fn iter_values_anon(&self) -> impl Iterator<Item=u32> + '_ {
|
||||||
| ++++
|
| ++++
|
||||||
|
|
||||||
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
|
error[E0700]: hidden type for `impl Iterator<Item = u32>` captures lifetime that does not appear in bounds
|
||||||
--> $DIR/static-return-lifetime-infered.rs:7:9
|
--> $DIR/static-return-lifetime-infered.rs:7:9
|
||||||
|
|
|
|
||||||
LL | fn iter_values_anon(&self) -> impl Iterator<Item=u32> {
|
LL | fn iter_values_anon(&self) -> impl Iterator<Item=u32> {
|
||||||
|
@ -24,7 +24,7 @@ help: to declare that the `impl Trait` captures `'_`, you can add an explicit `'
|
||||||
LL | fn iter_values_anon(&self) -> impl Iterator<Item=u32> + '_ {
|
LL | fn iter_values_anon(&self) -> impl Iterator<Item=u32> + '_ {
|
||||||
| ++++
|
| ++++
|
||||||
|
|
||||||
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
|
error[E0700]: hidden type for `impl Iterator<Item = u32>` captures lifetime that does not appear in bounds
|
||||||
--> $DIR/static-return-lifetime-infered.rs:12:9
|
--> $DIR/static-return-lifetime-infered.rs:12:9
|
||||||
|
|
|
|
||||||
LL | fn iter_values<'a>(&'a self) -> impl Iterator<Item=u32> {
|
LL | fn iter_values<'a>(&'a self) -> impl Iterator<Item=u32> {
|
||||||
|
@ -37,7 +37,7 @@ help: to declare that the `impl Trait` captures `'a`, you can add an explicit `'
|
||||||
LL | fn iter_values<'a>(&'a self) -> impl Iterator<Item=u32> + 'a {
|
LL | fn iter_values<'a>(&'a self) -> impl Iterator<Item=u32> + 'a {
|
||||||
| ++++
|
| ++++
|
||||||
|
|
||||||
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
|
error[E0700]: hidden type for `impl Iterator<Item = u32>` captures lifetime that does not appear in bounds
|
||||||
--> $DIR/static-return-lifetime-infered.rs:12:9
|
--> $DIR/static-return-lifetime-infered.rs:12:9
|
||||||
|
|
|
|
||||||
LL | fn iter_values<'a>(&'a self) -> impl Iterator<Item=u32> {
|
LL | fn iter_values<'a>(&'a self) -> impl Iterator<Item=u32> {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
|
error[E0700]: hidden type for `impl Iterator<Item = u8>` captures lifetime that does not appear in bounds
|
||||||
--> $DIR/issue-73159-rpit-static.rs:8:9
|
--> $DIR/issue-73159-rpit-static.rs:8:9
|
||||||
|
|
|
|
||||||
LL | impl<'a> Foo<'a> {
|
LL | impl<'a> Foo<'a> {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
|
error[E0700]: hidden type for `Opaque(DefId(0:11 ~ impl_trait_captures[1afc]::foo::{opaque#0}), [ReStatic, T, ReEarlyBound(0, 'a)])` captures lifetime that does not appear in bounds
|
||||||
--> $DIR/impl-trait-captures.rs:11:5
|
--> $DIR/impl-trait-captures.rs:11:5
|
||||||
|
|
|
|
||||||
LL | fn foo<'a, T>(x: &T) -> impl Foo<'a> {
|
LL | fn foo<'a, T>(x: &T) -> impl Foo<'a> {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
|
error[E0700]: hidden type for `impl Clone` captures lifetime that does not appear in bounds
|
||||||
--> $DIR/arbitrary_self_types_pin_lifetime_impl_trait-async.rs:8:48
|
--> $DIR/arbitrary_self_types_pin_lifetime_impl_trait-async.rs:8:48
|
||||||
|
|
|
|
||||||
LL | async fn f(self: Pin<&Self>) -> impl Clone { self }
|
LL | async fn f(self: Pin<&Self>) -> impl Clone { self }
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
|
error[E0700]: hidden type for `impl Clone` captures lifetime that does not appear in bounds
|
||||||
--> $DIR/arbitrary_self_types_pin_lifetime_impl_trait.rs:6:44
|
--> $DIR/arbitrary_self_types_pin_lifetime_impl_trait.rs:6:44
|
||||||
|
|
|
|
||||||
LL | fn f(self: Pin<&Self>) -> impl Clone { self }
|
LL | fn f(self: Pin<&Self>) -> impl Clone { self }
|
||||||
|
|
|
@ -17,7 +17,7 @@ where
|
||||||
G: Get<T>,
|
G: Get<T>,
|
||||||
{
|
{
|
||||||
move || {
|
move || {
|
||||||
//~^ ERROR hidden type for `impl Trait` captures lifetime
|
//~^ ERROR hidden type for `impl FnOnce()` captures lifetime
|
||||||
*dest = g.get();
|
*dest = g.get();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ LL | fn baz<G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
|
||||||
| |
|
| |
|
||||||
| help: consider introducing lifetime `'a` here: `'a,`
|
| help: consider introducing lifetime `'a` here: `'a,`
|
||||||
|
|
||||||
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
|
error[E0700]: hidden type for `impl FnOnce()` captures lifetime that does not appear in bounds
|
||||||
--> $DIR/missing-lifetimes-in-signature.rs:19:5
|
--> $DIR/missing-lifetimes-in-signature.rs:19:5
|
||||||
|
|
|
|
||||||
LL | fn foo<G, T>(g: G, dest: &mut T) -> impl FnOnce()
|
LL | fn foo<G, T>(g: G, dest: &mut T) -> impl FnOnce()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue