8000 Rollup of 5 pull requests by Dylan-DPC · Pull Request #99231 · rust-lang/rust · GitHub
[go: up one dir, main page]

Skip to content

Rollup of 5 pull requests #99231

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 24 commits into from
Jul 14, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
9395103
Give a better error when `x dist` fails for an optional tool
jyn514 Jul 11, 2022
40ae7b5
Parse closure binders
WaffleLapkin Jun 2, 2022
97fcead
--bless tests
WaffleLapkin Jun 2, 2022
f89ef3c
Comment out expr size check
WaffleLapkin Jul 12, 2022
c2dbd62
Lower closure binders to hir & properly check them
WaffleLapkin Jul 12, 2022
0c28484
make for<> in closures a possible place to suggest adding named lifetime
WaffleLapkin Jun 30, 2022
577f3c6
add test for implicit stuff in signatures of closures with `for<>`
WaffleLapkin Jun 24, 2022
3ebb852
Add `LifetimeBinderKind::Closure`
WaffleLapkin Jul 3, 2022
df4fee9
Add an indirection for closures in `hir::ExprKind`
WaffleLapkin Jul 11, 2022
d2923b4
Add back expr size checks
WaffleLapkin Jul 11, 2022
b504a18
implement rustfmt formatting for `for<>` closure binders
WaffleLapkin Jun 30, 2022
30a3673
Add rustfmt test for formatting `for<>` before closures
WaffleLapkin Jul 3, 2022
9aa142b
Fix clippy build
WaffleLapkin Jun 30, 2022
031b2c5
Always use CreateParameter mode for function definitions.
cjgillot Jun 19, 2022
c7ac816
Clippy fallout.
cjgillot Jun 4, 2022
3b1b38d
Bless ui-fulldeps tests.
cjgillot Jun 4, 2022
5a20834
Add feature gate.
cjgillot Jun 22, 2022
f94484f
reduce scope of allow(rustc::potential_query_instability) in rustc_span
NiklasJonsson Jul 10, 2022
d431338
Stabilize `core::ffi:c_*` and rexport in `std::ffi`
joshtriplett Jun 20, 2022
f5e9cb5
Rollup merge of #97720 - cjgillot:all-fresh, r=petrochenkov
Dylan-DPC Jul 14, 2022
103b860
Rollup merge of #98315 - joshtriplett:stabilize-core-ffi-c, r=Mark-Si…
Dylan-DPC Jul 14, 2022
e5a86d7
Rollup merge of #98705 - WaffleLapkin:closure_binder, r=cjgillot
Dylan-DPC Jul 14, 2022
85159a4
Rollup merge of #99126 - NiklasJonsson:84447/rustc_span, r=petrochenkov
Dylan-DPC Jul 14, 2022
c1b43ef
Rollup merge of #99139 - jyn514:dist-tool-help, r=Mark-Simulacrum
Dylan-DPC Jul 14, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8000
Prev Previous commit
Next Next commit
Lower closure binders to hir & properly check them
  • Loading branch information
WaffleLapkin committed Jul 12, 2022
commit c2dbd62c7c60cd4017c9d499101e40c129e4bc61
2 changes: 1 addition & 1 deletion compiler/rustc_ast/src/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -642,7 +642,7 @@ pub fn walk_generics<'a, V: Visitor<'a>>(visitor: &mut V, generics: &'a Generics
pub fn walk_closure_binder<'a, V: Visitor<'a>>(visitor: &mut V, binder: &'a ClosureBinder) {
match binder {
ClosureBinder::NotPresent => {}
ClosureBinder::For { span: _, generic_params } => {
ClosureBinder::For { generic_params, span: _ } => {
walk_list!(visitor, visit_generic_param, generic_params)
}
}
Expand Down
48 changes: 29 additions & 19 deletions compiler/rustc_ast_lowering/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -609,6 +609,7 @@ impl<'hir> LoweringContext<'_, 'hir> {

// `static |_task_context| -> <ret_ty> { body }`:
let generator_kind = hir::ExprKind::Closure {
binder: &hir::ClosureBinder::Default,
capture_clause,
bound_generic_params: &[],
fn_decl,
Expand Down Expand Up @@ -842,15 +843,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
body: &Expr,
fn_decl_span: Span,
) -> hir::ExprKind<'hir> {
// FIXME(waffle): lower binder
if let &ClosureBinder::For { span, .. } = binder {
self.sess
.struct_span_err(span, "`for<...>` binders for closures are not yet supported")
.help("consider removing `for<...>`")
.emit();
}
let (binder_clause, generic_params) = self.lower_closure_binder(binder);

let (body, generator_option) = self.with_new_scopes(move |this| {
let (body_id, generator_option) = self.with_new_scopes(move |this| {
let prev = this.current_item;
this.current_item = Some(fn_decl_span);
let mut generator_kind = None;
Expand All @@ -865,15 +860,16 @@ impl<'hir> LoweringContext<'_, 'hir> {
(body_id, generator_option)
});

self.with_lifetime_binder(closure_id, &[], |this, bound_generic_params| {
self.with_lifetime_binder(closure_id, generic_params, |this, bound_generic_params| {
// Lower outside new scope to preserve `is_in_loop_condition`.
let fn_decl = this.lower_fn_decl(decl, None, FnDeclKind::Closure, None);

hir::ExprKind::Closure {
binder: binder_clause,
capture_clause,
bound_generic_params,
fn_decl,
body,
body: body_id,
fn_decl_span: this.lower_span(fn_decl_span),
movability: generator_option,
}
Expand Down Expand Up @@ -918,6 +914,21 @@ impl<'hir> LoweringContext<'_, 'hir> {
}
}

fn lower_closure_binder<'c>(
&mut self,
binder: &'c ClosureBinder,
) -> (&'hir hir::ClosureBinder, &'c [GenericParam]) {
let (binder, params) = match binder {
ClosureBinder::NotPresent => (hir::ClosureBinder::Default, &[][..]),
&ClosureBinder::For { span, ref generic_params } => {
let span = self.lower_span(span);
(hir::ClosureBinder::For { span }, &**generic_params)
}
};

(self.arena.alloc(binder), params)
}

fn lower_expr_async_closure(
&mut self,
binder: &ClosureBinder,
Expand All @@ -928,17 +939,15 @@ impl<'hir> LoweringContext<'_, 'hir> {
body: &Expr,
fn_decl_span: Span,
) -> hir::ExprKind<'hir> {
// FIXME(waffle): lower binder
if let &ClosureBinder::For { span, .. } = binder {
self.sess
.struct_span_err(
span,
"`for<...>` binders for async closures are not yet supported",
)
.help("consider removing `for<...>`")
.emit();
self.tcx.sess.span_err(
span,
"`for<...>` binders on `async` closures are not currently supported",
);
}

let (binder_clause, generic_params) = self.lower_closure_binder(binder);

let outer_decl =
FnDecl { inputs: decl.inputs.clone(), output: FnRetTy::Default(fn_decl_span) };

Expand Down Expand Up @@ -976,13 +985,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
body_id
});

self.with_lifetime_binder(closure_id, &[], |this, bound_generic_params| {
self.with_lifetime_binder(closure_id, generic_params, |this, bound_generic_params| {
// We need to lower the declaration outside the new scope, because we
// have to conserve the state of being inside a loop condition for the
// closure argument types.
let fn_decl = this.lower_fn_decl(&outer_decl, None, FnDeclKind::Closure, None);

hir::ExprKind::Closure {
binder: binder_clause,
capture_clause,
bound_generic_params,
fn_decl,
Expand Down
12 changes: 12 additions & 0 deletions compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1931,6 +1931,7 @@ pub enum ExprKind<'hir> {
/// This may also be a generator literal or an `async block` as indicated by the
/// `Option<Movability>`.
Closure {
binder: &'hir ClosureBinder,
capture_clause: CaptureBy,
bound_generic_params: &'hir [GenericParam<'hir>],
fn_decl: &'hir FnDecl<'hir>,
Expand Down Expand Up @@ -2715,6 +2716,17 @@ impl FnRetTy<'_> {
}
}

/// Represents `for<...>` binder before a closure
#[derive(Copy, Clone, Debug, HashStable_Generic)]
pub enum ClosureBinder {
/// Binder is not specified.
Default,
/// Binder is specified.
///
/// Span points to the whole `for<...>`.
For { span: Span },
}

#[derive(Encodable, Debug, HashStable_Generic)]
pub struct Mod<'hir> {
pub spans: ModSpans,
Expand Down
11 changes: 9 additions & 2 deletions compiler/rustc_hir/src/intravisit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -925,7 +925,7 @@ pub fn walk_fn_kind<'v, V: Visitor<'v>>(visitor: &mut V, function_kind: FnKind<'
FnKind::ItemFn(_, generics, ..) => {
visitor.visit_generics(generics);
}
FnKind::Method(..) | FnKind::Closure => {}
FnKind::Closure | FnKind::Method(..) => {}
}
}

Expand Down Expand Up @@ -1145,6 +1145,7 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>)
walk_list!(visitor, visit_arm, arms);
}
ExprKind::Closure {
binder: _,
bound_generic_params,
ref fn_decl,
body,
Expand All @@ -1153,7 +1154,13 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>)
movability: _,
} => {
walk_list!(visitor, visit_generic_param, bound_generic_params);
visitor.visit_fn(FnKind::Closure, fn_decl, body, expression.span, expression.hir_id)
visitor.visit_fn(
FnKind::Closure,
fn_decl,
body,
expression.span,
expression.hir_id,
)
}
ExprKind::Block(ref block, ref opt_label) => {
walk_list!(visitor, visit_label, opt_label);
Expand Down
40 changes: 39 additions & 1 deletion compiler/rustc_hir_pretty/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use rustc_ast_pretty::pp::Breaks::{Consistent, Inconsistent};
use rustc_ast_pretty::pp::{self, Breaks};
use rustc_ast_pretty::pprust::{Comments, PrintState};
use rustc_hir as hir;
use rustc_hir::LifetimeParamKind;
use rustc_hir::{GenericArg, GenericParam, GenericParamKind, Node, Term};
use rustc_hir::{GenericBound, PatKind, RangeEnd, TraitBoundModifier};
use rustc_span::source_map::SourceMap;
Expand Down Expand Up @@ -1441,14 +1442,15 @@ impl<'a> State<'a> {
self.bclose(expr.span);
}
hir::ExprKind::Closure {
binder,
capture_clause,
bound_generic_params,
fn_decl,
body,
fn_decl_span: _,
movability: _,
} => {
self.print_formal_generic_params(bound_generic_params);
self.print_closure_binder(binder, bound_generic_params);
self.print_capture_clause(capture_clause);

self.print_closure_params(fn_decl, body);
Expand Down Expand Up @@ -2033,6 +2035,42 @@ impl<'a> State<'a> {
}
}

pub fn print_closure_binder(
&mut self,
binder: &hir::ClosureBinder,
generic_params: &[GenericParam<'_>],
) {
let generic_params = generic_params
.iter()
.filter(|p| {
matches!(
p,
GenericParam {
kind: GenericParamKind::Lifetime { kind: LifetimeParamKind::Explicit },
..
}
)
})
.collect::<Vec<_>>();

match binder {
hir::ClosureBinder::Default => {}
// we need to distinguish `|...| {}` from `for<> |...| {}` as `for<>` adds additional restrictions
hir::ClosureBinder::For { .. } if generic_params.is_empty() => self.word("for<>"),
hir::ClosureBinder::For { .. } => {
self.word("for");
self.word("<");

self.commasep(Inconsistent, &generic_params, |s, param| {
s.print_generic_param(param)
});

self.word(">");
self.nbsp();
}
}
}

pub fn print_bounds<'b>(
&mut self,
prefix: &'static str,
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_lint/src/early.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T>
self.check_id(closure_id);
}
}

run_early_pass!(self, check_fn_post, fk, span, id);
}

Expand Down
49 changes: 42 additions & 7 deletions compiler/rustc_resolve/src/late.rs
Original file line number Diff line number Diff line change
Expand Up @@ -844,19 +844,30 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
this.in_func_body = previous_state;
}
}
FnKind::Closure(declaration, body) => {
// We do not have any explicit generic lifetime parameter.
// FIXME(rfc3216): Change when implementing `for<>` bounds on closures.
FnKind::Closure(binder, declaration, body) => {
this.visit_closure_binder(binder);

this.with_lifetime_rib(
LifetimeRibKind::AnonymousCreateParameter {
binder: fn_id,
report_in_path: false,
match binder {
// We do not have any explicit generic lifetime parameter.
ClosureBinder::NotPresent => {
LifetimeRibKind::AnonymousCreateParameter {
binder: fn_id,
report_in_path: false,
}
}
ClosureBinder::For { .. } => LifetimeRibKind::AnonymousReportError,
},
// Add each argument to the rib.
|this| this.resolve_params(&declaration.inputs),
);
this.with_lifetime_rib(
LifetimeRibKind::AnonymousPassThrough(fn_id, true),
match binder {
ClosureBinder::NotPresent => {
LifetimeRibKind::AnonymousPassThrough(fn_id, true)
}
ClosureBinder::For { .. } => LifetimeRibKind::AnonymousReportError,
},
|this| visit::walk_fn_ret_ty(this, &declaration.output),
);

Expand Down Expand Up @@ -891,6 +902,18 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
}
}

fn visit_closure_binder(&mut self, b: &'ast ClosureBinder) {
match b {
ClosureBinder::NotPresent => {}
ClosureBinder::For { generic_params, .. } => {
self.visit_generic_params(
&generic_params,
self.diagnostic_metadata.current_self_item.is_some(),
);
}
}
}

fn visit_generic_arg(&mut self, arg: &'ast GenericArg) {
debug!("visit_generic_arg({:?})", arg);
let prev = replace(&mut self.diagnostic_metadata.currently_processing_generics, true);
Expand Down Expand Up @@ -3515,6 +3538,18 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
});
}
// For closures, ClosureOrAsyncRibKind is added in visit_fn
ExprKind::Closure(ClosureBinder::For { ref generic_params, span }, ..) => {
self.with_generic_param_rib(
&generic_params,
NormalRibKind,
LifetimeRibKind::Generics {
binder: expr.id,
kind: LifetimeBinderKind::Function,
span,
},
|this| visit::walk_expr(this, expr),
);
}
ExprKind::Closure(..) => visit::walk_expr(self, expr),
ExprKind::Async(..) => {
self.with_label_rib(ClosureOrAsyncRibKind, |this| visit::walk_expr(this, expr));
Expand Down
49 changes: 48 additions & 1 deletion compiler/rustc_resolve/src/late/lifetimes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -571,7 +571,51 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
}

fn visit_expr(&mut self, e: &'tcx hir::Expr<'tcx>) {
if let hir::ExprKind::Closure { bound_generic_params, .. } = e.kind {
if let hir::ExprKind::Closure { binder, bound_generic_params, fn_decl, .. } = e.kind {
if let &hir::ClosureBinder::For { span: for_sp, .. } = binder {
fn span_of_infer(ty: &hir::Ty<'_>) -> Option<Span> {
struct V(Option<Span>);

impl<'v> Visitor<'v> for V {
fn visit_ty(&mut self, t: &'v hir::Ty<'v>) {
match t.kind {
_ if self.0.is_some() => (),
hir::TyKind::Infer => {
self.0 = Some(t.span);
}
_ => intravisit::walk_ty(self, t),
}
}
}

let mut v = V(None);
v.visit_ty(ty);
v.0
}

let infer_in_rt_sp = match fn_decl.output {
hir::FnRetTy::DefaultReturn(sp) => Some(sp),
hir::FnRetTy::Return(ty) => span_of_infer(ty),
};

let infer_spans = fn_decl
.inputs
.into_iter()
.filter_map(span_of_infer)
.chain(infer_in_rt_sp)
.collect::<Vec<_>>();

if !infer_spans.is_empty() {
self.tcx.sess
.struct_span_err(
infer_spans,
"implicit types in closure signatures are forbidden when `for<...>` is present",
)
.span_label(for_sp, "`for<...>` is here")
.emit();
}
}

let next_early_index = self.next_early_index();
let (lifetimes, binders): (FxIndexMap<LocalDefId, Region>, Vec<_>) =
bound_generic_params
Expand All @@ -584,6 +628,9 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
(pair, r)
})
.unzip();

// FIXME: missing_named_lifetime_spots

self.map.late_bound_vars.insert(e.hir_id, binders);
let scope = Scope::Binder {
hir_id: e.hir_id,
Expand Down
1 change: 1 addition & 0 deletions src/test/ui/closures/binder/async-closure-with-binder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@
fn main() {
for<'a> async || ();
//~^ ERROR `for<...>` binders on `async` closures are not currently supported
//~^^ ERROR implicit types in closure signatures are forbidden when `for<...>` is present
}
Loading
0