Skip to content

Commit

Permalink
More polishing
Browse files Browse the repository at this point in the history
  • Loading branch information
compiler-errors committed Apr 5, 2024
1 parent e154b64 commit 4213228
Show file tree
Hide file tree
Showing 12 changed files with 79 additions and 5 deletions.
5 changes: 5 additions & 0 deletions compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_hir_analysis/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -371,6 +368,9 @@ hir_analysis_pass_to_variadic_function = can't pass `{$ty}` to variadic function
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_requires_note = the `{$trait_name}` impl for `{$ty}` requires that `{$error_predicate}`
hir_analysis_return_type_notation_equality_bound =
Expand Down
8 changes: 8 additions & 0 deletions compiler/rustc_hir_analysis/src/check/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -479,6 +479,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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_parse/src/parser/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
6 changes: 6 additions & 0 deletions compiler/rustc_resolve/src/late.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1062,6 +1062,12 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
PreciseCapturingArg::Lifetime(_) => {}

PreciseCapturingArg::Arg(path, id) => {
// we want `impl use<C>` 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()
};
Expand Down
7 changes: 7 additions & 0 deletions tests/ui/impl-trait/precise-capturing/apit.rs
Original file line number Diff line number Diff line change
@@ -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() {}
17 changes: 17 additions & 0 deletions tests/ui/impl-trait/precise-capturing/apit.stderr
Original file line number Diff line number Diff line change
@@ -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 <https://github.com/rust-lang/rust/issues/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

3 changes: 3 additions & 0 deletions tests/ui/impl-trait/precise-capturing/bad-params.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<hello> Sized {}
//~^ ERROR expected type or const parameter in `use<...>` precise captures list, found function

fn main() {}
8 changes: 7 additions & 1 deletion tests/ui/impl-trait/precise-capturing/bad-params.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,13 @@ LL | impl MyType {
LL | fn self_is_not_param() -> impl use<Self> 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<hello> 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`.
8 changes: 8 additions & 0 deletions tests/ui/impl-trait/precise-capturing/elided.rs
Original file line number Diff line number Diff line change
@@ -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() {}
11 changes: 11 additions & 0 deletions tests/ui/impl-trait/precise-capturing/elided.stderr
Original file line number Diff line number Diff line change
@@ -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 <https://github.com/rust-lang/rust/issues/123432> for more information
= note: `#[warn(incomplete_features)]` on by default

warning: 1 warning emitted

0 comments on commit 4213228

Please sign in to comment.