Parsing , pre-lowering support for precise captures
This commit is contained in:
parent
99d0186b1d
commit
a076eae0d2
@ -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),
|
||||
ImplTrait(NodeId, GenericBounds, Option<P<GenericArgs>>),
|
||||
/// No-op; kept solely so that we can pretty-print faithfully.
|
||||
Paren(P<Ty>),
|
||||
/// Unused for now.
|
||||
|
@ -518,9 +518,12 @@ pub fn noop_visit_ty<T: MutVisitor>(ty: &mut P<Ty>, vis: &mut T) {
|
||||
TyKind::TraitObject(bounds, _syntax) => {
|
||||
visit_vec(bounds, |bound| vis.visit_param_bound(bound))
|
||||
}
|
||||
TyKind::ImplTrait(id, bounds) => {
|
||||
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| {
|
||||
vis.visit_generic_args(precise_capturing);
|
||||
});
|
||||
}
|
||||
TyKind::MacCall(mac) => vis.visit_mac_call(mac),
|
||||
TyKind::AnonStruct(id, fields) | TyKind::AnonUnion(id, fields) => {
|
||||
|
@ -457,8 +457,9 @@ pub fn walk_ty<'a, V: Visitor<'a>>(visitor: &mut V, typ: &'a Ty) -> V::Result {
|
||||
TyKind::TraitObject(bounds, ..) => {
|
||||
walk_list!(visitor, visit_param_bound, bounds, BoundKind::TraitObject);
|
||||
}
|
||||
TyKind::ImplTrait(_, bounds) => {
|
||||
TyKind::ImplTrait(_, bounds, precise_capturing) => {
|
||||
walk_list!(visitor, visit_param_bound, bounds, BoundKind::Impl);
|
||||
visit_opt!(visitor, visit_generic_args, precise_capturing);
|
||||
}
|
||||
TyKind::Typeof(expression) => try_visit!(visitor.visit_anon_const(expression)),
|
||||
TyKind::Infer | TyKind::ImplicitSelf | TyKind::Dummy | TyKind::Err(_) => {}
|
||||
|
@ -1398,7 +1398,8 @@ fn lower_ty_direct(&mut self, t: &Ty, itctx: ImplTraitContext) -> hir::Ty<'hir>
|
||||
});
|
||||
hir::TyKind::TraitObject(bounds, lifetime_bound, *kind)
|
||||
}
|
||||
TyKind::ImplTrait(def_node_id, bounds) => {
|
||||
TyKind::ImplTrait(def_node_id, bounds, precise_capturing) => {
|
||||
assert!(precise_capturing.is_none(), "precise captures not supported yet!");
|
||||
let span = t.span;
|
||||
match itctx {
|
||||
ImplTraitContext::OpaqueTy { origin, fn_kind } => self.lower_opaque_impl_trait(
|
||||
|
@ -737,7 +737,7 @@ fn visit_ty_common(&mut self, ty: &'a Ty) {
|
||||
}
|
||||
}
|
||||
}
|
||||
TyKind::ImplTrait(_, bounds) => {
|
||||
TyKind::ImplTrait(_, bounds, _) => {
|
||||
if self.is_impl_trait_banned {
|
||||
self.dcx().emit_err(errors::ImplTraitPath { span: ty.span });
|
||||
}
|
||||
|
@ -569,6 +569,7 @@ macro_rules! gate_all {
|
||||
gate_all!(fn_delegation, "functions delegation is not yet fully implemented");
|
||||
gate_all!(postfix_match, "postfix match is experimental");
|
||||
gate_all!(mut_ref, "mutable by-reference bindings are experimental");
|
||||
gate_all!(precise_capturing, "precise captures on `impl Trait` are experimental");
|
||||
|
||||
if !visitor.features.never_patterns {
|
||||
if let Some(spans) = spans.get(&sym::never_patterns) {
|
||||
|
@ -1150,7 +1150,8 @@ pub fn print_type(&mut self, ty: &ast::Ty) {
|
||||
}
|
||||
self.print_type_bounds(bounds);
|
||||
}
|
||||
ast::TyKind::ImplTrait(_, bounds) => {
|
||||
ast::TyKind::ImplTrait(_, bounds, _precise_capturing) => {
|
||||
// TODO(precise_capturing):
|
||||
self.word_nbsp("impl");
|
||||
self.print_type_bounds(bounds);
|
||||
}
|
||||
|
@ -535,6 +535,8 @@ pub fn internal(&self, feature: Symbol) -> bool {
|
||||
(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
|
||||
|
@ -1235,7 +1235,7 @@ fn check_ty(&mut self, cx: &EarlyContext<'_>, ty: &ast::Ty) {
|
||||
ast::TyKind::TraitObject(..) => {}
|
||||
ast::TyKind::BareFn(b)
|
||||
if self.with_self_ty_parens && b.generic_params.len() > 0 => {}
|
||||
ast::TyKind::ImplTrait(_, bounds) if bounds.len() > 1 => {}
|
||||
ast::TyKind::ImplTrait(_, bounds, _) if bounds.len() > 1 => {}
|
||||
_ => {
|
||||
let spans = if !ty.span.from_expansion() {
|
||||
r.span
|
||||
|
@ -62,7 +62,7 @@ fn parse_ty_param(&mut self, preceding_attrs: AttrVec) -> PResult<'a, GenericPar
|
||||
let snapshot = self.create_snapshot_for_diagnostic();
|
||||
match self.parse_ty() {
|
||||
Ok(p) => {
|
||||
if let TyKind::ImplTrait(_, bounds) = &p.kind {
|
||||
if let TyKind::ImplTrait(_, bounds, None) = &p.kind {
|
||||
let span = impl_span.to(self.token.span.shrink_to_lo());
|
||||
let mut err = self.dcx().struct_span_err(
|
||||
span,
|
||||
|
@ -625,7 +625,7 @@ fn parse_item_impl(
|
||||
// This notably includes paths passed through `ty` macro fragments (#46438).
|
||||
TyKind::Path(None, path) => path,
|
||||
other => {
|
||||
if let TyKind::ImplTrait(_, bounds) = other
|
||||
if let TyKind::ImplTrait(_, bounds, None) = other
|
||||
&& let [bound] = bounds.as_slice()
|
||||
{
|
||||
// Suggest removing extra `impl` keyword:
|
||||
|
@ -316,7 +316,7 @@ fn parse_ty_common(
|
||||
TyKind::TraitObject(bounds, TraitObjectSyntax::Dyn)
|
||||
}
|
||||
(TyKind::TraitObject(bounds, _), kw::Impl) => {
|
||||
TyKind::ImplTrait(ast::DUMMY_NODE_ID, bounds)
|
||||
TyKind::ImplTrait(ast::DUMMY_NODE_ID, bounds, None)
|
||||
}
|
||||
_ => return Err(err),
|
||||
};
|
||||
@ -655,7 +655,6 @@ fn recover_fn_ptr_with_generics(
|
||||
|
||||
/// Parses an `impl B0 + ... + Bn` type.
|
||||
fn parse_impl_ty(&mut self, impl_dyn_multi: &mut bool) -> PResult<'a, TyKind> {
|
||||
// Always parse bounds greedily for better error recovery.
|
||||
if self.token.is_lifetime() {
|
||||
self.look_ahead(1, |t| {
|
||||
if let token::Ident(sym, _) = t.kind {
|
||||
@ -669,9 +668,26 @@ fn parse_impl_ty(&mut self, impl_dyn_multi: &mut bool) -> PResult<'a, TyKind> {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// parse precise captures, if any.
|
||||
let precise_capturing = if self.eat_keyword(kw::Use) {
|
||||
self.expect_lt()?;
|
||||
let use_span = self.prev_token.span;
|
||||
self.psess.gated_spans.gate(sym::precise_capturing, use_span);
|
||||
let lo = self.token.span;
|
||||
let args = self.parse_angle_args(None)?;
|
||||
self.expect_gt()?;
|
||||
Some(ast::AngleBracketedArgs { args, span: lo.to(self.prev_token.span) }.into())
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
// Always parse bounds greedily for better error recovery.
|
||||
let bounds = self.parse_generic_bounds()?;
|
||||
|
||||
*impl_dyn_multi = bounds.len() > 1 || self.prev_token.kind == TokenKind::BinOp(token::Plus);
|
||||
Ok(TyKind::ImplTrait(ast::DUMMY_NODE_ID, bounds))
|
||||
|
||||
Ok(TyKind::ImplTrait(ast::DUMMY_NODE_ID, bounds, precise_capturing))
|
||||
}
|
||||
|
||||
/// Is a `dyn B0 + ... + Bn` type allowed here?
|
||||
@ -957,7 +973,7 @@ fn parse_generic_ty_bound(
|
||||
Applicability::MaybeIncorrect,
|
||||
)
|
||||
}
|
||||
TyKind::ImplTrait(_, bounds)
|
||||
TyKind::ImplTrait(_, bounds, None)
|
||||
if let [GenericBound::Trait(tr, ..), ..] = bounds.as_slice() =>
|
||||
{
|
||||
(
|
||||
|
@ -793,7 +793,7 @@ fn visit_ty(&mut self, ty: &'ast Ty) {
|
||||
self.r.record_partial_res(ty.id, PartialRes::new(res));
|
||||
visit::walk_ty(self, ty)
|
||||
}
|
||||
TyKind::ImplTrait(node_id, _) => {
|
||||
TyKind::ImplTrait(node_id, _, _) => {
|
||||
let candidates = self.lifetime_elision_candidates.take();
|
||||
visit::walk_ty(self, ty);
|
||||
self.record_lifetime_params_for_impl_trait(*node_id);
|
||||
|
@ -3121,7 +3121,7 @@ fn add_missing_lifetime_specifiers_label(
|
||||
.inputs
|
||||
.iter()
|
||||
.filter_map(|param| match ¶m.ty.kind {
|
||||
TyKind::ImplTrait(_, bounds) => Some(bounds),
|
||||
TyKind::ImplTrait(_, bounds, _) => Some(bounds),
|
||||
_ => None,
|
||||
})
|
||||
.flat_map(|bounds| bounds.into_iter())
|
||||
|
@ -1375,6 +1375,7 @@
|
||||
powif32,
|
||||
powif64,
|
||||
pre_dash_lto: "pre-lto",
|
||||
precise_capturing,
|
||||
precise_pointer_size_matching,
|
||||
pref_align_of,
|
||||
prefetch_read_data,
|
||||
|
Loading…
Reference in New Issue
Block a user