Skip to content

Commit

Permalink
Auto merge of #17676 - winstxnhdw:precise-capturing, r=Veykril
Browse files Browse the repository at this point in the history
feat: add preliminary support for `+ use<..>` `precise_capturing` syntax

## Summary

This PR adds basic support for the following syntax.

```rs
fn captures<'a: 'a, 'b: 'b, T>() -> impl Sized + use<'b, T> {}
//                                  ~~~~~~~~~~~~~~~~~~~~~~~
//                          This opaque type does not capture `'a`.

fn outlives<'o, T: 'o>(_: T) {}

fn caller<'o, 'a, 'b: 'o, T: 'o>() {
    //        ~~
    //        ^ Note that we don't need `'a: 'o`.
    outlives::<'o>(captures::<'a, 'b, T>());
}
```

Related to #17598
  • Loading branch information
bors committed Jul 25, 2024
2 parents fa5ff86 + 9f74787 commit 0ba6f4e
Show file tree
Hide file tree
Showing 9 changed files with 237 additions and 89 deletions.
1 change: 1 addition & 0 deletions crates/hir-def/src/hir/type_ref.rs
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,7 @@ impl TypeBound {
None => TypeBound::Error,
}
}
ast::TypeBoundKind::Use(_) => TypeBound::Error,
ast::TypeBoundKind::Lifetime(lifetime) => {
TypeBound::Lifetime(LifetimeRef::new(&lifetime))
}
Expand Down
236 changes: 147 additions & 89 deletions crates/ide-db/src/generated/lints.rs

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions crates/parser/src/grammar/generic_params.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,12 @@ fn type_bound(p: &mut Parser<'_>) -> bool {
match p.current() {
LIFETIME_IDENT => lifetime(p),
T![for] => types::for_type(p, false),
// test precise_capturing
// fn captures<'a: 'a, 'b: 'b, T>() -> impl Sized + use<'b, T> {}
T![use] => {
p.bump_any();
generic_param_list(p)
}
T![?] if p.nth_at(1, T![for]) => {
// test question_for_type_trait_bound
// fn f<T>() where T: ?for<> Sized {}
Expand Down
4 changes: 4 additions & 0 deletions crates/parser/test_data/generated/runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,10 @@ mod ok {
#[test]
fn postfix_range() { run_and_expect_no_errors("test_data/parser/inline/ok/postfix_range.rs"); }
#[test]
fn precise_capturing() {
run_and_expect_no_errors("test_data/parser/inline/ok/precise_capturing.rs");
}
#[test]
fn pub_parens_typepath() {
run_and_expect_no_errors("test_data/parser/inline/ok/pub_parens_typepath.rs");
}
Expand Down
69 changes: 69 additions & 0 deletions crates/parser/test_data/parser/inline/ok/precise_capturing.rast
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
SOURCE_FILE
FN
FN_KW "fn"
WHITESPACE " "
NAME
IDENT "captures"
GENERIC_PARAM_LIST
L_ANGLE "<"
LIFETIME_PARAM
LIFETIME
LIFETIME_IDENT "'a"
COLON ":"
WHITESPACE " "
LIFETIME
LIFETIME_IDENT "'a"
COMMA ","
WHITESPACE " "
LIFETIME_PARAM
LIFETIME
LIFETIME_IDENT "'b"
COLON ":"
WHITESPACE " "
LIFETIME
LIFETIME_IDENT "'b"
COMMA ","
WHITESPACE " "
TYPE_PARAM
NAME
IDENT "T"
R_ANGLE ">"
PARAM_LIST
L_PAREN "("
R_PAREN ")"
WHITESPACE " "
RET_TYPE
THIN_ARROW "->"
WHITESPACE " "
IMPL_TRAIT_TYPE
IMPL_KW "impl"
WHITESPACE " "
TYPE_BOUND_LIST
TYPE_BOUND
PATH_TYPE
PATH
PATH_SEGMENT
NAME_REF
IDENT "Sized"
WHITESPACE " "
PLUS "+"
WHITESPACE " "
TYPE_BOUND
USE_KW "use"
GENERIC_PARAM_LIST
L_ANGLE "<"
LIFETIME_PARAM
LIFETIME
LIFETIME_IDENT "'b"
COMMA ","
WHITESPACE " "
TYPE_PARAM
NAME
IDENT "T"
R_ANGLE ">"
WHITESPACE " "
BLOCK_EXPR
STMT_LIST
L_CURLY "{"
R_CURLY "}"
WHITESPACE "\n"
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
fn captures<'a: 'a, 'b: 'b, T>() -> impl Sized + use<'b, T> {}
1 change: 1 addition & 0 deletions crates/syntax/rust.ungram
Original file line number Diff line number Diff line change
Expand Up @@ -629,6 +629,7 @@ TypeBoundList =
TypeBound =
Lifetime
| ('~' 'const' | 'const')? 'async'? '?'? Type
| 'use' GenericParamList

//************************//
// Patterns //
Expand Down
4 changes: 4 additions & 0 deletions crates/syntax/src/ast/generated/nodes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1788,6 +1788,8 @@ pub struct TypeBound {
pub(crate) syntax: SyntaxNode,
}
impl TypeBound {
#[inline]
pub fn generic_param_list(&self) -> Option<GenericParamList> { support::child(&self.syntax) }
#[inline]
pub fn lifetime(&self) -> Option<Lifetime> { support::child(&self.syntax) }
#[inline]
Expand All @@ -1799,6 +1801,8 @@ impl TypeBound {
#[inline]
pub fn const_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![const]) }
#[inline]
pub fn use_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![use]) }
#[inline]
pub fn tilde_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![~]) }
}

Expand Down
4 changes: 4 additions & 0 deletions crates/syntax/src/ast/node_ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -794,6 +794,8 @@ pub enum TypeBoundKind {
PathType(ast::PathType),
/// for<'a> ...
ForType(ast::ForType),
/// use
Use(ast::GenericParamList),
/// 'a
Lifetime(ast::Lifetime),
}
Expand All @@ -804,6 +806,8 @@ impl ast::TypeBound {
TypeBoundKind::PathType(path_type)
} else if let Some(for_type) = support::children(self.syntax()).next() {
TypeBoundKind::ForType(for_type)
} else if let Some(generic_param_list) = self.generic_param_list() {
TypeBoundKind::Use(generic_param_list)
} else if let Some(lifetime) = self.lifetime() {
TypeBoundKind::Lifetime(lifetime)
} else {
Expand Down

0 comments on commit 0ba6f4e

Please sign in to comment.