Validation and other things
This commit is contained in:
parent
41cf87b71b
commit
42ba57c013
@ -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.
|
||||
|
@ -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) => {
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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}`
|
||||
|
@ -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,
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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) => {
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
||||
|
@ -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(¶m.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
|
||||
|
@ -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"));
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -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> {
|
||||
|
33
compiler/rustc_hir_analysis/src/errors/precise_captures.rs
Normal file
33
compiler/rustc_hir_analysis/src/errors/precise_captures.rs
Normal 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,
|
||||
}
|
@ -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
|
||||
};
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
14
tests/ui/impl-trait/precise-capturing/bad-lifetimes.rs
Normal file
14
tests/ui/impl-trait/precise-capturing/bad-lifetimes.rs
Normal 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() {}
|
45
tests/ui/impl-trait/precise-capturing/bad-lifetimes.stderr
Normal file
45
tests/ui/impl-trait/precise-capturing/bad-lifetimes.stderr
Normal 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`.
|
16
tests/ui/impl-trait/precise-capturing/bad-params.rs
Normal file
16
tests/ui/impl-trait/precise-capturing/bad-params.rs
Normal 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() {}
|
30
tests/ui/impl-trait/precise-capturing/bad-params.stderr
Normal file
30
tests/ui/impl-trait/precise-capturing/bad-params.stderr
Normal 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`.
|
@ -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() {}
|
@ -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
|
||||
|
@ -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() {}
|
@ -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
|
||||
|
@ -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() {}
|
@ -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`.
|
@ -15,4 +15,4 @@ impl Trait<'_> for () {
|
||||
|
||||
fn hello() -> impl for<'a> Trait<'a, Item = impl use<> IntoIterator> {}
|
||||
|
||||
fn main() {}
|
||||
fn main() {}
|
||||
|
Loading…
x
Reference in New Issue
Block a user