Factor out the repeated assert_ty_bounds function.

This commit is contained in:
Nicholas Nethercote 2022-06-22 16:34:43 +10:00
parent e7396685a1
commit b7855fa9de
4 changed files with 42 additions and 44 deletions

View File

@ -3,9 +3,9 @@ use crate::deriving::generic::*;
use crate::deriving::path_std; use crate::deriving::path_std;
use rustc_ast::ptr::P; use rustc_ast::ptr::P;
use rustc_ast::{self as ast, Expr, GenericArg, Generics, ItemKind, MetaItem, VariantData}; use rustc_ast::{self as ast, Expr, Generics, ItemKind, MetaItem, VariantData};
use rustc_expand::base::{Annotatable, ExtCtxt}; use rustc_expand::base::{Annotatable, ExtCtxt};
use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::symbol::{kw, sym, Ident};
use rustc_span::Span; use rustc_span::Span;
pub fn expand_deriving_clone( pub fn expand_deriving_clone(
@ -107,28 +107,16 @@ fn cs_clone_shallow(
substr: &Substructure<'_>, substr: &Substructure<'_>,
is_union: bool, is_union: bool,
) -> P<Expr> { ) -> P<Expr> {
fn assert_ty_bounds(
cx: &mut ExtCtxt<'_>,
stmts: &mut Vec<ast::Stmt>,
ty: P<ast::Ty>,
span: Span,
helper_name: &str,
) {
// Generate statement `let _: helper_name<ty>;`,
// set the expn ID so we can use the unstable struct.
let span = cx.with_def_site_ctxt(span);
let assert_path = cx.path_all(
span,
true,
cx.std_path(&[sym::clone, Symbol::intern(helper_name)]),
vec![GenericArg::Type(ty)],
);
stmts.push(cx.stmt_let_type_only(span, cx.ty_path(assert_path)));
}
fn process_variant(cx: &mut ExtCtxt<'_>, stmts: &mut Vec<ast::Stmt>, variant: &VariantData) { fn process_variant(cx: &mut ExtCtxt<'_>, stmts: &mut Vec<ast::Stmt>, variant: &VariantData) {
for field in variant.fields() { for field in variant.fields() {
// let _: AssertParamIsClone<FieldTy>; // let _: AssertParamIsClone<FieldTy>;
assert_ty_bounds(cx, stmts, field.ty.clone(), field.span, "AssertParamIsClone"); super::assert_ty_bounds(
cx,
stmts,
field.ty.clone(),
field.span,
&[sym::clone, sym::AssertParamIsClone],
);
} }
} }
@ -136,7 +124,13 @@ fn cs_clone_shallow(
if is_union { if is_union {
// let _: AssertParamIsCopy<Self>; // let _: AssertParamIsCopy<Self>;
let self_ty = cx.ty_path(cx.path_ident(trait_span, Ident::with_dummy_span(kw::SelfUpper))); let self_ty = cx.ty_path(cx.path_ident(trait_span, Ident::with_dummy_span(kw::SelfUpper)));
assert_ty_bounds(cx, &mut stmts, self_ty, trait_span, "AssertParamIsCopy"); super::assert_ty_bounds(
cx,
&mut stmts,
self_ty,
trait_span,
&[sym::clone, sym::AssertParamIsCopy],
);
} else { } else {
match *substr.fields { match *substr.fields {
StaticStruct(vdata, ..) => { StaticStruct(vdata, ..) => {

View File

@ -3,9 +3,9 @@ use crate::deriving::generic::*;
use crate::deriving::path_std; use crate::deriving::path_std;
use rustc_ast::ptr::P; use rustc_ast::ptr::P;
use rustc_ast::{self as ast, Expr, GenericArg, MetaItem}; use rustc_ast::{self as ast, Expr, MetaItem};
use rustc_expand::base::{Annotatable, ExtCtxt}; use rustc_expand::base::{Annotatable, ExtCtxt};
use rustc_span::symbol::{sym, Ident, Symbol}; use rustc_span::symbol::{sym, Ident};
use rustc_span::Span; use rustc_span::Span;
pub fn expand_deriving_eq( pub fn expand_deriving_eq(
@ -55,24 +55,6 @@ fn cs_total_eq_assert(
trait_span: Span, trait_span: Span,
substr: &Substructure<'_>, substr: &Substructure<'_>,
) -> P<Expr> { ) -> P<Expr> {
fn assert_ty_bounds(
cx: &mut ExtCtxt<'_>,
stmts: &mut Vec<ast::Stmt>,
ty: P<ast::Ty>,
span: Span,
helper_name: &str,
) {
// Generate statement `let _: helper_name<ty>;`,
// set the expn ID so we can use the unstable struct.
let span = cx.with_def_site_ctxt(span);
let assert_path = cx.path_all(
span,
true,
cx.std_path(&[sym::cmp, Symbol::intern(helper_name)]),
vec![GenericArg::Type(ty)],
);
stmts.push(cx.stmt_let_type_only(span, cx.ty_path(assert_path)));
}
fn process_variant( fn process_variant(
cx: &mut ExtCtxt<'_>, cx: &mut ExtCtxt<'_>,
stmts: &mut Vec<ast::Stmt>, stmts: &mut Vec<ast::Stmt>,
@ -80,7 +62,13 @@ fn cs_total_eq_assert(
) { ) {
for field in variant.fields() { for field in variant.fields() {
// let _: AssertParamIsEq<FieldTy>; // let _: AssertParamIsEq<FieldTy>;
assert_ty_bounds(cx, stmts, field.ty.clone(), field.span, "AssertParamIsEq"); super::assert_ty_bounds(
cx,
stmts,
field.ty.clone(),
field.span,
&[sym::cmp, sym::AssertParamIsEq],
);
} }
} }

View File

@ -2,7 +2,7 @@
use rustc_ast as ast; use rustc_ast as ast;
use rustc_ast::ptr::P; use rustc_ast::ptr::P;
use rustc_ast::{Impl, ItemKind, MetaItem}; use rustc_ast::{GenericArg, Impl, ItemKind, MetaItem};
use rustc_expand::base::{Annotatable, ExpandResult, ExtCtxt, MultiItemModifier}; use rustc_expand::base::{Annotatable, ExpandResult, ExtCtxt, MultiItemModifier};
use rustc_span::symbol::{sym, Ident, Symbol}; use rustc_span::symbol::{sym, Ident, Symbol};
use rustc_span::Span; use rustc_span::Span;
@ -193,3 +193,16 @@ fn inject_impl_of_structural_trait(
push(Annotatable::Item(newitem)); push(Annotatable::Item(newitem));
} }
fn assert_ty_bounds(
cx: &mut ExtCtxt<'_>,
stmts: &mut Vec<ast::Stmt>,
ty: P<ast::Ty>,
span: Span,
assert_path: &[Symbol],
) {
// Generate statement `let _: assert_path<ty>;`.
let span = cx.with_def_site_ctxt(span);
let assert_path = cx.path_all(span, true, cx.std_path(assert_path), vec![GenericArg::Type(ty)]);
stmts.push(cx.stmt_let_type_only(span, cx.ty_path(assert_path)));
}

View File

@ -135,6 +135,9 @@ symbols! {
Arguments, Arguments,
AsMut, AsMut,
AsRef, AsRef,
AssertParamIsClone,
AssertParamIsCopy,
AssertParamIsEq,
AtomicBool, AtomicBool,
AtomicI128, AtomicI128,
AtomicI16, AtomicI16,