From 5b7af833825047f562313ed43bf03441b68743f5 Mon Sep 17 00:00:00 2001 From: Diggory Hardy Date: Mon, 21 Jan 2019 17:30:57 +0000 Subject: [PATCH] Use prefered solution for local crate references from procedural macros https://github.com/rust-lang/rust/pull/55275 --- kas-macros/src/layout_cw.rs | 44 +++++++++--------- kas-macros/src/layout_extern.rs | 20 ++++----- kas-macros/src/lib.rs | 79 +++++++++++++-------------------- src/lib.rs | 2 + 4 files changed, 66 insertions(+), 79 deletions(-) diff --git a/kas-macros/src/layout_cw.rs b/kas-macros/src/layout_cw.rs index 49a44ab46..ccdc0474e 100644 --- a/kas-macros/src/layout_cw.rs +++ b/kas-macros/src/layout_cw.rs @@ -9,14 +9,14 @@ use syn::Ident; use syn::parse::{Error, Result}; use crate::args::Child; -pub(crate) fn fns(c: &TokenStream, children: &Vec, layout: Option) +pub(crate) fn fns(children: &Vec, layout: Option) -> Result { let (constraints, appls) = if children.is_empty() { // TODO: warn on invalid layout specification (quote!{ - let v_w = #c::cw_var!(self, w); - let v_h = #c::cw_var!(self, h); + let v_w = kas::cw_var!(self, w); + let v_h = kas::cw_var!(self, h); let (min, hint) = tk.size_hints(self.tkd()); @@ -54,11 +54,11 @@ pub(crate) fn fns(c: &TokenStream, children: &Vec, layout: Option) let ident = &children[0].ident; (quote!{ s.add_constraint(cw::Constraint::new( - cw::Expression::from(#c::cw_var!(self, w)) - #c::cw_var!(self.#ident, w), + cw::Expression::from(kas::cw_var!(self, w)) - kas::cw_var!(self.#ident, w), cw::RelationalOperator::Equal, cw::strength::STRONG)).unwrap(); s.add_constraint(cw::Constraint::new( - cw::Expression::from(#c::cw_var!(self, h)) - #c::cw_var!(self.#ident, h), + cw::Expression::from(kas::cw_var!(self, h)) - kas::cw_var!(self.#ident, h), cw::RelationalOperator::Equal, cw::strength::STRONG)).unwrap(); self.#ident.init_constraints(tk, s, _use_default); @@ -67,8 +67,8 @@ pub(crate) fn fns(c: &TokenStream, children: &Vec, layout: Option) if let Some(l) = layout { if l == "horizontal" { let mut constr = quote!{ - let mut width = cw::Expression::from(#c::cw_var!(self, w)); - let height = cw::Expression::from(#c::cw_var!(self, h)); + let mut width = cw::Expression::from(kas::cw_var!(self, w)); + let height = cw::Expression::from(kas::cw_var!(self, h)); }; let mut appls = quote!{ let mut cpos = pos; }; @@ -76,8 +76,8 @@ pub(crate) fn fns(c: &TokenStream, children: &Vec, layout: Option) let ident = &child.ident; constr.append_all(quote!{ - let child_v_w = #c::cw_var!(self.#ident, w); - let child_v_h = #c::cw_var!(self.#ident, h); + let child_v_w = kas::cw_var!(self.#ident, w); + let child_v_h = kas::cw_var!(self.#ident, h); width -= child_v_w; s.add_constraint(cw::Constraint::new( height.clone() - child_v_h, @@ -92,7 +92,7 @@ pub(crate) fn fns(c: &TokenStream, children: &Vec, layout: Option) appls.append_all(quote!{ self.#ident.apply_constraints(tk, s, cpos); - cpos.0 += s.get_value(#c::cw_var!(self.#ident, w)) as i32; + cpos.0 += s.get_value(kas::cw_var!(self.#ident, w)) as i32; }); } @@ -106,8 +106,8 @@ pub(crate) fn fns(c: &TokenStream, children: &Vec, layout: Option) (constr, appls) } else if l == "vertical" { let mut constr = quote!{ - let width = cw::Expression::from(#c::cw_var!(self, w)); - let mut height = cw::Expression::from(#c::cw_var!(self, h)); + let width = cw::Expression::from(kas::cw_var!(self, w)); + let mut height = cw::Expression::from(kas::cw_var!(self, h)); }; let mut appls = quote!{ let mut cpos = pos; }; @@ -115,8 +115,8 @@ pub(crate) fn fns(c: &TokenStream, children: &Vec, layout: Option) let ident = &child.ident; constr.append_all(quote!{ - let child_v_w = #c::cw_var!(self.#ident, w); - let child_v_h = #c::cw_var!(self.#ident, h); + let child_v_w = kas::cw_var!(self.#ident, w); + let child_v_h = kas::cw_var!(self.#ident, h); s.add_constraint(cw::Constraint::new( width.clone() - child_v_w, cw::RelationalOperator::GreaterOrEqual, @@ -131,7 +131,7 @@ pub(crate) fn fns(c: &TokenStream, children: &Vec, layout: Option) appls.append_all(quote!{ self.#ident.apply_constraints(tk, s, cpos); - cpos.1 += s.get_value(#c::cw_var!(self.#ident, h)) as i32; + cpos.1 += s.get_value(kas::cw_var!(self.#ident, h)) as i32; }); } @@ -154,20 +154,20 @@ pub(crate) fn fns(c: &TokenStream, children: &Vec, layout: Option) } }; Ok(quote! { - fn init_constraints(&self, tk: &#c::TkWidget, - s: &mut #c::cw::Solver, _use_default: bool) + fn init_constraints(&self, tk: &kas::TkWidget, + s: &mut kas::cw::Solver, _use_default: bool) { - use #c::cw; + use kas::cw; #constraints } - fn apply_constraints(&mut self, tk: &#c::TkWidget, - s: &#c::cw::Solver, pos: #c::Coord) + fn apply_constraints(&mut self, tk: &kas::TkWidget, + s: &kas::cw::Solver, pos: kas::Coord) { #appls - let w = s.get_value(#c::cw_var!(self, w)) as i32; - let h = s.get_value(#c::cw_var!(self, h)) as i32; + let w = s.get_value(kas::cw_var!(self, w)) as i32; + let h = s.get_value(kas::cw_var!(self, h)) as i32; let tkd = self.tkd(); let rect = self.rect_mut(); rect.pos = pos; diff --git a/kas-macros/src/layout_extern.rs b/kas-macros/src/layout_extern.rs index fd0b00836..921e80f95 100644 --- a/kas-macros/src/layout_extern.rs +++ b/kas-macros/src/layout_extern.rs @@ -9,24 +9,24 @@ use syn::{parse_quote, Path, Ident}; use syn::parse::{Error, Result}; use crate::args::Child; -pub(crate) fn fns(c: &TokenStream, children: &Vec, layout: Option) +pub(crate) fn fns(children: &Vec, layout: Option) -> Result { let layout: Path = if let Some(l) = layout { if l == "single" { - parse_quote!{ #c::ChildLayout::None } + parse_quote!{ kas::ChildLayout::None } } else if l == "horizontal" { - parse_quote!{ #c::ChildLayout::Horizontal } + parse_quote!{ kas::ChildLayout::Horizontal } } else if l == "vertical" { - parse_quote!{ #c::ChildLayout::Vertical } + parse_quote!{ kas::ChildLayout::Vertical } } else if l == "grid" { - parse_quote!{ #c::ChildLayout::Grid } + parse_quote!{ kas::ChildLayout::Grid } } else { return Err(Error::new(l.span(), "expected one of: single, horizontal, vertical, grid")); } } else { - parse_quote!{ #c::ChildLayout::None } + parse_quote!{ kas::ChildLayout::None } }; let mut pos_rules = TokenStream::new(); @@ -40,19 +40,19 @@ pub(crate) fn fns(c: &TokenStream, children: &Vec, layout: Option) } Ok(quote! { - fn child_layout(&self) -> #c::ChildLayout { + fn child_layout(&self) -> kas::ChildLayout { #layout } - fn grid_pos(&self, _index: usize) -> Option<#c::GridPos> { + fn grid_pos(&self, _index: usize) -> Option { match _index { #pos_rules _ => None } } - fn sync_size(&mut self, tk: &#c::TkWidget) { - use #c::Core; + fn sync_size(&mut self, tk: &kas::TkWidget) { + use kas::Core; let new_rect = tk.get_rect(self.tkd()); *self.rect_mut() = new_rect; diff --git a/kas-macros/src/lib.rs b/kas-macros/src/lib.rs index 0530b3e68..2e0d598ff 100644 --- a/kas-macros/src/lib.rs +++ b/kas-macros/src/lib.rs @@ -10,7 +10,6 @@ extern crate proc_macro; mod args; -use std::env; use std::fmt::Write; use proc_macro2::{Span, TokenStream}; use quote::{quote, TokenStreamExt}; @@ -146,7 +145,6 @@ use self::args::{Class, ChildType}; #[proc_macro_derive(Widget, attributes(core, widget, handler))] pub fn derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream { let mut ast = parse_macro_input!(input as DeriveInput); - let c = c(); let args = match args::read_attrs(&mut ast) { Ok(w) => w, @@ -159,7 +157,7 @@ pub fn derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream { let class = args.widget.class; let count = args.children.len(); - let layout_fns = match layout::fns(&c, &args.children, args.widget.layout) { + let layout_fns = match layout::fns(&args.children, args.widget.layout) { Ok(fns) => fns, Err(err) => return err.to_compile_error().into(), }; @@ -176,58 +174,58 @@ pub fn derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream { let get_mut_rules = make_match_rules(&args.children, quote!{mut}); let mut toks = quote! { - impl #impl_generics #c::Core + impl #impl_generics kas::Core for #name #ty_generics #where_clause { fn number(&self) -> u32 { - use #c::Core; + use kas::Core; self.#core.number() } fn set_number(&mut self, number: u32) { - use #c::Core; + use kas::Core; self.#core.set_number(number); } - fn tkd(&self) -> #c::TkData { - use #c::Core; + fn tkd(&self) -> kas::TkData { + use kas::Core; self.#core.tkd() } - fn set_tkd(&mut self, tkd: #c::TkData) { - use #c::Core; + fn set_tkd(&mut self, tkd: kas::TkData) { + use kas::Core; self.#core.set_tkd(tkd) } - fn rect(&self) -> &#c::Rect { - use #c::Core; + fn rect(&self) -> &kas::Rect { + use kas::Core; self.#core.rect() } - fn rect_mut(&mut self) -> &mut #c::Rect { - use #c::Core; + fn rect_mut(&mut self) -> &mut kas::Rect { + use kas::Core; self.#core.rect_mut() } } - impl #impl_generics #c::Layout + impl #impl_generics kas::Layout for #name #ty_generics #where_clause { #layout_fns } - impl #impl_generics #c::Widget + impl #impl_generics kas::Widget for #name #ty_generics #where_clause { - fn class(&self) -> #c::Class { #class } + fn class(&self) -> kas::Class { #class } fn len(&self) -> usize { #count } - fn get(&self, _index: usize) -> Option<&#c::Widget> { + fn get(&self, _index: usize) -> Option<&kas::Widget> { match _index { #get_rules _ => None } } - fn get_mut(&mut self, _index: usize) -> Option<&mut #c::Widget> { + fn get_mut(&mut self, _index: usize) -> Option<&mut kas::Widget> { match _index { #get_mut_rules _ => None @@ -276,15 +274,15 @@ pub fn derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream { } toks.append_all(quote! { - impl #impl_generics #c::event::Handler + impl #impl_generics kas::event::Handler for #name #ty_generics #where_clause { type Response = #response; - fn handle_action(&mut self, _tk: &#c::TkWidget, action: #c::event::Action, + fn handle_action(&mut self, _tk: &kas::TkWidget, action: kas::event::Action, num: u32) -> Self::Response { - use #c::{Core, event::{Handler, err_unhandled, err_num}}; + use kas::{Core, event::{Handler, err_unhandled, err_num}}; if num == self.number() { // we may want to allow custom handlers on self here? @@ -442,10 +440,8 @@ pub fn make_widget(input: proc_macro::TokenStream) -> proc_macro::TokenStream { // Used to make fresh identifiers for generic types let mut name_buf = String::with_capacity(32); - let c = c(); - // fields of anonymous struct: - let mut field_toks = quote!{ #[core] core: #c::CoreData, }; + let mut field_toks = quote!{ #[core] core: kas::CoreData, }; // initialisers for these fields: let mut field_val_toks = quote!{ core: Default::default(), }; // debug impl @@ -463,10 +459,10 @@ pub fn make_widget(input: proc_macro::TokenStream) -> proc_macro::TokenStream { let widget_args = match args.class { Class::Container(layout) => quote!{ - class = #c::Class::Container, layout = #layout + class = kas::Class::Container, layout = #layout }, Class::Frame => quote!{ - class = #c::Class::Frame + class = kas::Class::Frame }, }; @@ -492,14 +488,14 @@ pub fn make_widget(input: proc_macro::TokenStream) -> proc_macro::TokenStream { gen_tys.push(ty.clone()); if let Some(ref wattr) = attr { if let Some(tyr) = gen_response { - handler_clauses.push(quote!{ #ty: #c::event::Handler }); + handler_clauses.push(quote!{ #ty: kas::event::Handler }); } else { // No typing. If a handler is specified, then the child must implement // Handler where the handler takes type X; otherwise // we use `msg.into()` and this conversion must be supported. if let Some(ref handler) = wattr.args.handler { if let Some(ty_bound) = find_handler_ty(handler, &args.impls) { - handler_clauses.push(quote!{ #ty: #c::event::Handler }); + handler_clauses.push(quote!{ #ty: kas::event::Handler }); } else { return quote!{}.into(); // exit after emitting error } @@ -507,17 +503,17 @@ pub fn make_widget(input: proc_macro::TokenStream) -> proc_macro::TokenStream { name_buf.push_str("R"); let tyr = Ident::new(&name_buf, Span::call_site()); handler_extra.push(tyr.clone()); - handler_clauses.push(quote!{ #ty: #c::event::Handler }); - handler_clauses.push(quote!{ #tyr: From<#c::event::NoResponse> }); + handler_clauses.push(quote!{ #ty: kas::event::Handler }); + handler_clauses.push(quote!{ #tyr: From }); handler_clauses.push(quote!{ #response: From<#tyr> }); } } if let Some(mut bound) = gen_bound { - bound.bounds.push(parse_quote!{ #c::Widget }); + bound.bounds.push(parse_quote!{ kas::Widget }); gen_ptrs.push(quote!{ #ty: #bound }); } else { - gen_ptrs.push(quote!{ #ty: #c::Widget }); + gen_ptrs.push(quote!{ #ty: kas::Widget }); } } else { gen_ptrs.push(quote!{ #ty }); @@ -563,7 +559,7 @@ pub fn make_widget(input: proc_macro::TokenStream) -> proc_macro::TokenStream { let toks = (quote!{ { #[widget(#widget_args)] #[handler(response = #response, generics = < #handler_extra > #handler_where)] - #[derive(Clone, Debug, #c::macros::Widget)] + #[derive(Clone, Debug, kas::macros::Widget)] struct AnonWidget<#gen_ptrs> { #field_toks } @@ -585,28 +581,17 @@ pub fn make_widget(input: proc_macro::TokenStream) -> proc_macro::TokenStream { #[proc_macro_derive(NoResponse)] pub fn derive_no_response(input: proc_macro::TokenStream) -> proc_macro::TokenStream { let ast = parse_macro_input!(input as DeriveInput); - let c = c(); let (impl_generics, ty_generics, where_clause) = ast.generics.split_for_impl(); let name = &ast.ident; let toks = quote!{ - impl #impl_generics From<#c::event::NoResponse> + impl #impl_generics From for #name #ty_generics #where_clause { - fn from(_: #c::event::NoResponse) -> Self { + fn from(_: kas::event::NoResponse) -> Self { #name::None } } }; toks.into() } - -// Our stand-in for $crate. Imperfect, but works (excepting other crates in -// the same package, i.e. doc-tests, examples, integration tests, benches). -fn c() -> TokenStream { - if env::var("CARGO_PKG_NAME") == Ok("kas".to_string()) { - parse_quote!( crate ) - } else { - parse_quote!( kas ) - } -} diff --git a/src/lib.rs b/src/lib.rs index 75599d4b7..34fa7ad1a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,11 +5,13 @@ //! KAS lib #![feature(unrestricted_attribute_tokens)] +#![feature(extern_crate_self)] #[doc(hidden)] #[cfg(feature = "cassowary")] pub extern crate cassowary as cw; // used by macros +extern crate self as kas; // required for reliable self-reference in kas_macros extern crate kas_macros; // internal modules: