From 9ca8fb51490ba1c28d6edd3cea16890d9d7025f7 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 5 Jun 2024 16:43:25 -0400 Subject: [PATCH] Detect duplicates --- compiler/rustc_ast_passes/messages.ftl | 7 +++++-- .../rustc_ast_passes/src/ast_validation.rs | 20 +++++++++++++++++-- compiler/rustc_ast_passes/src/errors.rs | 9 +++++++++ .../precise-capturing/duplicated-use.rs | 7 +++++++ .../precise-capturing/duplicated-use.stderr | 17 ++++++++++++++++ 5 files changed, 56 insertions(+), 4 deletions(-) create mode 100644 tests/ui/impl-trait/precise-capturing/duplicated-use.rs create mode 100644 tests/ui/impl-trait/precise-capturing/duplicated-use.stderr diff --git a/compiler/rustc_ast_passes/messages.ftl b/compiler/rustc_ast_passes/messages.ftl index 98da96543414c..63045a9d729c5 100644 --- a/compiler/rustc_ast_passes/messages.ftl +++ b/compiler/rustc_ast_passes/messages.ftl @@ -14,8 +14,6 @@ ast_passes_assoc_type_without_body = associated type in `impl` without body .suggestion = provide a definition for the type -ast_passes_precise_capturing_not_allowed_here = `use<...>` precise capturing syntax not allowed in {$loc} - ast_passes_at_least_one_trait = at least one trait must be specified 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 ast_passes_pattern_in_foreign = patterns aren't allowed in foreign function declarations .label = pattern not allowed in foreign function +ast_passes_precise_capturing_duplicated = duplicate `use<...>` precise capturing syntax + .label = second `use<...>` here + +ast_passes_precise_capturing_not_allowed_here = `use<...>` precise capturing syntax not allowed in {$loc} + ast_passes_show_span = {$msg} ast_passes_stability_outside_std = stability attributes may not be used outside of the standard library diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 34ff5a6ab1551..84165bc50f3fa 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -183,8 +183,24 @@ impl<'a> AstValidator<'a> { // Mirrors `visit::walk_ty`, but tracks relevant state. fn walk_ty(&mut self, t: &'a Ty) { match &t.kind { - TyKind::ImplTrait(..) => { - self.with_impl_trait(Some(t.span), |this| visit::walk_ty(this, t)) + TyKind::ImplTrait(_, bounds) => { + self.with_impl_trait(Some(t.span), |this| visit::walk_ty(this, t)); + + // FIXME(precise_capturing): If we were to allow `use` in other positions + // (e.g. GATs), then we must validate those as well. However, we don't have + // a good way of doing this with the current `Visitor` structure. + let mut use_bounds = bounds + .iter() + .filter_map(|bound| match bound { + GenericBound::Use(_, span) => Some(span), + _ => None, + }) + .copied(); + if let Some(bound1) = use_bounds.next() + && let Some(bound2) = use_bounds.next() + { + self.dcx().emit_err(errors::DuplicatePreciseCapturing { bound1, bound2 }); + } } TyKind::TraitObject(..) => self .with_tilde_const(Some(DisallowTildeConstContext::TraitObject), |this| { diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs index 0d84c93524e88..925bcc6cbf9bf 100644 --- a/compiler/rustc_ast_passes/src/errors.rs +++ b/compiler/rustc_ast_passes/src/errors.rs @@ -836,3 +836,12 @@ pub struct PreciseCapturingNotAllowedHere { pub span: Span, pub loc: &'static str, } + +#[derive(Diagnostic)] +#[diag(ast_passes_precise_capturing_duplicated)] +pub struct DuplicatePreciseCapturing { + #[primary_span] + pub bound1: Span, + #[label] + pub bound2: Span, +} diff --git a/tests/ui/impl-trait/precise-capturing/duplicated-use.rs b/tests/ui/impl-trait/precise-capturing/duplicated-use.rs new file mode 100644 index 0000000000000..21b5db5bb4b76 --- /dev/null +++ b/tests/ui/impl-trait/precise-capturing/duplicated-use.rs @@ -0,0 +1,7 @@ +#![feature(precise_capturing)] +//~^ WARN the feature `precise_capturing` is incomplete + +fn hello<'a>() -> impl Sized + use<'a> + use<'a> {} +//~^ ERROR duplicate `use<...>` precise capturing syntax + +fn main() {} diff --git a/tests/ui/impl-trait/precise-capturing/duplicated-use.stderr b/tests/ui/impl-trait/precise-capturing/duplicated-use.stderr new file mode 100644 index 0000000000000..6c5d9630b143f --- /dev/null +++ b/tests/ui/impl-trait/precise-capturing/duplicated-use.stderr @@ -0,0 +1,17 @@ +error: duplicate `use<...>` precise capturing syntax + --> $DIR/duplicated-use.rs:4:32 + | +LL | fn hello<'a>() -> impl Sized + use<'a> + use<'a> {} + | ^^^^^^^ ------- second `use<...>` here + +warning: the feature `precise_capturing` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/duplicated-use.rs:1:12 + | +LL | #![feature(precise_capturing)] + | ^^^^^^^^^^^^^^^^^ + | + = note: see issue #123432 for more information + = note: `#[warn(incomplete_features)]` on by default + +error: aborting due to 1 previous error; 1 warning emitted +