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

std::bad_typeid when checking parent selector on base level #1415

Closed
mahtd opened this issue Jul 28, 2015 · 19 comments · Fixed by #1430
Closed

std::bad_typeid when checking parent selector on base level #1415

mahtd opened this issue Jul 28, 2015 · 19 comments · Fixed by #1430

Comments

@mahtd
Copy link

mahtd commented Jul 28, 2015

This looks like a regression in master

Given the following code:

@mixin prepend-foo {
    $parent: &;

    @if $parent {
        .foo & {
            @content;
        }
    } @else {
        .foo {
            @content;
        }
    }
}

@include prepend-foo {
    .bar {
        color: red;
    }
}

Ruby Sass:

$ sass --version
Sass 3.4.16 (Selective Steve)
$ sass test.scss
.foo .bar {
  color: red; }

libsass 3.2:

$ sassc --version
sassc: 3.2.1
libsass: 3.2.5
sass2scss: 1.0.3
$ sassc test.scss
.foo .bar {
  color: red; }

libsass master:

$ sassc --version
sassc: 3.2.5-11-g3565
libsass: 3.2.5-151-g9b4e
sass2scss: 1.0.3
$ sassc test.scss
Error: std::bad_typeid
@saper
Copy link
Member

saper commented Jul 28, 2015

Commit 0e6b4a2 still works fine for me, master is broken

@saper
Copy link
Member

saper commented Jul 28, 2015

Bisect points at 9b4e424 - surprising :)

@xzyfer
Copy link
Contributor

xzyfer commented Jul 29, 2015

@saper can you please confirm your bisect. My bisect points to either 583eac1 or 9f5ef6d which is far more likely.

583eac1 frustratingly a compilation error so I can't easily determine which is the cause.

@xzyfer
Copy link
Contributor

xzyfer commented Jul 29, 2015

Looking the commits in question is almost certainly 9f5ef6d

@saper
Copy link
Member

saper commented Jul 29, 2015

yep, my bisect went bad, checking again.. didn't have compile errors though

@saper
Copy link
Member

saper commented Jul 29, 2015

This is the backtrace:

#0  __cxa_throw (thrown_exception=0x802430078, tinfo=0x80146a320 <typeinfo for std::bad_typeid>, dest=0x801264860 <std::exception::~exception()>)
    at /usr/src/lib/libcxxrt/../../contrib/libcxxrt/exception.cc:768
#1  0x000000080125af91 in __cxa_bad_typeid () at /usr/src/lib/libcxxrt/../../contrib/libcxxrt/auxhelper.cc:54
#2  0x0000000800b9b0d2 in Sass::Eval::operator() (this=0x7fffffffd978, v=0x802408100) at eval.cpp:711
#3  0x0000000800cd4cf1 in Sass::Variable::perform (this=0x802408100, op=0x7fffffffd978) at ./ast.hpp:1151
#4  0x0000000800bc22b3 in Sass::Expand::operator() (this=0x7fffffffd968, i=0x80244f660) at expand.cpp:324
#5  0x0000000800cd4781 in Sass::If::perform (this=0x80244f660, op=0x7fffffffd968) at ./ast.hpp:582
#6  0x0000000800bc7986 in Sass::Expand::append_block (this=0x7fffffffd968, b=0x80242b440) at expand.cpp:585
#7  0x0000000800bc71b4 in Sass::Expand::operator() (this=0x7fffffffd968, c=0x80244f700) at expand.cpp:555
#8  0x0000000800bcc401 in Sass::Mixin_Call::perform (this=0x80244f700, op=0x7fffffffd968) at ./ast.hpp:737
#9  0x0000000800bc7986 in Sass::Expand::append_block (this=0x7fffffffd968, b=0x80242b2c0) at expand.cpp:585
#10 0x0000000800bbe778 in Sass::Expand::operator() (this=0x7fffffffd968, b=0x80242b2c0) at expand.cpp:77
#11 0x0000000800b7f51e in Sass::Block::perform (this=0x80242b2c0, op=0x7fffffffd968) at ./ast.hpp:323
#12 0x0000000800b44fb2 in Sass::Context::parse_file (this=0x80240f400) at context.cpp:345
#13 0x0000000800cefbc4 in sass_parse_block (compiler=0x8024060e0) at sass_context.cpp:505
#14 0x0000000800cefa01 in sass_compiler_parse (compiler=0x8024060e0) at sass_context.cpp:654
#15 0x0000000800cef543 in sass_compile_context (c_ctx=0x80240b100, cpp_opt=...) at sass_context.cpp:538
#16 0x0000000800cef889 in sass_compile_file_context (file_ctx=0x80240b100) at sass_context.cpp:641
#17 0x0000000000401def in compile_file (options=0x802408080, input_path=0x7fffffffeab9 "/home/saper/sw/nodes-sass-problems/libsass/1415/test.scss", 
    outfile=0x0) at sassc.c:102
#18 0x00000000004024b0 in main (argc=<optimized out>, argv=<optimized out>) at sassc.c:274

On frame #2 the value is NULL, that's why we get the exception

@saper
Copy link
Member

saper commented Jul 29, 2015

When the $parent variable is set (breakpoint expand.cpp:274) , the selector() method at eval.cpp#L1509 at returns NULL. So the "selector stack" seems to be wrong.

@saper
Copy link
Member

saper commented Aug 2, 2015

Looks to me like a bigger issue now - during the expansion phase we traverse the tree lexically, while variables should actually be expanded from the dynamic context. The context of the mixin call is not known (not set), since we process @mixin first and @include later.

@xzyfer
Copy link
Contributor

xzyfer commented Aug 10, 2015

Minimal test case

$parent: &;

@if $parent {
  .foo {
    foo: bar;
  }
}

@xzyfer
Copy link
Contributor

xzyfer commented Aug 10, 2015

This variant also causes a segfault

@if & {
  .foo {
    foo: bar;
  }
}

@saper
Copy link
Member

saper commented Aug 10, 2015

The latter seems to be second half of the issue: the selector stack is empty, so we return NULL as a value and crash.

The first half exposed by the mixin case is that we have the selector stack is empty while it should not be (mixin call does not get its dynamic scope of selectors).

@xzyfer
Copy link
Contributor

xzyfer commented Aug 10, 2015

The first half exposed by the mixin case is that we have the selector stack is empty while it should not be

I'm not sure I'm following. Given this code, the selector stack should be empty, which is causing the error in my first example.

@include prepend-foo {
    .bar {
        color: red;
    }
}

@xzyfer
Copy link
Contributor

xzyfer commented Aug 10, 2015

We can see that the selector scope is being passed to the mixin

.baz {
    @include prepend-foo {
        .bar {
            color: red;
        }
    }
}

Produces

.foo .baz .bar {
  color: red; }

@saper
Copy link
Member

saper commented Aug 10, 2015

Sure, it is empty, because IT IS empty :) now I see it.

A quick workaround (or even a fix?) in #1430

@xzyfer
Copy link
Contributor

xzyfer commented Aug 10, 2015

That fix seems fine to me. I'll create the specs so can ship this.

xzyfer added a commit to xzyfer/sass-spec that referenced this issue Aug 10, 2015
@saper
Copy link
Member

saper commented Aug 10, 2015

I see lots of other methods happily returning 0 as Expression *. Maybe this should be handled at the @if level, for example.

@xzyfer
Copy link
Contributor

xzyfer commented Aug 10, 2015

If anything I'd say both, since & can be passed as function argument for things like selector_append

@xzyfer xzyfer closed this as completed Aug 10, 2015
@xzyfer xzyfer reopened this Aug 10, 2015
@xzyfer
Copy link
Contributor

xzyfer commented Aug 10, 2015

Returning null from the parent selector eval seems correct to me.

$list: selector_append(&, bar);

Should produce

Error: $selectors: null is not a valid selector: it must be a string,
       a list of strings, or a list of lists of strings for `selector_append'

We don't currently produce this error, but it implies having & expanding to null is the correct thing to do.

@xzyfer
Copy link
Contributor

xzyfer commented Aug 10, 2015

Spec added sass/sass-spec#468

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

Successfully merging a pull request may close this issue.

3 participants