From ac7651ccaf7447e695bf505916463927b78e433f Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 4 Apr 2024 20:36:18 -0400 Subject: [PATCH] More polishing --- compiler/rustc_hir/src/hir.rs | 5 +++++ compiler/rustc_hir_analysis/messages.ftl | 6 +++--- compiler/rustc_hir_analysis/src/check/check.rs | 8 ++++++++ .../nice_region_error/static_impl_trait.rs | 1 + compiler/rustc_parse/src/parser/ty.rs | 4 +++- compiler/rustc_resolve/src/late.rs | 6 ++++++ tests/ui/impl-trait/precise-capturing/apit.rs | 7 +++++++ .../ui/impl-trait/precise-capturing/apit.stderr | 17 +++++++++++++++++ .../impl-trait/precise-capturing/bad-params.rs | 3 +++ .../precise-capturing/bad-params.stderr | 8 +++++++- tests/ui/impl-trait/precise-capturing/elided.rs | 8 ++++++++ .../impl-trait/precise-capturing/elided.stderr | 11 +++++++++++ 12 files changed, 79 insertions(+), 5 deletions(-) create mode 100644 tests/ui/impl-trait/precise-capturing/apit.rs create mode 100644 tests/ui/impl-trait/precise-capturing/apit.stderr create mode 100644 tests/ui/impl-trait/precise-capturing/elided.rs create mode 100644 tests/ui/impl-trait/precise-capturing/elided.stderr diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 00b1ea061cc..b39056d8690 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -2568,6 +2568,11 @@ pub enum PreciseCapturingArg<'hir> { Param(PreciseCapturingNonLifetimeArg), } +/// We need to have a [`Node`] for the [`HirId`] that we attach the type/const param +/// resolution to. Lifetimes don't have this problem, and for them, it's actually +/// kind of detrimental to use a custom node type versus just using [`Lifetime`], +/// since resolve_bound_vars operates on `Lifetime`s. +// FIXME(precise_capturing): Investigate storing this as a path instead? #[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct PreciseCapturingNonLifetimeArg { pub hir_id: HirId, diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl index bc6583444c3..0ff78ebff99 100644 --- a/compiler/rustc_hir_analysis/messages.ftl +++ b/compiler/rustc_hir_analysis/messages.ftl @@ -39,9 +39,6 @@ hir_analysis_auto_deref_reached_recursion_limit = reached the recursion limit wh hir_analysis_bad_precise_capture = expected {$kind} parameter in `use<...>` precise captures list, found {$found} -hir_analysis_precise_capture_self_alias = `Self` can't be captured in `use<...>` precise captures list, since it is an alias - .label = `Self` is not a generic argument, but an alias to the type of the {$what} - hir_analysis_cannot_capture_late_bound_const = cannot capture late-bound const parameter in {$what} .label = parameter defined here @@ -374,6 +371,9 @@ hir_analysis_pattern_type_wild_pat = "wildcard patterns are not permitted for pa hir_analysis_placeholder_not_allowed_item_signatures = the placeholder `_` is not allowed within types on item signatures for {$kind} .label = not allowed in type signatures +hir_analysis_precise_capture_self_alias = `Self` can't be captured in `use<...>` precise captures list, since it is an alias + .label = `Self` is not a generic argument, but an alias to the type of the {$what} + hir_analysis_redundant_lifetime_args = unnecessary lifetime parameter `{$victim}` .note = you can use the `{$candidate}` lifetime directly, in place of `{$victim}` diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 1e8cd50ca0d..8c85d13650b 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -475,6 +475,14 @@ fn sanity_check_found_hidden_type<'tcx>( } } +/// Check that the opaque's precise captures list is valid (if present). +/// We check this for regular `impl Trait`s and also RPITITs, even though the latter +/// are technically GATs. +/// +/// This function is responsible for: +/// 1. Checking that all type/const params are mention in the captures list. +/// 2. Checking that all lifetimes that are implicitly captured are mentioned. +/// 3. Asserting that all parameters mentioned in the captures list are invariant. fn check_opaque_precise_captures<'tcx>(tcx: TyCtxt<'tcx>, opaque_def_id: LocalDefId) { let hir::OpaqueTy { precise_capturing_args, .. } = *tcx.hir_node_by_def_id(opaque_def_id).expect_item().expect_opaque_ty(); diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs index fe70b631cdb..0bbabefaf95 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs @@ -283,6 +283,7 @@ pub fn suggest_new_region_bound( continue; } match fn_return.kind { + // FIXME(precise_captures): Suggest adding to `use<...>` list instead. TyKind::OpaqueDef(item_id, _, _) => { let item = tcx.hir().item(item_id); let ItemKind::OpaqueTy(opaque) = &item.kind else { diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index f78a039394b..a6195fa7693 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -669,7 +669,9 @@ impl<'a> Parser<'a> { }) } - // parse precise captures, if any. + // parse precise captures, if any. This is `use<'lt, 'lt, P, P>`; a list of + // lifetimes and ident params (including SelfUpper). These are validated later + // for order, duplication, and whether they actually reference params. let precise_capturing = if self.eat_keyword(kw::Use) { let use_span = self.prev_token.span; self.psess.gated_spans.gate(sym::precise_capturing, use_span); diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 64434412886..ba1391bc378 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -1059,6 +1059,12 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast, PreciseCapturingArg::Lifetime(_) => {} PreciseCapturingArg::Arg(path, id) => { + // we want `impl use` to try to resolve `C` as both a type parameter or + // a const parameter. Since the resolver specifically doesn't allow having + // two generic params with the same name, even if they're a different namespace, + // it doesn't really matter which we try resolving first, but just like + // `Ty::Param` we just fall back to the value namespace only if it's missing + // from the type namespace. let mut check_ns = |ns| { self.maybe_resolve_ident_in_lexical_scope(path.segments[0].ident, ns).is_some() }; diff --git a/tests/ui/impl-trait/precise-capturing/apit.rs b/tests/ui/impl-trait/precise-capturing/apit.rs new file mode 100644 index 00000000000..efcac9ebb0b --- /dev/null +++ b/tests/ui/impl-trait/precise-capturing/apit.rs @@ -0,0 +1,7 @@ +#![feature(precise_capturing)] +//~^ WARN the feature `precise_capturing` is incomplete + +fn hello(_: impl use<> Sized) {} +//~^ ERROR `use<...>` precise capturing syntax not allowed on argument-position `impl Trait` + +fn main() {} diff --git a/tests/ui/impl-trait/precise-capturing/apit.stderr b/tests/ui/impl-trait/precise-capturing/apit.stderr new file mode 100644 index 00000000000..36bf80d9e2f --- /dev/null +++ b/tests/ui/impl-trait/precise-capturing/apit.stderr @@ -0,0 +1,17 @@ +warning: the feature `precise_capturing` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/apit.rs:1:12 + | +LL | #![feature(precise_capturing)] + | ^^^^^^^^^^^^^^^^^ + | + = note: see issue #123432 for more information + = note: `#[warn(incomplete_features)]` on by default + +error: `use<...>` precise capturing syntax not allowed on argument-position `impl Trait` + --> $DIR/apit.rs:4:18 + | +LL | fn hello(_: impl use<> Sized) {} + | ^^^ + +error: aborting due to 1 previous error; 1 warning emitted + diff --git a/tests/ui/impl-trait/precise-capturing/bad-params.rs b/tests/ui/impl-trait/precise-capturing/bad-params.rs index 195bd1b67ae..7970d49bf7c 100644 --- a/tests/ui/impl-trait/precise-capturing/bad-params.rs +++ b/tests/ui/impl-trait/precise-capturing/bad-params.rs @@ -13,4 +13,7 @@ impl MyType { //~^ ERROR `Self` can't be captured in `use<...>` precise captures list, since it is an alias } +fn hello() -> impl use Sized {} +//~^ ERROR expected type or const parameter in `use<...>` precise captures list, found function + fn main() {} diff --git a/tests/ui/impl-trait/precise-capturing/bad-params.stderr b/tests/ui/impl-trait/precise-capturing/bad-params.stderr index 09694a800c4..27bf05302f9 100644 --- a/tests/ui/impl-trait/precise-capturing/bad-params.stderr +++ b/tests/ui/impl-trait/precise-capturing/bad-params.stderr @@ -34,7 +34,13 @@ LL | impl MyType { LL | fn self_is_not_param() -> impl use Sized {} | ^^^^ -error: aborting due to 3 previous errors; 1 warning emitted +error: expected type or const parameter in `use<...>` precise captures list, found function + --> $DIR/bad-params.rs:16:24 + | +LL | fn hello() -> impl use Sized {} + | ^^^^^ + +error: aborting due to 4 previous errors; 1 warning emitted Some errors have detailed explanations: E0411, E0412. For more information about an error, try `rustc --explain E0411`. diff --git a/tests/ui/impl-trait/precise-capturing/elided.rs b/tests/ui/impl-trait/precise-capturing/elided.rs new file mode 100644 index 00000000000..de80e8a5d58 --- /dev/null +++ b/tests/ui/impl-trait/precise-capturing/elided.rs @@ -0,0 +1,8 @@ +//@ check-pass + +#![feature(precise_capturing)] +//~^ WARN the feature `precise_capturing` is incomplete + +fn elided(x: &()) -> impl use<'_> Sized { x } + +fn main() {} diff --git a/tests/ui/impl-trait/precise-capturing/elided.stderr b/tests/ui/impl-trait/precise-capturing/elided.stderr new file mode 100644 index 00000000000..38da0828de9 --- /dev/null +++ b/tests/ui/impl-trait/precise-capturing/elided.stderr @@ -0,0 +1,11 @@ +warning: the feature `precise_capturing` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/elided.rs:3:12 + | +LL | #![feature(precise_capturing)] + | ^^^^^^^^^^^^^^^^^ + | + = note: see issue #123432 for more information + = note: `#[warn(incomplete_features)]` on by default + +warning: 1 warning emitted +