Validation and other things

This commit is contained in:
Michael Goulet 2024-04-04 12:54:56 -04:00
parent 41cf87b71b
commit 42ba57c013
26 changed files with 418 additions and 19 deletions

View File

@ -2132,7 +2132,7 @@ pub enum TyKind {
/// The `NodeId` exists to prevent lowering from having to
/// generate `NodeId`s on the fly, which would complicate
/// the generation of opaque `type Foo = impl Trait` items significantly.
ImplTrait(NodeId, GenericBounds, Option<ThinVec<PreciseCapturingArg>>),
ImplTrait(NodeId, GenericBounds, Option<P<(ThinVec<PreciseCapturingArg>, Span)>>),
/// No-op; kept solely so that we can pretty-print faithfully.
Paren(P<Ty>),
/// Unused for now.

View File

@ -525,11 +525,11 @@ pub fn noop_visit_ty<T: MutVisitor>(ty: &mut P<Ty>, vis: &mut T) {
TyKind::ImplTrait(id, bounds, precise_capturing) => {
vis.visit_id(id);
visit_vec(bounds, |bound| vis.visit_param_bound(bound));
visit_opt(precise_capturing, |precise_capturing| {
if let Some((precise_capturing, _span)) = precise_capturing.as_deref_mut() {
for arg in precise_capturing {
vis.visit_precise_capturing_arg(arg);
}
});
}
}
TyKind::MacCall(mac) => vis.visit_mac_call(mac),
TyKind::AnonStruct(id, fields) | TyKind::AnonUnion(id, fields) => {

View File

@ -462,7 +462,7 @@ pub fn walk_ty<'a, V: Visitor<'a>>(visitor: &mut V, typ: &'a Ty) -> V::Result {
}
TyKind::ImplTrait(_, bounds, precise_capturing) => {
walk_list!(visitor, visit_param_bound, bounds, BoundKind::Impl);
if let Some(precise_capturing) = precise_capturing {
if let Some((precise_capturing, _span)) = precise_capturing.as_deref() {
for arg in precise_capturing {
try_visit!(visitor.visit_precise_capturing_arg(arg));
}

View File

@ -127,6 +127,8 @@ ast_lowering_never_pattern_with_guard =
a guard on a never pattern will never be run
.suggestion = remove this guard
ast_lowering_no_precise_captures_on_apit = `use<...>` precise capturing syntax not allowed on argument-position `impl Trait`
ast_lowering_previously_used_here = previously used here
ast_lowering_register1 = register `{$reg1_name}`

View File

@ -414,3 +414,10 @@ pub(crate) struct AsyncBoundOnlyForFnTraits {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(ast_lowering_no_precise_captures_on_apit)]
pub(crate) struct NoPreciseCapturesOnApit {
#[primary_span]
pub span: Span,
}

View File

@ -1409,13 +1409,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
bounds,
fn_kind,
itctx,
precise_capturing.as_deref(),
precise_capturing.as_deref().map(|(args, _)| args.as_slice()),
),
ImplTraitContext::Universal => {
assert!(
precise_capturing.is_none(),
"TODO: precise captures not supported on universals!"
);
if let Some(&(_, span)) = precise_capturing.as_deref() {
self.tcx.dcx().emit_err(errors::NoPreciseCapturesOnApit { span });
};
let span = t.span;
// HACK: pprust breaks strings with newlines when the type

View File

@ -1150,9 +1150,17 @@ impl<'a> State<'a> {
}
self.print_type_bounds(bounds);
}
ast::TyKind::ImplTrait(_, bounds, _precise_capturing) => {
// TODO(precise_capturing):
ast::TyKind::ImplTrait(_, bounds, precise_capturing_args) => {
self.word_nbsp("impl");
if let Some((precise_capturing_args, ..)) = precise_capturing_args.as_deref() {
self.word("use");
self.word("<");
self.commasep(Inconsistent, precise_capturing_args, |s, arg| match arg {
ast::PreciseCapturingArg::Arg(a, _) => s.print_ident(*a),
ast::PreciseCapturingArg::Lifetime(lt) => s.print_lifetime(*lt),
});
self.word(">")
}
self.print_type_bounds(bounds);
}
ast::TyKind::Array(ty, length) => {

View File

@ -535,8 +535,6 @@ declare_features! (
(unstable, must_not_suspend, "1.57.0", Some(83310)),
/// Allows `mut ref` and `mut ref mut` identifier patterns.
(incomplete, mut_ref, "CURRENT_RUSTC_VERSION", Some(123076)),
/// Allows `use<'a, 'b, A, B>` in `impl use<...> Trait` for precise capture of generic args.
(incomplete, precise_capturing, "CURRENT_RUSTC_VERSION", Some(123432)),
/// Allows using `#[naked]` on functions.
(unstable, naked_functions, "1.9.0", Some(90957)),
/// Allows specifying the as-needed link modifier
@ -569,6 +567,8 @@ declare_features! (
(unstable, optimize_attribute, "1.34.0", Some(54882)),
/// Allows postfix match `expr.match { ... }`
(unstable, postfix_match, "CURRENT_RUSTC_VERSION", Some(121618)),
/// Allows `use<'a, 'b, A, B>` in `impl use<...> Trait` for precise capture of generic args.
(incomplete, precise_capturing, "CURRENT_RUSTC_VERSION", Some(123432)),
/// Allows macro attributes on expressions, statements and non-inline modules.
(unstable, proc_macro_hygiene, "1.30.0", Some(54727)),
/// Allows `&raw const $place_expr` and `&raw mut $place_expr` expressions.

View File

@ -37,6 +37,8 @@ hir_analysis_auto_deref_reached_recursion_limit = reached the recursion limit wh
.label = deref recursion limit reached
.help = consider increasing the recursion limit by adding a `#![recursion_limit = "{$suggested_limit}"]` attribute to your crate (`{$crate_name}`)
hir_analysis_bad_precise_capture = expected {$kind} parameter in `use<...>` precise captures list, found {$found}
hir_analysis_cannot_capture_late_bound_const =
cannot capture late-bound const parameter in {$what}
.label = parameter defined here
@ -214,6 +216,10 @@ hir_analysis_late_bound_lifetime_in_apit = `impl Trait` can only mention lifetim
hir_analysis_late_bound_type_in_apit = `impl Trait` can only mention type parameters from an fn or impl
.label = type parameter declared here
hir_analysis_lifetime_not_captured = `impl Trait` captures lifetime parameter, but it is not mentioned in `use<...>` precise captures list
.label = lifetime captured due to being mentioned in the bounds of the `impl Trait`
.param_label = this lifetime parameter is captured
hir_analysis_lifetimes_or_bounds_mismatch_on_trait =
lifetime parameters or bounds on {$item_kind} `{$ident}` do not match the trait declaration
.label = lifetimes do not match {$item_kind} in trait
@ -339,6 +345,10 @@ hir_analysis_param_in_ty_of_assoc_const_binding =
*[normal] the {$param_def_kind} `{$param_name}` is defined here
}
hir_analysis_param_not_captured = `impl Trait` must mention all {$kind} parameters in scope
.label = {$kind} parameter is implicitly captured by this `impl Trait`
.note = currently, all {$kind} parameters are required to be mentioned in the precise captures list
hir_analysis_paren_sugar_attribute = the `#[rustc_paren_sugar]` attribute is a temporary means of controlling which traits can use parenthetical notation
.help = add `#![feature(unboxed_closures)]` to the crate attributes to use it

View File

@ -1,10 +1,10 @@
use crate::check::intrinsicck::InlineAsmCtxt;
use crate::errors::LinkageType;
use super::compare_impl_item::check_type_bounds;
use super::compare_impl_item::{compare_impl_method, compare_impl_ty};
use super::*;
use rustc_attr as attr;
use rustc_data_structures::unord::UnordSet;
use rustc_errors::{codes::*, MultiSpan};
use rustc_hir as hir;
use rustc_hir::def::{CtorKind, DefKind};
@ -12,6 +12,7 @@ use rustc_hir::Node;
use rustc_infer::infer::{RegionVariableOrigin, TyCtxtInferExt};
use rustc_infer::traits::{Obligation, TraitEngineExt as _};
use rustc_lint_defs::builtin::REPR_TRANSPARENT_EXTERNAL_PRIVATE_FIELDS;
use rustc_middle::middle::resolve_bound_vars::ResolvedArg;
use rustc_middle::middle::stability::EvalResult;
use rustc_middle::traits::ObligationCauseCode;
use rustc_middle::ty::fold::BottomUpFolder;
@ -474,6 +475,94 @@ fn sanity_check_found_hidden_type<'tcx>(
}
}
fn check_opaque_precise_captures<'tcx>(tcx: TyCtxt<'tcx>, opaque_def_id: LocalDefId) {
let hir::OpaqueTy { precise_capturing_args, .. } =
*tcx.hir_node_by_def_id(opaque_def_id).expect_item().expect_opaque_ty();
let Some(precise_capturing_args) = precise_capturing_args else {
// No precise capturing args; nothing to validate
return;
};
let mut expected_captures = UnordSet::default();
for arg in precise_capturing_args {
match *arg {
hir::PreciseCapturingArg::Lifetime(&hir::Lifetime { hir_id, .. })
| hir::PreciseCapturingArg::Param(_, hir_id) => match tcx.named_bound_var(hir_id) {
Some(ResolvedArg::EarlyBound(def_id)) => {
expected_captures.insert(def_id);
}
_ => {
tcx.dcx().span_delayed_bug(
tcx.hir().span(hir_id),
"parameter should have been resolved",
);
}
},
}
}
let variances = tcx.variances_of(opaque_def_id);
let mut def_id = Some(opaque_def_id.to_def_id());
while let Some(generics) = def_id {
let generics = tcx.generics_of(generics);
def_id = generics.parent;
for param in &generics.params {
if expected_captures.contains(&param.def_id) {
assert_eq!(
variances[param.index as usize],
ty::Invariant,
"precise captured param should be invariant"
);
continue;
}
match param.kind {
ty::GenericParamDefKind::Lifetime => {
// Check if the lifetime param was captured but isn't named in the precise captures list.
if variances[param.index as usize] == ty::Invariant {
let param_span =
if let ty::ReEarlyParam(ty::EarlyParamRegion { def_id, .. })
| ty::ReLateParam(ty::LateParamRegion {
bound_region: ty::BoundRegionKind::BrNamed(def_id, _),
..
}) = *tcx
.map_opaque_lifetime_to_parent_lifetime(param.def_id.expect_local())
{
Some(tcx.def_span(def_id))
} else {
None
};
// FIXME(precise_capturing): Structured suggestion for this would be useful
tcx.dcx().emit_err(errors::LifetimeNotCaptured {
use_span: tcx.def_span(param.def_id),
param_span,
opaque_span: tcx.def_span(opaque_def_id),
});
continue;
}
}
ty::GenericParamDefKind::Type { .. } => {
// FIXME(precise_capturing): Structured suggestion for this would be useful
tcx.dcx().emit_err(errors::ParamNotCaptured {
param_span: tcx.def_span(param.def_id),
opaque_span: tcx.def_span(opaque_def_id),
kind: "type",
});
}
ty::GenericParamDefKind::Const { .. } => {
// FIXME(precise_capturing): Structured suggestion for this would be useful
tcx.dcx().emit_err(errors::ParamNotCaptured {
param_span: tcx.def_span(param.def_id),
opaque_span: tcx.def_span(opaque_def_id),
kind: "const",
});
}
}
}
}
}
fn is_enum_of_nonnullable_ptr<'tcx>(
tcx: TyCtxt<'tcx>,
adt_def: AdtDef<'tcx>,
@ -499,7 +588,7 @@ fn check_static_linkage(tcx: TyCtxt<'_>, def_id: LocalDefId) {
ty::Adt(adt_def, args) => !is_enum_of_nonnullable_ptr(tcx, *adt_def, *args),
_ => true,
} {
tcx.dcx().emit_err(LinkageType { span: tcx.def_span(def_id) });
tcx.dcx().emit_err(errors::LinkageType { span: tcx.def_span(def_id) });
}
}
}
@ -566,6 +655,8 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
check_union(tcx, def_id);
}
DefKind::OpaqueTy => {
check_opaque_precise_captures(tcx, def_id);
let origin = tcx.opaque_type_origin(def_id);
if let hir::OpaqueTyOrigin::FnReturn(fn_def_id)
| hir::OpaqueTyOrigin::AsyncFn(fn_def_id) = origin

View File

@ -569,7 +569,13 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
LifetimeName::Error => {}
LifetimeName::ImplicitObjectLifetimeDefault
| LifetimeName::Infer
| LifetimeName::Static => todo!("TODO: Error on invalid lifetime"),
| LifetimeName::Static => {
self.tcx.dcx().emit_err(errors::BadPreciseCapture {
span: lt.ident.span,
kind: "lifetime",
found: format!("`{}`", lt.ident.name),
});
}
},
hir::PreciseCapturingArg::Param(res, hir_id) => match res {
Res::Def(DefKind::TyParam | DefKind::ConstParam, def_id)
@ -577,7 +583,10 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
self.resolve_type_ref(def_id.expect_local(), hir_id);
}
Res::Err => {}
_ => todo!("TODO: Error on invalid param res"),
_ => {
// This is handled in resolve
self.tcx.dcx().delayed_bug(format!("parameter should have been resolved"));
}
},
}
}

View File

@ -10,6 +10,9 @@ use rustc_span::{symbol::Ident, Span, Symbol};
mod pattern_types;
pub use pattern_types::*;
mod precise_captures;
pub(crate) use precise_captures::*;
#[derive(Diagnostic)]
#[diag(hir_analysis_ambiguous_assoc_item)]
pub struct AmbiguousAssocItem<'a> {

View File

@ -0,0 +1,33 @@
use rustc_macros::Diagnostic;
use rustc_span::Span;
#[derive(Diagnostic)]
#[diag(hir_analysis_param_not_captured)]
#[note]
pub struct ParamNotCaptured {
#[primary_span]
pub param_span: Span,
#[label]
pub opaque_span: Span,
pub kind: &'static str,
}
#[derive(Diagnostic)]
#[diag(hir_analysis_lifetime_not_captured)]
pub struct LifetimeNotCaptured {
#[primary_span]
pub use_span: Span,
#[label(hir_analysis_param_label)]
pub param_span: Option<Span>,
#[label]
pub opaque_span: Span,
}
#[derive(Diagnostic)]
#[diag(hir_analysis_bad_precise_capture)]
pub struct BadPreciseCapture {
#[primary_span]
pub span: Span,
pub kind: &'static str,
pub found: String,
}

View File

@ -674,7 +674,7 @@ impl<'a> Parser<'a> {
let use_span = self.prev_token.span;
self.psess.gated_spans.gate(sym::precise_capturing, use_span);
let args = self.parse_precise_capturing_args()?;
Some(args)
Some(P((args, use_span)))
} else {
None
};

View File

@ -1054,7 +1054,10 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
fn visit_precise_capturing_arg(&mut self, arg: &'ast PreciseCapturingArg) {
match arg {
// Lower the lifetime regularly; we'll resolve the lifetime and check
// it's a parameter later on in HIR lowering.
PreciseCapturingArg::Lifetime(_) => visit::walk_precise_capturing_arg(self, arg),
PreciseCapturingArg::Arg(ident, node_id) => {
let ident = ident.normalize_to_macros_2_0();
'found: {
@ -1064,6 +1067,38 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
if let Some(res) = rib_t.bindings.get(&ident).or(rib_v.bindings.get(&ident))
{
self.r.record_partial_res(*node_id, PartialRes::new(*res));
// Validate that this is a parameter
match res {
Res::Def(DefKind::TyParam | DefKind::ConstParam, _)
| Res::SelfTyParam { .. } => {}
Res::SelfTyAlias { .. } => {
self.report_error(
ident.span,
ResolutionError::FailedToResolve {
segment: Some(ident.name),
label: "`Self` cannot be captured because it is not a type parameter".to_string(),
suggestion: None,
module: None,
},
);
}
_ => {
self.report_error(
ident.span,
ResolutionError::FailedToResolve {
segment: Some(ident.name),
label: format!(
"expected type or const parameter, found {}",
res.descr()
),
suggestion: None,
module: None,
},
);
}
}
break 'found;
}
}

View File

@ -0,0 +1,14 @@
#![feature(precise_capturing)]
//~^ WARN the feature `precise_capturing` is incomplete
fn no_elided_lt() -> impl use<'_> Sized {}
//~^ ERROR missing lifetime specifier
//~| ERROR expected lifetime parameter in `use<...>` precise captures list, found `'_`
fn static_lt() -> impl use<'static> Sized {}
//~^ ERROR expected lifetime parameter in `use<...>` precise captures list, found `'static`
fn missing_lt() -> impl use<'missing> Sized {}
//~^ ERROR use of undeclared lifetime name `'missing`
fn main() {}

View File

@ -0,0 +1,45 @@
error[E0106]: missing lifetime specifier
--> $DIR/bad-lifetimes.rs:4:31
|
LL | fn no_elided_lt() -> impl use<'_> Sized {}
| ^^ expected named lifetime parameter
|
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static`, or if you will only have owned values
|
LL | fn no_elided_lt() -> impl use<'static> Sized {}
| ~~~~~~~
error[E0261]: use of undeclared lifetime name `'missing`
--> $DIR/bad-lifetimes.rs:11:29
|
LL | fn missing_lt() -> impl use<'missing> Sized {}
| - ^^^^^^^^ undeclared lifetime
| |
| help: consider introducing lifetime `'missing` here: `<'missing>`
warning: the feature `precise_capturing` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/bad-lifetimes.rs:1:12
|
LL | #![feature(precise_capturing)]
| ^^^^^^^^^^^^^^^^^
|
= note: see issue #123432 <https://github.com/rust-lang/rust/issues/123432> for more information
= note: `#[warn(incomplete_features)]` on by default
error: expected lifetime parameter in `use<...>` precise captures list, found `'_`
--> $DIR/bad-lifetimes.rs:4:31
|
LL | fn no_elided_lt() -> impl use<'_> Sized {}
| ^^
error: expected lifetime parameter in `use<...>` precise captures list, found `'static`
--> $DIR/bad-lifetimes.rs:8:28
|
LL | fn static_lt() -> impl use<'static> Sized {}
| ^^^^^^^
error: aborting due to 4 previous errors; 1 warning emitted
Some errors have detailed explanations: E0106, E0261.
For more information about an error, try `rustc --explain E0106`.

View File

@ -0,0 +1,16 @@
#![feature(precise_capturing)]
//~^ WARN the feature `precise_capturing` is incomplete
fn missing() -> impl use<T> Sized {}
//~^ ERROR could not find type or const parameter
fn missing_self() -> impl use<Self> Sized {}
//~^ ERROR could not find type or const parameter
struct MyType;
impl MyType {
fn self_is_not_param() -> impl use<Self> Sized {}
//~^ ERROR `Self` cannot be captured because it is not a type parameter
}
fn main() {}

View File

@ -0,0 +1,30 @@
error[E0433]: failed to resolve: could not find type or const parameter
--> $DIR/bad-params.rs:4:26
|
LL | fn missing() -> impl use<T> Sized {}
| ^ could not find type or const parameter
error[E0433]: failed to resolve: could not find type or const parameter
--> $DIR/bad-params.rs:7:31
|
LL | fn missing_self() -> impl use<Self> Sized {}
| ^^^^ could not find type or const parameter
error[E0433]: failed to resolve: `Self` cannot be captured because it is not a type parameter
--> $DIR/bad-params.rs:12:40
|
LL | fn self_is_not_param() -> impl use<Self> Sized {}
| ^^^^ `Self` cannot be captured because it is not a type parameter
warning: the feature `precise_capturing` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/bad-params.rs:1:12
|
LL | #![feature(precise_capturing)]
| ^^^^^^^^^^^^^^^^^
|
= note: see issue #123432 <https://github.com/rust-lang/rust/issues/123432> for more information
= note: `#[warn(incomplete_features)]` on by default
error: aborting due to 3 previous errors; 1 warning emitted
For more information about this error, try `rustc --explain E0433`.

View File

@ -0,0 +1,7 @@
#![feature(precise_capturing)]
//~^ WARN the feature `precise_capturing` is incomplete
fn constant<const C: usize>() -> impl use<> Sized {}
//~^ ERROR `impl Trait` must mention all const parameters in scope
fn main() {}

View File

@ -0,0 +1,19 @@
warning: the feature `precise_capturing` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/forgot-to-capture-const.rs:1:12
|
LL | #![feature(precise_capturing)]
| ^^^^^^^^^^^^^^^^^
|
= note: see issue #123432 <https://github.com/rust-lang/rust/issues/123432> for more information
= note: `#[warn(incomplete_features)]` on by default
error: `impl Trait` must mention all const parameters in scope
--> $DIR/forgot-to-capture-const.rs:4:13
|
LL | fn constant<const C: usize>() -> impl use<> Sized {}
| ^^^^^^^^^^^^^^ ---------------- const parameter is implicitly captured by this `impl Trait`
|
= note: currently, all const parameters are required to be mentioned in the precise captures list
error: aborting due to 1 previous error; 1 warning emitted

View File

@ -0,0 +1,7 @@
#![feature(precise_capturing)]
//~^ WARN the feature `precise_capturing` is incomplete
fn type_param<T>() -> impl use<> Sized {}
//~^ ERROR `impl Trait` must mention all type parameters in scope
fn main() {}

View File

@ -0,0 +1,19 @@
warning: the feature `precise_capturing` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/forgot-to-capture-lifetime.rs:1:12
|
LL | #![feature(precise_capturing)]
| ^^^^^^^^^^^^^^^^^
|
= note: see issue #123432 <https://github.com/rust-lang/rust/issues/123432> for more information
= note: `#[warn(incomplete_features)]` on by default
error: `impl Trait` must mention all type parameters in scope
--> $DIR/forgot-to-capture-lifetime.rs:4:15
|
LL | fn type_param<T>() -> impl use<> Sized {}
| ^ ---------------- type parameter is implicitly captured by this `impl Trait`
|
= note: currently, all type parameters are required to be mentioned in the precise captures list
error: aborting due to 1 previous error; 1 warning emitted

View File

@ -0,0 +1,10 @@
#![feature(precise_capturing)]
//~^ WARN the feature `precise_capturing` is incomplete
fn lifetime_in_bounds<'a>(x: &'a ()) -> impl use<> Into<&'a ()> { x }
//~^ ERROR `impl Trait` captures lifetime parameter, but it is not mentioned in `use<...>` precise captures list
fn lifetime_in_hidden<'a>(x: &'a ()) -> impl use<> Sized { x }
//~^ ERROR hidden type for `impl Sized` captures lifetime that does not appear in bounds
fn main() {}

View File

@ -0,0 +1,35 @@
warning: the feature `precise_capturing` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/forgot-to-capture-type.rs:1:12
|
LL | #![feature(precise_capturing)]
| ^^^^^^^^^^^^^^^^^
|
= note: see issue #123432 <https://github.com/rust-lang/rust/issues/123432> for more information
= note: `#[warn(incomplete_features)]` on by default
error: `impl Trait` captures lifetime parameter, but it is not mentioned in `use<...>` precise captures list
--> $DIR/forgot-to-capture-type.rs:4:58
|
LL | fn lifetime_in_bounds<'a>(x: &'a ()) -> impl use<> Into<&'a ()> { x }
| -- -----------------^^----
| | |
| | lifetime captured due to being mentioned in the bounds of the `impl Trait`
| this lifetime parameter is captured
error[E0700]: hidden type for `impl Sized` captures lifetime that does not appear in bounds
--> $DIR/forgot-to-capture-type.rs:7:60
|
LL | fn lifetime_in_hidden<'a>(x: &'a ()) -> impl use<> Sized { x }
| -- ---------------- ^
| | |
| | opaque type defined here
| hidden type `&'a ()` captures the lifetime `'a` as defined here
|
help: to declare that `impl Sized` captures `'a`, you can add an explicit `'a` lifetime bound
|
LL | fn lifetime_in_hidden<'a>(x: &'a ()) -> impl use<> Sized + 'a { x }
| ++++
error: aborting due to 2 previous errors; 1 warning emitted
For more information about this error, try `rustc --explain E0700`.

View File

@ -15,4 +15,4 @@ impl Trait<'_> for () {
fn hello() -> impl for<'a> Trait<'a, Item = impl use<> IntoIterator> {}
fn main() {}
fn main() {}