diff --git a/compiler/rustc_builtin_macros/src/deriving/reborrow.rs b/compiler/rustc_builtin_macros/src/deriving/reborrow.rs index dc45b1a896bc9..e9ad0b6ac5e88 100644 --- a/compiler/rustc_builtin_macros/src/deriving/reborrow.rs +++ b/compiler/rustc_builtin_macros/src/deriving/reborrow.rs @@ -1,9 +1,13 @@ -use rustc_ast::{self as ast, AttrArgs, GenericArg, GenericParamKind, Generics, ItemKind, token}; +use rustc_ast::{ + self as ast, AngleBracketedArg, AttrArgs, DUMMY_NODE_ID, GenericArg, GenericBound, + GenericParam, GenericParamKind, Generics, ItemKind, WherePredicate, WherePredicateKind, + WhereRegionPredicate, token, +}; use rustc_errors::E0802; use rustc_expand::base::ExtCtxt; use rustc_macros::Diagnostic; -use rustc_span::{Ident, Span, Symbol, sym}; -use thin_vec::ThinVec; +use rustc_span::{DUMMY_SP, Ident, Span, Symbol, sym}; +use thin_vec::{ThinVec, thin_vec}; macro_rules! path { ($span:expr, $($part:ident)::*) => { vec![$(Ident::new(sym::$part, $span),)*] } @@ -33,7 +37,7 @@ pub(crate) fn expand_deriving_coerce_shared( let Some((ident, generics)) = struct_def(cx, span, item, sym::CoerceShared) else { return; }; - let Some(target) = coerce_shared_target(cx, span, item) else { + let Some((target, generics)) = coerce_shared_target(cx, span, item, generics) else { return; }; @@ -41,7 +45,7 @@ pub(crate) fn expand_deriving_coerce_shared( cx, span, ident, - generics, + &generics, sym::CoerceShared, vec![GenericArg::Type(target)], push, @@ -71,7 +75,12 @@ fn struct_def<'a>( } } -fn coerce_shared_target(cx: &ExtCtxt<'_>, span: Span, item: &ast::Item) -> Option> { +fn coerce_shared_target( + cx: &ExtCtxt<'_>, + span: Span, + item: &ast::Item, + generics: &Generics, +) -> Option<(Box, Generics)> { let mut attrs = item.attrs.iter().filter(|attr| attr.has_name(sym::coerce_shared)); let Some(attr) = attrs.next() else { cx.dcx().emit_err(MissingTarget { span }); @@ -92,7 +101,7 @@ fn coerce_shared_target(cx: &ExtCtxt<'_>, span: Span, item: &ast::Item) -> Optio } let mut parser = cx.new_parser_from_tts(args.tokens.clone()); - let target = match parser.parse_ty() { + let mut target = match parser.parse_ty() { Ok(target) => target, Err(err) => { err.cancel(); @@ -105,7 +114,79 @@ fn coerce_shared_target(cx: &ExtCtxt<'_>, span: Span, item: &ast::Item) -> Optio return None; } - Some(target) + let rustc_ast::TyKind::Path(_, path) = &mut target.kind else { + cx.dcx().emit_err(MalformedTarget { span: attr.span }); + return None; + }; + + let Some(last) = path.segments.last_mut() else { + // FIXME(reborrow): we might want to support CoerceShared for Bar at some point. + cx.dcx().emit_err(MalformedTarget { span: attr.span }); + return None; + }; + + let Some(args) = last.args.as_deref_mut() else { + // FIXME(reborrow): same as above. + cx.dcx().emit_err(MalformedTarget { span: attr.span }); + return None; + }; + + let rustc_ast::GenericArgs::AngleBracketed(args) = args else { + cx.dcx().emit_err(MalformedTarget { span: attr.span }); + return None; + }; + + let mut own_params = generics.params.clone(); + let mut param_insert_index = own_params + .iter() + .enumerate() + .find(|(_, arg)| { + matches!( + arg.kind, + rustc_ast::GenericParamKind::Lifetime | rustc_ast::GenericParamKind::Type { .. } + ) + }) + .map(|(i, _)| i) + .unwrap_or(own_params.len()); + let mut own_where_clause = generics.where_clause.clone(); + + for arg in args.args.iter_mut() { + // Replace all lifetime parameters 'a with a new 'a_ where 'a: 'a_. + let AngleBracketedArg::Arg(GenericArg::Lifetime(arg)) = arg else { + continue; + }; + let lt = rustc_ast::Lifetime { + id: DUMMY_NODE_ID, + ident: Ident::with_dummy_span(Symbol::intern(&format!("{}_", arg.ident.as_str()))), + }; + // FIXME(reborrow): this is terribly inefficient. + own_params.insert( + param_insert_index, + GenericParam { + id: DUMMY_NODE_ID, + ident: lt.ident, + attrs: Default::default(), + bounds: Default::default(), + is_placeholder: false, + kind: GenericParamKind::Lifetime, + colon_span: None, + }, + ); + param_insert_index += 1; + own_where_clause.predicates.push(WherePredicate { + attrs: Default::default(), + kind: WherePredicateKind::RegionPredicate(WhereRegionPredicate { + lifetime: *arg, + bounds: thin_vec![GenericBound::Outlives(lt)], + }), + id: DUMMY_NODE_ID, + span: DUMMY_SP, + is_placeholder: false, + }); + *arg = lt; + } + + Some((target, Generics { params: own_params, where_clause: own_where_clause, span })) } fn push_marker_impl( @@ -125,15 +206,19 @@ fn push_marker_impl( let self_params: Vec<_> = generics .params .iter() - .map(|param| match param.kind { + .filter_map(|param| match param.kind { GenericParamKind::Lifetime => { - GenericArg::Lifetime(cx.lifetime(param.span(), param.ident)) + if trait_name == sym::CoerceShared && !param.ident.as_str().ends_with("_") { + None + } else { + Some(GenericArg::Lifetime(cx.lifetime(param.span(), param.ident))) + } } GenericParamKind::Type { .. } => { - GenericArg::Type(cx.ty_ident(param.span(), param.ident)) + Some(GenericArg::Type(cx.ty_ident(param.span(), param.ident))) } GenericParamKind::Const { .. } => { - GenericArg::Const(cx.const_ident(param.span(), param.ident)) + Some(GenericArg::Const(cx.const_ident(param.span(), param.ident))) } }) .collect(); diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs index efed5994f63fe..b6fa6fa6afcef 100644 --- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs +++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs @@ -472,7 +472,7 @@ pub(crate) fn reborrow_info<'tcx>( let source = tcx.type_of(impl_did).instantiate_identity().skip_norm_wip(); let trait_ref = tcx.impl_trait_ref(impl_did).instantiate_identity().skip_norm_wip(); - if trait_impl_lifetime_params_count(tcx, impl_did) != 1 { + if trait_impl_lifetime_params_count(tcx, impl_did) == 0 { return Err(tcx .dcx() .emit_err(diagnostics::CoerceSharedNotSingleLifetimeParam { span, trait_name })); @@ -492,20 +492,8 @@ pub(crate) fn reborrow_info<'tcx>( } }; - let lifetimes_count = generic_lifetime_params_count(args); let data_fields = collect_reborrow_data_fields(tcx, def, args); - if lifetimes_count != 1 { - let item = tcx.hir_expect_item(impl_did); - let _span = if let ItemKind::Impl(hir::Impl { of_trait: Some(of_trait), .. }) = &item.kind { - of_trait.trait_ref.path.span - } else { - tcx.def_span(impl_did) - }; - - return Err(tcx.dcx().emit_err(diagnostics::CoerceSharedMulti { span, trait_name })); - } - if data_fields.is_empty() { return Ok(()); } @@ -548,10 +536,6 @@ fn trait_impl_lifetime_params_count(tcx: TyCtxt<'_>, did: LocalDefId) -> usize { .count() } -fn generic_lifetime_params_count(args: &[ty::GenericArg<'_>]) -> usize { - args.iter().filter(|arg| arg.as_region().is_some()).count() -} - #[derive(Clone, Copy)] struct ReborrowDataField<'tcx> { ident: Ident, diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin/coerce_shared.rs b/compiler/rustc_hir_analysis/src/coherence/builtin/coerce_shared.rs index e405e149c8eef..c4f5e73959876 100644 --- a/compiler/rustc_hir_analysis/src/coherence/builtin/coerce_shared.rs +++ b/compiler/rustc_hir_analysis/src/coherence/builtin/coerce_shared.rs @@ -3,7 +3,7 @@ use rustc_errors::ErrorGuaranteed; use rustc_hir as hir; use rustc_hir::ItemKind; use rustc_hir::def_id::{DefId, LocalDefId}; -use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, TyCtxtInferExt}; +use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, SubregionOrigin, TyCtxtInferExt}; use rustc_infer::traits::{Obligation, TraitErrors}; use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt, TypingMode, Unnormalized}; use rustc_span::Span; @@ -239,7 +239,7 @@ pub(super) fn coerce_shared_info<'tcx>( let source = tcx.type_of(impl_did).instantiate_identity().skip_norm_wip(); let trait_ref = tcx.impl_trait_ref(impl_did).instantiate_identity().skip_norm_wip(); - if trait_impl_lifetime_params_count(tcx, impl_did) != 1 { + if trait_impl_lifetime_params_count(tcx, impl_did) == 0 { return Err(tcx .dcx() .emit_err(diagnostics::CoerceSharedNotSingleLifetimeParam { span, trait_name })); @@ -266,25 +266,6 @@ pub(super) fn coerce_shared_info<'tcx>( (&ty::Adt(def_a, args_a), &ty::Adt(def_b, args_b)) if def_a.is_struct() && def_b.is_struct() => { - let a_lifetime = single_region_arg(args_a); - let b_lifetime = single_region_arg(args_b); - - if a_lifetime.is_none() || b_lifetime.is_none() { - return Err(tcx.dcx().emit_err(diagnostics::CoerceSharedMulti { - span: diagnostic_context.trait_span, - trait_name, - })); - } - - if a_lifetime != b_lifetime { - return Err(tcx.dcx().emit_err(diagnostics::CoerceSharedLifetimeMismatch { - span: diagnostic_context.trait_span, - source_lifetime_span: diagnostic_context.source_lifetime_span, - target_lifetime_span: diagnostic_context.target_lifetime_span, - trait_name, - })); - } - validate_reborrow_field_access( tcx, impl_did, @@ -341,12 +322,6 @@ enum CoerceSharedFieldPairError<'tcx> { MissingSourceField { target: ReborrowDataField<'tcx> }, } -fn single_region_arg<'tcx>(args: ty::GenericArgsRef<'tcx>) -> Option> { - let mut lifetimes = args.iter().filter_map(|arg| arg.as_region()); - let lifetime = lifetimes.next()?; - lifetimes.next().is_none().then_some(lifetime) -} - // This is a coherence/WF check only. It verifies that the CoerceShared impl // describes a structurally valid field-wise relation. Runtime lowering of the // operation is not modeled here. @@ -789,7 +764,7 @@ fn field_tys_satisfy_relation_after_normalization_and_resolution<'tcx>( FieldRelation::Equal => { if infcx .at(&cause, param_env) - .relate(DefineOpaqueTypes::Yes, source_ty, ty::Variance::Invariant, target_ty) + .relate(DefineOpaqueTypes::Yes, source_ty, ty::Variance::Covariant, target_ty) .is_err() { return false; @@ -803,9 +778,12 @@ fn field_tys_satisfy_relation_after_normalization_and_resolution<'tcx>( else { return false; }; - if source_region != target_region { - return false; - } + infcx.sub_regions( + SubregionOrigin::RelateObjectBound(span), + target_region, + source_region, + ty::VisibleForLeakCheck::Yes, + ); if ocx.sup(&cause, param_env, target_referent_ty, source_referent_ty).is_err() { return false; } diff --git a/compiler/rustc_hir_analysis/src/diagnostics.rs b/compiler/rustc_hir_analysis/src/diagnostics.rs index ff5f7dbb119f1..a7785b9b0fd28 100644 --- a/compiler/rustc_hir_analysis/src/diagnostics.rs +++ b/compiler/rustc_hir_analysis/src/diagnostics.rs @@ -1360,31 +1360,6 @@ pub(crate) struct CoerceSharedNotSingleLifetimeParam { pub trait_name: &'static str, } -#[derive(Diagnostic)] -#[diag( - "implementing `{$trait_name}` requires exactly one lifetime argument in the reborrowed type" -)] -pub(crate) struct CoerceSharedMulti { - #[primary_span] - pub span: Span, - pub trait_name: &'static str, -} - -#[derive(Diagnostic)] -#[diag( - "implementing `{$trait_name}` requires source and target to use the same reborrow lifetime \ - argument" -)] -pub(crate) struct CoerceSharedLifetimeMismatch { - #[primary_span] - pub span: Span, - #[label("source reborrow lifetime")] - pub source_lifetime_span: Option, - #[label("target reborrow lifetime")] - pub target_lifetime_span: Option, - pub trait_name: &'static str, -} - #[derive(Diagnostic)] #[diag( "implementing `{$trait_name}` requires corresponding fields to match, \ diff --git a/tests/crashes/reborrow/malformed-marker-coerce-shared-issue-156309.rs b/tests/crashes/reborrow/malformed-marker-coerce-shared-issue-156309.rs index 14b7ec820a180..3bfa63b4f317e 100644 --- a/tests/crashes/reborrow/malformed-marker-coerce-shared-issue-156309.rs +++ b/tests/crashes/reborrow/malformed-marker-coerce-shared-issue-156309.rs @@ -16,7 +16,7 @@ struct CustomMarkerRef<'a>(PhantomData<(Debug, Clone, Copy)>); //~| ERROR impl<'a> Reborrow for CustomMarker<'a> {} -impl<'a> CoerceShared> for CustomMarker<'a> {} +impl<'a: 'b, 'b> CoerceShared> for CustomMarker<'a> {} //~^ ERROR fn method<'a>(_a: CustomMarkerRef<'a>) -> 'a () { diff --git a/tests/ui/reborrow/coerce-shared-associated-type-field.rs b/tests/ui/reborrow/coerce-shared-associated-type-field.rs index c40abe9de7b31..ee7ac79654e80 100644 --- a/tests/ui/reborrow/coerce-shared-associated-type-field.rs +++ b/tests/ui/reborrow/coerce-shared-associated-type-field.rs @@ -27,7 +27,7 @@ struct MyRef<'a> { impl Reborrow for MyMut<'_> {} -impl<'a> CoerceShared> for MyMut<'a> {} +impl<'a: 'b, 'b> CoerceShared> for MyMut<'a> {} //~^ ERROR fn main() {} diff --git a/tests/ui/reborrow/coerce-shared-associated-type-field.stderr b/tests/ui/reborrow/coerce-shared-associated-type-field.stderr index 7a78190595380..a159adfeba3b0 100644 --- a/tests/ui/reborrow/coerce-shared-associated-type-field.stderr +++ b/tests/ui/reborrow/coerce-shared-associated-type-field.stderr @@ -1,11 +1,11 @@ error: implementing `CoerceShared` currently requires source and target to have at most one non-ZST reborrow data field --> $DIR/coerce-shared-associated-type-field.rs:30:1 | -LL | impl<'a> CoerceShared> for MyMut<'a> {} - | ^^^^^^^^^^^^^^^^^^^^^^---------^^^^^^---------^^^ - | | | | - | | | source type has 2 non-ZST reborrow data fields - | | target type has 2 non-ZST reborrow data fields +LL | impl<'a: 'b, 'b> CoerceShared> for MyMut<'a> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---------^^^^^^---------^^^ + | | | | + | | | source type has 2 non-ZST reborrow data fields + | | target type has 2 non-ZST reborrow data fields | in this `CoerceShared` implementation | = note: this is a temporary restriction until `CoerceShared` lowering supports non-trivially memcpy-compatible field layouts diff --git a/tests/ui/reborrow/coerce-shared-decl-macro-hygiene.rs b/tests/ui/reborrow/coerce-shared-decl-macro-hygiene.rs index 59e0a8d96a33e..65b251c238fe0 100644 --- a/tests/ui/reborrow/coerce-shared-decl-macro-hygiene.rs +++ b/tests/ui/reborrow/coerce-shared-decl-macro-hygiene.rs @@ -21,7 +21,7 @@ macro my_macro($field:ident) { impl Reborrow for MyMut<'_> {} - impl<'a> CoerceShared> for MyMut<'a> {} + impl<'a: 'b, 'b> CoerceShared> for MyMut<'a> {} //~^ ERROR } diff --git a/tests/ui/reborrow/coerce-shared-decl-macro-hygiene.stderr b/tests/ui/reborrow/coerce-shared-decl-macro-hygiene.stderr index 4755ee557b742..fdb57b46f5517 100644 --- a/tests/ui/reborrow/coerce-shared-decl-macro-hygiene.stderr +++ b/tests/ui/reborrow/coerce-shared-decl-macro-hygiene.stderr @@ -3,11 +3,11 @@ error: implementing `CoerceShared` currently requires source and target to have | LL | macro my_macro($field:ident) { ... -LL | impl<'a> CoerceShared> for MyMut<'a> {} - | ^^^^^^^^^^^^^^^^^^^^^^---------^^^^^^---------^^^ - | | | | - | | | source type has 2 non-ZST reborrow data fields - | | target type has 2 non-ZST reborrow data fields +LL | impl<'a: 'b, 'b> CoerceShared> for MyMut<'a> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---------^^^^^^---------^^^ + | | | | + | | | source type has 2 non-ZST reborrow data fields + | | target type has 2 non-ZST reborrow data fields | in this `CoerceShared` implementation ... LL | my_macro!(field); diff --git a/tests/ui/reborrow/coerce-shared-field-lifetime-swap.rs b/tests/ui/reborrow/coerce-shared-field-lifetime-swap.rs index 71caf8a7ec6bf..5e419d9b07e2a 100644 --- a/tests/ui/reborrow/coerce-shared-field-lifetime-swap.rs +++ b/tests/ui/reborrow/coerce-shared-field-lifetime-swap.rs @@ -14,10 +14,10 @@ impl Reborrow for MyMut<'_> {} #[derive(Copy, Clone)] struct MyRef<'a> { x: &'a (), - //~^ ERROR y: &'static (), + //~^ ERROR } -impl<'a> CoerceShared> for MyMut<'a> {} +impl<'a: 'b, 'b> CoerceShared> for MyMut<'a> {} fn main() {} diff --git a/tests/ui/reborrow/coerce-shared-field-lifetime-swap.stderr b/tests/ui/reborrow/coerce-shared-field-lifetime-swap.stderr index 4958640257918..9b30edb32a1cd 100644 --- a/tests/ui/reborrow/coerce-shared-field-lifetime-swap.stderr +++ b/tests/ui/reborrow/coerce-shared-field-lifetime-swap.stderr @@ -1,14 +1,14 @@ error: implementing `CoerceShared` requires corresponding fields to match, be reborrowable with `CoerceShared`, or coerce a mutable reference field to a shared reference field - --> $DIR/coerce-shared-field-lifetime-swap.rs:16:5 + --> $DIR/coerce-shared-field-lifetime-swap.rs:17:5 | -LL | x: &'static (), - | -------------- source field `x` has type `&'static ()` +LL | y: &'a (), + | --------- source field `y` has type `&'a ()` ... -LL | x: &'a (), - | ^^^^^^^^^ target field `x` has type `&'a ()` +LL | y: &'static (), + | ^^^^^^^^^^^^^^ target field `y` has type `&'static ()` ... -LL | impl<'a> CoerceShared> for MyMut<'a> {} - | ------------------------------------------------- required by this `CoerceShared` implementation +LL | impl<'a: 'b, 'b> CoerceShared> for MyMut<'a> {} + | --------------------------------------------------------- required by this `CoerceShared` implementation error: aborting due to 1 previous error diff --git a/tests/ui/reborrow/coerce-shared-field-region-obligation.rs b/tests/ui/reborrow/coerce-shared-field-region-obligation.rs index 4a39301d6cd18..689da282ada4d 100644 --- a/tests/ui/reborrow/coerce-shared-field-region-obligation.rs +++ b/tests/ui/reborrow/coerce-shared-field-region-obligation.rs @@ -26,7 +26,8 @@ struct Target<'a> { field: FieldRef<'a, &'static ()>, } -impl<'a> CoerceShared> for Source<'a> {} +impl<'a: 'b, 'b> CoerceShared> for Source<'a> {} //~^ ERROR mismatched types +//~| ERROR cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements [E0803] fn main() {} diff --git a/tests/ui/reborrow/coerce-shared-field-region-obligation.stderr b/tests/ui/reborrow/coerce-shared-field-region-obligation.stderr index 06b89073f49e1..e1e7941f7e40e 100644 --- a/tests/ui/reborrow/coerce-shared-field-region-obligation.stderr +++ b/tests/ui/reborrow/coerce-shared-field-region-obligation.stderr @@ -1,18 +1,43 @@ error[E0308]: mismatched types --> $DIR/coerce-shared-field-region-obligation.rs:29:1 | -LL | impl<'a> CoerceShared> for Source<'a> {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetime mismatch +LL | impl<'a: 'b, 'b> CoerceShared> for Source<'a> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetime mismatch | - = note: expected trait `CoerceShared>` + = note: expected trait `CoerceShared>` found trait `CoerceShared>` note: the lifetime `'a` as defined here... --> $DIR/coerce-shared-field-region-obligation.rs:29:6 | -LL | impl<'a> CoerceShared> for Source<'a> {} +LL | impl<'a: 'b, 'b> CoerceShared> for Source<'a> {} | ^^ = note: ...does not necessarily outlive the static lifetime -error: aborting due to 1 previous error +error[E0803]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements + --> $DIR/coerce-shared-field-region-obligation.rs:29:1 + | +LL | impl<'a: 'b, 'b> CoerceShared> for Source<'a> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: first, the lifetime cannot outlive the lifetime `'b` as defined here... + --> $DIR/coerce-shared-field-region-obligation.rs:29:14 + | +LL | impl<'a: 'b, 'b> CoerceShared> for Source<'a> {} + | ^^ +note: ...but the lifetime must also be valid for the lifetime `'a` as defined here... + --> $DIR/coerce-shared-field-region-obligation.rs:29:6 + | +LL | impl<'a: 'b, 'b> CoerceShared> for Source<'a> {} + | ^^ +note: ...so that the types are compatible + --> $DIR/coerce-shared-field-region-obligation.rs:29:1 + | +LL | impl<'a: 'b, 'b> CoerceShared> for Source<'a> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: expected `CoerceShared>` + found `CoerceShared>` + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0308`. +Some errors have detailed explanations: E0308, E0803. +For more information about an error, try `rustc --explain E0308`. diff --git a/tests/ui/reborrow/coerce-shared-foreign-private-field.rs b/tests/ui/reborrow/coerce-shared-foreign-private-field.rs index fc039df249eae..e0a0dc52b8b50 100644 --- a/tests/ui/reborrow/coerce-shared-foreign-private-field.rs +++ b/tests/ui/reborrow/coerce-shared-foreign-private-field.rs @@ -16,7 +16,7 @@ struct LocalMut<'a> { impl<'a> Reborrow for LocalMut<'a> {} // Should error: ForeignRef has private fields. -impl<'a> CoerceShared> for LocalMut<'a> {} +impl<'a: 'b, 'b> CoerceShared> for LocalMut<'a> {} //~^ ERROR fn main() {} diff --git a/tests/ui/reborrow/coerce-shared-foreign-private-field.stderr b/tests/ui/reborrow/coerce-shared-foreign-private-field.stderr index a00a6b84ec788..5a73427f82c7f 100644 --- a/tests/ui/reborrow/coerce-shared-foreign-private-field.stderr +++ b/tests/ui/reborrow/coerce-shared-foreign-private-field.stderr @@ -1,10 +1,10 @@ error: implementing `CoerceShared` requires all target type fields to be accessible from the impl --> $DIR/coerce-shared-foreign-private-field.rs:19:1 | -LL | impl<'a> CoerceShared> for LocalMut<'a> {} - | ^^^^^^^^^^^^^^^^^^^^^^--------------^^^^^^^^^^^^^^^^^^^^^ - | | - | target type `ForeignRef` has inaccessible reborrow data fields +LL | impl<'a: 'b, 'b> CoerceShared> for LocalMut<'a> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--------------^^^^^^^^^^^^^^^^^^^^^ + | | + | target type `ForeignRef` has inaccessible reborrow data fields error: aborting due to 1 previous error diff --git a/tests/ui/reborrow/coerce-shared-foreign-private-tuple-field.rs b/tests/ui/reborrow/coerce-shared-foreign-private-tuple-field.rs index 466fe2c315263..a969697707e05 100644 --- a/tests/ui/reborrow/coerce-shared-foreign-private-tuple-field.rs +++ b/tests/ui/reborrow/coerce-shared-foreign-private-tuple-field.rs @@ -18,7 +18,7 @@ struct LocalPtrMut<'a>(*const i32, PhantomData<&'a ()>); impl<'a> Reborrow for LocalPtrMut<'a> {} -impl<'a> CoerceShared> for LocalPtrMut<'a> {} +impl<'a: 'b, 'b> CoerceShared> for LocalPtrMut<'a> {} //~^ ERROR fn main() {} diff --git a/tests/ui/reborrow/coerce-shared-foreign-private-tuple-field.stderr b/tests/ui/reborrow/coerce-shared-foreign-private-tuple-field.stderr index 2ae5963bbc55b..1758a472c9bba 100644 --- a/tests/ui/reborrow/coerce-shared-foreign-private-tuple-field.stderr +++ b/tests/ui/reborrow/coerce-shared-foreign-private-tuple-field.stderr @@ -1,10 +1,10 @@ error: implementing `CoerceShared` requires all target type fields to be accessible from the impl --> $DIR/coerce-shared-foreign-private-tuple-field.rs:21:1 | -LL | impl<'a> CoerceShared> for LocalPtrMut<'a> {} - | ^^^^^^^^^^^^^^^^^^^^^^-----------------^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | target type `ForeignPtrRef` has inaccessible reborrow data fields +LL | impl<'a: 'b, 'b> CoerceShared> for LocalPtrMut<'a> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-----------------^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | target type `ForeignPtrRef` has inaccessible reborrow data fields error: aborting due to 1 previous error diff --git a/tests/ui/reborrow/coerce-shared-lifetime-mismatch.rs b/tests/ui/reborrow/coerce-shared-lifetime-mismatch.rs index c7e3b4b12d4bc..61286bc9a38eb 100644 --- a/tests/ui/reborrow/coerce-shared-lifetime-mismatch.rs +++ b/tests/ui/reborrow/coerce-shared-lifetime-mismatch.rs @@ -15,11 +15,12 @@ impl<'a> Reborrow for CustomMarker<'a> {} struct StaticMarkerRef<'a>(PhantomData<&'a ()>); impl<'a> CoerceShared> for CustomMarker<'a> {} -//~^ ERROR fn method(_a: StaticMarkerRef<'static>) {} fn main() { let a = CustomMarker(PhantomData); method(a); + drop(a); + //~^ ERROR cannot move out of `a` because it is borrowed } diff --git a/tests/ui/reborrow/coerce-shared-lifetime-mismatch.stderr b/tests/ui/reborrow/coerce-shared-lifetime-mismatch.stderr index 38c3d3637b566..dbe65377f45c5 100644 --- a/tests/ui/reborrow/coerce-shared-lifetime-mismatch.stderr +++ b/tests/ui/reborrow/coerce-shared-lifetime-mismatch.stderr @@ -1,10 +1,16 @@ -error: implementing `CoerceShared` requires source and target to use the same reborrow lifetime argument - --> $DIR/coerce-shared-lifetime-mismatch.rs:17:10 +error[E0505]: cannot move out of `a` because it is borrowed + --> $DIR/coerce-shared-lifetime-mismatch.rs:24:10 | -LL | impl<'a> CoerceShared> for CustomMarker<'a> {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-------^^ -- source reborrow lifetime - | | - | target reborrow lifetime +LL | let a = CustomMarker(PhantomData); + | - binding `a` declared here +LL | method(a); + | - + | | + | borrow of `a` occurs here + | assignment requires that `a` is borrowed for `'static` +LL | drop(a); + | ^ move out of `a` occurs here error: aborting due to 1 previous error +For more information about this error, try `rustc --explain E0505`. diff --git a/tests/ui/reborrow/coerce-shared-multi-non-zst.rs b/tests/ui/reborrow/coerce-shared-multi-non-zst.rs index 6625593a4b32e..f606059671abd 100644 --- a/tests/ui/reborrow/coerce-shared-multi-non-zst.rs +++ b/tests/ui/reborrow/coerce-shared-multi-non-zst.rs @@ -16,7 +16,7 @@ struct Target<'a> { impl Reborrow for Source<'_> {} -impl<'a> CoerceShared> for Source<'a> {} -//~^ ERROR +impl<'a: 'b, 'b> CoerceShared> for Source<'a> {} +//~^ ERROR implementing `CoerceShared` currently requires source and target to have at most one non-ZST reborrow data field fn main() {} diff --git a/tests/ui/reborrow/coerce-shared-multi-non-zst.stderr b/tests/ui/reborrow/coerce-shared-multi-non-zst.stderr index 231e33f259c63..63f32e3bc8425 100644 --- a/tests/ui/reborrow/coerce-shared-multi-non-zst.stderr +++ b/tests/ui/reborrow/coerce-shared-multi-non-zst.stderr @@ -1,11 +1,11 @@ error: implementing `CoerceShared` currently requires source and target to have at most one non-ZST reborrow data field --> $DIR/coerce-shared-multi-non-zst.rs:19:1 | -LL | impl<'a> CoerceShared> for Source<'a> {} - | ^^^^^^^^^^^^^^^^^^^^^^----------^^^^^^----------^^^ - | | | | - | | | source type has 2 non-ZST reborrow data fields - | | target type has 2 non-ZST reborrow data fields +LL | impl<'a: 'b, 'b> CoerceShared> for Source<'a> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^----------^^^^^^----------^^^ + | | | | + | | | source type has 2 non-ZST reborrow data fields + | | target type has 2 non-ZST reborrow data fields | in this `CoerceShared` implementation | = note: this is a temporary restriction until `CoerceShared` lowering supports non-trivially memcpy-compatible field layouts diff --git a/tests/ui/reborrow/coerce-shared-mut-ref-field-validation.rs b/tests/ui/reborrow/coerce-shared-mut-ref-field-validation.rs index ee7685242070e..27684e34b461a 100644 --- a/tests/ui/reborrow/coerce-shared-mut-ref-field-validation.rs +++ b/tests/ui/reborrow/coerce-shared-mut-ref-field-validation.rs @@ -26,7 +26,7 @@ struct AliasRef<'a> { value: AliasRefField<'a>, } -impl<'a> CoerceShared> for AliasMut<'a> {} +impl<'a: 'b, 'b> CoerceShared> for AliasMut<'a> {} struct InnerLifetimeMut<'a> { value: &'a mut &'static (), @@ -39,7 +39,7 @@ struct InnerLifetimeRef<'a> { value: &'a &'a (), } -impl<'a> CoerceShared> for InnerLifetimeMut<'a> {} +impl<'a: 'b, 'b> CoerceShared> for InnerLifetimeMut<'a> {} struct RejectedInnerLifetimeMut<'a> { value: &'a mut &'a (), @@ -53,6 +53,6 @@ struct RejectedInnerLifetimeRef<'a> { //~^ ERROR } -impl<'a> CoerceShared> for RejectedInnerLifetimeMut<'a> {} +impl<'a: 'b, 'b> CoerceShared> for RejectedInnerLifetimeMut<'a> {} fn main() {} diff --git a/tests/ui/reborrow/coerce-shared-mut-ref-field-validation.stderr b/tests/ui/reborrow/coerce-shared-mut-ref-field-validation.stderr index 57159ff8ddd56..d310dcc1356da 100644 --- a/tests/ui/reborrow/coerce-shared-mut-ref-field-validation.stderr +++ b/tests/ui/reborrow/coerce-shared-mut-ref-field-validation.stderr @@ -5,10 +5,10 @@ LL | value: &'a mut &'a (), | --------------------- source field `value` has type `&'a mut &'a ()` ... LL | value: &'a &'static (), - | ^^^^^^^^^^^^^^^^^^^^^^ target field `value` has type `&'a &'static ()` + | ^^^^^^^^^^^^^^^^^^^^^^ target field `value` has type `&'b &'static ()` ... -LL | impl<'a> CoerceShared> for RejectedInnerLifetimeMut<'a> {} - | --------------------------------------------------------------------------------------- required by this `CoerceShared` implementation +LL | impl<'a: 'b, 'b> CoerceShared> for RejectedInnerLifetimeMut<'a> {} + | ----------------------------------------------------------------------------------------------- required by this `CoerceShared` implementation error: aborting due to 1 previous error diff --git a/tests/ui/reborrow/coerce-shared-normalize.rs b/tests/ui/reborrow/coerce-shared-normalize.rs index a212eaf27fccf..77b8d3e76a903 100644 --- a/tests/ui/reborrow/coerce-shared-normalize.rs +++ b/tests/ui/reborrow/coerce-shared-normalize.rs @@ -51,6 +51,6 @@ impl<'a> Copy for CustomRef<'a> {} impl<'a> Reborrow for CustomMut<'a> {} -impl<'a> CoerceShared> for CustomMutAlias<'a> {} +impl<'a: 'b, 'b> CoerceShared> for CustomMutAlias<'a> {} fn main() {} diff --git a/tests/ui/reborrow/coerce-shared-omitted-zst-field.rs b/tests/ui/reborrow/coerce-shared-omitted-zst-field.rs index f74c914acd272..3155ab3aa0b09 100644 --- a/tests/ui/reborrow/coerce-shared-omitted-zst-field.rs +++ b/tests/ui/reborrow/coerce-shared-omitted-zst-field.rs @@ -26,7 +26,7 @@ struct Target<'a> { value: &'a i32, } -impl<'a> CoerceShared> for Source<'a> {} +impl<'a: 'b, 'b> CoerceShared> for Source<'a> {} struct CopyZstSource<'a> { value: &'a mut i32, @@ -40,7 +40,7 @@ struct CopyZstTarget<'a> { value: &'a i32, } -impl<'a> CoerceShared> for CopyZstSource<'a> {} +impl<'a: 'b, 'b> CoerceShared> for CopyZstSource<'a> {} struct ReborrowZstSource<'a> { value: &'a mut i32, @@ -54,6 +54,6 @@ struct ReborrowZstTarget<'a> { value: &'a i32, } -impl<'a> CoerceShared> for ReborrowZstSource<'a> {} +impl<'a: 'b, 'b> CoerceShared> for ReborrowZstSource<'a> {} fn main() {} diff --git a/tests/ui/reborrow/coerce-shared-omitted-zst-field.stderr b/tests/ui/reborrow/coerce-shared-omitted-zst-field.stderr index 43a6705ce8688..a51696eb2420b 100644 --- a/tests/ui/reborrow/coerce-shared-omitted-zst-field.stderr +++ b/tests/ui/reborrow/coerce-shared-omitted-zst-field.stderr @@ -16,8 +16,8 @@ error: implementing `CoerceShared` requires source fields omitted from the targe LL | marker: NonCopyZst, | ^^^^^^^^^^^^^^^^^^ source field `marker` has type `NonCopyZst` ... -LL | impl<'a> CoerceShared> for Source<'a> {} - | --------------------------------------------------- required by this `CoerceShared` implementation +LL | impl<'a: 'b, 'b> CoerceShared> for Source<'a> {} + | ----------------------------------------------------------- required by this `CoerceShared` implementation error: aborting due to 2 previous errors diff --git a/tests/ui/reborrow/coerce-shared-reordered-field.rs b/tests/ui/reborrow/coerce-shared-reordered-field.rs index b182d9df26f59..e7669695e173c 100644 --- a/tests/ui/reborrow/coerce-shared-reordered-field.rs +++ b/tests/ui/reborrow/coerce-shared-reordered-field.rs @@ -18,7 +18,7 @@ struct ReorderRef<'a> { a: &'a u8, } -impl<'a> CoerceShared> for ReorderMut<'a> {} +impl<'a: 'b, 'b> CoerceShared> for ReorderMut<'a> {} //~^ ERROR fn read(value: ReorderRef<'_>) -> (u16, u8) { diff --git a/tests/ui/reborrow/coerce-shared-reordered-field.stderr b/tests/ui/reborrow/coerce-shared-reordered-field.stderr index 4dbc344aa9196..d5c8a5c672b7c 100644 --- a/tests/ui/reborrow/coerce-shared-reordered-field.stderr +++ b/tests/ui/reborrow/coerce-shared-reordered-field.stderr @@ -1,11 +1,11 @@ error: implementing `CoerceShared` currently requires source and target to have at most one non-ZST reborrow data field --> $DIR/coerce-shared-reordered-field.rs:21:1 | -LL | impl<'a> CoerceShared> for ReorderMut<'a> {} - | ^^^^^^^^^^^^^^^^^^^^^^--------------^^^^^^--------------^^^ - | | | | - | | | source type has 2 non-ZST reborrow data fields - | | target type has 2 non-ZST reborrow data fields +LL | impl<'a: 'b, 'b> CoerceShared> for ReorderMut<'a> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--------------^^^^^^--------------^^^ + | | | | + | | | source type has 2 non-ZST reborrow data fields + | | target type has 2 non-ZST reborrow data fields | in this `CoerceShared` implementation | = note: this is a temporary restriction until `CoerceShared` lowering supports non-trivially memcpy-compatible field layouts diff --git a/tests/ui/reborrow/coerce_shared_consteval.rs b/tests/ui/reborrow/coerce_shared_consteval.rs index 29b44b6438631..64797b3671b5e 100644 --- a/tests/ui/reborrow/coerce_shared_consteval.rs +++ b/tests/ui/reborrow/coerce_shared_consteval.rs @@ -14,7 +14,7 @@ impl Reborrow for MyMut<'_> {} #[derive(Clone, Copy)] pub struct MyRef<'a>(&'a u8); -impl<'a> CoerceShared> for MyMut<'a> {} +impl<'a: 'b, 'b> CoerceShared> for MyMut<'a> {} const fn consteval_reproducer() { let value = 1; diff --git a/tests/ui/reborrow/custom_marker_coerce_shared_move_no_conflict_manual.rs b/tests/ui/reborrow/custom_marker_coerce_shared_move_no_conflict_manual.rs index 4519e36a40b61..25873a72bdde6 100644 --- a/tests/ui/reborrow/custom_marker_coerce_shared_move_no_conflict_manual.rs +++ b/tests/ui/reborrow/custom_marker_coerce_shared_move_no_conflict_manual.rs @@ -1,6 +1,7 @@ +//@ run-pass + //! Test that CoerceShared with manually set lifetime bounds does allow moving a reborrowable type //! after CoerceShared. -//! This should probably work eventually, but right now it fails from trait well-formedness checks. #![feature(reborrow)] use std::marker::{CoerceShared, PhantomData, Reborrow}; @@ -8,7 +9,6 @@ use std::marker::{CoerceShared, PhantomData, Reborrow}; #[derive(Reborrow)] struct CustomMarker<'a>(PhantomData<&'a ()>); impl<'a: 'b, 'b> CoerceShared> for CustomMarker<'a> {} -//~^ ERROR: implementing `CoerceShared` requires that a single lifetime parameter is passed between source and target #[derive(Clone, Copy)] struct CustomMarkerRef<'a>(PhantomData<&'a ()>); @@ -21,7 +21,7 @@ fn move_into(_: T) {} fn main() { let a = CustomMarker(PhantomData); - let b = method(a); - let c = method(a); + let _b = method(a); + let _c = method(a); move_into(a); } diff --git a/tests/ui/reborrow/custom_marker_coerce_shared_move_no_conflict_manual.stderr b/tests/ui/reborrow/custom_marker_coerce_shared_move_no_conflict_manual.stderr deleted file mode 100644 index ce928c86d835c..0000000000000 --- a/tests/ui/reborrow/custom_marker_coerce_shared_move_no_conflict_manual.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: implementing `CoerceShared` requires that a single lifetime parameter is passed between source and target - --> $DIR/custom_marker_coerce_shared_move_no_conflict_manual.rs:10:1 - | -LL | impl<'a: 'b, 'b> CoerceShared> for CustomMarker<'a> {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 1 previous error - diff --git a/tests/ui/reborrow/derive_invalid_coherence.rs b/tests/ui/reborrow/derive_invalid_coherence.rs index c744d986b6a26..d8ed6c485d529 100644 --- a/tests/ui/reborrow/derive_invalid_coherence.rs +++ b/tests/ui/reborrow/derive_invalid_coherence.rs @@ -6,7 +6,6 @@ use std::marker::{CoerceShared, PhantomData, Reborrow}; #[derive(Reborrow)] -//~^ ERROR implementing `Reborrow` requires that a single lifetime parameter is passed between source and target struct TooManyLifetimes<'a, 'b>(PhantomData<(&'a (), &'b ())>); #[derive(Clone, Copy)] diff --git a/tests/ui/reborrow/derive_invalid_coherence.stderr b/tests/ui/reborrow/derive_invalid_coherence.stderr index 44d976d4893f0..c89c0df6e29ad 100644 --- a/tests/ui/reborrow/derive_invalid_coherence.stderr +++ b/tests/ui/reborrow/derive_invalid_coherence.stderr @@ -1,11 +1,5 @@ -error: implementing `Reborrow` requires that a single lifetime parameter is passed between source and target - --> $DIR/derive_invalid_coherence.rs:8:10 - | -LL | #[derive(Reborrow)] - | ^^^^^^^^ - error[E0277]: the trait bound `NotCopy: Copy` is not satisfied - --> $DIR/derive_invalid_coherence.rs:24:5 + --> $DIR/derive_invalid_coherence.rs:23:5 | LL | field: NotCopy, | ^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `NotCopy` @@ -17,17 +11,17 @@ LL | struct NotCopy; | error: implementing `CoerceShared` requires corresponding fields to match, be reborrowable with `CoerceShared`, or coerce a mutable reference field to a shared reference field - --> $DIR/derive_invalid_coherence.rs:13:22 + --> $DIR/derive_invalid_coherence.rs:12:22 | LL | struct BadTarget<'a>(&'a ()); - | ^^^^^^ target field `0` has type `&'a ()` + | ^^^^^^ target field `0` has type `&'a_ ()` ... LL | #[derive(Reborrow, CoerceShared)] | ------------ required by this `CoerceShared` implementation LL | #[coerce_shared(BadTarget<'a>)] LL | struct BadSource<'a>(&'a mut u32); - | ----------- source field `0` has type `&'a mut u32` + | ----------- source field `0` has type `&'a_ mut u32` -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/reborrow/derive_multiple_lifetimes.rs b/tests/ui/reborrow/derive_multiple_lifetimes.rs index c8ed4ea51488f..b6204646c6637 100644 --- a/tests/ui/reborrow/derive_multiple_lifetimes.rs +++ b/tests/ui/reborrow/derive_multiple_lifetimes.rs @@ -1,5 +1,3 @@ -//@ normalize-stderr: "\n\n$" -> "\n" - //! This test mirrors manual and derived impls with multiple lifetimes. The derive //! layer preserves both lifetimes; the current underlying trait validation rejects //! both forms with the same experimental one-lifetime limitation. @@ -15,10 +13,8 @@ struct ManualPair<'a, 'b, T> { } impl<'a, 'b, T> Reborrow for ManualPair<'a, 'b, T> {} -//~^ ERROR implementing `Reborrow` requires that a single lifetime parameter is passed between source and target #[derive(Reborrow)] -//~^ ERROR implementing `Reborrow` requires that a single lifetime parameter is passed between source and target struct DerivedPair<'a, 'b, T> { left: &'a mut T, right: &'b mut T, @@ -42,9 +38,8 @@ struct ManualMut<'a, 'b, T> { } impl<'a, 'b, T> Reborrow for ManualMut<'a, 'b, T> {} -//~^ ERROR implementing `Reborrow` requires that a single lifetime parameter is passed between source and target impl<'a, 'b, T> CoerceShared> for ManualMut<'a, 'b, T> {} -//~^ ERROR implementing `CoerceShared` requires that a single lifetime parameter is passed between source and target +//~^ ERROR implementing `CoerceShared` currently requires source and target to have at most one non-ZST reborrow data field struct DerivedShared<'a, 'b, T> { left: &'a T, @@ -59,8 +54,7 @@ impl<'a, 'b, T> Clone for DerivedShared<'a, 'b, T> { impl<'a, 'b, T> Copy for DerivedShared<'a, 'b, T> {} #[derive(Reborrow, CoerceShared)] -//~^ ERROR implementing `Reborrow` requires that a single lifetime parameter is passed between source and target -//~| ERROR implementing `CoerceShared` requires that a single lifetime parameter is passed between source and target +//~^ ERROR implementing `CoerceShared` currently requires source and target to have at most one non-ZST reborrow data field #[coerce_shared(DerivedShared<'a, 'b, T>)] struct DerivedMut<'a, 'b, T> { left: &'a mut T, diff --git a/tests/ui/reborrow/derive_multiple_lifetimes.stderr b/tests/ui/reborrow/derive_multiple_lifetimes.stderr index 70847e0a5820c..8ebdd92cde7eb 100644 --- a/tests/ui/reborrow/derive_multiple_lifetimes.stderr +++ b/tests/ui/reborrow/derive_multiple_lifetimes.stderr @@ -1,37 +1,28 @@ -error: implementing `Reborrow` requires that a single lifetime parameter is passed between source and target - --> $DIR/derive_multiple_lifetimes.rs:17:1 +error: implementing `CoerceShared` currently requires source and target to have at most one non-ZST reborrow data field + --> $DIR/derive_multiple_lifetimes.rs:41:1 | -LL | impl<'a, 'b, T> Reborrow for ManualPair<'a, 'b, T> {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: implementing `Reborrow` requires that a single lifetime parameter is passed between source and target - --> $DIR/derive_multiple_lifetimes.rs:20:10 - | -LL | #[derive(Reborrow)] - | ^^^^^^^^ - -error: implementing `Reborrow` requires that a single lifetime parameter is passed between source and target - --> $DIR/derive_multiple_lifetimes.rs:44:1 +LL | impl<'a, 'b, T> CoerceShared> for ManualMut<'a, 'b, T> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-----------------------^^^^^^--------------------^^^ + | | | | + | | | source type has 2 non-ZST reborrow data fields + | | target type has 2 non-ZST reborrow data fields + | in this `CoerceShared` implementation | -LL | impl<'a, 'b, T> Reborrow for ManualMut<'a, 'b, T> {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: this is a temporary restriction until `CoerceShared` lowering supports non-trivially memcpy-compatible field layouts -error: implementing `Reborrow` requires that a single lifetime parameter is passed between source and target - --> $DIR/derive_multiple_lifetimes.rs:61:10 +error: implementing `CoerceShared` currently requires source and target to have at most one non-ZST reborrow data field + --> $DIR/derive_multiple_lifetimes.rs:56:20 | LL | #[derive(Reborrow, CoerceShared)] - | ^^^^^^^^ - -error: implementing `CoerceShared` requires that a single lifetime parameter is passed between source and target - --> $DIR/derive_multiple_lifetimes.rs:46:1 + | ^^^^^^^^^^^^ + | | + | in this `CoerceShared` implementation + | source type has 2 non-ZST reborrow data fields +LL | +LL | #[coerce_shared(DerivedShared<'a, 'b, T>)] + | ------------------------ target type has 2 non-ZST reborrow data fields | -LL | impl<'a, 'b, T> CoerceShared> for ManualMut<'a, 'b, T> {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: this is a temporary restriction until `CoerceShared` lowering supports non-trivially memcpy-compatible field layouts -error: implementing `CoerceShared` requires that a single lifetime parameter is passed between source and target - --> $DIR/derive_multiple_lifetimes.rs:61:20 - | -LL | #[derive(Reborrow, CoerceShared)] - | ^^^^^^^^^^^^ +error: aborting due to 2 previous errors -error: aborting due to 6 previous errors diff --git a/tests/ui/reborrow/reborrow-promotion-rejected.rs b/tests/ui/reborrow/reborrow-promotion-rejected.rs index 8040ae2445139..23e8082f903ab 100644 --- a/tests/ui/reborrow/reborrow-promotion-rejected.rs +++ b/tests/ui/reborrow/reborrow-promotion-rejected.rs @@ -11,7 +11,7 @@ impl Reborrow for MyMut<'_> {} #[derive(Clone, Copy)] struct MyRef<'a>(&'a u8); -impl<'a> CoerceShared> for MyMut<'a> {} +impl<'a: 'b, 'b> CoerceShared> for MyMut<'a> {} const fn coerce(x: MyRef<'_>) -> MyRef<'_> { x