Use trait, not impl, definition for X_as_Trait functions
authorMatt Corallo <git@bluematt.me>
Fri, 23 Sep 2022 16:18:55 +0000 (16:18 +0000)
committerMatt Corallo <git@bluematt.me>
Fri, 23 Sep 2022 16:25:21 +0000 (16:25 +0000)
When we map a trait impl block, we historically didn't know how to
resolve the types in the trait context, so we just used the impl
context definitions and assumed the types were the same. Sadly, if
we have an associated type that is bounded by a trait, we need to
use the trait bound to figure out what to write for the X_as_Trait
method declarations.

Since we now have the ability to generate full trait-context type
resolvers, we do so here.

c-bindings-gen/src/main.rs

index 9c11cf374f1f2956205b6fe37dd4551b0f4908e8..2aeadaffac2e3024d3c92172bc24d82b5b06ca47 100644 (file)
@@ -947,7 +947,7 @@ fn writeln_impl<W: std::io::Write>(w: &mut W, i: &syn::ItemImpl, types: &mut Typ
                                                // mappings from a trai defined in a different file, we may mis-resolve or
                                                // fail to resolve the mapped types. Thus, we have to construct a new
                                                // resolver for the module that the trait was defined in here first.
-                                               let trait_resolver = get_module_type_resolver!(full_trait_path, types.crate_libs, types.crate_types);
+                                               let mut trait_resolver = get_module_type_resolver!(full_trait_path, types.crate_libs, types.crate_types);
                                                gen_types.learn_associated_types(trait_obj, &trait_resolver);
                                                let mut impl_associated_types = HashMap::new();
                                                for item in i.items.iter() {
@@ -1107,17 +1107,12 @@ fn writeln_impl<W: std::io::Write>(w: &mut W, i: &syn::ItemImpl, types: &mut Typ
                                                                                _ => {}
                                                                        }
                                                                }
-                                                               if uncallable_function {
-                                                                       let mut trait_resolver = get_module_type_resolver!(full_trait_path, $types.crate_libs, $types.crate_types);
-                                                                       write_method_params(w, &$trait_meth.sig, "c_void", &mut trait_resolver, Some(&meth_gen_types), true, true);
-                                                               } else {
-                                                                       write_method_params(w, &$m.sig, "c_void", $types, Some(&meth_gen_types), true, true);
-                                                               }
+                                                               write_method_params(w, &$trait_meth.sig, "c_void", &mut trait_resolver, Some(&meth_gen_types), true, true);
                                                                write!(w, " {{\n\t").unwrap();
                                                                if uncallable_function {
                                                                        write!(w, "unreachable!();").unwrap();
                                                                } else {
-                                                                       write_method_var_decl_body(w, &$m.sig, "", $types, Some(&meth_gen_types), false);
+                                                                       write_method_var_decl_body(w, &$trait_meth.sig, "", &mut trait_resolver, Some(&meth_gen_types), false);
                                                                        let mut takes_self = false;
                                                                        for inp in $m.sig.inputs.iter() {
                                                                                if let syn::FnArg::Receiver(_) = inp {
@@ -1147,7 +1142,7 @@ fn writeln_impl<W: std::io::Write>(w: &mut W, i: &syn::ItemImpl, types: &mut Typ
                                                                                },
                                                                                _ => {},
                                                                        }
-                                                                       write_method_call_params(w, &$m.sig, "", $types, Some(&meth_gen_types), &real_type, false);
+                                                                       write_method_call_params(w, &$trait_meth.sig, "", &mut trait_resolver, Some(&meth_gen_types), &real_type, false);
                                                                }
                                                                write!(w, "\n}}\n").unwrap();
                                                                if let syn::ReturnType::Type(_, rtype) = &$m.sig.output {
@@ -1185,7 +1180,6 @@ fn writeln_impl<W: std::io::Write>(w: &mut W, i: &syn::ItemImpl, types: &mut Typ
                                                                        assert!(meth.default.is_some());
                                                                        let old_gen_types = gen_types;
                                                                        gen_types = GenericTypes::new(Some(resolved_path.clone()));
-                                                                       let mut trait_resolver = get_module_type_resolver!(full_trait_path, types.crate_libs, types.crate_types);
                                                                        impl_meth!(meth, meth, full_trait_path, trait_obj, "", &mut trait_resolver);
                                                                        gen_types = old_gen_types;
                                                                },