mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-22 12:43:36 +00:00
Add validation check for ambiguous trait objects
This commit is contained in:
parent
87cb840a4e
commit
6f38552edb
@ -3,10 +3,11 @@
|
||||
mod block;
|
||||
|
||||
use crate::{
|
||||
ast, match_ast, AstNode, SyntaxError,
|
||||
algo, ast, match_ast, AstNode, SyntaxError,
|
||||
SyntaxKind::{BYTE, BYTE_STRING, CHAR, CONST, FN, INT_NUMBER, STRING, TYPE_ALIAS},
|
||||
SyntaxNode, SyntaxToken, TextSize, T,
|
||||
};
|
||||
use rowan::Direction;
|
||||
use rustc_lexer::unescape::{
|
||||
self, unescape_byte, unescape_byte_literal, unescape_char, unescape_literal, Mode,
|
||||
};
|
||||
@ -95,6 +96,9 @@ pub(crate) fn validate(root: &SyntaxNode) -> Vec<SyntaxError> {
|
||||
ast::Visibility(it) => validate_visibility(it, &mut errors),
|
||||
ast::RangeExpr(it) => validate_range_expr(it, &mut errors),
|
||||
ast::PathSegment(it) => validate_path_keywords(it, &mut errors),
|
||||
ast::RefType(it) => validate_trait_object_ref_ty(it, &mut errors),
|
||||
ast::PtrType(it) => validate_trait_object_ptr_ty(it, &mut errors),
|
||||
ast::FnPtrType(it) => validate_trait_object_fn_ptr_ret_ty(it, &mut errors),
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
@ -301,3 +305,42 @@ fn validate_path_keywords(segment: ast::PathSegment, errors: &mut Vec<SyntaxErro
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
fn validate_trait_object_ref_ty(ty: ast::RefType, errors: &mut Vec<SyntaxError>) {
|
||||
if let Some(ast::Type::DynTraitType(ty)) = ty.ty() {
|
||||
if let Some(err) = validate_trait_object_ty(ty) {
|
||||
errors.push(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn validate_trait_object_ptr_ty(ty: ast::PtrType, errors: &mut Vec<SyntaxError>) {
|
||||
if let Some(ast::Type::DynTraitType(ty)) = ty.ty() {
|
||||
if let Some(err) = validate_trait_object_ty(ty) {
|
||||
errors.push(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn validate_trait_object_fn_ptr_ret_ty(ty: ast::FnPtrType, errors: &mut Vec<SyntaxError>) {
|
||||
if let Some(ast::Type::DynTraitType(ty)) = ty.ret_type().and_then(|ty| ty.ty()) {
|
||||
if let Some(err) = validate_trait_object_ty(ty) {
|
||||
errors.push(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn validate_trait_object_ty(ty: ast::DynTraitType) -> Option<SyntaxError> {
|
||||
let tbl = ty.type_bound_list()?;
|
||||
|
||||
if tbl.bounds().count() > 1 {
|
||||
let dyn_token = ty.dyn_token()?;
|
||||
let potential_parentheses =
|
||||
algo::skip_trivia_token(dyn_token.prev_token()?, Direction::Prev)?;
|
||||
let kind = potential_parentheses.kind();
|
||||
if !matches!(kind, T!['('] | T![<] | T![=]) {
|
||||
return Some(SyntaxError::new("ambiguous `+` in a type", ty.syntax().text_range()));
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
@ -0,0 +1,192 @@
|
||||
SOURCE_FILE@0..187
|
||||
TYPE_ALIAS@0..35
|
||||
TYPE_KW@0..4 "type"
|
||||
WHITESPACE@4..5 " "
|
||||
NAME@5..8
|
||||
IDENT@5..8 "Foo"
|
||||
GENERIC_PARAM_LIST@8..12
|
||||
L_ANGLE@8..9 "<"
|
||||
LIFETIME_PARAM@9..11
|
||||
LIFETIME@9..11 "\'a"
|
||||
R_ANGLE@11..12 ">"
|
||||
WHITESPACE@12..13 " "
|
||||
EQ@13..14 "="
|
||||
WHITESPACE@14..15 " "
|
||||
REF_TYPE@15..34
|
||||
AMP@15..16 "&"
|
||||
LIFETIME@16..18 "\'a"
|
||||
WHITESPACE@18..19 " "
|
||||
DYN_TRAIT_TYPE@19..34
|
||||
DYN_KW@19..22 "dyn"
|
||||
WHITESPACE@22..23 " "
|
||||
TYPE_BOUND_LIST@23..34
|
||||
TYPE_BOUND@23..27
|
||||
PATH_TYPE@23..27
|
||||
PATH@23..27
|
||||
PATH_SEGMENT@23..27
|
||||
NAME_REF@23..27
|
||||
IDENT@23..27 "Send"
|
||||
WHITESPACE@27..28 " "
|
||||
PLUS@28..29 "+"
|
||||
WHITESPACE@29..30 " "
|
||||
TYPE_BOUND@30..34
|
||||
PATH_TYPE@30..34
|
||||
PATH@30..34
|
||||
PATH_SEGMENT@30..34
|
||||
NAME_REF@30..34
|
||||
IDENT@30..34 "Sync"
|
||||
SEMICOLON@34..35 ";"
|
||||
WHITESPACE@35..36 "\n"
|
||||
TYPE_ALIAS@36..70
|
||||
TYPE_KW@36..40 "type"
|
||||
WHITESPACE@40..41 " "
|
||||
NAME@41..44
|
||||
IDENT@41..44 "Foo"
|
||||
WHITESPACE@44..45 " "
|
||||
EQ@45..46 "="
|
||||
WHITESPACE@46..47 " "
|
||||
PTR_TYPE@47..69
|
||||
STAR@47..48 "*"
|
||||
CONST_KW@48..53 "const"
|
||||
WHITESPACE@53..54 " "
|
||||
DYN_TRAIT_TYPE@54..69
|
||||
DYN_KW@54..57 "dyn"
|
||||
WHITESPACE@57..58 " "
|
||||
TYPE_BOUND_LIST@58..69
|
||||
TYPE_BOUND@58..62
|
||||
PATH_TYPE@58..62
|
||||
PATH@58..62
|
||||
PATH_SEGMENT@58..62
|
||||
NAME_REF@58..62
|
||||
IDENT@58..62 "Send"
|
||||
WHITESPACE@62..63 " "
|
||||
PLUS@63..64 "+"
|
||||
WHITESPACE@64..65 " "
|
||||
TYPE_BOUND@65..69
|
||||
PATH_TYPE@65..69
|
||||
PATH@65..69
|
||||
PATH_SEGMENT@65..69
|
||||
NAME_REF@65..69
|
||||
IDENT@65..69 "Sync"
|
||||
SEMICOLON@69..70 ";"
|
||||
WHITESPACE@70..71 "\n"
|
||||
TYPE_ALIAS@71..109
|
||||
TYPE_KW@71..75 "type"
|
||||
WHITESPACE@75..76 " "
|
||||
NAME@76..79
|
||||
IDENT@76..79 "Foo"
|
||||
WHITESPACE@79..80 " "
|
||||
EQ@80..81 "="
|
||||
WHITESPACE@81..82 " "
|
||||
FN_PTR_TYPE@82..108
|
||||
FN_KW@82..84 "fn"
|
||||
PARAM_LIST@84..86
|
||||
L_PAREN@84..85 "("
|
||||
R_PAREN@85..86 ")"
|
||||
WHITESPACE@86..87 " "
|
||||
RET_TYPE@87..108
|
||||
THIN_ARROW@87..89 "->"
|
||||
WHITESPACE@89..90 " "
|
||||
DYN_TRAIT_TYPE@90..108
|
||||
DYN_KW@90..93 "dyn"
|
||||
WHITESPACE@93..94 " "
|
||||
TYPE_BOUND_LIST@94..108
|
||||
TYPE_BOUND@94..98
|
||||
PATH_TYPE@94..98
|
||||
PATH@94..98
|
||||
PATH_SEGMENT@94..98
|
||||
NAME_REF@94..98
|
||||
IDENT@94..98 "Send"
|
||||
WHITESPACE@98..99 " "
|
||||
PLUS@99..100 "+"
|
||||
WHITESPACE@100..101 " "
|
||||
TYPE_BOUND@101..108
|
||||
LIFETIME@101..108 "\'static"
|
||||
SEMICOLON@108..109 ";"
|
||||
WHITESPACE@109..110 "\n"
|
||||
FN@110..186
|
||||
FN_KW@110..112 "fn"
|
||||
WHITESPACE@112..113 " "
|
||||
NAME@113..117
|
||||
IDENT@113..117 "main"
|
||||
PARAM_LIST@117..119
|
||||
L_PAREN@117..118 "("
|
||||
R_PAREN@118..119 ")"
|
||||
WHITESPACE@119..120 " "
|
||||
BLOCK_EXPR@120..186
|
||||
L_CURLY@120..121 "{"
|
||||
WHITESPACE@121..126 "\n "
|
||||
LET_STMT@126..184
|
||||
LET_KW@126..129 "let"
|
||||
WHITESPACE@129..130 " "
|
||||
IDENT_PAT@130..131
|
||||
NAME@130..131
|
||||
IDENT@130..131 "b"
|
||||
WHITESPACE@131..132 " "
|
||||
EQ@132..133 "="
|
||||
WHITESPACE@133..134 " "
|
||||
CAST_EXPR@134..183
|
||||
PAREN_EXPR@134..138
|
||||
L_PAREN@134..135 "("
|
||||
REF_EXPR@135..137
|
||||
AMP@135..136 "&"
|
||||
PATH_EXPR@136..137
|
||||
PATH@136..137
|
||||
PATH_SEGMENT@136..137
|
||||
NAME_REF@136..137
|
||||
IDENT@136..137 "a"
|
||||
R_PAREN@137..138 ")"
|
||||
WHITESPACE@138..139 " "
|
||||
AS_KW@139..141 "as"
|
||||
WHITESPACE@141..142 " "
|
||||
REF_TYPE@142..183
|
||||
AMP@142..143 "&"
|
||||
DYN_TRAIT_TYPE@143..183
|
||||
DYN_KW@143..146 "dyn"
|
||||
WHITESPACE@146..147 " "
|
||||
TYPE_BOUND_LIST@147..183
|
||||
TYPE_BOUND@147..175
|
||||
PATH_TYPE@147..175
|
||||
PATH@147..175
|
||||
PATH_SEGMENT@147..175
|
||||
NAME_REF@147..150
|
||||
IDENT@147..150 "Add"
|
||||
GENERIC_ARG_LIST@150..175
|
||||
L_ANGLE@150..151 "<"
|
||||
TYPE_ARG@151..156
|
||||
PATH_TYPE@151..156
|
||||
PATH@151..156
|
||||
PATH_SEGMENT@151..156
|
||||
NAME_REF@151..156
|
||||
IDENT@151..156 "Other"
|
||||
COMMA@156..157 ","
|
||||
WHITESPACE@157..158 " "
|
||||
ASSOC_TYPE_ARG@158..174
|
||||
NAME_REF@158..164
|
||||
IDENT@158..164 "Output"
|
||||
WHITESPACE@164..165 " "
|
||||
EQ@165..166 "="
|
||||
WHITESPACE@166..167 " "
|
||||
PATH_TYPE@167..174
|
||||
PATH@167..174
|
||||
PATH_SEGMENT@167..174
|
||||
NAME_REF@167..174
|
||||
IDENT@167..174 "Addable"
|
||||
R_ANGLE@174..175 ">"
|
||||
WHITESPACE@175..176 " "
|
||||
PLUS@176..177 "+"
|
||||
WHITESPACE@177..178 " "
|
||||
TYPE_BOUND@178..183
|
||||
PATH_TYPE@178..183
|
||||
PATH@178..183
|
||||
PATH_SEGMENT@178..183
|
||||
NAME_REF@178..183
|
||||
IDENT@178..183 "Other"
|
||||
SEMICOLON@183..184 ";"
|
||||
WHITESPACE@184..185 "\n"
|
||||
R_CURLY@185..186 "}"
|
||||
WHITESPACE@186..187 "\n"
|
||||
error 19..34: ambiguous `+` in a type
|
||||
error 54..69: ambiguous `+` in a type
|
||||
error 90..108: ambiguous `+` in a type
|
||||
error 143..183: ambiguous `+` in a type
|
@ -0,0 +1,6 @@
|
||||
type Foo<'a> = &'a dyn Send + Sync;
|
||||
type Foo = *const dyn Send + Sync;
|
||||
type Foo = fn() -> dyn Send + 'static;
|
||||
fn main() {
|
||||
let b = (&a) as &dyn Add<Other, Output = Addable> + Other;
|
||||
}
|
200
crates/syntax/test_data/parser/ok/0069_multi_trait_object.rast
Normal file
200
crates/syntax/test_data/parser/ok/0069_multi_trait_object.rast
Normal file
@ -0,0 +1,200 @@
|
||||
SOURCE_FILE@0..195
|
||||
TYPE_ALIAS@0..37
|
||||
TYPE_KW@0..4 "type"
|
||||
WHITESPACE@4..5 " "
|
||||
NAME@5..8
|
||||
IDENT@5..8 "Foo"
|
||||
GENERIC_PARAM_LIST@8..12
|
||||
L_ANGLE@8..9 "<"
|
||||
LIFETIME_PARAM@9..11
|
||||
LIFETIME@9..11 "\'a"
|
||||
R_ANGLE@11..12 ">"
|
||||
WHITESPACE@12..13 " "
|
||||
EQ@13..14 "="
|
||||
WHITESPACE@14..15 " "
|
||||
REF_TYPE@15..36
|
||||
AMP@15..16 "&"
|
||||
LIFETIME@16..18 "\'a"
|
||||
WHITESPACE@18..19 " "
|
||||
PAREN_TYPE@19..36
|
||||
L_PAREN@19..20 "("
|
||||
DYN_TRAIT_TYPE@20..35
|
||||
DYN_KW@20..23 "dyn"
|
||||
WHITESPACE@23..24 " "
|
||||
TYPE_BOUND_LIST@24..35
|
||||
TYPE_BOUND@24..28
|
||||
PATH_TYPE@24..28
|
||||
PATH@24..28
|
||||
PATH_SEGMENT@24..28
|
||||
NAME_REF@24..28
|
||||
IDENT@24..28 "Send"
|
||||
WHITESPACE@28..29 " "
|
||||
PLUS@29..30 "+"
|
||||
WHITESPACE@30..31 " "
|
||||
TYPE_BOUND@31..35
|
||||
PATH_TYPE@31..35
|
||||
PATH@31..35
|
||||
PATH_SEGMENT@31..35
|
||||
NAME_REF@31..35
|
||||
IDENT@31..35 "Sync"
|
||||
R_PAREN@35..36 ")"
|
||||
SEMICOLON@36..37 ";"
|
||||
WHITESPACE@37..38 "\n"
|
||||
TYPE_ALIAS@38..74
|
||||
TYPE_KW@38..42 "type"
|
||||
WHITESPACE@42..43 " "
|
||||
NAME@43..46
|
||||
IDENT@43..46 "Foo"
|
||||
WHITESPACE@46..47 " "
|
||||
EQ@47..48 "="
|
||||
WHITESPACE@48..49 " "
|
||||
PTR_TYPE@49..73
|
||||
STAR@49..50 "*"
|
||||
CONST_KW@50..55 "const"
|
||||
WHITESPACE@55..56 " "
|
||||
PAREN_TYPE@56..73
|
||||
L_PAREN@56..57 "("
|
||||
DYN_TRAIT_TYPE@57..72
|
||||
DYN_KW@57..60 "dyn"
|
||||
WHITESPACE@60..61 " "
|
||||
TYPE_BOUND_LIST@61..72
|
||||
TYPE_BOUND@61..65
|
||||
PATH_TYPE@61..65
|
||||
PATH@61..65
|
||||
PATH_SEGMENT@61..65
|
||||
NAME_REF@61..65
|
||||
IDENT@61..65 "Send"
|
||||
WHITESPACE@65..66 " "
|
||||
PLUS@66..67 "+"
|
||||
WHITESPACE@67..68 " "
|
||||
TYPE_BOUND@68..72
|
||||
PATH_TYPE@68..72
|
||||
PATH@68..72
|
||||
PATH_SEGMENT@68..72
|
||||
NAME_REF@68..72
|
||||
IDENT@68..72 "Sync"
|
||||
R_PAREN@72..73 ")"
|
||||
SEMICOLON@73..74 ";"
|
||||
WHITESPACE@74..75 "\n"
|
||||
TYPE_ALIAS@75..115
|
||||
TYPE_KW@75..79 "type"
|
||||
WHITESPACE@79..80 " "
|
||||
NAME@80..83
|
||||
IDENT@80..83 "Foo"
|
||||
WHITESPACE@83..84 " "
|
||||
EQ@84..85 "="
|
||||
WHITESPACE@85..86 " "
|
||||
FN_PTR_TYPE@86..114
|
||||
FN_KW@86..88 "fn"
|
||||
PARAM_LIST@88..90
|
||||
L_PAREN@88..89 "("
|
||||
R_PAREN@89..90 ")"
|
||||
WHITESPACE@90..91 " "
|
||||
RET_TYPE@91..114
|
||||
THIN_ARROW@91..93 "->"
|
||||
WHITESPACE@93..94 " "
|
||||
PAREN_TYPE@94..114
|
||||
L_PAREN@94..95 "("
|
||||
DYN_TRAIT_TYPE@95..113
|
||||
DYN_KW@95..98 "dyn"
|
||||
WHITESPACE@98..99 " "
|
||||
TYPE_BOUND_LIST@99..113
|
||||
TYPE_BOUND@99..103
|
||||
PATH_TYPE@99..103
|
||||
PATH@99..103
|
||||
PATH_SEGMENT@99..103
|
||||
NAME_REF@99..103
|
||||
IDENT@99..103 "Send"
|
||||
WHITESPACE@103..104 " "
|
||||
PLUS@104..105 "+"
|
||||
WHITESPACE@105..106 " "
|
||||
TYPE_BOUND@106..113
|
||||
LIFETIME@106..113 "\'static"
|
||||
R_PAREN@113..114 ")"
|
||||
SEMICOLON@114..115 ";"
|
||||
WHITESPACE@115..116 "\n"
|
||||
FN@116..194
|
||||
FN_KW@116..118 "fn"
|
||||
WHITESPACE@118..119 " "
|
||||
NAME@119..123
|
||||
IDENT@119..123 "main"
|
||||
PARAM_LIST@123..125
|
||||
L_PAREN@123..124 "("
|
||||
R_PAREN@124..125 ")"
|
||||
WHITESPACE@125..126 " "
|
||||
BLOCK_EXPR@126..194
|
||||
L_CURLY@126..127 "{"
|
||||
WHITESPACE@127..132 "\n "
|
||||
LET_STMT@132..192
|
||||
LET_KW@132..135 "let"
|
||||
WHITESPACE@135..136 " "
|
||||
IDENT_PAT@136..137
|
||||
NAME@136..137
|
||||
IDENT@136..137 "b"
|
||||
WHITESPACE@137..138 " "
|
||||
EQ@138..139 "="
|
||||
WHITESPACE@139..140 " "
|
||||
CAST_EXPR@140..191
|
||||
PAREN_EXPR@140..144
|
||||
L_PAREN@140..141 "("
|
||||
REF_EXPR@141..143
|
||||
AMP@141..142 "&"
|
||||
PATH_EXPR@142..143
|
||||
PATH@142..143
|
||||
PATH_SEGMENT@142..143
|
||||
NAME_REF@142..143
|
||||
IDENT@142..143 "a"
|
||||
R_PAREN@143..144 ")"
|
||||
WHITESPACE@144..145 " "
|
||||
AS_KW@145..147 "as"
|
||||
WHITESPACE@147..148 " "
|
||||
REF_TYPE@148..191
|
||||
AMP@148..149 "&"
|
||||
PAREN_TYPE@149..191
|
||||
L_PAREN@149..150 "("
|
||||
DYN_TRAIT_TYPE@150..190
|
||||
DYN_KW@150..153 "dyn"
|
||||
WHITESPACE@153..154 " "
|
||||
TYPE_BOUND_LIST@154..190
|
||||
TYPE_BOUND@154..182
|
||||
PATH_TYPE@154..182
|
||||
PATH@154..182
|
||||
PATH_SEGMENT@154..182
|
||||
NAME_REF@154..157
|
||||
IDENT@154..157 "Add"
|
||||
GENERIC_ARG_LIST@157..182
|
||||
L_ANGLE@157..158 "<"
|
||||
TYPE_ARG@158..163
|
||||
PATH_TYPE@158..163
|
||||
PATH@158..163
|
||||
PATH_SEGMENT@158..163
|
||||
NAME_REF@158..163
|
||||
IDENT@158..163 "Other"
|
||||
COMMA@163..164 ","
|
||||
WHITESPACE@164..165 " "
|
||||
ASSOC_TYPE_ARG@165..181
|
||||
NAME_REF@165..171
|
||||
IDENT@165..171 "Output"
|
||||
WHITESPACE@171..172 " "
|
||||
EQ@172..173 "="
|
||||
WHITESPACE@173..174 " "
|
||||
PATH_TYPE@174..181
|
||||
PATH@174..181
|
||||
PATH_SEGMENT@174..181
|
||||
NAME_REF@174..181
|
||||
IDENT@174..181 "Addable"
|
||||
R_ANGLE@181..182 ">"
|
||||
WHITESPACE@182..183 " "
|
||||
PLUS@183..184 "+"
|
||||
WHITESPACE@184..185 " "
|
||||
TYPE_BOUND@185..190
|
||||
PATH_TYPE@185..190
|
||||
PATH@185..190
|
||||
PATH_SEGMENT@185..190
|
||||
NAME_REF@185..190
|
||||
IDENT@185..190 "Other"
|
||||
R_PAREN@190..191 ")"
|
||||
SEMICOLON@191..192 ";"
|
||||
WHITESPACE@192..193 "\n"
|
||||
R_CURLY@193..194 "}"
|
||||
WHITESPACE@194..195 "\n"
|
@ -0,0 +1,6 @@
|
||||
type Foo<'a> = &'a (dyn Send + Sync);
|
||||
type Foo = *const (dyn Send + Sync);
|
||||
type Foo = fn() -> (dyn Send + 'static);
|
||||
fn main() {
|
||||
let b = (&a) as &(dyn Add<Other, Output = Addable> + Other);
|
||||
}
|
Loading…
Reference in New Issue
Block a user