1
Fork 0

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:
bors 2022-07-26 10:35:25 +00:00
commit 2614e437f5
42 changed files with 350 additions and 171 deletions

View file

@ -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,
)); ));
} }

View file

@ -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,
}); });

View file

@ -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,
}); });
} }

View file

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

View file

@ -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)?;
} }

View file

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

View file

@ -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,
}
}))
}

View file

@ -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,
)
},
}); });
} }

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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")]

View file

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

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

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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