Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extra blanks in generated cpp_closures.cpp #96

Open
ratijas opened this issue Jul 21, 2021 · 4 comments
Open

Extra blanks in generated cpp_closures.cpp #96

ratijas opened this issue Jul 21, 2021 · 4 comments

Comments

@ratijas
Copy link
Contributor

ratijas commented Jul 21, 2021

In the generated cpp_closures.cpp, every chunk of code copied verbatim from cpp!([]{}) content is preceded by #line pragma and a line with an inconsistently large amount of spaces. Which probably indicated there is some minor bug in parser.

For example, these fragments of Rust:

    fn get_object_description() -> &'static QObjectDescriptor
    where
        Self: Sized,
    {
        unsafe {
            &*cpp!([]-> *const QObjectDescriptor as "RustQObjectDescriptor const*" {
                return RustQObjectDescriptor::instance<RustObject<QObject>>();
            })
        }
    }
    pub unsafe fn as_qvariant(&self) -> QVariant {
        let self_ = self.get_cpp_object();
        cpp!([self_ as "QObject*"] -> QVariant as "QVariant"  {
            return QVariant::fromValue(self_);
        })
    }
    pub fn destroyed_signal() -> Signal<fn()> {
        unsafe {
            Signal::new(cpp!([] -> SignalInner as "SignalInner"  {
                return &QObject::destroyed;
            }))
        }
    }
    pub fn set_object_name(&self, name: QString) {
        let self_ = self.get_cpp_object();
        unsafe {
            cpp!([self_ as "QObject*", name as "QString"] {
                if (self_) self_->setObjectName(std::move(name));
            })
        }
    }

produce this C++ output:

Extra blanks

Macro code responsible for this is probably somewhere around here:

// Like the write! macro, but add the #line directive (pointing to this file).
// Note: the string literal must be on on the same line of the macro
macro_rules! write_add_line {
($o:expr, $($e:tt)*) => {
(|| {
writeln!($o, "#line {} \"{}\"", line!(), file!().replace('\\', "\\\\"))?;
write!($o, $($e)*)
})()
};
}

@ratijas
Copy link
Contributor Author

ratijas commented Jul 23, 2021

After careful observation it becomes clear that whitespaces were actually a macro invocation code and rust syntax tokens. They got replaced instead of being removed to keep inner macro tokens at the same relative line:column locations as in original code.

So even though this

            &*cpp!([]-> *const QObjectDescriptor as "RustQObjectDescriptor const*" {
                return RustQObjectDescriptor::instance<RustObject<QObject>>();
            })

becomes this

#line 339 "src/lib.rs"
                                                                                    
                return RustQObjectDescriptor::instance<RustObject<QObject>>();
            
}

that's only to keep things in place which could possibly come after cpp!([]-> *const QObjectDescriptor as "RustQObjectDescriptor const*" { characters. It could be solved by "stripping" lines at the beginning & end of a macro, and incrementing #line counter accordingly.

@ogoffart
Copy link
Collaborator

But the extra whitespace is not really a problem, is it?

@ratijas
Copy link
Contributor Author

ratijas commented Jul 23, 2021 via email

@ogoffart
Copy link
Collaborator

What's important is that the error message the the compiler still points to the right location.
The trailing whitespace at the end of the line don't matter, but if it is not trailing, it is important to keep them.

the error location could be perfected. For example, the return type and the argument type are not in lines that are marked with #line so if there is a typo in these, it leads to difficult errors.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants