Skip to content

Inherited host bindings can write into wrong variable offset #66263

@crisbeto

Description

@crisbeto

If one directive with host bindings containing pure functions inherits from another one, both pure function instructions will end up writing into the same offset on the LView. The reason is that pure functions are set up to write to the binding root plus an offset, however the offsets overlap when the parent and child class host binding functions execute. This can lead to "changed after checked" errors.

It can be reproduced with the following tests:

it('should not throw', () => {
  @Directive({
    host: {
      '[attr.parent]': '["parent"][0]',
    },
  })
  class ParentDir {}

  @Directive({
    host: {
      '[attr.child]': '["child"][0]',
    },
    selector: 'some-dir',
  })
  class SomeDir extends ParentDir {}

  @Component({
    template: '<some-dir/>',
    imports: [SomeDir],
  })
  class App {}

  const fixture = TestBed.createComponent(App);
  fixture.detectChanges();
});

This produces two pureFunction(2, ...) instructions that both try to write into the same offset which eventually throw an error.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions