Skip to content

Commit a076eae

Browse files
Parsing , pre-lowering support for precise captures
1 parent 99d0186 commit a076eae

File tree

15 files changed

+41
-15
lines changed

15 files changed

+41
-15
lines changed

compiler/rustc_ast/src/ast.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2132,7 +2132,7 @@ pub enum TyKind {
21322132
/// The `NodeId` exists to prevent lowering from having to
21332133
/// generate `NodeId`s on the fly, which would complicate
21342134
/// the generation of opaque `type Foo = impl Trait` items significantly.
2135-
ImplTrait(NodeId, GenericBounds),
2135+
ImplTrait(NodeId, GenericBounds, Option<P<GenericArgs>>),
21362136
/// No-op; kept solely so that we can pretty-print faithfully.
21372137
Paren(P<Ty>),
21382138
/// Unused for now.

compiler/rustc_ast/src/mut_visit.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -518,9 +518,12 @@ pub fn noop_visit_ty<T: MutVisitor>(ty: &mut P<Ty>, vis: &mut T) {
518518
TyKind::TraitObject(bounds, _syntax) => {
519519
visit_vec(bounds, |bound| vis.visit_param_bound(bound))
520520
}
521-
TyKind::ImplTrait(id, bounds) => {
521+
TyKind::ImplTrait(id, bounds, precise_capturing) => {
522522
vis.visit_id(id);
523523
visit_vec(bounds, |bound| vis.visit_param_bound(bound));
524+
visit_opt(precise_capturing, |precise_capturing| {
525+
vis.visit_generic_args(precise_capturing);
526+
});
524527
}
525528
TyKind::MacCall(mac) => vis.visit_mac_call(mac),
526529
TyKind::AnonStruct(id, fields) | TyKind::AnonUnion(id, fields) => {

compiler/rustc_ast/src/visit.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -457,8 +457,9 @@ pub fn walk_ty<'a, V: Visitor<'a>>(visitor: &mut V, typ: &'a Ty) -> V::Result {
457457
TyKind::TraitObject(bounds, ..) => {
458458
walk_list!(visitor, visit_param_bound, bounds, BoundKind::TraitObject);
459459
}
460-
TyKind::ImplTrait(_, bounds) => {
460+
TyKind::ImplTrait(_, bounds, precise_capturing) => {
461461
walk_list!(visitor, visit_param_bound, bounds, BoundKind::Impl);
462+
visit_opt!(visitor, visit_generic_args, precise_capturing);
462463
}
463464
TyKind::Typeof(expression) => try_visit!(visitor.visit_anon_const(expression)),
464465
TyKind::Infer | TyKind::ImplicitSelf | TyKind::Dummy | TyKind::Err(_) => {}

compiler/rustc_ast_lowering/src/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1398,7 +1398,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
13981398
});
13991399
hir::TyKind::TraitObject(bounds, lifetime_bound, *kind)
14001400
}
1401-
TyKind::ImplTrait(def_node_id, bounds) => {
1401+
TyKind::ImplTrait(def_node_id, bounds, precise_capturing) => {
1402+
assert!(precise_capturing.is_none(), "precise captures not supported yet!");
14021403
let span = t.span;
14031404
match itctx {
14041405
ImplTraitContext::OpaqueTy { origin, fn_kind } => self.lower_opaque_impl_trait(

compiler/rustc_ast_passes/src/ast_validation.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -737,7 +737,7 @@ impl<'a> AstValidator<'a> {
737737
}
738738
}
739739
}
740-
TyKind::ImplTrait(_, bounds) => {
740+
TyKind::ImplTrait(_, bounds, _) => {
741741
if self.is_impl_trait_banned {
742742
self.dcx().emit_err(errors::ImplTraitPath { span: ty.span });
743743
}

compiler/rustc_ast_passes/src/feature_gate.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -569,6 +569,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
569569
gate_all!(fn_delegation, "functions delegation is not yet fully implemented");
570570
gate_all!(postfix_match, "postfix match is experimental");
571571
gate_all!(mut_ref, "mutable by-reference bindings are experimental");
572+
gate_all!(precise_capturing, "precise captures on `impl Trait` are experimental");
572573

573574
if !visitor.features.never_patterns {
574575
if let Some(spans) = spans.get(&sym::never_patterns) {

compiler/rustc_ast_pretty/src/pprust/state.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1150,7 +1150,8 @@ impl<'a> State<'a> {
11501150
}
11511151
self.print_type_bounds(bounds);
11521152
}
1153-
ast::TyKind::ImplTrait(_, bounds) => {
1153+
ast::TyKind::ImplTrait(_, bounds, _precise_capturing) => {
1154+
// TODO(precise_capturing):
11541155
self.word_nbsp("impl");
11551156
self.print_type_bounds(bounds);
11561157
}

compiler/rustc_feature/src/unstable.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -535,6 +535,8 @@ declare_features! (
535535
(unstable, must_not_suspend, "1.57.0", Some(83310)),
536536
/// Allows `mut ref` and `mut ref mut` identifier patterns.
537537
(incomplete, mut_ref, "CURRENT_RUSTC_VERSION", Some(123076)),
538+
/// Allows `use<'a, 'b, A, B>` in `impl use<...> Trait` for precise capture of generic args.
539+
(incomplete, precise_capturing, "CURRENT_RUSTC_VERSION", Some(123432)),
538540
/// Allows using `#[naked]` on functions.
539541
(unstable, naked_functions, "1.9.0", Some(90957)),
540542
/// Allows specifying the as-needed link modifier

compiler/rustc_lint/src/unused.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1235,7 +1235,7 @@ impl EarlyLintPass for UnusedParens {
12351235
ast::TyKind::TraitObject(..) => {}
12361236
ast::TyKind::BareFn(b)
12371237
if self.with_self_ty_parens && b.generic_params.len() > 0 => {}
1238-
ast::TyKind::ImplTrait(_, bounds) if bounds.len() > 1 => {}
1238+
ast::TyKind::ImplTrait(_, bounds, _) if bounds.len() > 1 => {}
12391239
_ => {
12401240
let spans = if !ty.span.from_expansion() {
12411241
r.span

compiler/rustc_parse/src/parser/generics.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ impl<'a> Parser<'a> {
6262
let snapshot = self.create_snapshot_for_diagnostic();
6363
match self.parse_ty() {
6464
Ok(p) => {
65-
if let TyKind::ImplTrait(_, bounds) = &p.kind {
65+
if let TyKind::ImplTrait(_, bounds, None) = &p.kind {
6666
let span = impl_span.to(self.token.span.shrink_to_lo());
6767
let mut err = self.dcx().struct_span_err(
6868
span,

compiler/rustc_parse/src/parser/item.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -625,7 +625,7 @@ impl<'a> Parser<'a> {
625625
// This notably includes paths passed through `ty` macro fragments (#46438).
626626
TyKind::Path(None, path) => path,
627627
other => {
628-
if let TyKind::ImplTrait(_, bounds) = other
628+
if let TyKind::ImplTrait(_, bounds, None) = other
629629
&& let [bound] = bounds.as_slice()
630630
{
631631
// Suggest removing extra `impl` keyword:

compiler/rustc_parse/src/parser/ty.rs

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,7 @@ impl<'a> Parser<'a> {
316316
TyKind::TraitObject(bounds, TraitObjectSyntax::Dyn)
317317
}
318318
(TyKind::TraitObject(bounds, _), kw::Impl) => {
319-
TyKind::ImplTrait(ast::DUMMY_NODE_ID, bounds)
319+
TyKind::ImplTrait(ast::DUMMY_NODE_ID, bounds, None)
320320
}
321321
_ => return Err(err),
322322
};
@@ -655,7 +655,6 @@ impl<'a> Parser<'a> {
655655

656656
/// Parses an `impl B0 + ... + Bn` type.
657657
fn parse_impl_ty(&mut self, impl_dyn_multi: &mut bool) -> PResult<'a, TyKind> {
658-
// Always parse bounds greedily for better error recovery.
659658
if self.token.is_lifetime() {
660659
self.look_ahead(1, |t| {
661660
if let token::Ident(sym, _) = t.kind {
@@ -669,9 +668,26 @@ impl<'a> Parser<'a> {
669668
}
670669
})
671670
}
671+
672+
// parse precise captures, if any.
673+
let precise_capturing = if self.eat_keyword(kw::Use) {
674+
self.expect_lt()?;
675+
let use_span = self.prev_token.span;
676+
self.psess.gated_spans.gate(sym::precise_capturing, use_span);
677+
let lo = self.token.span;
678+
let args = self.parse_angle_args(None)?;
679+
self.expect_gt()?;
680+
Some(ast::AngleBracketedArgs { args, span: lo.to(self.prev_token.span) }.into())
681+
} else {
682+
None
683+
};
684+
685+
// Always parse bounds greedily for better error recovery.
672686
let bounds = self.parse_generic_bounds()?;
687+
673688
*impl_dyn_multi = bounds.len() > 1 || self.prev_token.kind == TokenKind::BinOp(token::Plus);
674-
Ok(TyKind::ImplTrait(ast::DUMMY_NODE_ID, bounds))
689+
690+
Ok(TyKind::ImplTrait(ast::DUMMY_NODE_ID, bounds, precise_capturing))
675691
}
676692

677693
/// Is a `dyn B0 + ... + Bn` type allowed here?
@@ -957,7 +973,7 @@ impl<'a> Parser<'a> {
957973
Applicability::MaybeIncorrect,
958974
)
959975
}
960-
TyKind::ImplTrait(_, bounds)
976+
TyKind::ImplTrait(_, bounds, None)
961977
if let [GenericBound::Trait(tr, ..), ..] = bounds.as_slice() =>
962978
{
963979
(

compiler/rustc_resolve/src/late.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -793,7 +793,7 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
793793
self.r.record_partial_res(ty.id, PartialRes::new(res));
794794
visit::walk_ty(self, ty)
795795
}
796-
TyKind::ImplTrait(node_id, _) => {
796+
TyKind::ImplTrait(node_id, _, _) => {
797797
let candidates = self.lifetime_elision_candidates.take();
798798
visit::walk_ty(self, ty);
799799
self.record_lifetime_params_for_impl_trait(*node_id);

compiler/rustc_resolve/src/late/diagnostics.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3121,7 +3121,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
31213121
.inputs
31223122
.iter()
31233123
.filter_map(|param| match &param.ty.kind {
3124-
TyKind::ImplTrait(_, bounds) => Some(bounds),
3124+
TyKind::ImplTrait(_, bounds, _) => Some(bounds),
31253125
_ => None,
31263126
})
31273127
.flat_map(|bounds| bounds.into_iter())

compiler/rustc_span/src/symbol.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1375,6 +1375,7 @@ symbols! {
13751375
powif32,
13761376
powif64,
13771377
pre_dash_lto: "pre-lto",
1378+
precise_capturing,
13781379
precise_pointer_size_matching,
13791380
pref_align_of,
13801381
prefetch_read_data,

0 commit comments

Comments
 (0)