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,
|
||||
/// The hidden type.
|
||||
hidden_ty: Ty<'tcx>,
|
||||
/// The opaque type.
|
||||
key: ty::OpaqueTypeKey<'tcx>,
|
||||
/// The unexpected region.
|
||||
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_key = self.regioncx.name_regions(self.infcx.tcx, key);
|
||||
let named_region = self.regioncx.name_regions(self.infcx.tcx, member_region);
|
||||
self.buffer_error(unexpected_hidden_region_diagnostic(
|
||||
self.infcx.tcx,
|
||||
span,
|
||||
named_ty,
|
||||
named_region,
|
||||
named_key,
|
||||
));
|
||||
}
|
||||
|
||||
|
|
|
@ -38,6 +38,8 @@ pub(crate) struct NllMemberConstraint<'tcx> {
|
|||
/// The hidden type in which `R0` appears. (Used in error reporting.)
|
||||
pub(crate) hidden_ty: Ty<'tcx>,
|
||||
|
||||
pub(crate) key: ty::OpaqueTypeKey<'tcx>,
|
||||
|
||||
/// The region `R0`.
|
||||
pub(crate) member_region_vid: ty::RegionVid,
|
||||
|
||||
|
@ -90,6 +92,7 @@ impl<'tcx> MemberConstraintSet<'tcx, ty::RegionVid> {
|
|||
member_region_vid,
|
||||
definition_span: m_c.definition_span,
|
||||
hidden_ty: m_c.hidden_ty,
|
||||
key: m_c.key,
|
||||
start_index,
|
||||
end_index,
|
||||
});
|
||||
|
|
|
@ -1763,6 +1763,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
errors_buffer.push(RegionErrorKind::UnexpectedHiddenRegion {
|
||||
span: m_c.definition_span,
|
||||
hidden_ty: m_c.hidden_ty,
|
||||
key: m_c.key,
|
||||
member_region,
|
||||
});
|
||||
}
|
||||
|
|
|
@ -246,7 +246,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||
// after producing an error for each of them.
|
||||
let definition_ty = instantiated_ty.ty.fold_with(&mut ReverseMapper::new(
|
||||
self.tcx,
|
||||
def_id,
|
||||
opaque_type_key,
|
||||
map,
|
||||
instantiated_ty.ty,
|
||||
instantiated_ty.span,
|
||||
|
@ -429,7 +429,7 @@ fn check_opaque_type_parameter_valid(
|
|||
struct ReverseMapper<'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
|
||||
opaque_type_def_id: LocalDefId,
|
||||
key: ty::OpaqueTypeKey<'tcx>,
|
||||
map: FxHashMap<GenericArg<'tcx>, GenericArg<'tcx>>,
|
||||
map_missing_regions_to_empty: bool,
|
||||
|
||||
|
@ -443,14 +443,14 @@ struct ReverseMapper<'tcx> {
|
|||
impl<'tcx> ReverseMapper<'tcx> {
|
||||
fn new(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
opaque_type_def_id: LocalDefId,
|
||||
key: ty::OpaqueTypeKey<'tcx>,
|
||||
map: FxHashMap<GenericArg<'tcx>, GenericArg<'tcx>>,
|
||||
hidden_ty: Ty<'tcx>,
|
||||
span: Span,
|
||||
) -> Self {
|
||||
Self {
|
||||
tcx,
|
||||
opaque_type_def_id,
|
||||
key,
|
||||
map,
|
||||
map_missing_regions_to_empty: false,
|
||||
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()) {
|
||||
Some(GenericArgKind::Lifetime(r1)) => r1,
|
||||
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() {
|
||||
unexpected_hidden_region_diagnostic(
|
||||
self.tcx,
|
||||
self.tcx.def_span(self.opaque_type_def_id),
|
||||
self.tcx.def_span(self.key.def_id),
|
||||
hidden_ty,
|
||||
r,
|
||||
self.key,
|
||||
)
|
||||
.emit();
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ use std::convert::TryFrom;
|
|||
use rustc_hir::def_id::DefId;
|
||||
use rustc_middle::mir::{
|
||||
self,
|
||||
interpret::{ConstValue, GlobalId, InterpResult, Scalar},
|
||||
interpret::{ConstValue, GlobalId, InterpResult, PointerArithmetic, Scalar},
|
||||
BinOp,
|
||||
};
|
||||
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.
|
||||
// That means they are definitely not pointing to the same allocation.
|
||||
throw_ub_format!(
|
||||
"{} called on pointers into different allocations",
|
||||
"`{}` called on pointers into different allocations",
|
||||
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.
|
||||
if a_alloc_id != b_alloc_id {
|
||||
throw_ub_format!(
|
||||
"{} called on pointers into different allocations",
|
||||
"`{}` called on pointers into different allocations",
|
||||
intrinsic_name
|
||||
);
|
||||
}
|
||||
|
@ -346,47 +346,71 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
};
|
||||
|
||||
// Compute distance.
|
||||
let distance = {
|
||||
// The subtraction is always done in `isize` to enforce
|
||||
// the "no more than `isize::MAX` apart" requirement.
|
||||
let a_offset = ImmTy::from_uint(a_offset, isize_layout);
|
||||
let b_offset = ImmTy::from_uint(b_offset, isize_layout);
|
||||
let (val, overflowed, _ty) =
|
||||
self.overflowing_binary_op(BinOp::Sub, &a_offset, &b_offset)?;
|
||||
if overflowed {
|
||||
throw_ub_format!("pointers were too far apart for {}", intrinsic_name);
|
||||
}
|
||||
val.to_machine_isize(self)?
|
||||
let dist = {
|
||||
// Addresses are unsigned, so this is a `usize` computation. We have to do the
|
||||
// overflow check separately anyway.
|
||||
let (val, overflowed, _ty) = {
|
||||
let a_offset = ImmTy::from_uint(a_offset, usize_layout);
|
||||
let b_offset = ImmTy::from_uint(b_offset, usize_layout);
|
||||
self.overflowing_binary_op(BinOp::Sub, &a_offset, &b_offset)?
|
||||
};
|
||||
|
||||
// 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.
|
||||
let min_ptr = if distance >= 0 { b } else { a };
|
||||
self.check_ptr_access_align(
|
||||
min_ptr,
|
||||
Size::from_bytes(distance.unsigned_abs()),
|
||||
Align::ONE,
|
||||
CheckInAllocMsg::OffsetFromTest,
|
||||
)?;
|
||||
|
||||
if intrinsic_name == sym::ptr_offset_from_unsigned && distance < 0 {
|
||||
if overflowed {
|
||||
// a < b
|
||||
if intrinsic_name == sym::ptr_offset_from_unsigned {
|
||||
throw_ub_format!(
|
||||
"{} called when first pointer has smaller offset than second: {} < {}",
|
||||
"`{}` 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
|
||||
}
|
||||
};
|
||||
|
||||
// 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.
|
||||
let min_ptr = if dist >= 0 { b } else { a };
|
||||
self.check_ptr_access_align(
|
||||
min_ptr,
|
||||
Size::from_bytes(dist.unsigned_abs()),
|
||||
Align::ONE,
|
||||
CheckInAllocMsg::OffsetFromTest,
|
||||
)?;
|
||||
|
||||
// Perform division by size to compute return value.
|
||||
let ret_layout = if intrinsic_name == sym::ptr_offset_from_unsigned {
|
||||
assert!(0 <= dist && dist <= self.machine_isize_max());
|
||||
usize_layout
|
||||
} else {
|
||||
assert!(self.machine_isize_min() <= dist && dist <= self.machine_isize_max());
|
||||
isize_layout
|
||||
};
|
||||
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.
|
||||
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);
|
||||
self.exact_div(&val, &size, dest)?;
|
||||
}
|
||||
|
|
|
@ -237,12 +237,14 @@ pub fn unexpected_hidden_region_diagnostic<'tcx>(
|
|||
span: Span,
|
||||
hidden_ty: Ty<'tcx>,
|
||||
hidden_region: ty::Region<'tcx>,
|
||||
opaque_ty: ty::OpaqueTypeKey<'tcx>,
|
||||
) -> 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!(
|
||||
tcx.sess,
|
||||
span,
|
||||
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.
|
||||
|
|
|
@ -21,7 +21,7 @@ use rustc_middle::infer::unify_key::{ConstVarValue, ConstVariableValue};
|
|||
use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind, ToType};
|
||||
use rustc_middle::mir::interpret::{ErrorHandled, EvalToValTreeResult};
|
||||
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::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
|
||||
use rustc_middle::ty::relate::RelateResult;
|
||||
|
@ -966,14 +966,14 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||
#[instrument(skip(self), level = "debug")]
|
||||
pub fn member_constraint(
|
||||
&self,
|
||||
opaque_type_def_id: LocalDefId,
|
||||
key: ty::OpaqueTypeKey<'tcx>,
|
||||
definition_span: Span,
|
||||
hidden_ty: Ty<'tcx>,
|
||||
region: ty::Region<'tcx>,
|
||||
in_regions: &Lrc<Vec<ty::Region<'tcx>>>,
|
||||
) {
|
||||
self.inner.borrow_mut().unwrap_region_constraints().member_constraint(
|
||||
opaque_type_def_id,
|
||||
key,
|
||||
definition_span,
|
||||
hidden_ty,
|
||||
region,
|
||||
|
@ -1675,7 +1675,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||
#[instrument(skip(self), level = "debug")]
|
||||
pub fn const_eval_resolve(
|
||||
&self,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
mut param_env: ty::ParamEnv<'tcx>,
|
||||
unevaluated: ty::Unevaluated<'tcx>,
|
||||
span: Option<Span>,
|
||||
) -> EvalToValTreeResult<'tcx> {
|
||||
|
@ -1686,12 +1686,21 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||
// variables
|
||||
if substs.has_infer_types_or_consts() {
|
||||
let ac = AbstractConst::new(self.tcx, unevaluated.shrink());
|
||||
if let Ok(None) = ac {
|
||||
match ac {
|
||||
Ok(None) => {
|
||||
substs = InternalSubsts::identity_for_item(self.tcx, unevaluated.def.did);
|
||||
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)),
|
||||
}
|
||||
}
|
||||
|
||||
let param_env_erased = self.tcx.erase_regions(param_env);
|
||||
let substs_erased = self.tcx.erase_regions(substs);
|
||||
|
@ -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 {
|
||||
op: |r| {
|
||||
self.member_constraint(
|
||||
opaque_type_key.def_id,
|
||||
span,
|
||||
concrete_ty,
|
||||
r,
|
||||
&choice_regions,
|
||||
)
|
||||
},
|
||||
op: |r| self.member_constraint(opaque_type_key, 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::undo_log::UndoLogs;
|
||||
use rustc_data_structures::unify as ut;
|
||||
use rustc_hir::def_id::LocalDefId;
|
||||
use rustc_index::vec::IndexVec;
|
||||
use rustc_middle::infer::unify_key::{RegionVidKey, UnifiedRegion};
|
||||
use rustc_middle::ty::ReStatic;
|
||||
|
@ -533,7 +532,7 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
|
|||
|
||||
pub fn member_constraint(
|
||||
&mut self,
|
||||
opaque_type_def_id: LocalDefId,
|
||||
key: ty::OpaqueTypeKey<'tcx>,
|
||||
definition_span: Span,
|
||||
hidden_ty: Ty<'tcx>,
|
||||
member_region: ty::Region<'tcx>,
|
||||
|
@ -546,7 +545,7 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
|
|||
}
|
||||
|
||||
self.data.member_constraints.push(MemberConstraint {
|
||||
opaque_type_def_id,
|
||||
key,
|
||||
definition_span,
|
||||
hidden_ty,
|
||||
member_region,
|
||||
|
|
|
@ -2,9 +2,8 @@ pub mod canonical;
|
|||
pub mod unify_key;
|
||||
|
||||
use crate::ty::Region;
|
||||
use crate::ty::Ty;
|
||||
use crate::ty::{OpaqueTypeKey, Ty};
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
use rustc_hir::def_id::LocalDefId;
|
||||
use rustc_span::Span;
|
||||
|
||||
/// 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)]
|
||||
pub struct MemberConstraint<'tcx> {
|
||||
/// The `DefId` of the opaque type causing this constraint: used for error reporting.
|
||||
pub opaque_type_def_id: LocalDefId,
|
||||
/// The `DefId` and substs of the opaque type causing this constraint.
|
||||
/// Used for error reporting.
|
||||
pub key: OpaqueTypeKey<'tcx>,
|
||||
|
||||
/// The span where the hidden type was instantiated.
|
||||
pub definition_span: Span,
|
||||
|
|
|
@ -42,7 +42,7 @@ fn unsafe_derive_on_repr_packed(tcx: TyCtxt<'_>, def_id: LocalDefId) {
|
|||
"that does not derive `Copy`"
|
||||
};
|
||||
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")),
|
||||
extra
|
||||
);
|
||||
|
|
|
@ -703,13 +703,42 @@ impl<'tcx> TypeVisitor<'tcx> for OrphanChecker<'tcx> {
|
|||
}
|
||||
}
|
||||
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(
|
||||
DUMMY_SP,
|
||||
format!("ty_is_local invoked on closure or generator: {:?}", 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
|
||||
// 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));
|
||||
match concrete {
|
||||
Err(ErrorHandled::TooGeneric) => Err(if uv.has_infer_types_or_consts() {
|
||||
NotConstEvaluatable::MentionsInfer
|
||||
} 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(
|
||||
Err(ErrorHandled::TooGeneric) => {
|
||||
Err(NotConstEvaluatable::Error(infcx.tcx.sess.delay_span_bug(
|
||||
span,
|
||||
format!("Missing value for constant, but no error reported?"),
|
||||
);
|
||||
NotConstEvaluatable::Error(guar)
|
||||
}),
|
||||
)))
|
||||
}
|
||||
Err(ErrorHandled::Linted) => {
|
||||
let reported = infcx
|
||||
.tcx
|
||||
|
|
|
@ -730,7 +730,7 @@ impl<T: ?Sized> *const T {
|
|||
/// }
|
||||
///
|
||||
/// // 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")]
|
||||
#[rustc_const_unstable(feature = "const_ptr_sub_ptr", issue = "95892")]
|
||||
|
|
|
@ -13,7 +13,7 @@ LL | | }
|
|||
|
|
||||
= 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
|
||||
|
|
||||
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)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
|
@ -21,11 +23,6 @@ where
|
|||
}
|
||||
|
||||
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();
|
||||
//~^ ERROR type annotations needed
|
||||
|
||||
_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) }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
| |
|
||||
| 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
|
||||
|
|
||||
::: $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) }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
| |
|
||||
| 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
|
||||
|
|
||||
::: $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) }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
| |
|
||||
| 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
|
||||
|
|
||||
::: $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) }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
| |
|
||||
| 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
|
||||
|
|
||||
::: $SRC_DIR/core/src/slice/raw.rs:LL:COL
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#![feature(core_intrinsics)]
|
||||
|
||||
use std::intrinsics::{ptr_offset_from, ptr_offset_from_unsigned};
|
||||
use std::ptr;
|
||||
|
||||
#[repr(C)]
|
||||
struct Struct {
|
||||
|
@ -75,9 +76,21 @@ pub const DIFFERENT_ALLOC_UNSIGNED: usize = {
|
|||
let base_ptr: *const Struct = &uninit as *const _ as *const Struct;
|
||||
let uninit2 = std::mem::MaybeUninit::<Struct>::uninit();
|
||||
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
|
||||
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 = {
|
||||
|
@ -86,5 +99,27 @@ const WRONG_ORDER_UNSIGNED: usize = {
|
|||
unsafe { ptr_offset_from_unsigned(p, p.add(2) ) } //~ERROR evaluation of constant value failed
|
||||
//~| 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() {}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
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) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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
|
||||
--> $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) }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
| |
|
||||
| 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
|
||||
|
|
||||
::: $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 }
|
||||
| ----------------------------------- 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
|
||||
--> $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) }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ exact_div: 1_isize cannot be divided by 2_isize without remainder
|
||||
|
||||
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) }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds offset_from: null pointer is a dangling pointer (it has no provenance)
|
||||
|
||||
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) }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds offset_from: 0x8[noalloc] is a dangling pointer (it has no provenance)
|
||||
|
||||
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) }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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
|
||||
--> $DIR/offset_from_ub.rs:61:14
|
||||
--> $DIR/offset_from_ub.rs:62:14
|
||||
|
|
||||
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
|
||||
|
||||
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) }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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
|
||||
--> $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) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ptr_offset_from_unsigned called on pointers into different allocations
|
||||
LL | unsafe { ptr_offset_from_unsigned(field_ptr, base_ptr) }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from_unsigned` called on pointers into different allocations
|
||||
|
||||
error[E0080]: evaluation of constant value failed
|
||||
--> $DIR/offset_from_ub.rs:86: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
|
||||
LL | unsafe { ptr_offset_from(ptr2, ptr1) }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `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`.
|
||||
|
|
|
@ -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
|
||||
|
|
||||
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: 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
|
||||
|
|
||||
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: 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
|
||||
|
|
||||
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: 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
|
||||
|
|
||||
LL | #[derive(Debug, Default)]
|
||||
|
@ -46,7 +46,7 @@ LL | #[derive(Debug, Default)]
|
|||
error: aborting due to 4 previous errors
|
||||
|
||||
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
|
||||
|
|
||||
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)
|
||||
|
||||
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
|
||||
|
|
||||
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)
|
||||
|
||||
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
|
||||
|
|
||||
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)
|
||||
|
||||
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
|
||||
|
|
||||
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
|
||||
|
|
||||
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 {
|
||||
| ++++
|
||||
|
||||
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
|
||||
|
|
||||
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;
|
||||
}
|
||||
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() {}
|
||||
|
|
|
@ -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
|
||||
|
|
||||
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]
|
||||
// ```
|
||||
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 {
|
||||
|
|
|
@ -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
|
||||
|
|
||||
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.
|
||||
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 {
|
||||
|
|
|
@ -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
|
||||
|
|
||||
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
|
||||
|
|
||||
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 }
|
||||
| ++++
|
||||
|
||||
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
|
||||
|
|
||||
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 }
|
||||
| ~~~~~~~~~~~~
|
||||
|
||||
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
|
||||
|
|
||||
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> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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
|
||||
--> $DIR/negative-reasoning.rs:19:25
|
||||
|
|
|
@ -15,7 +15,7 @@ fn foo<'x, 'y>(x: Cell<&'x u32>) -> impl Trait<'y>
|
|||
where 'x: 'y
|
||||
{
|
||||
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() { }
|
||||
|
|
|
@ -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
|
||||
|
|
||||
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
|
||||
|
|
||||
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> + '_ {
|
||||
| ++++
|
||||
|
||||
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
|
||||
|
|
||||
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> + '_ {
|
||||
| ++++
|
||||
|
||||
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
|
||||
|
|
||||
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 {
|
||||
| ++++
|
||||
|
||||
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
|
||||
|
|
||||
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
|
||||
|
|
||||
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
|
||||
|
|
||||
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
|
||||
|
|
||||
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
|
||||
|
|
||||
LL | fn f(self: Pin<&Self>) -> impl Clone { self }
|
||||
|
|
|
@ -17,7 +17,7 @@ where
|
|||
G: Get<T>,
|
||||
{
|
||||
move || {
|
||||
//~^ ERROR hidden type for `impl Trait` captures lifetime
|
||||
//~^ ERROR hidden type for `impl FnOnce()` captures lifetime
|
||||
*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,`
|
||||
|
||||
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
|
||||
|
|
||||
LL | fn foo<G, T>(g: G, dest: &mut T) -> impl FnOnce()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue