mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-18 09:53:26 +00:00
rustc_builtin_macros
: remove ref
patterns
... and other pattern matching improvements
This commit is contained in:
parent
244990a6e9
commit
700c095306
@ -17,31 +17,22 @@ pub fn expand(
|
|||||||
check_builtin_macro_attribute(ecx, meta_item, sym::alloc_error_handler);
|
check_builtin_macro_attribute(ecx, meta_item, sym::alloc_error_handler);
|
||||||
|
|
||||||
let orig_item = item.clone();
|
let orig_item = item.clone();
|
||||||
let not_function = || {
|
|
||||||
ecx.sess
|
|
||||||
.parse_sess
|
|
||||||
.span_diagnostic
|
|
||||||
.span_err(item.span(), "alloc_error_handler must be a function");
|
|
||||||
vec![orig_item.clone()]
|
|
||||||
};
|
|
||||||
|
|
||||||
// Allow using `#[alloc_error_handler]` on an item statement
|
// Allow using `#[alloc_error_handler]` on an item statement
|
||||||
// FIXME - if we get deref patterns, use them to reduce duplication here
|
// FIXME - if we get deref patterns, use them to reduce duplication here
|
||||||
let (item, is_stmt, sig_span) = match &item {
|
let (item, is_stmt, sig_span) =
|
||||||
Annotatable::Item(item) => match item.kind {
|
if let Annotatable::Item(item) = &item
|
||||||
ItemKind::Fn(ref fn_kind) => (item, false, ecx.with_def_site_ctxt(fn_kind.sig.span)),
|
&& let ItemKind::Fn(fn_kind) = &item.kind
|
||||||
_ => return not_function(),
|
{
|
||||||
},
|
(item, false, ecx.with_def_site_ctxt(fn_kind.sig.span))
|
||||||
Annotatable::Stmt(stmt) => match &stmt.kind {
|
} else if let Annotatable::Stmt(stmt) = &item
|
||||||
StmtKind::Item(item_) => match item_.kind {
|
&& let StmtKind::Item(item) = &stmt.kind
|
||||||
ItemKind::Fn(ref fn_kind) => {
|
&& let ItemKind::Fn(fn_kind) = &item.kind
|
||||||
(item_, true, ecx.with_def_site_ctxt(fn_kind.sig.span))
|
{
|
||||||
}
|
(item, true, ecx.with_def_site_ctxt(fn_kind.sig.span))
|
||||||
_ => return not_function(),
|
} else {
|
||||||
},
|
ecx.sess.parse_sess.span_diagnostic.span_err(item.span(), "alloc_error_handler must be a function");
|
||||||
_ => return not_function(),
|
return vec![orig_item.clone()];
|
||||||
},
|
|
||||||
_ => return not_function(),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Generate a bunch of new items using the AllocFnFactory
|
// Generate a bunch of new items using the AllocFnFactory
|
||||||
|
@ -191,19 +191,19 @@ impl<'cx, 'a> Context<'cx, 'a> {
|
|||||||
///
|
///
|
||||||
/// See [Self::manage_initial_capture] and [Self::manage_try_capture]
|
/// See [Self::manage_initial_capture] and [Self::manage_try_capture]
|
||||||
fn manage_cond_expr(&mut self, expr: &mut P<Expr>) {
|
fn manage_cond_expr(&mut self, expr: &mut P<Expr>) {
|
||||||
match (*expr).kind {
|
match &mut expr.kind {
|
||||||
ExprKind::AddrOf(_, mutability, ref mut local_expr) => {
|
ExprKind::AddrOf(_, mutability, local_expr) => {
|
||||||
self.with_is_consumed_management(
|
self.with_is_consumed_management(
|
||||||
matches!(mutability, Mutability::Mut),
|
matches!(mutability, Mutability::Mut),
|
||||||
|this| this.manage_cond_expr(local_expr)
|
|this| this.manage_cond_expr(local_expr)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
ExprKind::Array(ref mut local_exprs) => {
|
ExprKind::Array(local_exprs) => {
|
||||||
for local_expr in local_exprs {
|
for local_expr in local_exprs {
|
||||||
self.manage_cond_expr(local_expr);
|
self.manage_cond_expr(local_expr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ExprKind::Binary(ref op, ref mut lhs, ref mut rhs) => {
|
ExprKind::Binary(op, lhs, rhs) => {
|
||||||
self.with_is_consumed_management(
|
self.with_is_consumed_management(
|
||||||
matches!(
|
matches!(
|
||||||
op.node,
|
op.node,
|
||||||
@ -226,56 +226,56 @@ impl<'cx, 'a> Context<'cx, 'a> {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
ExprKind::Call(_, ref mut local_exprs) => {
|
ExprKind::Call(_, local_exprs) => {
|
||||||
for local_expr in local_exprs {
|
for local_expr in local_exprs {
|
||||||
self.manage_cond_expr(local_expr);
|
self.manage_cond_expr(local_expr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ExprKind::Cast(ref mut local_expr, _) => {
|
ExprKind::Cast(local_expr, _) => {
|
||||||
self.manage_cond_expr(local_expr);
|
self.manage_cond_expr(local_expr);
|
||||||
}
|
}
|
||||||
ExprKind::Index(ref mut prefix, ref mut suffix) => {
|
ExprKind::Index(prefix, suffix) => {
|
||||||
self.manage_cond_expr(prefix);
|
self.manage_cond_expr(prefix);
|
||||||
self.manage_cond_expr(suffix);
|
self.manage_cond_expr(suffix);
|
||||||
}
|
}
|
||||||
ExprKind::MethodCall(ref mut call) => {
|
ExprKind::MethodCall(call) => {
|
||||||
for arg in call.args.iter_mut() {
|
for arg in &mut call.args {
|
||||||
self.manage_cond_expr(arg);
|
self.manage_cond_expr(arg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ExprKind::Path(_, Path { ref segments, .. }) if let &[ref path_segment] = &segments[..] => {
|
ExprKind::Path(_, Path { segments, .. }) if let [path_segment] = &segments[..] => {
|
||||||
let path_ident = path_segment.ident;
|
let path_ident = path_segment.ident;
|
||||||
self.manage_initial_capture(expr, path_ident);
|
self.manage_initial_capture(expr, path_ident);
|
||||||
}
|
}
|
||||||
ExprKind::Paren(ref mut local_expr) => {
|
ExprKind::Paren(local_expr) => {
|
||||||
self.manage_cond_expr(local_expr);
|
self.manage_cond_expr(local_expr);
|
||||||
}
|
}
|
||||||
ExprKind::Range(ref mut prefix, ref mut suffix, _) => {
|
ExprKind::Range(prefix, suffix, _) => {
|
||||||
if let Some(ref mut elem) = prefix {
|
if let Some(elem) = prefix {
|
||||||
self.manage_cond_expr(elem);
|
self.manage_cond_expr(elem);
|
||||||
}
|
}
|
||||||
if let Some(ref mut elem) = suffix {
|
if let Some(elem) = suffix {
|
||||||
self.manage_cond_expr(elem);
|
self.manage_cond_expr(elem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ExprKind::Repeat(ref mut local_expr, ref mut elem) => {
|
ExprKind::Repeat(local_expr, elem) => {
|
||||||
self.manage_cond_expr(local_expr);
|
self.manage_cond_expr(local_expr);
|
||||||
self.manage_cond_expr(&mut elem.value);
|
self.manage_cond_expr(&mut elem.value);
|
||||||
}
|
}
|
||||||
ExprKind::Struct(ref mut elem) => {
|
ExprKind::Struct(elem) => {
|
||||||
for field in &mut elem.fields {
|
for field in &mut elem.fields {
|
||||||
self.manage_cond_expr(&mut field.expr);
|
self.manage_cond_expr(&mut field.expr);
|
||||||
}
|
}
|
||||||
if let StructRest::Base(ref mut local_expr) = elem.rest {
|
if let StructRest::Base(local_expr) = &mut elem.rest {
|
||||||
self.manage_cond_expr(local_expr);
|
self.manage_cond_expr(local_expr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ExprKind::Tup(ref mut local_exprs) => {
|
ExprKind::Tup(local_exprs) => {
|
||||||
for local_expr in local_exprs {
|
for local_expr in local_exprs {
|
||||||
self.manage_cond_expr(local_expr);
|
self.manage_cond_expr(local_expr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ExprKind::Unary(un_op, ref mut local_expr) => {
|
ExprKind::Unary(un_op, local_expr) => {
|
||||||
self.with_is_consumed_management(
|
self.with_is_consumed_management(
|
||||||
matches!(un_op, UnOp::Neg | UnOp::Not),
|
matches!(un_op, UnOp::Neg | UnOp::Not),
|
||||||
|this| this.manage_cond_expr(local_expr)
|
|this| this.manage_cond_expr(local_expr)
|
||||||
|
@ -20,7 +20,7 @@ pub fn expand_concat(
|
|||||||
for e in es {
|
for e in es {
|
||||||
match e.kind {
|
match e.kind {
|
||||||
ast::ExprKind::Lit(token_lit) => match ast::LitKind::from_token_lit(token_lit) {
|
ast::ExprKind::Lit(token_lit) => match ast::LitKind::from_token_lit(token_lit) {
|
||||||
Ok(ast::LitKind::Str(ref s, _) | ast::LitKind::Float(ref s, _)) => {
|
Ok(ast::LitKind::Str(s, _) | ast::LitKind::Float(s, _)) => {
|
||||||
accumulator.push_str(s.as_str());
|
accumulator.push_str(s.as_str());
|
||||||
}
|
}
|
||||||
Ok(ast::LitKind::Char(c)) => {
|
Ok(ast::LitKind::Char(c)) => {
|
||||||
|
@ -144,8 +144,8 @@ pub fn expand_concat_bytes(
|
|||||||
let mut missing_literals = vec![];
|
let mut missing_literals = vec![];
|
||||||
let mut has_errors = false;
|
let mut has_errors = false;
|
||||||
for e in es {
|
for e in es {
|
||||||
match e.kind {
|
match &e.kind {
|
||||||
ast::ExprKind::Array(ref exprs) => {
|
ast::ExprKind::Array(exprs) => {
|
||||||
for expr in exprs {
|
for expr in exprs {
|
||||||
if let Some(elem) =
|
if let Some(elem) =
|
||||||
handle_array_element(cx, &mut has_errors, &mut missing_literals, expr)
|
handle_array_element(cx, &mut has_errors, &mut missing_literals, expr)
|
||||||
@ -154,7 +154,7 @@ pub fn expand_concat_bytes(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast::ExprKind::Repeat(ref expr, ref count) => {
|
ast::ExprKind::Repeat(expr, count) => {
|
||||||
if let ast::ExprKind::Lit(token_lit) = count.value.kind
|
if let ast::ExprKind::Lit(token_lit) = count.value.kind
|
||||||
&& let Ok(ast::LitKind::Int(count_val, _)) =
|
&& let Ok(ast::LitKind::Int(count_val, _)) =
|
||||||
ast::LitKind::from_token_lit(token_lit)
|
ast::LitKind::from_token_lit(token_lit)
|
||||||
@ -170,7 +170,7 @@ pub fn expand_concat_bytes(
|
|||||||
cx.span_err(count.value.span, "repeat count is not a positive number");
|
cx.span_err(count.value.span, "repeat count is not a positive number");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast::ExprKind::Lit(token_lit) => match ast::LitKind::from_token_lit(token_lit) {
|
&ast::ExprKind::Lit(token_lit) => match ast::LitKind::from_token_lit(token_lit) {
|
||||||
Ok(ast::LitKind::Byte(val)) => {
|
Ok(ast::LitKind::Byte(val)) => {
|
||||||
accumulator.push(val);
|
accumulator.push(val);
|
||||||
}
|
}
|
||||||
@ -184,7 +184,7 @@ pub fn expand_concat_bytes(
|
|||||||
has_errors = true;
|
has_errors = true;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
ast::ExprKind::IncludedBytes(ref bytes) => {
|
ast::ExprKind::IncludedBytes(bytes) => {
|
||||||
accumulator.extend_from_slice(bytes);
|
accumulator.extend_from_slice(bytes);
|
||||||
}
|
}
|
||||||
ast::ExprKind::Err => {
|
ast::ExprKind::Err => {
|
||||||
|
@ -32,10 +32,10 @@ pub fn expand_deriving_clone(
|
|||||||
let bounds;
|
let bounds;
|
||||||
let substructure;
|
let substructure;
|
||||||
let is_simple;
|
let is_simple;
|
||||||
match *item {
|
match item {
|
||||||
Annotatable::Item(ref annitem) => match annitem.kind {
|
Annotatable::Item(annitem) => match &annitem.kind {
|
||||||
ItemKind::Struct(_, Generics { ref params, .. })
|
ItemKind::Struct(_, Generics { params, .. })
|
||||||
| ItemKind::Enum(_, Generics { ref params, .. }) => {
|
| ItemKind::Enum(_, Generics { params, .. }) => {
|
||||||
let container_id = cx.current_expansion.id.expn_data().parent.expect_local();
|
let container_id = cx.current_expansion.id.expn_data().parent.expect_local();
|
||||||
let has_derive_copy = cx.resolver.has_derive_copy(container_id);
|
let has_derive_copy = cx.resolver.has_derive_copy(container_id);
|
||||||
if has_derive_copy
|
if has_derive_copy
|
||||||
@ -166,13 +166,13 @@ fn cs_clone(
|
|||||||
};
|
};
|
||||||
|
|
||||||
let vdata;
|
let vdata;
|
||||||
match *substr.fields {
|
match substr.fields {
|
||||||
Struct(vdata_, ref af) => {
|
Struct(vdata_, af) => {
|
||||||
ctor_path = cx.path(trait_span, vec![substr.type_ident]);
|
ctor_path = cx.path(trait_span, vec![substr.type_ident]);
|
||||||
all_fields = af;
|
all_fields = af;
|
||||||
vdata = vdata_;
|
vdata = *vdata_;
|
||||||
}
|
}
|
||||||
EnumMatching(.., variant, ref af) => {
|
EnumMatching(.., variant, af) => {
|
||||||
ctor_path = cx.path(trait_span, vec![substr.type_ident, variant.ident]);
|
ctor_path = cx.path(trait_span, vec![substr.type_ident, variant.ident]);
|
||||||
all_fields = af;
|
all_fields = af;
|
||||||
vdata = &variant.data;
|
vdata = &variant.data;
|
||||||
|
@ -78,11 +78,11 @@ fn decodable_substructure(
|
|||||||
let blkarg = Ident::new(sym::_d, trait_span);
|
let blkarg = Ident::new(sym::_d, trait_span);
|
||||||
let blkdecoder = cx.expr_ident(trait_span, blkarg);
|
let blkdecoder = cx.expr_ident(trait_span, blkarg);
|
||||||
|
|
||||||
let expr = match *substr.fields {
|
let expr = match substr.fields {
|
||||||
StaticStruct(_, ref summary) => {
|
StaticStruct(_, summary) => {
|
||||||
let nfields = match *summary {
|
let nfields = match summary {
|
||||||
Unnamed(ref fields, _) => fields.len(),
|
Unnamed(fields, _) => fields.len(),
|
||||||
Named(ref fields) => fields.len(),
|
Named(fields) => fields.len(),
|
||||||
};
|
};
|
||||||
let fn_read_struct_field_path: Vec<_> =
|
let fn_read_struct_field_path: Vec<_> =
|
||||||
cx.def_site_path(&[sym::rustc_serialize, sym::Decoder, sym::read_struct_field]);
|
cx.def_site_path(&[sym::rustc_serialize, sym::Decoder, sym::read_struct_field]);
|
||||||
@ -119,7 +119,7 @@ fn decodable_substructure(
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
StaticEnum(_, ref fields) => {
|
StaticEnum(_, fields) => {
|
||||||
let variant = Ident::new(sym::i, trait_span);
|
let variant = Ident::new(sym::i, trait_span);
|
||||||
|
|
||||||
let mut arms = Vec::with_capacity(fields.len() + 1);
|
let mut arms = Vec::with_capacity(fields.len() + 1);
|
||||||
@ -194,10 +194,10 @@ fn decode_static_fields<F>(
|
|||||||
where
|
where
|
||||||
F: FnMut(&mut ExtCtxt<'_>, Span, Symbol, usize) -> P<Expr>,
|
F: FnMut(&mut ExtCtxt<'_>, Span, Symbol, usize) -> P<Expr>,
|
||||||
{
|
{
|
||||||
match *fields {
|
match fields {
|
||||||
Unnamed(ref fields, is_tuple) => {
|
Unnamed(fields, is_tuple) => {
|
||||||
let path_expr = cx.expr_path(outer_pat_path);
|
let path_expr = cx.expr_path(outer_pat_path);
|
||||||
if !is_tuple {
|
if !*is_tuple {
|
||||||
path_expr
|
path_expr
|
||||||
} else {
|
} else {
|
||||||
let fields = fields
|
let fields = fields
|
||||||
@ -209,7 +209,7 @@ where
|
|||||||
cx.expr_call(trait_span, path_expr, fields)
|
cx.expr_call(trait_span, path_expr, fields)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Named(ref fields) => {
|
Named(fields) => {
|
||||||
// use the field's span to get nicer error messages.
|
// use the field's span to get nicer error messages.
|
||||||
let fields = fields
|
let fields = fields
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -62,15 +62,12 @@ fn default_struct_substructure(
|
|||||||
let default_call = |span| cx.expr_call_global(span, default_ident.clone(), Vec::new());
|
let default_call = |span| cx.expr_call_global(span, default_ident.clone(), Vec::new());
|
||||||
|
|
||||||
let expr = match summary {
|
let expr = match summary {
|
||||||
Unnamed(ref fields, is_tuple) => {
|
Unnamed(_, false) => cx.expr_ident(trait_span, substr.type_ident),
|
||||||
if !is_tuple {
|
Unnamed(fields, true) => {
|
||||||
cx.expr_ident(trait_span, substr.type_ident)
|
|
||||||
} else {
|
|
||||||
let exprs = fields.iter().map(|sp| default_call(*sp)).collect();
|
let exprs = fields.iter().map(|sp| default_call(*sp)).collect();
|
||||||
cx.expr_call_ident(trait_span, substr.type_ident, exprs)
|
cx.expr_call_ident(trait_span, substr.type_ident, exprs)
|
||||||
}
|
}
|
||||||
}
|
Named(fields) => {
|
||||||
Named(ref fields) => {
|
|
||||||
let default_fields = fields
|
let default_fields = fields
|
||||||
.iter()
|
.iter()
|
||||||
.map(|&(ident, span)| cx.field_imm(span, ident, default_call(span)))
|
.map(|&(ident, span)| cx.field_imm(span, ident, default_call(span)))
|
||||||
|
@ -164,8 +164,8 @@ fn encodable_substructure(
|
|||||||
],
|
],
|
||||||
));
|
));
|
||||||
|
|
||||||
match *substr.fields {
|
match substr.fields {
|
||||||
Struct(_, ref fields) => {
|
Struct(_, fields) => {
|
||||||
let fn_emit_struct_field_path =
|
let fn_emit_struct_field_path =
|
||||||
cx.def_site_path(&[sym::rustc_serialize, sym::Encoder, sym::emit_struct_field]);
|
cx.def_site_path(&[sym::rustc_serialize, sym::Encoder, sym::emit_struct_field]);
|
||||||
let mut stmts = Vec::new();
|
let mut stmts = Vec::new();
|
||||||
@ -224,7 +224,7 @@ fn encodable_substructure(
|
|||||||
BlockOrExpr::new_expr(expr)
|
BlockOrExpr::new_expr(expr)
|
||||||
}
|
}
|
||||||
|
|
||||||
EnumMatching(idx, _, variant, ref fields) => {
|
EnumMatching(idx, _, variant, fields) => {
|
||||||
// We're not generating an AST that the borrow checker is expecting,
|
// We're not generating an AST that the borrow checker is expecting,
|
||||||
// so we need to generate a unique local variable to take the
|
// so we need to generate a unique local variable to take the
|
||||||
// mutable loan out on, otherwise we get conflicts which don't
|
// mutable loan out on, otherwise we get conflicts which don't
|
||||||
@ -274,7 +274,7 @@ fn encodable_substructure(
|
|||||||
vec![
|
vec![
|
||||||
blkencoder,
|
blkencoder,
|
||||||
name,
|
name,
|
||||||
cx.expr_usize(trait_span, idx),
|
cx.expr_usize(trait_span, *idx),
|
||||||
cx.expr_usize(trait_span, fields.len()),
|
cx.expr_usize(trait_span, fields.len()),
|
||||||
blk,
|
blk,
|
||||||
],
|
],
|
||||||
|
@ -369,16 +369,15 @@ fn find_type_parameters(
|
|||||||
|
|
||||||
impl<'a, 'b> visit::Visitor<'a> for Visitor<'a, 'b> {
|
impl<'a, 'b> visit::Visitor<'a> for Visitor<'a, 'b> {
|
||||||
fn visit_ty(&mut self, ty: &'a ast::Ty) {
|
fn visit_ty(&mut self, ty: &'a ast::Ty) {
|
||||||
if let ast::TyKind::Path(_, ref path) = ty.kind {
|
if let ast::TyKind::Path(_, path) = &ty.kind
|
||||||
if let Some(segment) = path.segments.first() {
|
&& let Some(segment) = path.segments.first()
|
||||||
if self.ty_param_names.contains(&segment.ident.name) {
|
&& self.ty_param_names.contains(&segment.ident.name)
|
||||||
|
{
|
||||||
self.type_params.push(TypeParameter {
|
self.type_params.push(TypeParameter {
|
||||||
bound_generic_params: self.bound_generic_params_stack.clone(),
|
bound_generic_params: self.bound_generic_params_stack.clone(),
|
||||||
ty: P(ty.clone()),
|
ty: P(ty.clone()),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
visit::walk_ty(self, ty)
|
visit::walk_ty(self, ty)
|
||||||
}
|
}
|
||||||
@ -428,8 +427,8 @@ impl<'a> TraitDef<'a> {
|
|||||||
push: &mut dyn FnMut(Annotatable),
|
push: &mut dyn FnMut(Annotatable),
|
||||||
from_scratch: bool,
|
from_scratch: bool,
|
||||||
) {
|
) {
|
||||||
match *item {
|
match item {
|
||||||
Annotatable::Item(ref item) => {
|
Annotatable::Item(item) => {
|
||||||
let is_packed = item.attrs.iter().any(|attr| {
|
let is_packed = item.attrs.iter().any(|attr| {
|
||||||
for r in attr::find_repr_attrs(&cx.sess, attr) {
|
for r in attr::find_repr_attrs(&cx.sess, attr) {
|
||||||
if let attr::ReprPacked(_) = r {
|
if let attr::ReprPacked(_) = r {
|
||||||
@ -438,10 +437,10 @@ impl<'a> TraitDef<'a> {
|
|||||||
}
|
}
|
||||||
false
|
false
|
||||||
});
|
});
|
||||||
let has_no_type_params = match item.kind {
|
let has_no_type_params = match &item.kind {
|
||||||
ast::ItemKind::Struct(_, ref generics)
|
ast::ItemKind::Struct(_, generics)
|
||||||
| ast::ItemKind::Enum(_, ref generics)
|
| ast::ItemKind::Enum(_, generics)
|
||||||
| ast::ItemKind::Union(_, ref generics) => !generics
|
| ast::ItemKind::Union(_, generics) => !generics
|
||||||
.params
|
.params
|
||||||
.iter()
|
.iter()
|
||||||
.any(|param| matches!(param.kind, ast::GenericParamKind::Type { .. })),
|
.any(|param| matches!(param.kind, ast::GenericParamKind::Type { .. })),
|
||||||
@ -451,8 +450,8 @@ impl<'a> TraitDef<'a> {
|
|||||||
let copy_fields =
|
let copy_fields =
|
||||||
is_packed && has_no_type_params && cx.resolver.has_derive_copy(container_id);
|
is_packed && has_no_type_params && cx.resolver.has_derive_copy(container_id);
|
||||||
|
|
||||||
let newitem = match item.kind {
|
let newitem = match &item.kind {
|
||||||
ast::ItemKind::Struct(ref struct_def, ref generics) => self.expand_struct_def(
|
ast::ItemKind::Struct(struct_def, generics) => self.expand_struct_def(
|
||||||
cx,
|
cx,
|
||||||
&struct_def,
|
&struct_def,
|
||||||
item.ident,
|
item.ident,
|
||||||
@ -460,7 +459,7 @@ impl<'a> TraitDef<'a> {
|
|||||||
from_scratch,
|
from_scratch,
|
||||||
copy_fields,
|
copy_fields,
|
||||||
),
|
),
|
||||||
ast::ItemKind::Enum(ref enum_def, ref generics) => {
|
ast::ItemKind::Enum(enum_def, generics) => {
|
||||||
// We ignore `is_packed` here, because `repr(packed)`
|
// We ignore `is_packed` here, because `repr(packed)`
|
||||||
// enums cause an error later on.
|
// enums cause an error later on.
|
||||||
//
|
//
|
||||||
@ -468,7 +467,7 @@ impl<'a> TraitDef<'a> {
|
|||||||
// downstream in blatantly illegal code, so it is fine.
|
// downstream in blatantly illegal code, so it is fine.
|
||||||
self.expand_enum_def(cx, enum_def, item.ident, generics, from_scratch)
|
self.expand_enum_def(cx, enum_def, item.ident, generics, from_scratch)
|
||||||
}
|
}
|
||||||
ast::ItemKind::Union(ref struct_def, ref generics) => {
|
ast::ItemKind::Union(struct_def, generics) => {
|
||||||
if self.supports_unions {
|
if self.supports_unions {
|
||||||
self.expand_struct_def(
|
self.expand_struct_def(
|
||||||
cx,
|
cx,
|
||||||
@ -663,12 +662,11 @@ impl<'a> TraitDef<'a> {
|
|||||||
|
|
||||||
for field_ty_param in field_ty_params {
|
for field_ty_param in field_ty_params {
|
||||||
// if we have already handled this type, skip it
|
// if we have already handled this type, skip it
|
||||||
if let ast::TyKind::Path(_, ref p) = field_ty_param.ty.kind {
|
if let ast::TyKind::Path(_, p) = &field_ty_param.ty.kind
|
||||||
if p.segments.len() == 1
|
&& let [sole_segment] = &*p.segments
|
||||||
&& ty_param_names.contains(&p.segments[0].ident.name)
|
&& ty_param_names.contains(&sole_segment.ident.name)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
};
|
|
||||||
}
|
}
|
||||||
let mut bounds: Vec<_> = self
|
let mut bounds: Vec<_> = self
|
||||||
.additional_bounds
|
.additional_bounds
|
||||||
|
@ -115,7 +115,7 @@ impl Ty {
|
|||||||
self_ty: Ident,
|
self_ty: Ident,
|
||||||
generics: &Generics,
|
generics: &Generics,
|
||||||
) -> ast::Path {
|
) -> ast::Path {
|
||||||
match *self {
|
match self {
|
||||||
Self_ => {
|
Self_ => {
|
||||||
let params: Vec<_> = generics
|
let params: Vec<_> = generics
|
||||||
.params
|
.params
|
||||||
@ -135,7 +135,7 @@ impl Ty {
|
|||||||
|
|
||||||
cx.path_all(span, false, vec![self_ty], params)
|
cx.path_all(span, false, vec![self_ty], params)
|
||||||
}
|
}
|
||||||
Path(ref p) => p.to_path(cx, span, self_ty, generics),
|
Path(p) => p.to_path(cx, span, self_ty, generics),
|
||||||
Ref(..) => cx.span_bug(span, "ref in a path in generic `derive`"),
|
Ref(..) => cx.span_bug(span, "ref in a path in generic `derive`"),
|
||||||
Unit => cx.span_bug(span, "unit in a path in generic `derive`"),
|
Unit => cx.span_bug(span, "unit in a path in generic `derive`"),
|
||||||
}
|
}
|
||||||
@ -180,10 +180,7 @@ impl Bounds {
|
|||||||
let params = self
|
let params = self
|
||||||
.bounds
|
.bounds
|
||||||
.iter()
|
.iter()
|
||||||
.map(|t| {
|
.map(|&(name, ref bounds)| mk_ty_param(cx, span, name, &bounds, self_ty, self_generics))
|
||||||
let (name, ref bounds) = *t;
|
|
||||||
mk_ty_param(cx, span, name, &bounds, self_ty, self_generics)
|
|
||||||
})
|
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
Generics {
|
Generics {
|
||||||
|
@ -125,12 +125,12 @@ fn inject_impl_of_structural_trait(
|
|||||||
structural_path: generic::ty::Path,
|
structural_path: generic::ty::Path,
|
||||||
push: &mut dyn FnMut(Annotatable),
|
push: &mut dyn FnMut(Annotatable),
|
||||||
) {
|
) {
|
||||||
let Annotatable::Item(ref item) = *item else {
|
let Annotatable::Item(item) = item else {
|
||||||
unreachable!();
|
unreachable!();
|
||||||
};
|
};
|
||||||
|
|
||||||
let generics = match item.kind {
|
let generics = match &item.kind {
|
||||||
ItemKind::Struct(_, ref generics) | ItemKind::Enum(_, ref generics) => generics,
|
ItemKind::Struct(_, generics) | ItemKind::Enum(_, generics) => generics,
|
||||||
// Do not inject `impl Structural for Union`. (`PartialEq` does not
|
// Do not inject `impl Structural for Union`. (`PartialEq` does not
|
||||||
// support unions, so we will see error downstream.)
|
// support unions, so we will see error downstream.)
|
||||||
ItemKind::Union(..) => return,
|
ItemKind::Union(..) => return,
|
||||||
|
@ -53,7 +53,7 @@ pub fn expand_env<'cx>(
|
|||||||
tts: TokenStream,
|
tts: TokenStream,
|
||||||
) -> Box<dyn base::MacResult + 'cx> {
|
) -> Box<dyn base::MacResult + 'cx> {
|
||||||
let mut exprs = match get_exprs_from_tts(cx, sp, tts) {
|
let mut exprs = match get_exprs_from_tts(cx, sp, tts) {
|
||||||
Some(ref exprs) if exprs.is_empty() => {
|
Some(exprs) if exprs.is_empty() => {
|
||||||
cx.span_err(sp, "env! takes 1 or 2 arguments");
|
cx.span_err(sp, "env! takes 1 or 2 arguments");
|
||||||
return DummyResult::any(sp);
|
return DummyResult::any(sp);
|
||||||
}
|
}
|
||||||
|
@ -13,23 +13,23 @@ pub(crate) mod printf {
|
|||||||
|
|
||||||
impl<'a> Substitution<'a> {
|
impl<'a> Substitution<'a> {
|
||||||
pub fn as_str(&self) -> &str {
|
pub fn as_str(&self) -> &str {
|
||||||
match *self {
|
match self {
|
||||||
Substitution::Format(ref fmt) => fmt.span,
|
Substitution::Format(fmt) => fmt.span,
|
||||||
Substitution::Escape(_) => "%%",
|
Substitution::Escape(_) => "%%",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn position(&self) -> Option<InnerSpan> {
|
pub fn position(&self) -> Option<InnerSpan> {
|
||||||
match *self {
|
match self {
|
||||||
Substitution::Format(ref fmt) => Some(fmt.position),
|
Substitution::Format(fmt) => Some(fmt.position),
|
||||||
Substitution::Escape((start, end)) => Some(InnerSpan::new(start, end)),
|
&Substitution::Escape((start, end)) => Some(InnerSpan::new(start, end)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_position(&mut self, start: usize, end: usize) {
|
pub fn set_position(&mut self, start: usize, end: usize) {
|
||||||
match self {
|
match self {
|
||||||
Substitution::Format(ref mut fmt) => fmt.position = InnerSpan::new(start, end),
|
Substitution::Format(fmt) => fmt.position = InnerSpan::new(start, end),
|
||||||
Substitution::Escape(ref mut pos) => *pos = (start, end),
|
Substitution::Escape(pos) => *pos = (start, end),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -38,8 +38,8 @@ pub(crate) mod printf {
|
|||||||
/// This ignores cases where the substitution does not have an exact equivalent, or where
|
/// This ignores cases where the substitution does not have an exact equivalent, or where
|
||||||
/// the substitution would be unnecessary.
|
/// the substitution would be unnecessary.
|
||||||
pub fn translate(&self) -> Result<String, Option<String>> {
|
pub fn translate(&self) -> Result<String, Option<String>> {
|
||||||
match *self {
|
match self {
|
||||||
Substitution::Format(ref fmt) => fmt.translate(),
|
Substitution::Format(fmt) => fmt.translate(),
|
||||||
Substitution::Escape(_) => Err(None),
|
Substitution::Escape(_) => Err(None),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -635,23 +635,17 @@ pub mod shell {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn position(&self) -> Option<InnerSpan> {
|
pub fn position(&self) -> Option<InnerSpan> {
|
||||||
match self {
|
let (Self::Ordinal(_, pos) | Self::Name(_, pos) | Self::Escape(pos)) = self;
|
||||||
Substitution::Ordinal(_, pos)
|
Some(InnerSpan::new(pos.0, pos.1))
|
||||||
| Substitution::Name(_, pos)
|
|
||||||
| Substitution::Escape(pos) => Some(InnerSpan::new(pos.0, pos.1)),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_position(&mut self, start: usize, end: usize) {
|
pub fn set_position(&mut self, start: usize, end: usize) {
|
||||||
match self {
|
let (Self::Ordinal(_, pos) | Self::Name(_, pos) | Self::Escape(pos)) = self;
|
||||||
Substitution::Ordinal(_, ref mut pos)
|
*pos = (start, end);
|
||||||
| Substitution::Name(_, ref mut pos)
|
|
||||||
| Substitution::Escape(ref mut pos) => *pos = (start, end),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn translate(&self) -> Result<String, Option<String>> {
|
pub fn translate(&self) -> Result<String, Option<String>> {
|
||||||
match *self {
|
match self {
|
||||||
Substitution::Ordinal(n, _) => Ok(format!("{{{}}}", n)),
|
Substitution::Ordinal(n, _) => Ok(format!("{{{}}}", n)),
|
||||||
Substitution::Name(n, _) => Ok(format!("{{{}}}", n)),
|
Substitution::Name(n, _) => Ok(format!("{{{}}}", n)),
|
||||||
Substitution::Escape(_) => Err(None),
|
Substitution::Escape(_) => Err(None),
|
||||||
|
@ -20,26 +20,22 @@ pub fn expand(
|
|||||||
check_builtin_macro_attribute(ecx, meta_item, sym::global_allocator);
|
check_builtin_macro_attribute(ecx, meta_item, sym::global_allocator);
|
||||||
|
|
||||||
let orig_item = item.clone();
|
let orig_item = item.clone();
|
||||||
let not_static = || {
|
|
||||||
ecx.sess.parse_sess.span_diagnostic.span_err(item.span(), "allocators must be statics");
|
|
||||||
vec![orig_item.clone()]
|
|
||||||
};
|
|
||||||
|
|
||||||
// Allow using `#[global_allocator]` on an item statement
|
// Allow using `#[global_allocator]` on an item statement
|
||||||
// FIXME - if we get deref patterns, use them to reduce duplication here
|
// FIXME - if we get deref patterns, use them to reduce duplication here
|
||||||
let (item, is_stmt, ty_span) = match &item {
|
let (item, is_stmt, ty_span) =
|
||||||
Annotatable::Item(item) => match item.kind {
|
if let Annotatable::Item(item) = &item
|
||||||
ItemKind::Static(ref ty, ..) => (item, false, ecx.with_def_site_ctxt(ty.span)),
|
&& let ItemKind::Static(ty, ..) = &item.kind
|
||||||
_ => return not_static(),
|
{
|
||||||
},
|
(item, false, ecx.with_def_site_ctxt(ty.span))
|
||||||
Annotatable::Stmt(stmt) => match &stmt.kind {
|
} else if let Annotatable::Stmt(stmt) = &item
|
||||||
StmtKind::Item(item_) => match item_.kind {
|
&& let StmtKind::Item(item) = &stmt.kind
|
||||||
ItemKind::Static(ref ty, ..) => (item_, true, ecx.with_def_site_ctxt(ty.span)),
|
&& let ItemKind::Static(ty, ..) = &item.kind
|
||||||
_ => return not_static(),
|
{
|
||||||
},
|
(item, true, ecx.with_def_site_ctxt(ty.span))
|
||||||
_ => return not_static(),
|
} else {
|
||||||
},
|
ecx.sess.parse_sess.span_diagnostic.span_err(item.span(), "allocators must be statics");
|
||||||
_ => return not_static(),
|
return vec![orig_item.clone()]
|
||||||
};
|
};
|
||||||
|
|
||||||
// Generate a bunch of new items using the AllocFnFactory
|
// Generate a bunch of new items using the AllocFnFactory
|
||||||
|
@ -466,7 +466,8 @@ fn test_type(cx: &ExtCtxt<'_>) -> TestType {
|
|||||||
fn has_test_signature(cx: &ExtCtxt<'_>, i: &ast::Item) -> bool {
|
fn has_test_signature(cx: &ExtCtxt<'_>, i: &ast::Item) -> bool {
|
||||||
let has_should_panic_attr = cx.sess.contains_name(&i.attrs, sym::should_panic);
|
let has_should_panic_attr = cx.sess.contains_name(&i.attrs, sym::should_panic);
|
||||||
let sd = &cx.sess.parse_sess.span_diagnostic;
|
let sd = &cx.sess.parse_sess.span_diagnostic;
|
||||||
if let ast::ItemKind::Fn(box ast::Fn { ref sig, ref generics, .. }) = i.kind {
|
match &i.kind {
|
||||||
|
ast::ItemKind::Fn(box ast::Fn { sig, generics, .. }) => {
|
||||||
if let ast::Unsafe::Yes(span) = sig.header.unsafety {
|
if let ast::Unsafe::Yes(span) = sig.header.unsafety {
|
||||||
sd.struct_span_err(i.span, "unsafe functions cannot be used for tests")
|
sd.struct_span_err(i.span, "unsafe functions cannot be used for tests")
|
||||||
.span_label(span, "`unsafe` because of this")
|
.span_label(span, "`unsafe` because of this")
|
||||||
@ -482,9 +483,9 @@ fn has_test_signature(cx: &ExtCtxt<'_>, i: &ast::Item) -> bool {
|
|||||||
|
|
||||||
// If the termination trait is active, the compiler will check that the output
|
// If the termination trait is active, the compiler will check that the output
|
||||||
// type implements the `Termination` trait as `libtest` enforces that.
|
// type implements the `Termination` trait as `libtest` enforces that.
|
||||||
let has_output = match sig.decl.output {
|
let has_output = match &sig.decl.output {
|
||||||
ast::FnRetTy::Default(..) => false,
|
ast::FnRetTy::Default(..) => false,
|
||||||
ast::FnRetTy::Ty(ref t) if t.kind.is_unit() => false,
|
ast::FnRetTy::Ty(t) if t.kind.is_unit() => false,
|
||||||
_ => true,
|
_ => true,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -500,7 +501,10 @@ fn has_test_signature(cx: &ExtCtxt<'_>, i: &ast::Item) -> bool {
|
|||||||
}
|
}
|
||||||
(true, false) => {
|
(true, false) => {
|
||||||
if !generics.params.is_empty() {
|
if !generics.params.is_empty() {
|
||||||
sd.span_err(i.span, "functions used as tests must have signature fn() -> ()");
|
sd.span_err(
|
||||||
|
i.span,
|
||||||
|
"functions used as tests must have signature fn() -> ()",
|
||||||
|
);
|
||||||
false
|
false
|
||||||
} else {
|
} else {
|
||||||
true
|
true
|
||||||
@ -508,19 +512,21 @@ fn has_test_signature(cx: &ExtCtxt<'_>, i: &ast::Item) -> bool {
|
|||||||
}
|
}
|
||||||
(false, _) => true,
|
(false, _) => true,
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
_ => {
|
||||||
// should be unreachable because `is_test_fn_item` should catch all non-fn items
|
// should be unreachable because `is_test_fn_item` should catch all non-fn items
|
||||||
|
debug_assert!(false);
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn has_bench_signature(cx: &ExtCtxt<'_>, i: &ast::Item) -> bool {
|
fn has_bench_signature(cx: &ExtCtxt<'_>, i: &ast::Item) -> bool {
|
||||||
let has_sig = if let ast::ItemKind::Fn(box ast::Fn { ref sig, .. }) = i.kind {
|
let has_sig = match &i.kind {
|
||||||
// N.B., inadequate check, but we're running
|
// N.B., inadequate check, but we're running
|
||||||
// well before resolve, can't get too deep.
|
// well before resolve, can't get too deep.
|
||||||
sig.decl.inputs.len() == 1
|
ast::ItemKind::Fn(box ast::Fn { sig, .. }) => sig.decl.inputs.len() == 1,
|
||||||
} else {
|
_ => false,
|
||||||
false
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if !has_sig {
|
if !has_sig {
|
||||||
|
@ -131,8 +131,9 @@ impl<'a> MutVisitor for TestHarnessGenerator<'a> {
|
|||||||
|
|
||||||
// We don't want to recurse into anything other than mods, since
|
// We don't want to recurse into anything other than mods, since
|
||||||
// mods or tests inside of functions will break things
|
// mods or tests inside of functions will break things
|
||||||
if let ast::ItemKind::Mod(_, ModKind::Loaded(.., ref spans)) = item.kind {
|
if let ast::ItemKind::Mod(_, ModKind::Loaded(.., ast::ModSpans { inner_span: span, .. })) =
|
||||||
let ast::ModSpans { inner_span: span, inject_use_span: _ } = *spans;
|
item.kind
|
||||||
|
{
|
||||||
let prev_tests = mem::take(&mut self.tests);
|
let prev_tests = mem::take(&mut self.tests);
|
||||||
noop_visit_item_kind(&mut item.kind, self);
|
noop_visit_item_kind(&mut item.kind, self);
|
||||||
self.add_test_cases(item.id, span, prev_tests);
|
self.add_test_cases(item.id, span, prev_tests);
|
||||||
|
Loading…
Reference in New Issue
Block a user