Skip to content

Commit 0387724

Browse files
Detect duplicates
1 parent 36cdd0b commit 0387724

File tree

6 files changed

+63
-8
lines changed

6 files changed

+63
-8
lines changed

compiler/rustc_ast_lowering/src/lib.rs

+7-4
Original file line numberDiff line numberDiff line change
@@ -1534,10 +1534,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
15341534
let opaque_ty_span = self.mark_span_with_reason(DesugaringKind::OpaqueTy, span, None);
15351535

15361536
let captured_lifetimes_to_duplicate = if let Some(args) =
1537-
bounds.iter().find_map(|bound| match bound {
1538-
ast::GenericBound::Use(a, _) => Some(a),
1539-
_ => None,
1540-
}) {
1537+
// We only look for one `use<...>` syntax since we syntactially reject more than one.
1538+
bounds.iter().find_map(
1539+
|bound| match bound {
1540+
ast::GenericBound::Use(a, _) => Some(a),
1541+
_ => None,
1542+
},
1543+
) {
15411544
// We'll actually validate these later on; all we need is the list of
15421545
// lifetimes to duplicate during this portion of lowering.
15431546
args.iter()

compiler/rustc_ast_passes/messages.ftl

+5-2
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,6 @@ ast_passes_assoc_type_without_body =
1414
associated type in `impl` without body
1515
.suggestion = provide a definition for the type
1616
17-
ast_passes_precise_capturing_not_allowed_here = `use<...>` precise capturing syntax not allowed in {$loc}
18-
1917
ast_passes_at_least_one_trait = at least one trait must be specified
2018
2119
ast_passes_auto_generic = auto traits cannot have generic parameters
@@ -212,6 +210,11 @@ ast_passes_pattern_in_fn_pointer = patterns aren't allowed in function pointer t
212210
ast_passes_pattern_in_foreign = patterns aren't allowed in foreign function declarations
213211
.label = pattern not allowed in foreign function
214212
213+
ast_passes_precise_capturing_duplicated = duplicate `use<...>` precise capturing syntax
214+
.label = second `use<...>` here
215+
216+
ast_passes_precise_capturing_not_allowed_here = `use<...>` precise capturing syntax not allowed in {$loc}
217+
215218
ast_passes_show_span = {$msg}
216219
217220
ast_passes_stability_outside_std = stability attributes may not be used outside of the standard library

compiler/rustc_ast_passes/src/ast_validation.rs

+18-2
Original file line numberDiff line numberDiff line change
@@ -183,8 +183,24 @@ impl<'a> AstValidator<'a> {
183183
// Mirrors `visit::walk_ty`, but tracks relevant state.
184184
fn walk_ty(&mut self, t: &'a Ty) {
185185
match &t.kind {
186-
TyKind::ImplTrait(..) => {
187-
self.with_impl_trait(Some(t.span), |this| visit::walk_ty(this, t))
186+
TyKind::ImplTrait(_, bounds) => {
187+
self.with_impl_trait(Some(t.span), |this| visit::walk_ty(this, t));
188+
189+
// FIXME(precise_capturing): If we were to allow `use` in other positions
190+
// (e.g. GATs), then we must validate those as well. However, we don't have
191+
// a good way of doing this with the current `Visitor` structure.
192+
let mut use_bounds = bounds
193+
.iter()
194+
.filter_map(|bound| match bound {
195+
GenericBound::Use(_, span) => Some(span),
196+
_ => None,
197+
})
198+
.copied();
199+
if let Some(bound1) = use_bounds.next()
200+
&& let Some(bound2) = use_bounds.next()
201+
{
202+
self.dcx().emit_err(errors::DuplicatePreciseCapturing { bound1, bound2 });
203+
}
188204
}
189205
TyKind::TraitObject(..) => self
190206
.with_tilde_const(Some(DisallowTildeConstContext::TraitObject), |this| {

compiler/rustc_ast_passes/src/errors.rs

+9
Original file line numberDiff line numberDiff line change
@@ -836,3 +836,12 @@ pub struct PreciseCapturingNotAllowedHere {
836836
pub span: Span,
837837
pub loc: &'static str,
838838
}
839+
840+
#[derive(Diagnostic)]
841+
#[diag(ast_passes_precise_capturing_duplicated)]
842+
pub struct DuplicatePreciseCapturing {
843+
#[primary_span]
844+
pub bound1: Span,
845+
#[label]
846+
pub bound2: Span,
847+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#![feature(precise_capturing)]
2+
//~^ WARN the feature `precise_capturing` is incomplete
3+
4+
fn hello<'a>() -> impl Sized + use<'a> + use<'a> {}
5+
//~^ ERROR duplicate `use<...>` precise capturing syntax
6+
7+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
error: duplicate `use<...>` precise capturing syntax
2+
--> $DIR/duplicated-use.rs:4:32
3+
|
4+
LL | fn hello<'a>() -> impl Sized + use<'a> + use<'a> {}
5+
| ^^^^^^^ ------- second `use<...>` here
6+
7+
warning: the feature `precise_capturing` is incomplete and may not be safe to use and/or cause compiler crashes
8+
--> $DIR/duplicated-use.rs:1:12
9+
|
10+
LL | #![feature(precise_capturing)]
11+
| ^^^^^^^^^^^^^^^^^
12+
|
13+
= note: see issue #123432 <https://github.com/rust-lang/rust/issues/123432> for more information
14+
= note: `#[warn(incomplete_features)]` on by default
15+
16+
error: aborting due to 1 previous error; 1 warning emitted
17+

0 commit comments

Comments
 (0)