diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index 1d66153734c78..176090c3b7a14 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -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, )); } diff --git a/compiler/rustc_borrowck/src/member_constraints.rs b/compiler/rustc_borrowck/src/member_constraints.rs index e91fcf1472df1..43253a2aab00c 100644 --- a/compiler/rustc_borrowck/src/member_constraints.rs +++ b/compiler/rustc_borrowck/src/member_constraints.rs @@ -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, }); diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index 9040cfcf54f41..2894c6d29ec43 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -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, }); } diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs index 407bbf48813c3..d6712b6a4799c 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs @@ -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>>, 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>>, 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(); } diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index 025f8647c95b5..08209eb793216 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -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)?; + 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)? + }; 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 // 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( min_ptr, - Size::from_bytes(distance.unsigned_abs()), + Size::from_bytes(dist.unsigned_abs()), Align::ONE, 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. 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)?; } diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index e06af1fac0699..be764cfe83bc3 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -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. diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 5e7c0661728aa..0ac6e8c541b55 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -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>>, ) { 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, ) -> EvalToValTreeResult<'tcx> { @@ -1686,10 +1686,19 @@ 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 { - substs = InternalSubsts::identity_for_item(self.tcx, unevaluated.def.did); - } else { - return Err(ErrorHandled::TooGeneric); + 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)), } } @@ -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, + } + })) +} diff --git a/compiler/rustc_infer/src/infer/opaque_types.rs b/compiler/rustc_infer/src/infer/opaque_types.rs index 7b0ff9552a3a4..a6c5ed579c736 100644 --- a/compiler/rustc_infer/src/infer/opaque_types.rs +++ b/compiler/rustc_infer/src/infer/opaque_types.rs @@ -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), }); } diff --git a/compiler/rustc_infer/src/infer/region_constraints/mod.rs b/compiler/rustc_infer/src/infer/region_constraints/mod.rs index 551f398e0c2c4..0d4472a1cfd9c 100644 --- a/compiler/rustc_infer/src/infer/region_constraints/mod.rs +++ b/compiler/rustc_infer/src/infer/region_constraints/mod.rs @@ -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, diff --git a/compiler/rustc_middle/src/infer/mod.rs b/compiler/rustc_middle/src/infer/mod.rs index 8b2f9bdfd486b..38868c2104953 100644 --- a/compiler/rustc_middle/src/infer/mod.rs +++ b/compiler/rustc_middle/src/infer/mod.rs @@ -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, diff --git a/compiler/rustc_mir_transform/src/check_packed_ref.rs b/compiler/rustc_mir_transform/src/check_packed_ref.rs index c21c1efe99112..3b7ba3f9a67ac 100644 --- a/compiler/rustc_mir_transform/src/check_packed_ref.rs +++ b/compiler/rustc_mir_transform/src/check_packed_ref.rs @@ -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 ); diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index 9983438233e1e..fa94aa19abda5 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -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. diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs index decbf0133114f..254bc4ab66386 100644 --- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs +++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs @@ -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 diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index e289a8e6bd5f9..e0655d68d2cfa 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -730,7 +730,7 @@ impl *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")] diff --git a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.stderr b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.stderr index cdb141c0e3ea2..3128b4df4e2d1 100644 --- a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.stderr +++ b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.stderr @@ -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> { diff --git a/src/test/ui/coherence/issue-99663-2.rs b/src/test/ui/coherence/issue-99663-2.rs new file mode 100644 index 0000000000000..10a0a568849bf --- /dev/null +++ b/src/test/ui/coherence/issue-99663-2.rs @@ -0,0 +1,22 @@ +// check-pass + +#![feature(type_alias_impl_trait)] + +struct Outer { + i: InnerSend, +} + +type InnerSend = impl Send; + +fn constrain() -> InnerSend { + () +} + +trait SendMustNotImplDrop {} + +#[allow(drop_bounds)] +impl SendMustNotImplDrop for T {} + +impl SendMustNotImplDrop for Outer {} + +fn main() {} diff --git a/src/test/ui/coherence/issue-99663.rs b/src/test/ui/coherence/issue-99663.rs new file mode 100644 index 0000000000000..a2d4d398ce1d5 --- /dev/null +++ b/src/test/ui/coherence/issue-99663.rs @@ -0,0 +1,22 @@ +// check-pass + +#![feature(type_alias_impl_trait)] + +struct Send { + i: InnerSend, +} + +type InnerSend = impl Sized; + +fn constrain() -> InnerSend { + () +} + +trait SendMustNotImplDrop {} + +#[allow(drop_bounds)] +impl SendMustNotImplDrop for T {} + +impl SendMustNotImplDrop for Send {} + +fn main() {} diff --git a/src/test/ui/const-generics/generic_const_exprs/const_eval_resolve_canonical.rs b/src/test/ui/const-generics/generic_const_exprs/const_eval_resolve_canonical.rs index 18f33acaabbba..5874625adff61 100644 --- a/src/test/ui/const-generics/generic_const_exprs/const_eval_resolve_canonical.rs +++ b/src/test/ui/const-generics/generic_const_exprs/const_eval_resolve_canonical.rs @@ -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 } diff --git a/src/test/ui/const-generics/generic_const_exprs/const_eval_resolve_canonical.stderr b/src/test/ui/const-generics/generic_const_exprs/const_eval_resolve_canonical.stderr deleted file mode 100644 index 9e8328d37017e..0000000000000 --- a/src/test/ui/const-generics/generic_const_exprs/const_eval_resolve_canonical.stderr +++ /dev/null @@ -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) -> <() 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`. diff --git a/src/test/ui/const-ptr/forbidden_slices.32bit.stderr b/src/test/ui/const-ptr/forbidden_slices.32bit.stderr index c2d22ca4917db..f3bf9c496da7b 100644 --- a/src/test/ui/const-ptr/forbidden_slices.32bit.stderr +++ b/src/test/ui/const-ptr/forbidden_slices.32bit.stderr @@ -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::::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::::sub_ptr` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL | ::: $SRC_DIR/core/src/slice/raw.rs:LL:COL diff --git a/src/test/ui/const-ptr/forbidden_slices.64bit.stderr b/src/test/ui/const-ptr/forbidden_slices.64bit.stderr index da9df1c63a4cb..5f2821a91937b 100644 --- a/src/test/ui/const-ptr/forbidden_slices.64bit.stderr +++ b/src/test/ui/const-ptr/forbidden_slices.64bit.stderr @@ -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::::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::::sub_ptr` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL | ::: $SRC_DIR/core/src/slice/raw.rs:LL:COL diff --git a/src/test/ui/consts/offset_from_ub.rs b/src/test/ui/consts/offset_from_ub.rs index db2d421427c3e..1f29a690550bc 100644 --- a/src/test/ui/consts/offset_from_ub.rs +++ b/src/test/ui/consts/offset_from_ub.rs @@ -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::::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::(); + 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::(); + 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::(); + 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::(); + let ptr2 = ptr1.wrapping_offset(isize::MAX); + unsafe { ptr2.offset_from(ptr1) } + //~^ inside +}; +pub const OFFSET_VERY_FAR2: isize = { + let ptr1 = ptr::null::(); + let ptr2 = ptr1.wrapping_offset(isize::MAX); + unsafe { ptr1.offset_from(ptr2.wrapping_offset(1)) } + //~^ inside +}; fn main() {} diff --git a/src/test/ui/consts/offset_from_ub.stderr b/src/test/ui/consts/offset_from_ub.stderr index 94d778bc8a150..62a087d94d356 100644 --- a/src/test/ui/consts/offset_from_ub.stderr +++ b/src/test/ui/consts/offset_from_ub.stderr @@ -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::::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(ptr2, ptr1) } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from` called when first pointer is too far ahead of second + +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 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `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::::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::::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 10 previous errors +error: aborting due to 15 previous errors For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/derives/deriving-with-repr-packed.stderr b/src/test/ui/derives/deriving-with-repr-packed.stderr index 1f98da5b70e9f..d3fe550c3e48f 100644 --- a/src/test/ui/derives/deriving-with-repr-packed.stderr +++ b/src/test/ui/derives/deriving-with-repr-packed.stderr @@ -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 = 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 = 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 = 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)] diff --git a/src/test/ui/impl-trait/hidden-lifetimes.stderr b/src/test/ui/impl-trait/hidden-lifetimes.stderr index 97652f5462ef0..efc228de58be5 100644 --- a/src/test/ui/impl-trait/hidden-lifetimes.stderr +++ b/src/test/ui/impl-trait/hidden-lifetimes.stderr @@ -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>) -> impl Swap + 'a { diff --git a/src/test/ui/impl-trait/multiple-lifetimes/error-handling-2.rs b/src/test/ui/impl-trait/multiple-lifetimes/error-handling-2.rs index f5aaf1185211b..2a2be6b742992 100644 --- a/src/test/ui/impl-trait/multiple-lifetimes/error-handling-2.rs +++ b/src/test/ui/impl-trait/multiple-lifetimes/error-handling-2.rs @@ -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() {} diff --git a/src/test/ui/impl-trait/multiple-lifetimes/error-handling-2.stderr b/src/test/ui/impl-trait/multiple-lifetimes/error-handling-2.stderr index b837b64110365..9087570809404 100644 --- a/src/test/ui/impl-trait/multiple-lifetimes/error-handling-2.stderr +++ b/src/test/ui/impl-trait/multiple-lifetimes/error-handling-2.stderr @@ -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> { diff --git a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.rs b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.rs index 47e05bce0f8de..c6eea5323fd80 100644 --- a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.rs +++ b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.rs @@ -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 { diff --git a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.stderr b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.stderr index 15476c706a7f2..cb1dc0b7d50ae 100644 --- a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.stderr +++ b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.stderr @@ -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> diff --git a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.rs b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.rs index 321cb8c92a177..adcbca2a438b4 100644 --- a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.rs +++ b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.rs @@ -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 { diff --git a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.stderr b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.stderr index 7315aa8e9d478..4388e6601a6cf 100644 --- a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.stderr +++ b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.stderr @@ -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> diff --git a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr index 586563c39061e..16767abd72241 100644 --- a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr +++ b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr @@ -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) { diff --git a/src/test/ui/impl-trait/negative-reasoning.stderr b/src/test/ui/impl-trait/negative-reasoning.stderr index 2eea726a19c5a..479b451855d55 100644 --- a/src/test/ui/impl-trait/negative-reasoning.stderr +++ b/src/test/ui/impl-trait/negative-reasoning.stderr @@ -7,7 +7,7 @@ LL | impl AnotherTrait for T {} LL | impl AnotherTrait for D { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `D` | - = 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 diff --git a/src/test/ui/impl-trait/region-escape-via-bound.rs b/src/test/ui/impl-trait/region-escape-via-bound.rs index a04cb1702b638..fe60c76ca1755 100644 --- a/src/test/ui/impl-trait/region-escape-via-bound.rs +++ b/src/test/ui/impl-trait/region-escape-via-bound.rs @@ -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() { } diff --git a/src/test/ui/impl-trait/region-escape-via-bound.stderr b/src/test/ui/impl-trait/region-escape-via-bound.stderr index bc02f7694d7f6..fdb2fe022b4d2 100644 --- a/src/test/ui/impl-trait/region-escape-via-bound.stderr +++ b/src/test/ui/impl-trait/region-escape-via-bound.stderr @@ -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> diff --git a/src/test/ui/impl-trait/static-return-lifetime-infered.stderr b/src/test/ui/impl-trait/static-return-lifetime-infered.stderr index 951abb127c13f..b868152315503 100644 --- a/src/test/ui/impl-trait/static-return-lifetime-infered.stderr +++ b/src/test/ui/impl-trait/static-return-lifetime-infered.stderr @@ -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` captures lifetime that does not appear in bounds --> $DIR/static-return-lifetime-infered.rs:7:9 | LL | fn iter_values_anon(&self) -> impl Iterator { @@ -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 + '_ { | ++++ -error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds +error[E0700]: hidden type for `impl Iterator` captures lifetime that does not appear in bounds --> $DIR/static-return-lifetime-infered.rs:7:9 | LL | fn iter_values_anon(&self) -> impl Iterator { @@ -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 + '_ { | ++++ -error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds +error[E0700]: hidden type for `impl Iterator` 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 { @@ -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 + 'a { | ++++ -error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds +error[E0700]: hidden type for `impl Iterator` 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 { diff --git a/src/test/ui/nll/issue-73159-rpit-static.stderr b/src/test/ui/nll/issue-73159-rpit-static.stderr index ab0dfe5fca41c..260b9b59772ef 100644 --- a/src/test/ui/nll/issue-73159-rpit-static.stderr +++ b/src/test/ui/nll/issue-73159-rpit-static.stderr @@ -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` captures lifetime that does not appear in bounds --> $DIR/issue-73159-rpit-static.rs:8:9 | LL | impl<'a> Foo<'a> { diff --git a/src/test/ui/nll/ty-outlives/impl-trait-captures.stderr b/src/test/ui/nll/ty-outlives/impl-trait-captures.stderr index 06256ebbc29a3..330c6fafa2d61 100644 --- a/src/test/ui/nll/ty-outlives/impl-trait-captures.stderr +++ b/src/test/ui/nll/ty-outlives/impl-trait-captures.stderr @@ -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> { diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr index 5b8b9bb68ad1e..7e7d60d0ff90a 100644 --- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr @@ -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 } diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.stderr index abdc650c68e78..30d2250c0c81d 100644 --- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.stderr +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.stderr @@ -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 } diff --git a/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.rs b/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.rs index 19a791a8c43af..b641f5941dcef 100644 --- a/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.rs +++ b/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.rs @@ -17,7 +17,7 @@ where G: Get, { move || { - //~^ ERROR hidden type for `impl Trait` captures lifetime + //~^ ERROR hidden type for `impl FnOnce()` captures lifetime *dest = g.get(); } } diff --git a/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr b/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr index e3fe25d5f9c97..0d749f04bea77 100644 --- a/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr +++ b/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr @@ -6,7 +6,7 @@ LL | fn baz(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: G, dest: &mut T) -> impl FnOnce()