Allign RecordPat with RecordExpr

This commit is contained in:
Aleksey Kladov 2020-07-31 19:54:16 +02:00
parent 572f1c08b6
commit 14cb96ec0e
22 changed files with 78 additions and 85 deletions

View File

@ -57,7 +57,7 @@ fn reorder<R: AstNode>(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
fn get_fields_kind(node: &SyntaxNode) -> Vec<SyntaxKind> {
match node.kind() {
RECORD_EXPR => vec![RECORD_EXPR_FIELD],
RECORD_PAT => vec![RECORD_FIELD_PAT, BIND_PAT],
RECORD_PAT => vec![RECORD_PAT_FIELD, BIND_PAT],
_ => vec![],
}
}
@ -66,7 +66,7 @@ fn get_field_name(node: &SyntaxNode) -> String {
let res = match_ast! {
match node {
ast::RecordExprField(field) => field.field_name().map(|it| it.to_string()),
ast::RecordFieldPat(field) => field.field_name().map(|it| it.to_string()),
ast::RecordPatField(field) => field.field_name().map(|it| it.to_string()),
_ => None,
}
};

View File

@ -216,7 +216,7 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
self.imp.resolve_record_field(field)
}
pub fn resolve_record_field_pat(&self, field: &ast::RecordFieldPat) -> Option<Field> {
pub fn resolve_record_field_pat(&self, field: &ast::RecordPatField) -> Option<Field> {
self.imp.resolve_record_field_pat(field)
}
@ -429,7 +429,7 @@ impl<'db> SemanticsImpl<'db> {
self.analyze(field.syntax()).resolve_record_field(self.db, field)
}
fn resolve_record_field_pat(&self, field: &ast::RecordFieldPat) -> Option<Field> {
fn resolve_record_field_pat(&self, field: &ast::RecordPatField) -> Option<Field> {
self.analyze(field.syntax()).resolve_record_field_pat(self.db, field)
}

View File

@ -182,7 +182,7 @@ impl SourceAnalyzer {
pub(crate) fn resolve_record_field_pat(
&self,
_db: &dyn HirDatabase,
field: &ast::RecordFieldPat,
field: &ast::RecordPatField,
) -> Option<Field> {
let pat_id = self.pat_id(&field.pat()?)?;
let struct_field = self.infer.as_ref()?.record_field_pat_resolution(pat_id)?;

View File

@ -1,6 +1,8 @@
//! Transforms `ast::Expr` into an equivalent `hir_def::expr::Expr`
//! representation.
use std::{any::type_name, sync::Arc};
use either::Either;
use hir_expand::{
hygiene::Hygiene,
@ -10,11 +12,12 @@ use hir_expand::{
use ra_arena::Arena;
use ra_syntax::{
ast::{
self, ArgListOwner, ArrayExprKind, LiteralKind, LoopBodyOwner, NameOwner,
self, ArgListOwner, ArrayExprKind, AstChildren, LiteralKind, LoopBodyOwner, NameOwner,
SlicePatComponents,
},
AstNode, AstPtr,
};
use rustc_hash::FxHashMap;
use test_utils::mark;
use crate::{
@ -35,9 +38,6 @@ use crate::{
};
use super::{ExprSource, PatSource};
use ast::AstChildren;
use rustc_hash::FxHashMap;
use std::{any::type_name, sync::Arc};
pub(crate) struct LowerCtx {
hygiene: Hygiene,
@ -786,29 +786,26 @@ impl ExprCollector<'_> {
ast::Pat::PlaceholderPat(_) => Pat::Wild,
ast::Pat::RecordPat(p) => {
let path = p.path().and_then(|path| self.expander.parse_path(path));
let record_field_pat_list =
p.record_field_pat_list().expect("every struct should have a field list");
let mut fields: Vec<_> = record_field_pat_list
.bind_pats()
.filter_map(|bind_pat| {
let ast_pat =
ast::Pat::cast(bind_pat.syntax().clone()).expect("bind pat is a pat");
let args: Vec<_> = p
.record_pat_field_list()
.expect("every struct should have a field list")
.fields()
.filter_map(|f| {
let ast_pat = f.pat()?;
let pat = self.collect_pat(ast_pat);
let name = bind_pat.name()?.as_name();
let name = f.field_name()?.as_name();
Some(RecordFieldPat { name, pat })
})
.collect();
let iter = record_field_pat_list.record_field_pats().filter_map(|f| {
let ast_pat = f.pat()?;
let pat = self.collect_pat(ast_pat);
let name = f.field_name()?.as_name();
Some(RecordFieldPat { name, pat })
});
fields.extend(iter);
let ellipsis = record_field_pat_list.dotdot_token().is_some();
let ellipsis = p
.record_pat_field_list()
.expect("every struct should have a field list")
.dotdot_token()
.is_some();
Pat::Record { path, args: fields, ellipsis }
Pat::Record { path, args, ellipsis }
}
ast::Pat::SlicePat(p) => {
let SlicePatComponents { prefix, slice, suffix } = p.components();

View File

@ -92,7 +92,7 @@ impl AstDiagnostic for MissingFields {
#[derive(Debug)]
pub struct MissingPatFields {
pub file: HirFileId,
pub field_list: AstPtr<ast::RecordFieldPatList>,
pub field_list: AstPtr<ast::RecordPatFieldList>,
pub missed_fields: Vec<Name>,
}

View File

@ -131,7 +131,7 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
if let Some(expr) = source_ptr.value.as_ref().left() {
let root = source_ptr.file_syntax(db.upcast());
if let ast::Pat::RecordPat(record_pat) = expr.to_node(&root) {
if let Some(field_list) = record_pat.record_field_pat_list() {
if let Some(field_list) = record_pat.record_pat_field_list() {
let variant_data = variant_data(db.upcast(), variant_def);
let missed_fields = missed_fields
.into_iter()

View File

@ -265,7 +265,7 @@ impl<'a> CompletionContext<'a> {
return;
}
// FIXME: remove this (V) duplication and make the check more precise
if name_ref.syntax().ancestors().find_map(ast::RecordFieldPatList::cast).is_some() {
if name_ref.syntax().ancestors().find_map(ast::RecordPatFieldList::cast).is_some() {
self.record_pat_syntax =
self.sema.find_node_at_offset_with_macros(&original_file, offset);
}
@ -283,7 +283,7 @@ impl<'a> CompletionContext<'a> {
{
self.is_pat_binding_or_const = false;
}
if bind_pat.syntax().parent().and_then(ast::RecordFieldPatList::cast).is_some() {
if bind_pat.syntax().parent().and_then(ast::RecordPatFieldList::cast).is_some() {
self.is_pat_binding_or_const = false;
}
if let Some(let_stmt) = bind_pat.syntax().ancestors().find_map(ast::LetStmt::cast) {
@ -300,7 +300,7 @@ impl<'a> CompletionContext<'a> {
return;
}
// FIXME: remove this (^) duplication and make the check more precise
if name.syntax().ancestors().find_map(ast::RecordFieldPatList::cast).is_some() {
if name.syntax().ancestors().find_map(ast::RecordPatFieldList::cast).is_some() {
self.record_pat_syntax =
self.sema.find_node_at_offset_with_macros(&original_file, offset);
}

View File

@ -37,7 +37,7 @@ fn try_extend_selection(
let string_kinds = [COMMENT, STRING, RAW_STRING, BYTE_STRING, RAW_BYTE_STRING];
let list_kinds = [
RECORD_FIELD_PAT_LIST,
RECORD_PAT_FIELD_LIST,
MATCH_ARM_LIST,
RECORD_FIELD_LIST,
TUPLE_FIELD_LIST,

View File

@ -86,7 +86,7 @@ fn fold_kind(kind: SyntaxKind) -> Option<FoldKind> {
USE => Some(FoldKind::Imports),
ARG_LIST | PARAM_LIST => Some(FoldKind::ArgList),
RECORD_FIELD_LIST
| RECORD_FIELD_PAT_LIST
| RECORD_PAT_FIELD_LIST
| RECORD_EXPR_FIELD_LIST
| ITEM_LIST
| EXTERN_ITEM_LIST

View File

@ -131,7 +131,7 @@ pub fn classify_name(sema: &Semantics<RootDatabase>, name: &ast::Name) -> Option
ast::BindPat(it) => {
let local = sema.to_def(&it)?;
if let Some(record_field_pat) = it.syntax().parent().and_then(ast::RecordFieldPat::cast) {
if let Some(record_field_pat) = it.syntax().parent().and_then(ast::RecordPatField::cast) {
if record_field_pat.name_ref().is_none() {
if let Some(field) = sema.resolve_record_field_pat(&record_field_pat) {
let field = Definition::Field(field);
@ -247,7 +247,7 @@ pub fn classify_name_ref(
}
}
if let Some(record_field_pat) = ast::RecordFieldPat::cast(parent.clone()) {
if let Some(record_field_pat) = ast::RecordPatField::cast(parent.clone()) {
if let Some(field) = sema.resolve_record_field_pat(&record_field_pat) {
let field = Definition::Field(field);
return Some(NameRefClass::Definition(field));

View File

@ -217,7 +217,7 @@ fn record_field_pat_list(p: &mut Parser) {
bind_pat(p, false);
}
}
m.complete(p, RECORD_FIELD_PAT);
m.complete(p, RECORD_PAT_FIELD);
}
}
if !p.at(T!['}']) {
@ -225,7 +225,7 @@ fn record_field_pat_list(p: &mut Parser) {
}
}
p.expect(T!['}']);
m.complete(p, RECORD_FIELD_PAT_LIST);
m.complete(p, RECORD_PAT_FIELD_LIST);
}
// test placeholder_pat

View File

@ -161,8 +161,8 @@ pub enum SyntaxKind {
DOT_DOT_PAT,
PATH_PAT,
RECORD_PAT,
RECORD_FIELD_PAT_LIST,
RECORD_FIELD_PAT,
RECORD_PAT_FIELD_LIST,
RECORD_PAT_FIELD,
TUPLE_STRUCT_PAT,
TUPLE_PAT,
SLICE_PAT,

View File

@ -1192,7 +1192,7 @@ pub struct RecordPat {
}
impl RecordPat {
pub fn path(&self) -> Option<Path> { support::child(&self.syntax) }
pub fn record_field_pat_list(&self) -> Option<RecordFieldPatList> {
pub fn record_pat_field_list(&self) -> Option<RecordPatFieldList> {
support::child(&self.syntax)
}
}
@ -1234,24 +1234,21 @@ impl TupleStructPat {
pub fn r_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![')']) }
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct RecordFieldPatList {
pub struct RecordPatFieldList {
pub(crate) syntax: SyntaxNode,
}
impl RecordFieldPatList {
impl RecordPatFieldList {
pub fn l_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['{']) }
pub fn record_field_pats(&self) -> AstChildren<RecordFieldPat> {
support::children(&self.syntax)
}
pub fn bind_pats(&self) -> AstChildren<BindPat> { support::children(&self.syntax) }
pub fn fields(&self) -> AstChildren<RecordPatField> { support::children(&self.syntax) }
pub fn dotdot_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![..]) }
pub fn r_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['}']) }
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct RecordFieldPat {
pub struct RecordPatField {
pub(crate) syntax: SyntaxNode,
}
impl ast::AttrsOwner for RecordFieldPat {}
impl RecordFieldPat {
impl ast::AttrsOwner for RecordPatField {}
impl RecordPatField {
pub fn name_ref(&self) -> Option<NameRef> { support::child(&self.syntax) }
pub fn colon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![:]) }
pub fn pat(&self) -> Option<Pat> { support::child(&self.syntax) }
@ -2724,8 +2721,8 @@ impl AstNode for TupleStructPat {
}
fn syntax(&self) -> &SyntaxNode { &self.syntax }
}
impl AstNode for RecordFieldPatList {
fn can_cast(kind: SyntaxKind) -> bool { kind == RECORD_FIELD_PAT_LIST }
impl AstNode for RecordPatFieldList {
fn can_cast(kind: SyntaxKind) -> bool { kind == RECORD_PAT_FIELD_LIST }
fn cast(syntax: SyntaxNode) -> Option<Self> {
if Self::can_cast(syntax.kind()) {
Some(Self { syntax })
@ -2735,8 +2732,8 @@ impl AstNode for RecordFieldPatList {
}
fn syntax(&self) -> &SyntaxNode { &self.syntax }
}
impl AstNode for RecordFieldPat {
fn can_cast(kind: SyntaxKind) -> bool { kind == RECORD_FIELD_PAT }
impl AstNode for RecordPatField {
fn can_cast(kind: SyntaxKind) -> bool { kind == RECORD_PAT_FIELD }
fn cast(syntax: SyntaxNode) -> Option<Self> {
if Self::can_cast(syntax.kind()) {
Some(Self { syntax })
@ -4059,12 +4056,12 @@ impl std::fmt::Display for TupleStructPat {
std::fmt::Display::fmt(self.syntax(), f)
}
}
impl std::fmt::Display for RecordFieldPatList {
impl std::fmt::Display for RecordPatFieldList {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
std::fmt::Display::fmt(self.syntax(), f)
}
}
impl std::fmt::Display for RecordFieldPat {
impl std::fmt::Display for RecordPatField {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
std::fmt::Display::fmt(self.syntax(), f)
}

View File

@ -227,7 +227,7 @@ impl fmt::Display for NameOrNameRef {
}
}
impl ast::RecordFieldPat {
impl ast::RecordPatField {
/// Deals with field init shorthand
pub fn field_name(&self) -> Option<NameOrNameRef> {
if let Some(name_ref) = self.name_ref() {

View File

@ -58,7 +58,7 @@ SOURCE_FILE@0..103
NAME_REF@62..65
IDENT@62..65 "Bar"
WHITESPACE@65..66 " "
RECORD_FIELD_PAT_LIST@66..72
RECORD_PAT_FIELD_LIST@66..72
L_CURLY@66..67 "{"
WHITESPACE@67..68 " "
DOT2@68..70 ".."

View File

@ -20,7 +20,7 @@ SOURCE_FILE@0..119
NAME_REF@19..20
IDENT@19..20 "S"
WHITESPACE@20..21 " "
RECORD_FIELD_PAT_LIST@21..23
RECORD_PAT_FIELD_LIST@21..23
L_CURLY@21..22 "{"
R_CURLY@22..23 "}"
WHITESPACE@23..24 " "
@ -40,16 +40,16 @@ SOURCE_FILE@0..119
NAME_REF@38..39
IDENT@38..39 "S"
WHITESPACE@39..40 " "
RECORD_FIELD_PAT_LIST@40..56
RECORD_PAT_FIELD_LIST@40..56
L_CURLY@40..41 "{"
WHITESPACE@41..42 " "
RECORD_FIELD_PAT@42..43
RECORD_PAT_FIELD@42..43
BIND_PAT@42..43
NAME@42..43
IDENT@42..43 "f"
COMMA@43..44 ","
WHITESPACE@44..45 " "
RECORD_FIELD_PAT@45..54
RECORD_PAT_FIELD@45..54
BIND_PAT@45..54
REF_KW@45..48 "ref"
WHITESPACE@48..49 " "
@ -76,10 +76,10 @@ SOURCE_FILE@0..119
NAME_REF@71..72
IDENT@71..72 "S"
WHITESPACE@72..73 " "
RECORD_FIELD_PAT_LIST@73..84
RECORD_PAT_FIELD_LIST@73..84
L_CURLY@73..74 "{"
WHITESPACE@74..75 " "
RECORD_FIELD_PAT@75..79
RECORD_PAT_FIELD@75..79
NAME_REF@75..76
IDENT@75..76 "h"
COLON@76..77 ":"
@ -107,10 +107,10 @@ SOURCE_FILE@0..119
NAME_REF@99..100
IDENT@99..100 "S"
WHITESPACE@100..101 " "
RECORD_FIELD_PAT_LIST@101..110
RECORD_PAT_FIELD_LIST@101..110
L_CURLY@101..102 "{"
WHITESPACE@102..103 " "
RECORD_FIELD_PAT@103..107
RECORD_PAT_FIELD@103..107
NAME_REF@103..104
IDENT@103..104 "h"
COLON@104..105 ":"

View File

@ -40,10 +40,10 @@ SOURCE_FILE@0..118
NAME_REF@44..49
IDENT@44..49 "Outer"
WHITESPACE@49..50 " "
RECORD_FIELD_PAT_LIST@50..81
RECORD_PAT_FIELD_LIST@50..81
L_CURLY@50..51 "{"
WHITESPACE@51..52 " "
RECORD_FIELD_PAT@52..57
RECORD_PAT_FIELD@52..57
BOX_PAT@52..57
BOX_KW@52..55 "box"
WHITESPACE@55..56 " "
@ -52,7 +52,7 @@ SOURCE_FILE@0..118
IDENT@56..57 "i"
COMMA@57..58 ","
WHITESPACE@58..59 " "
RECORD_FIELD_PAT@59..79
RECORD_PAT_FIELD@59..79
NAME_REF@59..60
IDENT@59..60 "j"
COLON@60..61 ":"

View File

@ -20,10 +20,10 @@ SOURCE_FILE@0..63
NAME_REF@19..20
IDENT@19..20 "S"
WHITESPACE@20..21 " "
RECORD_FIELD_PAT_LIST@21..29
RECORD_PAT_FIELD_LIST@21..29
L_CURLY@21..22 "{"
WHITESPACE@22..23 " "
RECORD_FIELD_PAT@23..27
RECORD_PAT_FIELD@23..27
NAME_REF@23..24
INT_NUMBER@23..24 "0"
COLON@24..25 ":"
@ -50,10 +50,10 @@ SOURCE_FILE@0..63
NAME_REF@44..45
IDENT@44..45 "S"
WHITESPACE@45..46 " "
RECORD_FIELD_PAT_LIST@46..54
RECORD_PAT_FIELD_LIST@46..54
L_CURLY@46..47 "{"
WHITESPACE@47..48 " "
RECORD_FIELD_PAT@48..52
RECORD_PAT_FIELD@48..52
NAME_REF@48..49
IDENT@48..49 "x"
COLON@49..50 ":"

View File

@ -64,16 +64,16 @@ SOURCE_FILE@0..170
NAME_REF@57..58
IDENT@57..58 "S"
WHITESPACE@58..59 " "
RECORD_FIELD_PAT_LIST@59..67
RECORD_PAT_FIELD_LIST@59..67
L_CURLY@59..60 "{"
WHITESPACE@60..61 " "
RECORD_FIELD_PAT@61..62
RECORD_PAT_FIELD@61..62
BIND_PAT@61..62
NAME@61..62
IDENT@61..62 "a"
COMMA@62..63 ","
WHITESPACE@63..64 " "
RECORD_FIELD_PAT@64..65
RECORD_PAT_FIELD@64..65
BIND_PAT@64..65
NAME@64..65
IDENT@64..65 "b"

View File

@ -67,16 +67,16 @@ SOURCE_FILE@0..137
NAME_REF@56..57
IDENT@56..57 "S"
WHITESPACE@57..58 " "
RECORD_FIELD_PAT_LIST@58..66
RECORD_PAT_FIELD_LIST@58..66
L_CURLY@58..59 "{"
WHITESPACE@59..60 " "
RECORD_FIELD_PAT@60..61
RECORD_PAT_FIELD@60..61
BIND_PAT@60..61
NAME@60..61
IDENT@60..61 "a"
COMMA@61..62 ","
WHITESPACE@62..63 " "
RECORD_FIELD_PAT@63..64
RECORD_PAT_FIELD@63..64
BIND_PAT@63..64
NAME@63..64
IDENT@63..64 "b"

View File

@ -131,8 +131,8 @@ pub(crate) const KINDS_SRC: KindsSrc = KindsSrc {
"DOT_DOT_PAT",
"PATH_PAT",
"RECORD_PAT",
"RECORD_FIELD_PAT_LIST",
"RECORD_FIELD_PAT",
"RECORD_PAT_FIELD_LIST",
"RECORD_PAT_FIELD",
"TUPLE_STRUCT_PAT",
"TUPLE_PAT",
"SLICE_PAT",

View File

@ -529,16 +529,15 @@ RefPat =
'&' 'mut'? Pat
RecordPat =
Path RecordFieldPatList
Path RecordPatFieldList
RecordFieldPatList =
RecordPatFieldList =
'{'
record_field_pats:RecordFieldPat*
BindPat*
fields:(RecordPatField (',' RecordPatField)* ','?)
'..'?
'}'
RecordFieldPat =
RecordPatField =
Attr* (NameRef ':')? Pat
OrPat =