diff options
| author | Michael Goulet <michael@errs.io> | 2024-04-04 15:06:30 -0400 |
|---|---|---|
| committer | Michael Goulet <michael@errs.io> | 2024-04-15 16:45:26 -0400 |
| commit | ce8961039e244b1e4e0fa02fc10d59a22abc9ea3 (patch) | |
| tree | 82e0bc2d330f071eb561dc164c60f1385f7fadbc /compiler/rustc_hir_analysis/src | |
| parent | 02d7317af218343818dcb107cda80750e9604a3a (diff) | |
| download | rust-ce8961039e244b1e4e0fa02fc10d59a22abc9ea3.tar.gz rust-ce8961039e244b1e4e0fa02fc10d59a22abc9ea3.zip | |
Some ordering and duplication checks
Diffstat (limited to 'compiler/rustc_hir_analysis/src')
| -rw-r--r-- | compiler/rustc_hir_analysis/src/check/check.rs | 57 | ||||
| -rw-r--r-- | compiler/rustc_hir_analysis/src/errors/precise_captures.rs | 22 |
2 files changed, 64 insertions, 15 deletions
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 592a8648f14..1e8cd50ca0d 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -4,7 +4,7 @@ use super::compare_impl_item::check_type_bounds; use super::compare_impl_item::{compare_impl_method, compare_impl_ty}; use super::*; use rustc_attr as attr; -use rustc_data_structures::unord::UnordSet; +use rustc_data_structures::unord::{UnordMap, UnordSet}; use rustc_errors::{codes::*, MultiSpan}; use rustc_hir as hir; use rustc_hir::def::{CtorKind, DefKind}; @@ -484,22 +484,51 @@ fn check_opaque_precise_captures<'tcx>(tcx: TyCtxt<'tcx>, opaque_def_id: LocalDe }; let mut expected_captures = UnordSet::default(); + let mut seen_params = UnordMap::default(); + let mut prev_non_lifetime_param = None; for arg in precise_capturing_args { - match *arg { - hir::PreciseCapturingArg::Lifetime(&hir::Lifetime { hir_id, .. }) - | hir::PreciseCapturingArg::Param(hir::PreciseCapturingNonLifetimeArg { - hir_id, .. - }) => match tcx.named_bound_var(hir_id) { - Some(ResolvedArg::EarlyBound(def_id)) => { - expected_captures.insert(def_id); + let (hir_id, ident) = match *arg { + hir::PreciseCapturingArg::Param(hir::PreciseCapturingNonLifetimeArg { + hir_id, + ident, + .. + }) => { + if prev_non_lifetime_param.is_none() { + prev_non_lifetime_param = Some(ident); } - _ => { - tcx.dcx().span_delayed_bug( - tcx.hir().span(hir_id), - "parameter should have been resolved", - ); + (hir_id, ident) + } + hir::PreciseCapturingArg::Lifetime(&hir::Lifetime { hir_id, ident, .. }) => { + if let Some(prev_non_lifetime_param) = prev_non_lifetime_param { + tcx.dcx().emit_err(errors::LifetimesMustBeFirst { + lifetime_span: ident.span, + name: ident.name, + other_span: prev_non_lifetime_param.span, + }); } - }, + (hir_id, ident) + } + }; + + let ident = ident.normalize_to_macros_2_0(); + if let Some(span) = seen_params.insert(ident, ident.span) { + tcx.dcx().emit_err(errors::DuplicatePreciseCapture { + name: ident.name, + first_span: span, + second_span: ident.span, + }); + } + + match tcx.named_bound_var(hir_id) { + Some(ResolvedArg::EarlyBound(def_id)) => { + expected_captures.insert(def_id); + } + _ => { + tcx.dcx().span_delayed_bug( + tcx.hir().span(hir_id), + "parameter should have been resolved", + ); + } } } diff --git a/compiler/rustc_hir_analysis/src/errors/precise_captures.rs b/compiler/rustc_hir_analysis/src/errors/precise_captures.rs index 3b22437abb2..e2eb9c72bf2 100644 --- a/compiler/rustc_hir_analysis/src/errors/precise_captures.rs +++ b/compiler/rustc_hir_analysis/src/errors/precise_captures.rs @@ -1,5 +1,5 @@ use rustc_macros::Diagnostic; -use rustc_span::Span; +use rustc_span::{Span, Symbol}; #[derive(Diagnostic)] #[diag(hir_analysis_param_not_captured)] @@ -31,3 +31,23 @@ pub struct BadPreciseCapture { pub kind: &'static str, pub found: String, } + +#[derive(Diagnostic)] +#[diag(hir_analysis_duplicate_precise_capture)] +pub struct DuplicatePreciseCapture { + #[primary_span] + pub first_span: Span, + pub name: Symbol, + #[label] + pub second_span: Span, +} + +#[derive(Diagnostic)] +#[diag(hir_analysis_lifetime_must_be_first)] +pub struct LifetimesMustBeFirst { + #[primary_span] + pub lifetime_span: Span, + pub name: Symbol, + #[label] + pub other_span: Span, +} |
