|
1 | 1 | //! Printing logic for basic blocks of Rust-mapped code - parts of functions and declarations but
|
2 | 2 | //! not the full mapping logic.
|
3 | 3 |
|
4 |
| -use std::collections::HashMap; |
5 | 4 | use std::fs::File;
|
6 | 5 | use std::io::Write;
|
7 | 6 | use proc_macro2::{TokenTree, Span};
|
@@ -77,7 +76,7 @@ pub fn writeln_docs<W: std::io::Write>(w: &mut W, attrs: &[syn::Attribute], pref
|
77 | 76 | ///
|
78 | 77 | /// this_param is used when returning Self or accepting a self parameter, and should be the
|
79 | 78 | /// concrete, mapped type.
|
80 |
| -pub fn write_method_params<W: std::io::Write>(w: &mut W, sig: &syn::Signature, associated_types: &HashMap<&syn::Ident, &syn::Ident>, this_param: &str, types: &mut TypeResolver, generics: Option<&GenericTypes>, self_ptr: bool, fn_decl: bool) { |
| 79 | +pub fn write_method_params<W: std::io::Write>(w: &mut W, sig: &syn::Signature, this_param: &str, types: &mut TypeResolver, generics: Option<&GenericTypes>, self_ptr: bool, fn_decl: bool) { |
81 | 80 | if sig.constness.is_some() || sig.asyncness.is_some() || sig.unsafety.is_some() ||
|
82 | 81 | sig.abi.is_some() || sig.variadic.is_some() {
|
83 | 82 | unimplemented!();
|
@@ -140,26 +139,16 @@ pub fn write_method_params<W: std::io::Write>(w: &mut W, sig: &syn::Signature, a
|
140 | 139 | syn::ReturnType::Type(_, rtype) => {
|
141 | 140 | write!(w, " -> ").unwrap();
|
142 | 141 | if let Some(mut remaining_path) = first_seg_self(&*rtype) {
|
143 |
| - if let Some(associated_seg) = get_single_remaining_path_seg(&mut remaining_path) { |
144 |
| - // We're returning an associated type in a trait impl. Its probably a safe bet |
145 |
| - // that its also a trait, so just return the trait type. |
146 |
| - let real_type = associated_types.get(associated_seg).unwrap(); |
147 |
| - types.write_c_type(w, &syn::Type::Path(syn::TypePath { qself: None, |
148 |
| - path: syn::PathSegment { |
149 |
| - ident: (*real_type).clone(), |
150 |
| - arguments: syn::PathArguments::None |
151 |
| - }.into() |
152 |
| - }), generics, true); |
153 |
| - } else { |
| 142 | + if remaining_path.next().is_none() { |
154 | 143 | write!(w, "{}", this_param).unwrap();
|
| 144 | + return; |
155 | 145 | }
|
| 146 | + } |
| 147 | + if let syn::Type::Reference(r) = &**rtype { |
| 148 | + // We can't return a reference, cause we allocate things on the stack. |
| 149 | + types.write_c_type(w, &*r.elem, generics, true); |
156 | 150 | } else {
|
157 |
| - if let syn::Type::Reference(r) = &**rtype { |
158 |
| - // We can't return a reference, cause we allocate things on the stack. |
159 |
| - types.write_c_type(w, &*r.elem, generics, true); |
160 |
| - } else { |
161 |
| - types.write_c_type(w, &*rtype, generics, true); |
162 |
| - } |
| 151 | + types.write_c_type(w, &*rtype, generics, true); |
163 | 152 | }
|
164 | 153 | },
|
165 | 154 | _ => {},
|
@@ -222,7 +211,7 @@ pub fn write_method_var_decl_body<W: std::io::Write>(w: &mut W, sig: &syn::Signa
|
222 | 211 | ///
|
223 | 212 | /// The return value is expected to be bound to a variable named `ret` which is available after a
|
224 | 213 | /// method-call-ending semicolon.
|
225 |
| -pub fn write_method_call_params<W: std::io::Write>(w: &mut W, sig: &syn::Signature, associated_types: &HashMap<&syn::Ident, &syn::Ident>, extra_indent: &str, types: &TypeResolver, generics: Option<&GenericTypes>, this_type: &str, to_c: bool) { |
| 214 | +pub fn write_method_call_params<W: std::io::Write>(w: &mut W, sig: &syn::Signature, extra_indent: &str, types: &TypeResolver, generics: Option<&GenericTypes>, this_type: &str, to_c: bool) { |
226 | 215 | let mut first_arg = true;
|
227 | 216 | let mut num_unused = 0;
|
228 | 217 | for inp in sig.inputs.iter() {
|
@@ -285,26 +274,12 @@ pub fn write_method_call_params<W: std::io::Write>(w: &mut W, sig: &syn::Signatu
|
285 | 274 | syn::ReturnType::Type(_, rtype) => {
|
286 | 275 | write!(w, ";\n\t{}", extra_indent).unwrap();
|
287 | 276 |
|
| 277 | + let self_segs_iter = first_seg_self(&*rtype); |
288 | 278 | if to_c && first_seg_self(&*rtype).is_some() {
|
289 | 279 | // Assume rather blindly that we're returning an associated trait from a C fn call to a Rust trait object.
|
290 | 280 | write!(w, "ret").unwrap();
|
291 |
| - } else if !to_c && first_seg_self(&*rtype).is_some() { |
292 |
| - if let Some(mut remaining_path) = first_seg_self(&*rtype) { |
293 |
| - if let Some(associated_seg) = get_single_remaining_path_seg(&mut remaining_path) { |
294 |
| - let real_type = associated_types.get(associated_seg).unwrap(); |
295 |
| - if let Some(t) = types.crate_types.traits.get(&types.maybe_resolve_ident(&real_type).unwrap()) { |
296 |
| - // We're returning an associated trait from a Rust fn call to a C trait |
297 |
| - // object. |
298 |
| - writeln!(w, "let mut rust_obj = {} {{ inner: Box::into_raw(Box::new(ret)), is_owned: true }};", this_type).unwrap(); |
299 |
| - writeln!(w, "\t{}let mut ret = {}_as_{}(&rust_obj);", extra_indent, this_type, t.ident).unwrap(); |
300 |
| - writeln!(w, "\t{}// We want to free rust_obj when ret gets drop()'d, not rust_obj, so wipe rust_obj's pointer and set ret's free() fn", extra_indent).unwrap(); |
301 |
| - writeln!(w, "\t{}rust_obj.inner = std::ptr::null_mut();", extra_indent).unwrap(); |
302 |
| - writeln!(w, "\t{}ret.free = Some({}_free_void);", extra_indent, this_type).unwrap(); |
303 |
| - writeln!(w, "\t{}ret", extra_indent).unwrap(); |
304 |
| - return; |
305 |
| - } |
306 |
| - } |
307 |
| - } |
| 281 | + } else if !to_c && self_segs_iter.is_some() && self_segs_iter.unwrap().next().is_none() { |
| 282 | + // If we're returning "Self" (and not "Self::X"), just do it manually |
308 | 283 | write!(w, "{} {{ inner: Box::into_raw(Box::new(ret)), is_owned: true }}", this_type).unwrap();
|
309 | 284 | } else if to_c {
|
310 | 285 | let new_var = types.write_from_c_conversion_new_var(w, &syn::Ident::new("ret", Span::call_site()), rtype, generics);
|
|
0 commit comments