Skip to content

Commit 6380193

Browse files
committed
Ban in-band in fn-syntax on AST.
1 parent dea3949 commit 6380193

File tree

3 files changed

+40
-48
lines changed

3 files changed

+40
-48
lines changed

compiler/rustc_resolve/src/late.rs

+37-4
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,7 @@ enum LifetimeRibKind {
248248
#[derive(Copy, Clone, Debug)]
249249
enum LifetimeBinderKind {
250250
BareFnType,
251+
FnTrait,
251252
PolyTrait,
252253
WhereBound,
253254
Item,
@@ -260,6 +261,7 @@ impl LifetimeBinderKind {
260261
use LifetimeBinderKind::*;
261262
match self {
262263
BareFnType => "type",
264+
FnTrait => "bound",
263265
PolyTrait => "bound",
264266
WhereBound => "bound",
265267
Item => "item",
@@ -271,15 +273,15 @@ impl LifetimeBinderKind {
271273
fn allow_in_band(self) -> bool {
272274
use LifetimeBinderKind::*;
273275
match self {
274-
BareFnType | PolyTrait | WhereBound | Item => false,
276+
BareFnType | FnTrait | PolyTrait | WhereBound | Item => false,
275277
Function | ImplBlock => true,
276278
}
277279
}
278280

279281
fn transparent_in_band(self) -> bool {
280282
use LifetimeBinderKind::*;
281283
match self {
282-
BareFnType | Function | ImplBlock => false,
284+
BareFnType | Function | FnTrait | ImplBlock => false,
283285
_ => true,
284286
}
285287
}
@@ -856,9 +858,18 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
856858
if let Some(ref args) = path_segment.args {
857859
match &**args {
858860
GenericArgs::AngleBracketed(..) => visit::walk_generic_args(self, path_span, args),
859-
GenericArgs::Parenthesized(..) => self.with_lifetime_rib(
861+
GenericArgs::Parenthesized(data) => self.with_lifetime_rib(
860862
LifetimeRibKind::AnonymousPassThrough(path_segment.id),
861-
|this| visit::walk_generic_args(this, path_span, args),
863+
|this| {
864+
this.with_lifetime_rib(
865+
LifetimeRibKind::Generics {
866+
parent: path_segment.id,
867+
kind: LifetimeBinderKind::FnTrait,
868+
span: data.span,
869+
},
870+
|this| visit::walk_generic_args(this, path_span, args),
871+
)
872+
},
862873
),
863874
}
864875
}
@@ -1214,6 +1225,28 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
12141225
self.r.lifetimes_res_map.insert(lifetime.id, region);
12151226
return;
12161227
}
1228+
LifetimeRibKind::Generics {
1229+
kind: LifetimeBinderKind::BareFnType | LifetimeBinderKind::FnTrait,
1230+
..
1231+
} => {
1232+
rustc_errors::struct_span_err!(
1233+
self.r.session,
1234+
lifetime.ident.span,
1235+
E0687,
1236+
"lifetimes used in `fn` or `Fn` syntax must be \
1237+
explicitly declared using `<...>` binders"
1238+
)
1239+
.span_label(lifetime.ident.span, "in-band lifetime definition")
1240+
.emit();
1241+
let res_ident =
1242+
Ident::new(lifetime.ident.name, res_span.normalize_to_macros_2_0());
1243+
1244+
self.lifetime_ribs[in_band_rib_index]
1245+
.bindings
1246+
.insert(res_ident, LifetimeRes::Error);
1247+
self.r.lifetimes_res_map.insert(lifetime.id, LifetimeRes::Error);
1248+
return;
1249+
}
12171250
_ => {}
12181251
}
12191252
}

compiler/rustc_resolve/src/late/diagnostics.rs

+3
Original file line numberDiff line numberDiff line change
@@ -1797,6 +1797,9 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
17971797
if !kind.transparent_in_band() {
17981798
suggests_in_band = kind.allow_in_band();
17991799
}
1800+
if let LifetimeBinderKind::FnTrait = kind {
1801+
continue;
1802+
}
18001803

18011804
if span.from_expansion() && suggest_note {
18021805
suggest_note = false; // Avoid displaying the same help multiple times.

compiler/rustc_resolve/src/late/lifetimes.rs

-44
Original file line numberDiff line numberDiff line change
@@ -168,9 +168,6 @@ crate struct LifetimeContext<'a, 'tcx> {
168168
map: &'a mut NamedRegionMap,
169169
scope: ScopeRef<'a>,
170170

171-
/// Used to disallow the use of in-band lifetimes in `fn` or `Fn` syntax.
172-
is_in_fn_syntax: bool,
173-
174171
/// Indicates that we only care about the definition of a trait. This should
175172
/// be false if the `Item` we are resolving lifetimes for is not a trait or
176173
/// we eventually need lifetimes resolve for trait items.
@@ -451,7 +448,6 @@ fn do_resolve(
451448
tcx,
452449
map: &mut named_region_map,
453450
scope: ROOT_SCOPE,
454-
is_in_fn_syntax: false,
455451
trait_definition_only,
456452
xcrate_object_lifetime_defaults: Default::default(),
457453
lifetime_uses: &mut Default::default(),
@@ -869,8 +865,6 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
869865
match ty.kind {
870866
hir::TyKind::BareFn(ref c) => {
871867
let next_early_index = self.next_early_index();
872-
let was_in_fn_syntax = self.is_in_fn_syntax;
873-
self.is_in_fn_syntax = true;
874868
let lifetime_span: Option<Span> =
875869
c.generic_params.iter().rev().find_map(|param| match param.kind {
876870
GenericParamKind::Lifetime { .. } => Some(param.span),
@@ -911,7 +905,6 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
911905
intravisit::walk_ty(this, ty);
912906
});
913907
self.missing_named_lifetime_spots.pop();
914-
self.is_in_fn_syntax = was_in_fn_syntax;
915908
}
916909
hir::TyKind::TraitObject(bounds, ref lifetime, _) => {
917910
debug!(?bounds, ?lifetime, "TraitObject");
@@ -1685,7 +1678,6 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
16851678
tcx: *tcx,
16861679
map,
16871680
scope: &wrap_scope,
1688-
is_in_fn_syntax: self.is_in_fn_syntax,
16891681
trait_definition_only: self.trait_definition_only,
16901682
xcrate_object_lifetime_defaults,
16911683
lifetime_uses,
@@ -2209,39 +2201,6 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
22092201
}
22102202
}
22112203

2212-
// Check for fn-syntax conflicts with in-band lifetime definitions
2213-
if !self.trait_definition_only && self.is_in_fn_syntax {
2214-
match def {
2215-
Region::EarlyBound(_, _, LifetimeDefOrigin::InBand)
2216-
| Region::LateBound(_, _, _, LifetimeDefOrigin::InBand) => {
2217-
struct_span_err!(
2218-
self.tcx.sess,
2219-
lifetime_ref.span,
2220-
E0687,
2221-
"lifetimes used in `fn` or `Fn` syntax must be \
2222-
explicitly declared using `<...>` binders"
2223-
)
2224-
.span_label(lifetime_ref.span, "in-band lifetime definition")
2225-
.emit();
2226-
}
2227-
2228-
Region::Static
2229-
| Region::EarlyBound(
2230-
_,
2231-
_,
2232-
LifetimeDefOrigin::ExplicitOrElided | LifetimeDefOrigin::Error,
2233-
)
2234-
| Region::LateBound(
2235-
_,
2236-
_,
2237-
_,
2238-
LifetimeDefOrigin::ExplicitOrElided | LifetimeDefOrigin::Error,
2239-
)
2240-
| Region::LateBoundAnon(..)
2241-
| Region::Free(..) => {}
2242-
}
2243-
}
2244-
22452204
self.insert_lifetime(lifetime_ref, def);
22462205
} else {
22472206
self.tcx.sess.delay_span_bug(
@@ -2263,10 +2222,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
22632222
);
22642223

22652224
if generic_args.parenthesized {
2266-
let was_in_fn_syntax = self.is_in_fn_syntax;
2267-
self.is_in_fn_syntax = true;
22682225
self.visit_fn_like_elision(generic_args.inputs(), Some(generic_args.bindings[0].ty()));
2269-
self.is_in_fn_syntax = was_in_fn_syntax;
22702226
return;
22712227
}
22722228

0 commit comments

Comments
 (0)