mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-30 02:33:55 +00:00
Remove PatWildMulti
This commit is contained in:
parent
cc8d398e28
commit
3468b8d42c
@ -104,7 +104,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
|
||||
hir::PatQPath(..) |
|
||||
hir::PatLit(..) |
|
||||
hir::PatRange(..) |
|
||||
hir::PatWild(_) => {
|
||||
hir::PatWild => {
|
||||
self.add_ast_node(pat.id, &[pred])
|
||||
}
|
||||
|
||||
|
@ -176,7 +176,7 @@ impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> {
|
||||
if mode == Mode::ConstFn {
|
||||
for arg in &fd.inputs {
|
||||
match arg.pat.node {
|
||||
hir::PatWild(_) => {}
|
||||
hir::PatWild => {}
|
||||
hir::PatIdent(hir::BindByValue(hir::MutImmutable), _, None) => {}
|
||||
_ => {
|
||||
span_err!(self.tcx.sess, arg.pat.span, E0022,
|
||||
|
@ -47,7 +47,7 @@ use util::nodemap::FnvHashMap;
|
||||
|
||||
pub const DUMMY_WILD_PAT: &'static Pat = &Pat {
|
||||
id: DUMMY_NODE_ID,
|
||||
node: hir::PatWild(hir::PatWildSingle),
|
||||
node: hir::PatWild,
|
||||
span: DUMMY_SP
|
||||
};
|
||||
|
||||
@ -521,7 +521,7 @@ fn construct_witness<'a,'tcx>(cx: &MatchCheckCtxt<'a,'tcx>, ctor: &Constructor,
|
||||
if let VariantKind::Struct = v.kind() {
|
||||
let field_pats: Vec<_> = v.fields.iter()
|
||||
.zip(pats)
|
||||
.filter(|&(_, ref pat)| pat.node != hir::PatWild(hir::PatWildSingle))
|
||||
.filter(|&(_, ref pat)| pat.node != hir::PatWild)
|
||||
.map(|(field, pat)| Spanned {
|
||||
span: DUMMY_SP,
|
||||
node: hir::FieldPat {
|
||||
@ -553,7 +553,7 @@ fn construct_witness<'a,'tcx>(cx: &MatchCheckCtxt<'a,'tcx>, ctor: &Constructor,
|
||||
},
|
||||
_ => unreachable!()
|
||||
},
|
||||
ty::TyStr => hir::PatWild(hir::PatWildSingle),
|
||||
ty::TyStr => hir::PatWild,
|
||||
|
||||
_ => {
|
||||
assert_eq!(pats_len, 1);
|
||||
@ -570,7 +570,7 @@ fn construct_witness<'a,'tcx>(cx: &MatchCheckCtxt<'a,'tcx>, ctor: &Constructor,
|
||||
_ => {
|
||||
match *ctor {
|
||||
ConstantValue(ref v) => hir::PatLit(const_val_to_expr(v)),
|
||||
_ => hir::PatWild(hir::PatWildSingle),
|
||||
_ => hir::PatWild,
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -799,7 +799,7 @@ fn pat_constructors(cx: &MatchCheckCtxt, p: &Pat,
|
||||
},
|
||||
hir::PatBox(_) | hir::PatTup(_) | hir::PatRegion(..) =>
|
||||
vec!(Single),
|
||||
hir::PatWild(_) =>
|
||||
hir::PatWild =>
|
||||
vec!(),
|
||||
}
|
||||
}
|
||||
@ -862,7 +862,7 @@ pub fn specialize<'a>(cx: &MatchCheckCtxt, r: &[&'a Pat],
|
||||
id: pat_id, ref node, span: pat_span
|
||||
} = raw_pat(r[col]);
|
||||
let head: Option<Vec<&Pat>> = match *node {
|
||||
hir::PatWild(_) =>
|
||||
hir::PatWild =>
|
||||
Some(vec![DUMMY_WILD_PAT; arity]),
|
||||
|
||||
hir::PatIdent(_, _, _) => {
|
||||
|
@ -142,7 +142,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
|
||||
_ => self.tcx.sess.span_bug(lhs.span, "non-ADT in struct pattern")
|
||||
};
|
||||
for pat in pats {
|
||||
if let hir::PatWild(hir::PatWildSingle) = pat.node.pat.node {
|
||||
if let hir::PatWild = pat.node.pat.node {
|
||||
continue;
|
||||
}
|
||||
self.insert_def_id(variant.field_named(pat.node.name).did);
|
||||
|
@ -1141,7 +1141,7 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
|
||||
// will visit the substructure recursively.
|
||||
}
|
||||
|
||||
hir::PatWild(_) | hir::PatTup(..) | hir::PatBox(..) |
|
||||
hir::PatWild | hir::PatTup(..) | hir::PatBox(..) |
|
||||
hir::PatRegion(..) | hir::PatLit(..) | hir::PatRange(..) |
|
||||
hir::PatVec(..) => {
|
||||
// Similarly, each of these cases does not
|
||||
|
@ -1211,7 +1211,7 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
|
||||
};
|
||||
|
||||
match pat.node {
|
||||
hir::PatWild(_) => {
|
||||
hir::PatWild => {
|
||||
// _
|
||||
}
|
||||
|
||||
|
@ -101,7 +101,7 @@ pub fn pat_is_binding(dm: &DefMap, pat: &hir::Pat) -> bool {
|
||||
pub fn pat_is_binding_or_wild(dm: &DefMap, pat: &hir::Pat) -> bool {
|
||||
match pat.node {
|
||||
hir::PatIdent(..) => pat_is_binding(dm, pat),
|
||||
hir::PatWild(_) => true,
|
||||
hir::PatWild => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
|
@ -543,11 +543,6 @@ pub fn check_pat(tcx: &ty::ctxt, pat: &hir::Pat,
|
||||
// Foo(a, b, c)
|
||||
hir::PatEnum(_, Some(ref pat_fields)) => {
|
||||
for (field, struct_field) in pat_fields.iter().zip(&v.fields) {
|
||||
// a .. pattern is fine, but anything positional is
|
||||
// not.
|
||||
if let hir::PatWild(hir::PatWildMulti) = field.node {
|
||||
continue
|
||||
}
|
||||
maybe_do_stability_check(tcx, struct_field.did, field.span, cb)
|
||||
}
|
||||
}
|
||||
|
@ -1010,7 +1010,7 @@ pub fn noop_fold_pat<T: Folder>(p: P<Pat>, folder: &mut T) -> P<Pat> {
|
||||
Pat {
|
||||
id: folder.new_id(id),
|
||||
node: match node {
|
||||
PatWild(k) => PatWild(k),
|
||||
PatWild => PatWild,
|
||||
PatIdent(binding_mode, pth1, sub) => {
|
||||
PatIdent(binding_mode,
|
||||
Spanned {
|
||||
|
@ -24,7 +24,6 @@ pub use self::Item_::*;
|
||||
pub use self::Mutability::*;
|
||||
pub use self::Pat_::*;
|
||||
pub use self::PathListItem_::*;
|
||||
pub use self::PatWildKind::*;
|
||||
pub use self::PrimTy::*;
|
||||
pub use self::Stmt_::*;
|
||||
pub use self::StructFieldKind::*;
|
||||
@ -393,19 +392,10 @@ pub enum BindingMode {
|
||||
BindByValue(Mutability),
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
|
||||
pub enum PatWildKind {
|
||||
/// Represents the wildcard pattern `_`
|
||||
PatWildSingle,
|
||||
|
||||
/// Represents the wildcard pattern `..`
|
||||
PatWildMulti,
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
||||
pub enum Pat_ {
|
||||
/// Represents a wildcard pattern (either `_` or `..`)
|
||||
PatWild(PatWildKind),
|
||||
/// Represents a wildcard pattern (`_`)
|
||||
PatWild,
|
||||
|
||||
/// A PatIdent may either be a new bound variable,
|
||||
/// or a nullary enum (in which case the third field
|
||||
|
@ -818,7 +818,7 @@ pub fn lower_pat(_lctx: &LoweringContext, p: &Pat) -> P<hir::Pat> {
|
||||
P(hir::Pat {
|
||||
id: p.id,
|
||||
node: match p.node {
|
||||
PatWild(k) => hir::PatWild(lower_pat_wild_kind(_lctx, k)),
|
||||
PatWild => hir::PatWild,
|
||||
PatIdent(ref binding_mode, pth1, ref sub) => {
|
||||
hir::PatIdent(lower_binding_mode(_lctx, binding_mode),
|
||||
pth1,
|
||||
@ -1482,13 +1482,6 @@ pub fn lower_block_check_mode(_lctx: &LoweringContext, b: &BlockCheckMode) -> hi
|
||||
}
|
||||
}
|
||||
|
||||
pub fn lower_pat_wild_kind(_lctx: &LoweringContext, p: PatWildKind) -> hir::PatWildKind {
|
||||
match p {
|
||||
PatWildSingle => hir::PatWildSingle,
|
||||
PatWildMulti => hir::PatWildMulti,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn lower_binding_mode(_lctx: &LoweringContext, b: &BindingMode) -> hir::BindingMode {
|
||||
match *b {
|
||||
BindByRef(m) => hir::BindByRef(lower_mutability(_lctx, m)),
|
||||
@ -1670,7 +1663,7 @@ fn pat_ident_binding_mode(lctx: &LoweringContext,
|
||||
}
|
||||
|
||||
fn pat_wild(lctx: &LoweringContext, span: Span) -> P<hir::Pat> {
|
||||
pat(lctx, span, hir::PatWild(hir::PatWildSingle))
|
||||
pat(lctx, span, hir::PatWild)
|
||||
}
|
||||
|
||||
fn pat(lctx: &LoweringContext, span: Span, pat: hir::Pat_) -> P<hir::Pat> {
|
||||
|
@ -1719,8 +1719,7 @@ impl<'a> State<'a> {
|
||||
/* Pat isn't normalized, but the beauty of it
|
||||
is that it doesn't matter */
|
||||
match pat.node {
|
||||
hir::PatWild(hir::PatWildSingle) => try!(word(&mut self.s, "_")),
|
||||
hir::PatWild(hir::PatWildMulti) => try!(word(&mut self.s, "..")),
|
||||
hir::PatWild => try!(word(&mut self.s, "_")),
|
||||
hir::PatIdent(binding_mode, ref path1, ref sub) => {
|
||||
match binding_mode {
|
||||
hir::BindByRef(mutbl) => {
|
||||
@ -1815,13 +1814,10 @@ impl<'a> State<'a> {
|
||||
if !before.is_empty() {
|
||||
try!(self.word_space(","));
|
||||
}
|
||||
if p.node != hir::PatWild {
|
||||
try!(self.print_pat(&**p));
|
||||
match **p {
|
||||
hir::Pat { node: hir::PatWild(hir::PatWildMulti), .. } => {
|
||||
// this case is handled by print_pat
|
||||
}
|
||||
_ => try!(word(&mut self.s, "..")),
|
||||
}
|
||||
try!(word(&mut self.s, ".."));
|
||||
if !after.is_empty() {
|
||||
try!(self.word_space(","));
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ pub fn walk_pat<F>(pat: &Pat, mut it: F) -> bool
|
||||
slice.iter().all(|p| walk_pat_(&**p, it)) &&
|
||||
after.iter().all(|p| walk_pat_(&**p, it))
|
||||
}
|
||||
PatWild(_) |
|
||||
PatWild |
|
||||
PatLit(_) |
|
||||
PatRange(_, _) |
|
||||
PatIdent(_, _, _) |
|
||||
|
@ -466,7 +466,7 @@ pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat) {
|
||||
visitor.visit_expr(lower_bound);
|
||||
visitor.visit_expr(upper_bound)
|
||||
}
|
||||
PatWild(_) => (),
|
||||
PatWild => (),
|
||||
PatVec(ref prepatterns, ref slice_pattern, ref postpatterns) => {
|
||||
walk_list!(visitor, visit_pat, prepatterns);
|
||||
walk_list!(visitor, visit_pat, slice_pattern);
|
||||
|
@ -139,7 +139,7 @@ impl<'tcx> Mirror<'tcx> for PatNode<'tcx> {
|
||||
|
||||
fn make_mirror<'a>(self, cx: &mut Cx<'a, 'tcx>) -> Pattern<'tcx> {
|
||||
let kind = match self.pat.node {
|
||||
hir::PatWild(..) => PatternKind::Wild,
|
||||
hir::PatWild => PatternKind::Wild,
|
||||
|
||||
hir::PatLit(ref value) => {
|
||||
let value = const_eval::eval_const_expr(cx.tcx, value);
|
||||
|
@ -962,7 +962,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> {
|
||||
match self.tcx.pat_ty(pattern).sty {
|
||||
ty::TyStruct(def, _) => {
|
||||
for (i, field) in fields.iter().enumerate() {
|
||||
if let hir::PatWild(..) = field.node {
|
||||
if let hir::PatWild = field.node {
|
||||
continue
|
||||
}
|
||||
self.check_field(field.span,
|
||||
|
@ -866,7 +866,7 @@ fn pick_column_to_specialize(def_map: &DefMap, m: &[Match]) -> Option<usize> {
|
||||
|
||||
let column_contains_any_nonwild_patterns = |&col: &usize| -> bool {
|
||||
m.iter().any(|row| match row.pats[col].node {
|
||||
hir::PatWild(_) => false,
|
||||
hir::PatWild => false,
|
||||
_ => true
|
||||
})
|
||||
};
|
||||
@ -1629,7 +1629,7 @@ fn trans_match_inner<'blk, 'tcx>(scope_cx: Block<'blk, 'tcx>,
|
||||
// to the default arm.
|
||||
let has_default = arms.last().map_or(false, |arm| {
|
||||
arm.pats.len() == 1
|
||||
&& arm.pats.last().unwrap().node == hir::PatWild(hir::PatWildSingle)
|
||||
&& arm.pats.last().unwrap().node == hir::PatWild
|
||||
});
|
||||
|
||||
compile_submatch(bcx, &matches[..], &[discr_datum.match_input()], &chk, has_default);
|
||||
@ -1948,7 +1948,7 @@ pub fn bind_irrefutable_pat<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
cleanup_scope)
|
||||
});
|
||||
}
|
||||
hir::PatQPath(..) | hir::PatWild(_) | hir::PatLit(_) |
|
||||
hir::PatQPath(..) | hir::PatWild | hir::PatLit(_) |
|
||||
hir::PatRange(_, _) => ()
|
||||
}
|
||||
return bcx;
|
||||
|
@ -235,7 +235,7 @@ fn walk_pattern(cx: &CrateContext,
|
||||
}
|
||||
}
|
||||
|
||||
hir::PatWild(_) => {
|
||||
hir::PatWild => {
|
||||
scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata);
|
||||
}
|
||||
|
||||
|
@ -44,7 +44,7 @@ pub fn check_pat<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
|
||||
expected);
|
||||
|
||||
match pat.node {
|
||||
hir::PatWild(_) => {
|
||||
hir::PatWild => {
|
||||
fcx.write_ty(pat.id, expected);
|
||||
}
|
||||
hir::PatLit(ref lt) => {
|
||||
|
@ -2218,7 +2218,7 @@ fn compute_type_scheme_of_foreign_fn_decl<'a, 'tcx>(
|
||||
for i in &decl.inputs {
|
||||
match (*i).pat.node {
|
||||
hir::PatIdent(_, _, _) => (),
|
||||
hir::PatWild(hir::PatWildSingle) => (),
|
||||
hir::PatWild => (),
|
||||
_ => {
|
||||
span_err!(ccx.tcx.sess, (*i).pat.span, E0130,
|
||||
"patterns aren't allowed in foreign function declarations");
|
||||
|
@ -2528,8 +2528,7 @@ fn name_from_pat(p: &hir::Pat) -> String {
|
||||
debug!("Trying to get a name from pattern: {:?}", p);
|
||||
|
||||
match p.node {
|
||||
PatWild(PatWildSingle) => "_".to_string(),
|
||||
PatWild(PatWildMulti) => "..".to_string(),
|
||||
PatWild => "_".to_string(),
|
||||
PatIdent(_, ref p, _) => p.node.to_string(),
|
||||
PatEnum(ref p, _) => path_to_string(p),
|
||||
PatQPath(..) => panic!("tried to get argument name from PatQPath, \
|
||||
|
@ -31,7 +31,6 @@ pub use self::MetaItem_::*;
|
||||
pub use self::Mutability::*;
|
||||
pub use self::Pat_::*;
|
||||
pub use self::PathListItem_::*;
|
||||
pub use self::PatWildKind::*;
|
||||
pub use self::PrimTy::*;
|
||||
pub use self::Sign::*;
|
||||
pub use self::Stmt_::*;
|
||||
@ -569,19 +568,10 @@ pub enum BindingMode {
|
||||
BindByValue(Mutability),
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
|
||||
pub enum PatWildKind {
|
||||
/// Represents the wildcard pattern `_`
|
||||
PatWildSingle,
|
||||
|
||||
/// Represents the wildcard pattern `..`
|
||||
PatWildMulti,
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
||||
pub enum Pat_ {
|
||||
/// Represents a wildcard pattern (either `_` or `..`)
|
||||
PatWild(PatWildKind),
|
||||
/// Represents a wildcard pattern (`_`)
|
||||
PatWild,
|
||||
|
||||
/// A PatIdent may either be a new bound variable,
|
||||
/// or a nullary enum (in which case the third field
|
||||
|
@ -356,7 +356,7 @@ impl DummyResult {
|
||||
pub fn raw_pat(sp: Span) -> ast::Pat {
|
||||
ast::Pat {
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
node: ast::PatWild(ast::PatWildSingle),
|
||||
node: ast::PatWild,
|
||||
span: sp,
|
||||
}
|
||||
}
|
||||
|
@ -801,7 +801,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
|
||||
P(ast::Pat { id: ast::DUMMY_NODE_ID, node: pat, span: span })
|
||||
}
|
||||
fn pat_wild(&self, span: Span) -> P<ast::Pat> {
|
||||
self.pat(span, ast::PatWild(ast::PatWildSingle))
|
||||
self.pat(span, ast::PatWild)
|
||||
}
|
||||
fn pat_lit(&self, span: Span, expr: P<ast::Expr>) -> P<ast::Pat> {
|
||||
self.pat(span, ast::PatLit(expr))
|
||||
|
@ -1125,7 +1125,7 @@ pub fn noop_fold_pat<T: Folder>(p: P<Pat>, folder: &mut T) -> P<Pat> {
|
||||
p.map(|Pat {id, node, span}| Pat {
|
||||
id: folder.new_id(id),
|
||||
node: match node {
|
||||
PatWild(k) => PatWild(k),
|
||||
PatWild => PatWild,
|
||||
PatIdent(binding_mode, pth1, sub) => {
|
||||
PatIdent(binding_mode,
|
||||
Spanned{span: folder.new_span(pth1.span),
|
||||
|
@ -41,8 +41,7 @@ use ast::{MutImmutable, MutMutable, Mac_};
|
||||
use ast::{MutTy, BiMul, Mutability};
|
||||
use ast::{MethodImplItem, NamedField, UnNeg, NoReturn, UnNot};
|
||||
use ast::{Pat, PatBox, PatEnum, PatIdent, PatLit, PatQPath, PatMac, PatRange};
|
||||
use ast::{PatRegion, PatStruct, PatTup, PatVec, PatWild, PatWildMulti};
|
||||
use ast::PatWildSingle;
|
||||
use ast::{PatRegion, PatStruct, PatTup, PatVec, PatWild};
|
||||
use ast::{PolyTraitRef, QSelf};
|
||||
use ast::{Return, BiShl, BiShr, Stmt, StmtDecl};
|
||||
use ast::{StmtExpr, StmtSemi, StmtMac, VariantData, StructField};
|
||||
@ -3078,7 +3077,7 @@ impl<'a> Parser<'a> {
|
||||
self.check(&token::CloseDelim(token::Bracket)) {
|
||||
slice = Some(P(ast::Pat {
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
node: PatWild(PatWildMulti),
|
||||
node: PatWild,
|
||||
span: self.span,
|
||||
}));
|
||||
before_slice = false;
|
||||
@ -3215,7 +3214,7 @@ impl<'a> Parser<'a> {
|
||||
token::Underscore => {
|
||||
// Parse _
|
||||
try!(self.bump());
|
||||
pat = PatWild(PatWildSingle);
|
||||
pat = PatWild;
|
||||
}
|
||||
token::BinOp(token::And) | token::AndAnd => {
|
||||
// Parse &pat / &mut pat
|
||||
|
@ -2406,8 +2406,7 @@ impl<'a> State<'a> {
|
||||
/* Pat isn't normalized, but the beauty of it
|
||||
is that it doesn't matter */
|
||||
match pat.node {
|
||||
ast::PatWild(ast::PatWildSingle) => try!(word(&mut self.s, "_")),
|
||||
ast::PatWild(ast::PatWildMulti) => try!(word(&mut self.s, "..")),
|
||||
ast::PatWild => try!(word(&mut self.s, "_")),
|
||||
ast::PatIdent(binding_mode, ref path1, ref sub) => {
|
||||
match binding_mode {
|
||||
ast::BindByRef(mutbl) => {
|
||||
@ -2503,13 +2502,10 @@ impl<'a> State<'a> {
|
||||
|s, p| s.print_pat(&**p)));
|
||||
if let Some(ref p) = *slice {
|
||||
if !before.is_empty() { try!(self.word_space(",")); }
|
||||
if p.node != ast::PatWild {
|
||||
try!(self.print_pat(&**p));
|
||||
match **p {
|
||||
ast::Pat { node: ast::PatWild(ast::PatWildMulti), .. } => {
|
||||
// this case is handled by print_pat
|
||||
}
|
||||
_ => try!(word(&mut self.s, "..")),
|
||||
}
|
||||
try!(word(&mut self.s, ".."));
|
||||
if !after.is_empty() { try!(self.word_space(",")); }
|
||||
}
|
||||
try!(self.commasep(Inconsistent,
|
||||
|
@ -451,7 +451,7 @@ pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat) {
|
||||
visitor.visit_expr(lower_bound);
|
||||
visitor.visit_expr(upper_bound)
|
||||
}
|
||||
PatWild(_) => (),
|
||||
PatWild => (),
|
||||
PatVec(ref prepatterns, ref slice_pattern, ref postpatterns) => {
|
||||
walk_list!(visitor, visit_pat, prepatterns);
|
||||
walk_list!(visitor, visit_pat, slice_pattern);
|
||||
|
@ -10,7 +10,7 @@ digraph block {
|
||||
N8[label="(dummy_node)"];
|
||||
N9[label="local x"];
|
||||
N10[label="local y"];
|
||||
N11[label="pat .."];
|
||||
N11[label="pat _"];
|
||||
N12[label="pat [x, y, ..]"];
|
||||
N13[label="expr x"];
|
||||
N14[label="expr y"];
|
||||
|
Loading…
Reference in New Issue
Block a user