From 468f7ba42a9edafd332e0a07b2174c63375cc4c2 Mon Sep 17 00:00:00 2001 From: Noah <33094578+coolreader18@users.noreply.github.com> Date: Mon, 13 Jan 2020 11:41:20 -0600 Subject: [PATCH 1/4] Clarify that the compile error is for python code in py_compile_bytecode --- derive/src/compile_bytecode.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/derive/src/compile_bytecode.rs b/derive/src/compile_bytecode.rs index b1c1c9cbe7..32166c6b6b 100644 --- a/derive/src/compile_bytecode.rs +++ b/derive/src/compile_bytecode.rs @@ -43,8 +43,9 @@ impl CompilationSource { mode: compile::Mode, module_name: String, ) -> Result { - compile::compile(source, mode, module_name, 0) - .map_err(|err| Diagnostic::spans_error(self.span, format!("Compile error: {}", err))) + compile::compile(source, mode, module_name, 0).map_err(|err| { + Diagnostic::spans_error(self.span, format!("Python compile error: {}", err)) + }) } fn compile( From c9a78bc025d7b8b24d5d49bf382e1c3878c0d523 Mon Sep 17 00:00:00 2001 From: Noah <33094578+coolreader18@users.noreply.github.com> Date: Mon, 13 Jan 2020 11:41:59 -0600 Subject: [PATCH 2/4] Put diagnostics inside generated macro for result_to_tokens_expr --- derive/src/lib.rs | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/derive/src/lib.rs b/derive/src/lib.rs index 8638dd8da0..0f6909ad54 100644 --- a/derive/src/lib.rs +++ b/derive/src/lib.rs @@ -20,10 +20,7 @@ use quote::ToTokens; use syn::{parse_macro_input, AttributeArgs, DeriveInput, Item}; fn result_to_tokens(result: Result) -> TokenStream { - match result { - Ok(tokens) => tokens.into(), - Err(diagnostic) => diagnostic.into_token_stream().into(), - } + result.unwrap_or_else(ToTokens::into_token_stream).into() } #[proc_macro_derive(FromArgs, attributes(pyarg))] @@ -54,13 +51,13 @@ pub fn pystruct_sequence(attr: TokenStream, item: TokenStream) -> TokenStream { } fn result_to_tokens_expr(result: Result) -> TokenStream { - result_to_tokens(result.map(|out_expr| { - quote::quote! { - macro_rules! __proc_macro_call { - () => {{ #out_expr }}; - } + let tokens2 = result.unwrap_or_else(ToTokens::into_token_stream); + let ret = quote::quote! { + macro_rules! __proc_macro_call { + () => {{ #tokens2 }} } - })) + }; + ret.into() } #[proc_macro] From 80f4f911db7f61eb124c9285891f852fb60063f0 Mon Sep 17 00:00:00 2001 From: Noah <33094578+coolreader18@users.noreply.github.com> Date: Mon, 13 Jan 2020 11:42:31 -0600 Subject: [PATCH 3/4] Point to the specific function that's not IntoPyFunc for pyimpl --- derive/src/pyclass.rs | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/derive/src/pyclass.rs b/derive/src/pyclass.rs index ef6f6ab675..9a25f9f9f0 100644 --- a/derive/src/pyclass.rs +++ b/derive/src/pyclass.rs @@ -1,6 +1,6 @@ use super::Diagnostic; use proc_macro2::{Span, TokenStream as TokenStream2}; -use quote::quote; +use quote::{quote, quote_spanned}; use std::collections::{HashMap, HashSet}; use syn::{ spanned::Spanned, Attribute, AttributeArgs, Ident, ImplItem, Index, Item, Lit, Meta, MethodSig, @@ -305,23 +305,32 @@ pub fn impl_pyimpl(_attr: AttributeArgs, item: Item) -> Result Some(quote! { - class.set_str_attr(#py_name, ctx.new_method(Self::#item_ident)); - }), + } => { + let new_meth = quote_spanned!(item_ident.span()=> .new_method(Self::#item_ident)); + Some(quote! { + class.set_str_attr(#py_name, ctx#new_meth); + }) + } ClassItem::ClassMethod { item_ident, py_name, - } => Some(quote! { - class.set_str_attr(#py_name, ctx.new_classmethod(Self::#item_ident)); - }), + } => { + let new_meth = quote_spanned!(item_ident.span()=> .new_classmethod(Self::#item_ident)); + Some(quote! { + class.set_str_attr(#py_name, ctx#new_meth); + }) + } ClassItem::Slot { slot_ident, item_ident, - } => Some(quote! { - class.slots.borrow_mut().#slot_ident = Some( + } => { + let into_func = quote_spanned! {item_ident.span()=> ::rustpython_vm::function::IntoPyNativeFunc::into_func(Self::#item_ident) - ); - }), + }; + Some(quote! { + (*class.slots.borrow_mut()).#slot_ident = Some(#into_func); + }) + } _ => None, }); From b29707cda4f8338ccd22779ab21e6b9dea51f1e6 Mon Sep 17 00:00:00 2001 From: coolreader18 <33094578+coolreader18@users.noreply.github.com> Date: Mon, 13 Jan 2020 19:56:18 -0600 Subject: [PATCH 4/4] Say what file failed to compile in py_compile_bytecode --- Cargo.lock | 1 + derive/Cargo.toml | 1 + derive/src/compile_bytecode.rs | 36 +++++++++++++++++++++------------- 3 files changed, 24 insertions(+), 14 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0f89629450..2ad5d25e0b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1310,6 +1310,7 @@ dependencies = [ name = "rustpython-derive" version = "0.1.1" dependencies = [ + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "maplit 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/derive/Cargo.toml b/derive/Cargo.toml index 6e64abd557..a4af80af64 100644 --- a/derive/Cargo.toml +++ b/derive/Cargo.toml @@ -17,3 +17,4 @@ proc-macro2 = "0.4.27" rustpython-compiler = { path = "../compiler", version = "0.1.1" } rustpython-bytecode = { path = "../bytecode", version = "0.1.1" } maplit = "1.0" +lazy_static = "1" diff --git a/derive/src/compile_bytecode.rs b/derive/src/compile_bytecode.rs index 32166c6b6b..f133d55bd0 100644 --- a/derive/src/compile_bytecode.rs +++ b/derive/src/compile_bytecode.rs @@ -25,6 +25,12 @@ use std::path::{Path, PathBuf}; use syn::parse::{Parse, ParseStream, Result as ParseResult}; use syn::{self, parse2, Lit, LitByteStr, LitStr, Meta, Token}; +lazy_static::lazy_static! { + static ref CARGO_MANIFEST_DIR: PathBuf = PathBuf::from( + env::var_os("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR is not present"), + ); +} + enum CompilationSourceKind { File(PathBuf), SourceCode(String), @@ -37,14 +43,18 @@ struct CompilationSource { } impl CompilationSource { - fn compile_string( + fn compile_string D>( &self, source: &str, mode: compile::Mode, module_name: String, + origin: F, ) -> Result { compile::compile(source, mode, module_name, 0).map_err(|err| { - Diagnostic::spans_error(self.span, format!("Python compile error: {}", err)) + Diagnostic::spans_error( + self.span, + format!("Python compile error from {}: {}", origin(), err), + ) }) } @@ -55,10 +65,7 @@ impl CompilationSource { ) -> Result, Diagnostic> { Ok(match &self.kind { CompilationSourceKind::File(rel_path) => { - let mut path = PathBuf::from( - env::var_os("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR is not present"), - ); - path.push(rel_path); + let path = CARGO_MANIFEST_DIR.join(rel_path); let source = fs::read_to_string(&path).map_err(|err| { Diagnostic::spans_error( self.span, @@ -67,7 +74,7 @@ impl CompilationSource { })?; hashmap! { module_name.clone() => FrozenModule { - code: self.compile_string(&source, mode, module_name)?, + code: self.compile_string(&source, mode, module_name, || rel_path.display())?, package: false, }, } @@ -75,17 +82,13 @@ impl CompilationSource { CompilationSourceKind::SourceCode(code) => { hashmap! { module_name.clone() => FrozenModule { - code: self.compile_string(code, mode, module_name)?, + code: self.compile_string(code, mode, module_name, || "string literal")?, package: false, }, } } CompilationSourceKind::Dir(rel_path) => { - let mut path = PathBuf::from( - env::var_os("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR is not present"), - ); - path.push(rel_path); - self.compile_dir(&path, String::new(), mode)? + self.compile_dir(&CARGO_MANIFEST_DIR.join(rel_path), String::new(), mode)? } }) } @@ -133,7 +136,12 @@ impl CompilationSource { code_map.insert( module_name.clone(), FrozenModule { - code: self.compile_string(&source, mode, module_name)?, + code: self.compile_string(&source, mode, module_name, || { + path.strip_prefix(&*CARGO_MANIFEST_DIR) + .ok() + .unwrap_or(&path) + .display() + })?, package: is_init, }, );