Bug 1574201. Remove support for IDL "implements" statements. r=edgar
authorBoris Zbarsky <bzbarsky@mit.edu>
Wed, 25 Sep 2019 19:59:00 +0000
changeset 494972 7914ef375e3c8fb2c6148b97decff55594a27f54
parent 494971 ab74e2147c5c1761ac324bbdf993d6aa0891ca96
child 494973 ed5efc0182326c0a131b71cd150da351d5b4d400
push id114131
push userdluca@mozilla.com
push dateThu, 26 Sep 2019 09:47:34 +0000
treeherdermozilla-inbound@1dc1a755079a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersedgar
bugs1574201
milestone71.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1574201. Remove support for IDL "implements" statements. r=edgar A bunch of loop-detection, etc, complexity goes away because mixins are not interfaces and the mixin syntax does not allow various things we had to guard against in terms of maplikes and whatnot. Differential Revision: https://phabricator.services.mozilla.com/D46524
dom/bindings/Codegen.py
dom/bindings/Configuration.py
dom/bindings/parser/WebIDL.py
dom/bindings/parser/tests/test_distinguishability.py
dom/bindings/parser/tests/test_exposed_extended_attribute.py
dom/bindings/parser/tests/test_implements.py
dom/bindings/parser/tests/test_interface.py
dom/bindings/parser/tests/test_interface_maplikesetlikeiterable.py
dom/bindings/parser/tests/test_securecontext_extended_attribute.py
dom/bindings/parser/tests/test_unforgeable.py
dom/bindings/test/TestBindingHeader.h
dom/bindings/test/TestCodeGen.webidl
dom/bindings/test/TestExampleGen.webidl
dom/bindings/test/TestJSImplGen.webidl
tools/lint/file-whitespace.yml
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -1113,23 +1113,16 @@ class CGHeaders(CGWrapper):
                 parent = parent.parent
         interfaceDeps.extend(jsonInterfaceParents)
 
         bindingIncludes = set(self.getDeclarationFilename(d) for d in interfaceDeps)
 
         # Grab all the implementation declaration files we need.
         implementationIncludes = set(d.headerFile for d in descriptors if d.needsHeaderInclude())
 
-        # Grab the includes for checking hasInstance
-        interfacesImplementingSelf = set()
-        for d in descriptors:
-            interfacesImplementingSelf |= d.interface.interfacesImplementingSelf
-        implementationIncludes |= set(self.getDeclarationFilename(i) for i in
-                                      interfacesImplementingSelf)
-
         # Now find all the things we'll need as arguments because we
         # need to wrap or unwrap them.
         bindingHeaders = set()
         declareIncludes = set(declareIncludes)
 
         def addHeadersForType(typeAndPossibleDictionary):
             """
             Add the relevant headers for this type.  We use dictionary, if
@@ -5775,18 +5768,17 @@ def getJSToNativeConversionInfo(type, de
         templateBody = ""
         if forceOwningType:
             templateBody += fill(
                 """
                 static_assert(IsRefcounted<${typeName}>::value, "We can only store refcounted classes.");
                 """,
                 typeName=typeName)
 
-        if (not descriptor.interface.isConsequential() and
-            not descriptor.interface.isExternal()):
+        if (not descriptor.interface.isExternal()):
             if failureCode is not None:
                 templateBody += str(CastableObjectUnwrapper(
                     descriptor,
                     "${val}",
                     "${maybeMutableVal}",
                     "${declName}",
                     failureCode))
             else:
@@ -5794,21 +5786,20 @@ def getJSToNativeConversionInfo(type, de
                     descriptor,
                     "${val}",
                     "${maybeMutableVal}",
                     "${declName}",
                     exceptionCode,
                     isCallbackReturnValue,
                     firstCap(sourceDescription)))
         else:
-            # Either external, or new-binding non-castable.  We always have a
-            # holder for these, because we don't actually know whether we have
-            # to addref when unwrapping or not.  So we just pass an
-            # getter_AddRefs(RefPtr) to XPConnect and if we'll need a release
-            # it'll put a non-null pointer in there.
+            # External interface.  We always have a holder for these, because we
+            # don't actually know whether we have to addref when unwrapping or not.
+            # So we just pass an getter_AddRefs(RefPtr) to XPConnect and if we'll
+            # need a release it'll put a non-null pointer in there.
             if forceOwningType:
                 # Don't return a holderType in this case; our declName
                 # will just own stuff.
                 templateBody += "RefPtr<" + typeName + "> ${holderName};\n"
             else:
                 holderType = "RefPtr<" + typeName + ">"
             templateBody += (
                 "JS::Rooted<JSObject*> source(cx, &${val}.toObject());\n" +
@@ -8861,20 +8852,16 @@ class CGAbstractBindingMethod(CGAbstract
         if self.getThisObj is not None:
             body += self.getThisObj.define() + "\n"
         body += "%s* self;\n" % self.descriptor.nativeType
         body += dedent(
             """
             JS::Rooted<JS::Value> rootSelf(cx, JS::ObjectValue(*obj));
             """)
 
-        # Our descriptor might claim that we're not castable, simply because
-        # we're someone's consequential interface.  But for this-unwrapping, we
-        # know that we're the real deal.  So fake a descriptor here for
-        # consumption by CastableObjectUnwrapper.
         body += str(CastableObjectUnwrapper(
             self.descriptor,
             "rootSelf",
             "&rootSelf",
             "self",
             self.unwrapFailureCode))
 
         return body + self.generate_code().define()
--- a/dom/bindings/Configuration.py
+++ b/dom/bindings/Configuration.py
@@ -1,13 +1,13 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this file,
 # You can obtain one at http://mozilla.org/MPL/2.0/.
 
-from WebIDL import IDLImplementsStatement, IDLIncludesStatement
+from WebIDL import IDLIncludesStatement
 import os
 from collections import defaultdict
 
 autogenerated_comment = "/* THIS FILE IS AUTOGENERATED - DO NOT EDIT */\n"
 
 
 class DescriptorProvider:
     """
@@ -41,41 +41,19 @@ class Configuration(DescriptorProvider):
             return any(isChildPath(path, root) for root in webRoots)
 
         # Build descriptors for all the interfaces we have in the parse data.
         # This allows callers to specify a subset of interfaces by filtering
         # |parseData|.
         self.descriptors = []
         self.interfaces = {}
         self.descriptorsByName = {}
-        self.optimizedOutDescriptorNames = set()
         self.generatedEvents = generatedEvents
         self.maxProtoChainLength = 0
         for thing in parseData:
-            if isinstance(thing, IDLImplementsStatement):
-                # Our build system doesn't support dep build involving
-                # addition/removal of "implements" statements that appear in a
-                # different .webidl file than their LHS interface.  Make sure we
-                # don't have any of those.  See similar block below for partial
-                # interfaces!
-                #
-                # But whitelist a RHS that is LegacyQueryInterface,
-                # since people shouldn't be adding any of those.
-                if (thing.implementor.filename() != thing.filename() and
-                    thing.implementee.identifier.name != "LegacyQueryInterface"):
-                    raise TypeError(
-                        "The binding build system doesn't really support "
-                        "'implements' statements which don't appear in the "
-                        "file in which the left-hand side of the statement is "
-                        "defined.  Don't do this unless your right-hand side "
-                        "is LegacyQueryInterface.\n"
-                        "%s\n"
-                        "%s" %
-                        (thing.location, thing.implementor.location))
-
             if isinstance(thing, IDLIncludesStatement):
                 # Our build system doesn't support dep build involving
                 # addition/removal of "includes" statements that appear in a
                 # different .webidl file than their LHS interface.  Make sure we
                 # don't have any of those.  See similar block below for partial
                 # interfaces!
                 #
                 # But whitelist a RHS that is LegacyQueryInterface,
@@ -121,27 +99,20 @@ class Configuration(DescriptorProvider):
                     raise TypeError(
                         "Interfaces which are exposed to the web may only be "
                         "defined in a DOM WebIDL root %r. Consider marking "
                         "the interface [ChromeOnly] or [Func='IsChromeOrXBL'] "
                         "if you do not want it exposed to the web.\n"
                         "%s" %
                         (webRoots, iface.location))
             self.interfaces[iface.identifier.name] = iface
-            if iface.identifier.name not in config:
-                # Completely skip consequential interfaces with no descriptor
-                # if they have no interface object because chances are we
-                # don't need to do anything interesting with them.
-                if iface.isConsequential() and not iface.hasInterfaceObject():
-                    self.optimizedOutDescriptorNames.add(iface.identifier.name)
-                    continue
-                entry = {}
-            else:
-                entry = config[iface.identifier.name]
+
+            entry = config.get(iface.identifier.name, {})
             assert not isinstance(entry, list)
+
             desc = Descriptor(self, iface, entry)
             self.descriptors.append(desc)
             # Setting up descriptorsByName while iterating through interfaces
             # means we can get the nativeType of iterable interfaces without
             # having to do multiple loops.
             assert desc.interface.identifier.name not in self.descriptorsByName
             self.descriptorsByName[desc.interface.identifier.name] = desc
 
@@ -286,22 +257,16 @@ class Configuration(DescriptorProvider):
         # We may have optimized out this descriptor, but the chances of anyone
         # asking about it are then slim.  Put the check for that _after_ we've
         # done our normal lookup.  But that means we have to do our normal
         # lookup in a way that will not throw if it fails.
         d = self.descriptorsByName.get(interfaceName, None)
         if d:
             return d
 
-        if interfaceName in self.optimizedOutDescriptorNames:
-            raise NoSuchDescriptorError(
-                "No descriptor for '%s', which is a mixin ([NoInterfaceObject] "
-                "and a consequential interface) without an explicit "
-                "Bindings.conf annotation." % interfaceName)
-
         raise NoSuchDescriptorError("For " + interfaceName + " found no matches")
 
 
 class NoSuchDescriptorError(TypeError):
     def __init__(self, str):
         TypeError.__init__(self, str)
 
 
@@ -405,20 +370,16 @@ class Descriptor(DescriptorProvider):
 
         self.notflattened = desc.get('notflattened', False)
         self.register = desc.get('register', True)
 
         # If we're concrete, we need to crawl our ancestor interfaces and mark
         # them as having a concrete descendant.
         concreteDefault = (not self.interface.isExternal() and
                            not self.interface.isCallback() and
-                           # Exclude interfaces that are used as the RHS of
-                           # "implements", because those would typically not be
-                           # concrete.
-                           not self.interface.isConsequential() and
                            not self.interface.isNamespace() and
                            # We're going to assume that leaf interfaces are
                            # concrete; otherwise what's the point?  Also
                            # interfaces with constructors had better be
                            # concrete; otherwise how can you construct them?
                            (not self.interface.hasChildInterfaces() or
                             self.interface.ctor() is not None))
 
--- a/dom/bindings/parser/WebIDL.py
+++ b/dom/bindings/parser/WebIDL.py
@@ -528,19 +528,16 @@ class IDLExternalInterface(IDLObjectWith
         return False
 
     def isExternal(self):
         return True
 
     def isInterface(self):
         return True
 
-    def isConsequential(self):
-        return False
-
     def addExtendedAttributes(self, attrs):
         if len(attrs) != 0:
             raise WebIDLError("There are no extended attributes that are "
                               "allowed on external interfaces",
                               [attrs[0].location, self.location])
 
     def resolve(self, parentScope):
         pass
@@ -871,26 +868,21 @@ class IDLInterfaceOrNamespace(IDLInterfa
         self.parent = None
         self._callback = False
         self.maplikeOrSetlikeOrIterable = None
         # namedConstructors needs deterministic ordering because bindings code
         # outputs the constructs in the order that namedConstructors enumerates
         # them.
         self.namedConstructors = list()
         self.legacyWindowAliases = []
-        self.implementedInterfaces = set()
         self.includedMixins = set()
-        self._consequential = False
         # self.interfacesBasedOnSelf is the set of interfaces that inherit from
-        # self or have self as a consequential interface, including self itself.
+        # self, including self itself.
         # Used for distinguishability checking.
         self.interfacesBasedOnSelf = set([self])
-        # self.interfacesImplementingSelf is the set of interfaces that directly
-        # have self as a consequential interface
-        self.interfacesImplementingSelf = set()
         self._hasChildInterfaces = False
         self._isOnGlobalProtoChain = False
         # Tracking of the number of reserved slots we need for our
         # members and those of ancestor interfaces.
         self.totalMembersInSlots = 0
         # Tracking of the number of own own members we have in slots
         self._ownMembersInSlots = 0
         # If this is an iterator interface, we need to know what iterable
@@ -1014,20 +1006,18 @@ class IDLInterfaceOrNamespace(IDLInterfa
             # Make sure that we're not exposed in places where our parent is not
             if not self.exposureSet.issubset(self.parent.exposureSet):
                 raise WebIDLError("Interface %s is exposed in globals where its "
                                   "parent interface %s is not exposed." %
                                   (self.identifier.name,
                                    self.parent.identifier.name),
                                   [self.location, self.parent.location])
 
-            # Callbacks must not inherit from non-callbacks or inherit from
-            # anything that has consequential interfaces.
+            # Callbacks must not inherit from non-callbacks.
             # XXXbz Can non-callbacks inherit from callbacks?  Spec issue pending.
-            # XXXbz Can callbacks have consequential interfaces?  Spec issue pending
             if self.isCallback():
                 if not self.parent.isCallback():
                     raise WebIDLError("Callback interface %s inheriting from "
                                       "non-callback interface %s" %
                                       (self.identifier.name,
                                        self.parent.identifier.name),
                                       [self.location, self.parent.location])
             elif self.parent.isCallback():
@@ -1054,33 +1044,24 @@ class IDLInterfaceOrNamespace(IDLInterfa
                 not self.getExtendedAttribute("SecureContext")):
                 raise WebIDLError("Interface %s does not have "
                                   "[SecureContext] but inherits from "
                                   "interface %s which does" %
                                   (self.identifier.name,
                                    self.parent.identifier.name),
                                   [self.location, self.parent.location])
 
-        for iface in self.implementedInterfaces:
-            iface.finish(scope)
         for mixin in self.includedMixins:
             mixin.finish(scope)
 
         cycleInGraph = self.findInterfaceLoopPoint(self)
         if cycleInGraph:
-            raise WebIDLError("Interface %s has itself as ancestor or "
-                              "implemented interface" % self.identifier.name,
-                              [self.location, cycleInGraph.location])
-
-        if self.isCallback():
-            # "implements" should have made sure we have no
-            # consequential interfaces.
-            assert len(self.getConsequentialInterfaces()) == 0
-            # And that we're not consequential.
-            assert not self.isConsequential()
+            raise WebIDLError(
+                "Interface %s has itself as ancestor" % self.identifier.name,
+                [self.location, cycleInGraph.location])
 
         self.finishMembers(scope)
 
         ctor = self.ctor()
         if ctor is not None:
             if not self.hasInterfaceObject():
                 raise WebIDLError(
                     "Can't have both a constructor and [NoInterfaceObject]",
@@ -1113,68 +1094,31 @@ class IDLInterfaceOrNamespace(IDLInterfa
             ctor._exposureGlobalNames.update(self._exposureGlobalNames)
             ctor.finish(scope)
 
         # Make a copy of our member list, so things that implement us
         # can get those without all the stuff we implement ourselves
         # admixed.
         self.originalMembers = list(self.members)
 
-        # Import everything from our consequential interfaces into
-        # self.members.  Sort our consequential interfaces by name
-        # just so we have a consistent order.
-        for iface in sorted(self.getConsequentialInterfaces(),
-                            key=lambda x: x.identifier.name):
-            # Flag the interface as being someone's consequential interface
-            iface.setIsConsequentialInterfaceOf(self)
-            # Verify that we're not exposed somewhere where iface is not exposed
-            if not self.exposureSet.issubset(iface.exposureSet):
-                raise WebIDLError("Interface %s is exposed in globals where its "
-                                  "consequential interface %s is not exposed." %
-                                  (self.identifier.name, iface.identifier.name),
-                                  [self.location, iface.location])
-
-            # If we have a maplike or setlike, and the consequential interface
-            # also does, throw an error.
-            if iface.maplikeOrSetlikeOrIterable and self.maplikeOrSetlikeOrIterable:
-                raise WebIDLError("Maplike/setlike/iterable interface %s cannot have "
-                                  "maplike/setlike/iterable interface %s as a "
-                                  "consequential interface" %
-                                  (self.identifier.name,
-                                   iface.identifier.name),
-                                  [self.maplikeOrSetlikeOrIterable.location,
-                                   iface.maplikeOrSetlikeOrIterable.location])
-            additionalMembers = iface.originalMembers
-            for additionalMember in additionalMembers:
-                for member in self.members:
-                    if additionalMember.identifier.name == member.identifier.name:
-                        raise WebIDLError(
-                            "Multiple definitions of %s on %s coming from 'implements' statements" %
-                            (member.identifier.name, self),
-                            [additionalMember.location, member.location])
-            self.members.extend(additionalMembers)
-            iface.interfacesImplementingSelf.add(self)
-
         for mixin in sorted(self.includedMixins,
                             key=lambda x: x.identifier.name):
             self.members.extend(mixin.members)
 
         for ancestor in self.getInheritedInterfaces():
             ancestor.interfacesBasedOnSelf.add(self)
             if (ancestor.maplikeOrSetlikeOrIterable is not None and
                 self.maplikeOrSetlikeOrIterable is not None):
                 raise WebIDLError("Cannot have maplike/setlike on %s that "
                                   "inherits %s, which is already "
                                   "maplike/setlike" %
                                   (self.identifier.name,
                                    ancestor.identifier.name),
                                   [self.maplikeOrSetlikeOrIterable.location,
                                    ancestor.maplikeOrSetlikeOrIterable.location])
-            for ancestorConsequential in ancestor.getConsequentialInterfaces():
-                ancestorConsequential.interfacesBasedOnSelf.add(self)
 
         # Deal with interfaces marked [Unforgeable], now that we have our full
         # member list, except unforgeables pulled in from parents.  We want to
         # do this before we set "originatingInterface" on our unforgeable
         # members.
         if self.getExtendedAttribute("Unforgeable"):
             # Check that the interface already has all the things the
             # spec would otherwise require us to synthesize and is
@@ -1235,23 +1179,22 @@ class IDLInterfaceOrNamespace(IDLInterfa
                 if member.slotIndices is None:
                     member.slotIndices = dict()
                 member.slotIndices[self.identifier.name] = self.totalMembersInSlots
                 self.totalMembersInSlots += 1
                 if member.getExtendedAttribute("StoreInSlot"):
                     self._ownMembersInSlots += 1
 
         if self.parent:
-            # Make sure we don't shadow any of the [Unforgeable] attributes on
-            # our ancestor interfaces.  We don't have to worry about
-            # consequential interfaces here, because those have already been
-            # imported into the relevant .members lists.  And we don't have to
-            # worry about anything other than our parent, because it has already
-            # imported its ancestors unforgeable attributes into its member
-            # list.
+            # Make sure we don't shadow any of the [Unforgeable] attributes on our
+            # ancestor interfaces.  We don't have to worry about mixins here, because
+            # those have already been imported into the relevant .members lists.  And
+            # we don't have to worry about anything other than our parent, because it
+            # has already imported its ancestors' unforgeable attributes into its
+            # member list.
             for unforgeableMember in (member for member in self.parent.members if
                                       (member.isAttr() or member.isMethod()) and
                                       member.isUnforgeable()):
                 shadows = [m for m in self.members if
                            (m.isAttr() or m.isMethod()) and
                            not m.isStatic() and
                            m.identifier.name == unforgeableMember.identifier.name]
                 if len(shadows) != 0:
@@ -1377,27 +1320,16 @@ class IDLInterfaceOrNamespace(IDLInterfa
                     raise WebIDLError("conflicting [%s=%s] definitions" %
                                       (attributeName, name),
                                       [member.location, m.location])
                 if m.isAttr() and m != member and name in m.bindingAliases:
                     raise WebIDLError("conflicting [%s=%s] definitions" %
                                       (attributeName, name),
                                       [member.location, m.location])
 
-        # We don't support consequential unforgeable interfaces.  Need to check
-        # this here, because in finish() an interface might not know yet that
-        # it's consequential.
-        if self.getExtendedAttribute("Unforgeable") and self.isConsequential():
-            raise WebIDLError(
-                "%s is an unforgeable consequential interface" %
-                self.identifier.name,
-                [self.location] +
-                list(i.location for i in
-                     (self.interfacesBasedOnSelf - {self})))
-
         # We also don't support inheriting from unforgeable interfaces.
         if self.getExtendedAttribute("Unforgeable") and self.hasChildInterfaces():
             locations = ([self.location] +
                          list(i.location for i in
                               self.interfacesBasedOnSelf if i.parent == self))
             raise WebIDLError("%s is an unforgeable ancestor interface" %
                               self.identifier.name,
                               locations)
@@ -1546,39 +1478,30 @@ class IDLInterfaceOrNamespace(IDLInterfa
         if indexedGetter and not hasLengthAttribute:
             raise WebIDLError('Interface with an indexed getter does not have '
                               'an integer-typed "length" attribute',
                               [self.location, indexedGetter.location])
 
     def isExternal(self):
         return False
 
-    def setIsConsequentialInterfaceOf(self, other):
-        self._consequential = True
-        self.interfacesBasedOnSelf.add(other)
-
-    def isConsequential(self):
-        return self._consequential
-
     def setCallback(self, value):
         self._callback = value
 
     def isCallback(self):
         return self._callback
 
     def isSingleOperationInterface(self):
         assert self.isCallback() or self.isJSImplemented()
         return (
             # JS-implemented things should never need the
             # this-handling weirdness of single-operation interfaces.
             not self.isJSImplemented() and
             # Not inheriting from another interface
             not self.parent and
-            # No consequential interfaces
-            len(self.getConsequentialInterfaces()) == 0 and
             # No attributes of any kinds
             not any(m.isAttr() for m in self.members) and
             # There is at least one regular operation, and all regular
             # operations have the same identifier
             len(set(m.identifier.name for m in self.members if
                     m.isMethod() and not m.isStatic())) == 1)
 
     def inheritanceDepth(self):
@@ -1596,20 +1519,16 @@ class IDLInterfaceOrNamespace(IDLInterfa
         if self.isCallback():
             return self.hasConstants()
         return not hasattr(self, "_noInterfaceObject")
 
     def hasInterfacePrototypeObject(self):
         return (not self.isCallback() and not self.isNamespace()
                 and self.getUserData('hasConcreteDescendant', False))
 
-    def addImplementedInterface(self, implementedInterface):
-        assert(isinstance(implementedInterface, IDLInterface))
-        self.implementedInterfaces.add(implementedInterface)
-
     def addIncludedMixin(self, includedMixin):
         assert(isinstance(includedMixin, IDLInterfaceMixin))
         self.includedMixins.add(includedMixin)
 
     def getInheritedInterfaces(self):
         """
         Returns a list of the interfaces this interface inherits from
         (not including this interface itself).  The list is in order
@@ -1617,51 +1536,29 @@ class IDLInterfaceOrNamespace(IDLInterfa
         """
         assert(self._finished)
         if not self.parent:
             return []
         parentInterfaces = self.parent.getInheritedInterfaces()
         parentInterfaces.insert(0, self.parent)
         return parentInterfaces
 
-    def getConsequentialInterfaces(self):
-        assert(self._finished)
-        # The interfaces we implement directly
-        consequentialInterfaces = set(self.implementedInterfaces)
-
-        # And their inherited interfaces
-        for iface in self.implementedInterfaces:
-            consequentialInterfaces |= set(iface.getInheritedInterfaces())
-
-        # And now collect up the consequential interfaces of all of those
-        temp = set()
-        for iface in consequentialInterfaces:
-            temp |= iface.getConsequentialInterfaces()
-
-        return consequentialInterfaces | temp
-
     def findInterfaceLoopPoint(self, otherInterface):
         """
-        Finds an interface, amongst our ancestors and consequential interfaces,
-        that inherits from otherInterface or implements otherInterface
-        directly.  If there is no such interface, returns None.
+        Finds an interface amongst our ancestors that inherits from otherInterface.
+        If there is no such interface, returns None.
         """
         if self.parent:
             if self.parent == otherInterface:
                 return self
             loopPoint = self.parent.findInterfaceLoopPoint(otherInterface)
             if loopPoint:
                 return loopPoint
-        if otherInterface in self.implementedInterfaces:
-            return self
-        for iface in self.implementedInterfaces:
-            loopPoint = iface.findInterfaceLoopPoint(otherInterface)
-            if loopPoint:
-                return loopPoint
         return None
+
     def setNonPartial(self, location, parent, members):
         assert not parent or isinstance(parent, IDLIdentifierPlaceholder)
         IDLInterfaceOrInterfaceMixinOrNamespace.setNonPartial(self, location, members)
         assert not self.parent
         self.parent = parent
 
     def getJSImplementation(self):
         classId = self.getExtendedAttribute("JSImplementation")
@@ -1685,17 +1582,16 @@ class IDLInterfaceOrNamespace(IDLInterfa
     def hasChildInterfaces(self):
         return self._hasChildInterfaces
 
     def isOnGlobalProtoChain(self):
         return self._isOnGlobalProtoChain
 
     def _getDependentObjects(self):
         deps = set(self.members)
-        deps.update(self.implementedInterfaces)
         deps.update(self.includedMixins)
         if self.parent:
             deps.add(self.parent)
         return deps
 
     def hasMembersInSlots(self):
         return self._ownMembersInSlots != 0
 
@@ -5543,62 +5439,16 @@ class IDLConstructor(IDLMethod):
         self.addExtendedAttributes(self._initExtendedAttrs)
         self._initExtendedAttrs = []
         # Constructors are always NewObject.  Whether they throw or not is
         # indicated by [Throws] annotations in the usual way.
         self.addExtendedAttributes(
             [IDLExtendedAttribute(self.location, ("NewObject",))])
 
 
-class IDLImplementsStatement(IDLObject):
-    def __init__(self, location, implementor, implementee):
-        IDLObject.__init__(self, location)
-        self.implementor = implementor
-        self.implementee = implementee
-        self._finished = False
-
-    def finish(self, scope):
-        if self._finished:
-            return
-        assert(isinstance(self.implementor, IDLIdentifierPlaceholder))
-        assert(isinstance(self.implementee, IDLIdentifierPlaceholder))
-        implementor = self.implementor.finish(scope)
-        implementee = self.implementee.finish(scope)
-        # NOTE: we depend on not setting self.implementor and
-        # self.implementee here to keep track of the original
-        # locations.
-        if not isinstance(implementor, IDLInterface):
-            raise WebIDLError("Left-hand side of 'implements' is not an "
-                              "interface",
-                              [self.implementor.location])
-        if implementor.isCallback():
-            raise WebIDLError("Left-hand side of 'implements' is a callback "
-                              "interface",
-                              [self.implementor.location])
-        if not isinstance(implementee, IDLInterface):
-            raise WebIDLError("Right-hand side of 'implements' is not an "
-                              "interface",
-                              [self.implementee.location])
-        if implementee.isCallback():
-            raise WebIDLError("Right-hand side of 'implements' is a callback "
-                              "interface",
-                              [self.implementee.location])
-        implementor.addImplementedInterface(implementee)
-        self.implementor = implementor
-        self.implementee = implementee
-
-    def validate(self):
-        pass
-
-    def addExtendedAttributes(self, attrs):
-        if len(attrs) != 0:
-            raise WebIDLError("There are no extended attributes that are "
-                              "allowed on implements statements",
-                              [attrs[0].location, self.location])
-
 class IDLIncludesStatement(IDLObject):
     def __init__(self, location, interface, mixin):
         IDLObject.__init__(self, location)
         self.interface = interface
         self.mixin = mixin
         self._finished = False
 
     def finish(self, scope):
@@ -5738,17 +5588,16 @@ class Tokenizer(object):
         "interface": "INTERFACE",
         "partial": "PARTIAL",
         "mixin": "MIXIN",
         "dictionary": "DICTIONARY",
         "exception": "EXCEPTION",
         "enum": "ENUM",
         "callback": "CALLBACK",
         "typedef": "TYPEDEF",
-        "implements": "IMPLEMENTS",
         "includes": "INCLUDES",
         "const": "CONST",
         "null": "NULL",
         "true": "TRUE",
         "false": "FALSE",
         "serializer": "SERIALIZER",
         "stringifier": "STRINGIFIER",
         "unrestricted": "UNRESTRICTED",
@@ -5902,17 +5751,16 @@ class Parser(Tokenizer):
         """
             Definition : CallbackOrInterfaceOrMixin
                        | Namespace
                        | Partial
                        | Dictionary
                        | Exception
                        | Enum
                        | Typedef
-                       | ImplementsStatement
                        | IncludesStatement
         """
         p[0] = p[1]
         assert p[1]  # We might not have implemented something ...
 
     def p_CallbackOrInterfaceOrMixinCallback(self, p):
         """
             CallbackOrInterfaceOrMixin : CALLBACK CallbackRestOrInterface
@@ -6435,26 +6283,16 @@ class Parser(Tokenizer):
     def p_Typedef(self, p):
         """
             Typedef : TYPEDEF TypeWithExtendedAttributes IDENTIFIER SEMICOLON
         """
         typedef = IDLTypedef(self.getLocation(p, 1), self.globalScope(),
                              p[2], p[3])
         p[0] = typedef
 
-    def p_ImplementsStatement(self, p):
-        """
-            ImplementsStatement : ScopedName IMPLEMENTS ScopedName SEMICOLON
-        """
-        assert(p[2] == "implements")
-        implementor = IDLIdentifierPlaceholder(self.getLocation(p, 1), p[1])
-        implementee = IDLIdentifierPlaceholder(self.getLocation(p, 3), p[3])
-        p[0] = IDLImplementsStatement(self.getLocation(p, 1), implementor,
-                                      implementee)
-
     def p_IncludesStatement(self, p):
         """
             IncludesStatement : ScopedName INCLUDES ScopedName SEMICOLON
         """
         assert(p[2] == "includes")
         interface = IDLIdentifierPlaceholder(self.getLocation(p, 1), p[1])
         mixin = IDLIdentifierPlaceholder(self.getLocation(p, 3), p[3])
         p[0] = IDLIncludesStatement(self.getLocation(p, 1), interface, mixin)
@@ -6906,17 +6744,16 @@ class Parser(Tokenizer):
                          | CALLBACK
                          | CONST
                          | CONSTRUCTOR
                          | DELETER
                          | DICTIONARY
                          | ENUM
                          | EXCEPTION
                          | GETTER
-                         | IMPLEMENTS
                          | INHERIT
                          | INTERFACE
                          | ITERABLE
                          | LEGACYCALLER
                          | MAPLIKE
                          | PARTIAL
                          | REQUIRED
                          | SERIALIZER
@@ -7033,17 +6870,16 @@ class Parser(Tokenizer):
                   | CONST
                   | CONSTRUCTOR
                   | DELETER
                   | DOUBLE
                   | EXCEPTION
                   | FALSE
                   | FLOAT
                   | GETTER
-                  | IMPLEMENTS
                   | INHERIT
                   | INTERFACE
                   | LONG
                   | MODULE
                   | NULL
                   | OBJECT
                   | OCTET
                   | OPTIONAL
@@ -7575,30 +7411,23 @@ class Parser(Tokenizer):
                 itr_iface._exposureGlobalNames = set(iface._exposureGlobalNames)
                 # Always append generated iterable interfaces after the
                 # interface they're a member of, otherwise nativeType generation
                 # won't work correctly.
                 itr_iface.iterableInterface = iface
                 self._productions.append(itr_iface)
                 iterable.iteratorType = IDLWrapperType(iface.location, itr_iface)
 
-        # Then, finish all the IDLImplementsStatements.  In particular, we
-        # have to make sure we do those before we do the IDLInterfaces.
-        # XXX khuey hates this bit and wants to nuke it from orbit.
-        implementsStatements = [p for p in self._productions if
-                                isinstance(p, IDLImplementsStatement)]
         # Make sure we finish IDLIncludesStatements before we finish the
         # IDLInterfaces.
+        # XXX khuey hates this bit and wants to nuke it from orbit.
         includesStatements = [p for p in self._productions if
                                 isinstance(p, IDLIncludesStatement)]
         otherStatements = [p for p in self._productions if
-                           not isinstance(p, (IDLImplementsStatement,
-                                              IDLIncludesStatement))]
-        for production in implementsStatements:
-            production.finish(self.globalScope())
+                           not isinstance(p, IDLIncludesStatement)]
         for production in includesStatements:
             production.finish(self.globalScope())
         for production in otherStatements:
             production.finish(self.globalScope())
 
         # Do any post-finish validation we need to do
         for production in self._productions:
             production.validate()
--- a/dom/bindings/parser/tests/test_distinguishability.py
+++ b/dom/bindings/parser/tests/test_distinguishability.py
@@ -54,30 +54,25 @@ def WebIDLTest(parser, harness):
                "nullable type")
 
     parser = parser.reset()
     parser.parse("""
       interface TestIface {
         void passKid(Kid arg);
         void passParent(Parent arg);
         void passGrandparent(Grandparent arg);
-        void passImplemented(Implemented arg);
-        void passImplementedParent(ImplementedParent arg);
         void passUnrelated1(Unrelated1 arg);
         void passUnrelated2(Unrelated2 arg);
         void passArrayBuffer(ArrayBuffer arg);
         void passArrayBuffer(ArrayBufferView arg);
       };
 
       interface Kid : Parent {};
       interface Parent : Grandparent {};
       interface Grandparent {};
-      interface Implemented : ImplementedParent {};
-      Parent implements Implemented;
-      interface ImplementedParent {};
       interface Unrelated1 {};
       interface Unrelated2 {};
     """)
     results = parser.finish()
 
     iface = results[0]
     harness.ok(iface.isInterface(), "Should have interface")
     argTypes = [firstArgType(method) for method in iface.members]
@@ -151,18 +146,17 @@ def WebIDLTest(parser, harness):
         threw = True
 
     harness.ok(threw, "Should throw when there is no distinguishing index")
 
     # Now let's test our whole distinguishability table
     argTypes = [ "long", "short", "long?", "short?", "boolean",
                  "boolean?", "DOMString", "ByteString", "Enum", "Enum2",
                  "Interface", "Interface?",
-                 "AncestorInterface", "UnrelatedInterface",
-                 "ImplementedInterface", "CallbackInterface",
+                 "AncestorInterface", "UnrelatedInterface", "CallbackInterface",
                  "CallbackInterface?", "CallbackInterface2",
                  "object", "Callback", "Callback2", "Dict",
                  "Dict2", "sequence<long>", "sequence<short>",
                  "record<DOMString, object>",
                  "record<USVString, Dict>",
                  "record<ByteString, long>",
                  "Date", "Date?", "any",
                  "Promise<any>", "Promise<any>?",
@@ -185,17 +179,17 @@ def WebIDLTest(parser, harness):
     nonBooleans = allBut(argTypes, booleans)
     strings = [ "DOMString", "ByteString", "Enum", "Enum2", "USVString", "JSString" ]
     nonStrings = allBut(argTypes, strings)
     nonObjects = primitives + strings
     objects = allBut(argTypes, nonObjects )
     bufferSourceTypes = ["ArrayBuffer", "ArrayBufferView", "Uint8Array", "Uint16Array"]
     sharedBufferSourceTypes = ["SharedArrayBuffer"]
     interfaces = [ "Interface", "Interface?", "AncestorInterface",
-                   "UnrelatedInterface", "ImplementedInterface" ] + bufferSourceTypes + sharedBufferSourceTypes
+                   "UnrelatedInterface" ] + bufferSourceTypes + sharedBufferSourceTypes
     nullables = (["long?", "short?", "boolean?", "Interface?",
                   "CallbackInterface?", "Dict", "Dict2",
                   "Date?", "any", "Promise<any>?"] +
                  allBut(unions, [ "(long or Callback)" ]))
     dates = [ "Date", "Date?" ]
     sequences = [ "sequence<long>", "sequence<short>" ]
     nonUserObjects = nonObjects + interfaces + dates + sequences
     otherObjects = allBut(argTypes, nonUserObjects + ["object"])
@@ -225,17 +219,16 @@ def WebIDLTest(parser, harness):
     setDistinguishable("JSString", nonStrings)
     setDistinguishable("Enum", nonStrings)
     setDistinguishable("Enum2", nonStrings)
     setDistinguishable("Interface", notRelatedInterfaces)
     setDistinguishable("Interface?", allBut(notRelatedInterfaces, nullables))
     setDistinguishable("AncestorInterface", notRelatedInterfaces)
     setDistinguishable("UnrelatedInterface",
                        allBut(argTypes, ["object", "UnrelatedInterface"]))
-    setDistinguishable("ImplementedInterface", notRelatedInterfaces)
     setDistinguishable("CallbackInterface", nonUserObjects)
     setDistinguishable("CallbackInterface?", allBut(nonUserObjects, nullables))
     setDistinguishable("CallbackInterface2", nonUserObjects)
     setDistinguishable("object", nonObjects)
     setDistinguishable("Callback", nonUserObjects)
     setDistinguishable("Callback2", nonUserObjects)
     setDistinguishable("Dict", allBut(nonUserObjects, nullables))
     setDistinguishable("Dict2", allBut(nonUserObjects, nullables))
@@ -267,18 +260,16 @@ def WebIDLTest(parser, harness):
 
     def checkDistinguishability(parser, type1, type2):
         idlTemplate = """
           enum Enum { "a", "b" };
           enum Enum2 { "c", "d" };
           interface Interface : AncestorInterface {};
           interface AncestorInterface {};
           interface UnrelatedInterface {};
-          interface ImplementedInterface {};
-          Interface implements ImplementedInterface;
           callback interface CallbackInterface {};
           callback interface CallbackInterface2 {};
           callback Callback = any();
           callback Callback2 = long(short arg);
           // Give our dictionaries required members so we don't need to
           // mess with optional and default values.
           dictionary Dict { required long member; };
           dictionary Dict2 { required long member; };
--- a/dom/bindings/parser/tests/test_exposed_extended_attribute.py
+++ b/dom/bindings/parser/tests/test_exposed_extended_attribute.py
@@ -85,21 +85,21 @@ def WebIDLTest(parser, harness):
       [Global=Baz2] interface Baz {};
 
       [Exposed=Foo]
       interface Iface3 {
         void method4();
       };
 
       [Exposed=(Foo,Bar1)]
-      interface Mixin {
+      interface mixin Mixin {
         void method5();
       };
 
-      Iface3 implements Mixin;
+      Iface3 includes Mixin;
     """)
     results = parser.finish()
     harness.check(len(results), 6, "Should know about six things");
     iface = results[3]
     harness.ok(isinstance(iface, WebIDL.IDLInterface),
                "Should have an interface here");
     members = iface.members
     harness.check(len(members), 2, "Should have two members")
@@ -193,30 +193,45 @@ def WebIDLTest(parser, harness):
 
         results = parser.finish()
     except Exception as x:
         threw = True
 
     harness.ok(threw, "Should have thrown on member exposed where its interface is not.")
 
     parser = parser.reset()
-    threw = False
-    try:
-        parser.parse("""
-            [Global] interface Foo {};
-            [Global] interface Bar {};
+    parser.parse("""
+        [Global] interface Foo {};
+        [Global] interface Bar {};
+
+        [Exposed=Foo]
+        interface Baz {
+          void method();
+        };
 
-            [Exposed=Foo]
-            interface Baz {
-              void method();
-            };
+        [Exposed=Bar]
+        interface mixin Mixin {
+          void otherMethod();
+        };
+
+        Baz includes Mixin;
+    """)
+
+    results = parser.finish()
 
-            [Exposed=Bar]
-            interface Mixin {};
-
-            Baz implements Mixin;
-        """)
+    harness.check(len(results), 5, "Should know about five things");
+    iface = results[2]
+    harness.ok(isinstance(iface, WebIDL.IDLInterface),
+               "Should have an interface here");
+    members = iface.members
+    harness.check(len(members), 2, "Should have two members")
 
-        results = parser.finish()
-    except Exception as x:
-        threw = True
+    harness.ok(members[0].exposureSet == set(["Foo"]),
+               "method should have the right exposure set")
+    harness.ok(members[0]._exposureGlobalNames == set(["Foo"]),
+               "method should have the right exposure global names")
 
-    harness.ok(threw, "Should have thrown on LHS of implements being exposed where RHS is not.")
+    harness.ok(members[1].exposureSet == set(["Bar"]),
+               "otherMethod should have the right exposure set")
+    harness.ok(members[1]._exposureGlobalNames == set(["Bar"]),
+               "otherMethod should have the right exposure global names")
+
+
deleted file mode 100644
--- a/dom/bindings/parser/tests/test_implements.py
+++ /dev/null
@@ -1,216 +0,0 @@
-# Import the WebIDL module, so we can do isinstance checks and whatnot
-import WebIDL
-
-def WebIDLTest(parser, harness):
-    # Basic functionality
-    threw = False
-    try:
-        parser.parse("""
-            A implements B;
-            interface B {
-              attribute long x;
-            };
-            interface A {
-              attribute long y;
-            };
-        """)
-        results = parser.finish()
-    except:
-        threw = True
-
-    harness.ok(not threw, "Should not have thrown on implements statement "
-               "before interfaces")
-    harness.check(len(results), 3, "We have three statements")
-    harness.ok(isinstance(results[1], WebIDL.IDLInterface), "B is an interface")
-    harness.check(len(results[1].members), 1, "B has one member")
-    A = results[2]
-    harness.ok(isinstance(A, WebIDL.IDLInterface), "A is an interface")
-    harness.check(len(A.members), 2, "A has two members")
-    harness.check(A.members[0].identifier.name, "y", "First member is 'y'")
-    harness.check(A.members[1].identifier.name, "x", "Second member is 'x'")
-
-    # Duplicated member names not allowed
-    threw = False
-    try:
-        parser.parse("""
-            C implements D;
-            interface D {
-              attribute long x;
-            };
-            interface C {
-              attribute long x;
-            };
-        """)
-        parser.finish()
-    except:
-        threw = True
-
-    harness.ok(threw, "Should have thrown on implemented interface duplicating "
-               "a name on base interface")
-
-    # Same, but duplicated across implemented interfaces
-    threw = False
-    try:
-        parser.parse("""
-            E implements F;
-            E implements G;
-            interface F {
-              attribute long x;
-            };
-            interface G {
-              attribute long x;
-            };
-            interface E {};
-        """)
-        parser.finish()
-    except:
-        threw = True
-
-    harness.ok(threw, "Should have thrown on implemented interfaces "
-               "duplicating each other's member names")
-
-    # Same, but duplicated across indirectly implemented interfaces
-    threw = False
-    try:
-        parser.parse("""
-            H implements I;
-            H implements J;
-            I implements K;
-            interface K {
-              attribute long x;
-            };
-            interface L {
-              attribute long x;
-            };
-            interface I {};
-            interface J : L {};
-            interface H {};
-        """)
-        parser.finish()
-    except:
-        threw = True
-
-    harness.ok(threw, "Should have thrown on indirectly implemented interfaces "
-               "duplicating each other's member names")
-
-    # Same, but duplicated across an implemented interface and its parent
-    threw = False
-    try:
-        parser.parse("""
-            M implements N;
-            interface O {
-              attribute long x;
-            };
-            interface N : O {
-              attribute long x;
-            };
-            interface M {};
-        """)
-        parser.finish()
-    except:
-        threw = True
-
-    harness.ok(threw, "Should have thrown on implemented interface and its "
-               "ancestor duplicating member names")
-
-    # Reset the parser so we can actually find things where we expect
-    # them in the list
-    parser = parser.reset()
-
-    # Diamonds should be allowed
-    threw = False
-    try:
-        parser.parse("""
-            P implements Q;
-            P implements R;
-            Q implements S;
-            R implements S;
-            interface Q {};
-            interface R {};
-            interface S {
-              attribute long x;
-            };
-            interface P {};
-        """)
-        results = parser.finish()
-    except:
-        threw = True
-
-    harness.ok(not threw, "Diamond inheritance is fine")
-    harness.check(results[6].identifier.name, "S", "We should be looking at 'S'")
-    harness.check(len(results[6].members), 1, "S should have one member")
-    harness.check(results[6].members[0].identifier.name, "x",
-                  "S's member should be 'x'")
-
-    parser = parser.reset()
-    threw = False
-    try:
-        parser.parse("""
-            interface TestInterface {
-            };
-            callback interface TestCallbackInterface {
-            };
-            TestInterface implements TestCallbackInterface;
-        """)
-        results = parser.finish()
-    except:
-        threw = True
-
-    harness.ok(threw,
-               "Should not allow callback interfaces on the right-hand side "
-               "of 'implements'")
-
-    parser = parser.reset()
-    threw = False
-    try:
-        parser.parse("""
-            interface TestInterface {
-            };
-            callback interface TestCallbackInterface {
-            };
-            TestCallbackInterface implements TestInterface;
-        """)
-        results = parser.finish()
-    except:
-        threw = True
-
-    harness.ok(threw,
-               "Should not allow callback interfaces on the left-hand side of "
-               "'implements'")
-    
-    parser = parser.reset()
-    threw = False
-    try:
-        parser.parse("""
-            interface TestInterface {
-            };
-            dictionary Dict {
-            };
-            Dict implements TestInterface;
-        """)
-        results = parser.finish()
-    except:
-        threw = True
-
-    harness.ok(threw,
-               "Should not allow non-interfaces on the left-hand side "
-               "of 'implements'")
-
-    parser = parser.reset()
-    threw = False
-    try:
-        parser.parse("""
-            interface TestInterface {
-            };
-            dictionary Dict {
-            };
-            TestInterface implements Dict;
-        """)
-        results = parser.finish()
-    except:
-        threw = True
-
-    harness.ok(threw,
-               "Should not allow non-interfaces on the right-hand side "
-               "of 'implements'")
-
--- a/dom/bindings/parser/tests/test_interface.py
+++ b/dom/bindings/parser/tests/test_interface.py
@@ -79,110 +79,16 @@ def WebIDLTest(parser, harness):
         threw = True
 
     harness.ok(threw, "Should not allow indirect cycles in interface inheritance chains")
 
     parser = parser.reset()
     threw = False
     try:
         parser.parse("""
-            interface A {};
-            interface B {};
-            A implements B;
-            B implements A;
-        """)
-        results = parser.finish()
-    except:
-        threw = True
-
-    harness.ok(threw, "Should not allow cycles via implements")
-
-    parser = parser.reset()
-    threw = False
-    try:
-        parser.parse("""
-            interface A {};
-            interface C {};
-            interface B {};
-            A implements C;
-            C implements B;
-            B implements A;
-        """)
-        results = parser.finish()
-    except:
-        threw = True
-
-    harness.ok(threw, "Should not allow indirect cycles via implements")
-
-    parser = parser.reset()
-    threw = False
-    try:
-        parser.parse("""
-            interface A : B {};
-            interface B {};
-            B implements A;
-        """)
-        results = parser.finish()
-    except:
-        threw = True
-
-    harness.ok(threw, "Should not allow inheriting from an interface that implements us")
-
-    parser = parser.reset()
-    threw = False
-    try:
-        parser.parse("""
-            interface A : B {};
-            interface B {};
-            interface C {};
-            B implements C;
-            C implements A;
-        """)
-        results = parser.finish()
-    except:
-        threw = True
-
-    harness.ok(threw, "Should not allow inheriting from an interface that indirectly implements us")
-
-    parser = parser.reset()
-    threw = False
-    try:
-        parser.parse("""
-            interface A : B {};
-            interface B : C {};
-            interface C {};
-            C implements A;
-        """)
-        results = parser.finish()
-    except:
-        threw = True
-
-    harness.ok(threw, "Should not allow indirectly inheriting from an interface that implements us")
-
-    parser = parser.reset()
-    threw = False
-    try:
-        parser.parse("""
-            interface A : B {};
-            interface B : C {};
-            interface C {};
-            interface D {};
-            C implements D;
-            D implements A;
-        """)
-        results = parser.finish()
-    except:
-        threw = True
-
-    harness.ok(threw, "Should not allow indirectly inheriting from an interface that indirectly implements us")
-
-    parser = parser.reset()
-    threw = False
-    try:
-        parser.parse("""
             interface A;
             interface B : A {};
         """)
         results = parser.finish()
     except:
         threw = True
 
     harness.ok(threw, "Should not allow inheriting from an interface that is only forward declared")
--- a/dom/bindings/parser/tests/test_interface_maplikesetlikeiterable.py
+++ b/dom/bindings/parser/tests/test_interface_maplikesetlikeiterable.py
@@ -247,26 +247,16 @@ def WebIDLTest(parser, harness):
                """
                interface Foo1 {
                maplike<long, long>;
                };
                interface Foo2 : Foo1 {
                };
                """, mapRWMembers, numProductions=2)
 
-    shouldPass("Implements with maplike/setlike",
-               """
-               interface Foo1 {
-               maplike<long, long>;
-               };
-               interface Foo2 {
-               };
-               Foo2 implements Foo1;
-               """, mapRWMembers, numProductions=3)
-
     shouldPass("JS Implemented maplike interface",
                """
                [JSImplementation="@mozilla.org/dom/test-interface-js-maplike;1"]
                interface Foo1 {
                constructor();
                setlike<long>;
                };
                """, setRWChromeMembers)
@@ -345,41 +335,16 @@ def WebIDLTest(parser, harness):
                };
                interface Foo2 : Foo1 {
                };
                interface Foo3 : Foo2 {
                setlike<long>;
                };
                """)
 
-    shouldFail("Consequential interface with conflicting maplike/setlike",
-               """
-               interface Foo1 {
-               maplike<long, long>;
-               };
-               interface Foo2 {
-               setlike<long>;
-               };
-               Foo2 implements Foo1;
-               """)
-
-    shouldFail("Consequential interfaces with conflicting maplike/setlike",
-               """
-               interface Foo1 {
-               maplike<long, long>;
-               };
-               interface Foo2 {
-               setlike<long>;
-               };
-               interface Foo3 {
-               };
-               Foo3 implements Foo1;
-               Foo3 implements Foo2;
-               """)
-
     #
     # Member name collision tests
     #
 
     def testConflictingMembers(likeMember, conflictName, expectedMembers, methodPasses):
         """
         Tests for maplike/setlike member generation against conflicting member
         names. If methodPasses is True, this means we expect the interface to
@@ -472,62 +437,38 @@ def WebIDLTest(parser, harness):
                };
                interface Foo2 : Foo1 {
                };
                interface Foo3 : Foo2 {
                void entries();
                };
                """, mapRWMembers, numProductions=3)
 
-    shouldFail("Interface with consequential maplike/setlike interface member collision",
-               """
-               interface Foo1 {
-               void entries();
-               };
-               interface Foo2 {
-               maplike<long, long>;
-               };
-               Foo1 implements Foo2;
-               """)
-
-    shouldFail("Maplike interface with consequential interface member collision",
+    shouldFail("Maplike interface with mixin member collision",
                """
                interface Foo1 {
                maplike<long, long>;
                };
-               interface Foo2 {
+               interface mixin Foo2 {
                void entries();
                };
-               Foo1 implements Foo2;
+               Foo1 includes Foo2;
                """)
 
-    shouldPass("Consequential Maplike interface with inherited interface member collision",
-               """
-               interface Foo1 {
-               maplike<long, long>;
-               };
-               interface Foo2 {
-               void entries();
-               };
-               interface Foo3 : Foo2 {
-               };
-               Foo3 implements Foo1;
-               """, mapRWMembers, numProductions=4)
-
     shouldPass("Inherited Maplike interface with consequential interface member collision",
                """
                interface Foo1 {
                maplike<long, long>;
                };
-               interface Foo2 {
+               interface mixin Foo2 {
                void entries();
                };
                interface Foo3 : Foo1 {
                };
-               Foo3 implements Foo2;
+               Foo3 includes Foo2;
                """, mapRWMembers, numProductions=4)
 
     shouldFail("Inheritance of name collision with child maplike/setlike",
                """
                interface Foo1 {
                void entries();
                };
                interface Foo2 : Foo1 {
@@ -640,17 +581,17 @@ def WebIDLTest(parser, harness):
                };
                interface Foo2 : Foo1 {
                };
                interface Foo3 : Foo2 {
                maplike<long, long>;
                };
                """)
 
-    shouldPass("Implemented interface with readonly allowable overrides",
+    shouldPass("Interface with readonly allowable overrides",
                """
                interface Foo1 {
                readonly setlike<long>;
                readonly attribute boolean clear;
                };
                """, setROMembers + [("clear", WebIDL.IDLAttribute)])
 
     shouldPass("JS Implemented read-only interface with readonly allowable overrides",
--- a/dom/bindings/parser/tests/test_securecontext_extended_attribute.py
+++ b/dom/bindings/parser/tests/test_securecontext_extended_attribute.py
@@ -283,43 +283,42 @@ def WebIDLTest(parser, harness):
               void testSecureMethod(byte foo);
             };
         """)
         results = parser.finish()
     except:
         threw = True
     harness.ok(threw, "[SecureContext] must appear on interfaces that inherit from another [SecureContext] interface")
 
-    # Test 'implements'. The behavior tested here may have to change depending
-    # on the resolution of https://github.com/heycam/webidl/issues/118
+    # Test 'includes'.
     parser = parser.reset()
     parser.parse("""
         [SecureContext]
-        interface TestSecureContextInterfaceThatImplementsNonSecureContextInterface {
+        interface TestSecureContextInterfaceThatIncludesNonSecureContextMixin {
           const octet TEST_CONSTANT = 0;
         };
-        interface TestNonSecureContextInterface {
+        interface mixin TestNonSecureContextMixin {
           const octet TEST_CONSTANT_2 = 0;
           readonly attribute byte testAttribute2;
           void testMethod2(byte foo);
         };
-        TestSecureContextInterfaceThatImplementsNonSecureContextInterface implements TestNonSecureContextInterface;
+        TestSecureContextInterfaceThatIncludesNonSecureContextMixin includes TestNonSecureContextMixin;
      """)
     results = parser.finish()
-    harness.check(len(results[0].members), 4, "TestSecureContextInterfaceThatImplementsNonSecureContextInterface should have two members")
+    harness.check(len(results[0].members), 4, "TestSecureContextInterfaceThatImplementsNonSecureContextInterface should have four members")
     harness.ok(results[0].getExtendedAttribute("SecureContext"),
                "Interface should have [SecureContext] extended attribute")
     harness.ok(results[0].members[0].getExtendedAttribute("SecureContext"),
                "[SecureContext] should propagate from interface to constant members even when other members are copied from a non-[SecureContext] interface")
     harness.ok(results[0].members[1].getExtendedAttribute("SecureContext") is None,
-               "Constants copied from non-[SecureContext] interface should not be [SecureContext]")
+               "Constants copied from non-[SecureContext] mixin should not be [SecureContext]")
     harness.ok(results[0].members[2].getExtendedAttribute("SecureContext") is None,
-               "Attributes copied from non-[SecureContext] interface should not be [SecureContext]")
+               "Attributes copied from non-[SecureContext] mixin should not be [SecureContext]")
     harness.ok(results[0].members[3].getExtendedAttribute("SecureContext") is None,
-               "Methods copied from non-[SecureContext] interface should not be [SecureContext]")
+               "Methods copied from non-[SecureContext] mixin should not be [SecureContext]")
  
     # Test SecureContext and NoInterfaceObject
     parser = parser.reset()
     parser.parse("""
         [NoInterfaceObject, SecureContext]
         interface TestSecureContextNoInterfaceObject {
           void testSecureMethod(byte foo);
         };
--- a/dom/bindings/parser/tests/test_unforgeable.py
+++ b/dom/bindings/parser/tests/test_unforgeable.py
@@ -136,39 +136,39 @@ def WebIDLTest(parser, harness):
                "Should have thrown when shadowing unforgeable operation on "
                "parent with attribute.")
 
     parser = parser.reset();
     parser.parse("""
             interface Child : Parent {
             };
             interface Parent {};
-            interface Consequential {
+            interface mixin Mixin {
               [Unforgeable] readonly attribute long foo;
             };
-            Parent implements Consequential;
+            Parent includes Mixin;
         """)
 
     results = parser.finish()
     harness.check(len(results), 4,
                   "Should be able to inherit from an interface with a "
-                  "consequential interface with [Unforgeable] properties.")
+                  "mixin with [Unforgeable] properties.")
 
     parser = parser.reset();
     threw = False
     try:
         parser.parse("""
             interface Child : Parent {
               void foo();
             };
             interface Parent {};
-            interface Consequential {
+            interface mixin Mixin {
               [Unforgeable] readonly attribute long foo;
             };
-            Parent implements Consequential;
+            Parent includes Mixin;
         """)
 
         results = parser.finish()
     except:
         threw = True
 
     harness.ok(threw,
                "Should have thrown when shadowing unforgeable attribute "
@@ -177,24 +177,24 @@ def WebIDLTest(parser, harness):
     parser = parser.reset();
     threw = False
     try:
         parser.parse("""
             interface Child : Parent {
             };
             interface Parent : GrandParent {};
             interface GrandParent {};
-            interface Consequential {
+            interface mixin Mixin {
               [Unforgeable] readonly attribute long foo;
             };
-            GrandParent implements Consequential;
-            interface ChildConsequential {
+            GrandParent includes Mixin;
+            interface mixin ChildMixin {
               void foo();
             };
-            Child implements ChildConsequential;
+            Child includes ChildMixin;
         """)
 
         results = parser.finish()
     except:
         threw = True
 
     harness.ok(threw,
                "Should have thrown when our consequential interface shadows unforgeable attribute "
@@ -203,24 +203,24 @@ def WebIDLTest(parser, harness):
     parser = parser.reset();
     threw = False
     try:
         parser.parse("""
             interface Child : Parent {
             };
             interface Parent : GrandParent {};
             interface GrandParent {};
-            interface Consequential {
+            interface mixin Mixin {
               [Unforgeable] void foo();
             };
-            GrandParent implements Consequential;
-            interface ChildConsequential {
+            GrandParent includes Mixin;
+            interface mixin ChildMixin {
               void foo();
             };
-            Child implements ChildConsequential;
+            Child includes ChildMixin;
         """)
 
         results = parser.finish()
     except:
         threw = True
 
     harness.ok(threw,
                "Should have thrown when our consequential interface shadows unforgeable operation "
--- a/dom/bindings/test/TestBindingHeader.h
+++ b/dom/bindings/test/TestBindingHeader.h
@@ -55,41 +55,16 @@ class nsRenamedInterface : public nsISup
   NS_DECL_ISUPPORTS
 
   // We need a GetParentObject to make binding codegen happy
   virtual nsISupports* GetParentObject();
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsRenamedInterface, NS_RENAMED_INTERFACE_IID)
 
-// IID for the IndirectlyImplementedInterface
-#define NS_INDIRECTLY_IMPLEMENTED_INTERFACE_IID      \
-  {                                                  \
-    0xfed55b69, 0x7012, 0x4849, {                    \
-      0xaf, 0x56, 0x4b, 0xa9, 0xee, 0x41, 0x30, 0x89 \
-    }                                                \
-  }
-
-class IndirectlyImplementedInterface : public nsISupports,
-                                       public nsWrapperCache {
- public:
-  NS_DECLARE_STATIC_IID_ACCESSOR(NS_INDIRECTLY_IMPLEMENTED_INTERFACE_IID)
-  NS_DECL_ISUPPORTS
-
-  // We need a GetParentObject to make binding codegen happy
-  virtual nsISupports* GetParentObject();
-
-  bool IndirectlyImplementedProperty();
-  void IndirectlyImplementedProperty(bool);
-  void IndirectlyImplementedMethod();
-};
-
-NS_DEFINE_STATIC_IID_ACCESSOR(IndirectlyImplementedInterface,
-                              NS_INDIRECTLY_IMPLEMENTED_INTERFACE_IID)
-
 // IID for the TestExternalInterface
 #define NS_TEST_EXTERNAL_INTERFACE_IID               \
   {                                                  \
     0xd5ba0c99, 0x9b1d, 0x4e71, {                    \
       0x8a, 0x94, 0x56, 0x38, 0x6c, 0xa3, 0xda, 0x3d \
     }                                                \
   }
 class TestExternalInterface : public nsISupports {
@@ -130,17 +105,17 @@ class TestInterface : public nsISupports
   static already_AddRefed<TestInterface> Constructor(const GlobalObject&,
                                                      const nsAString&);
   static already_AddRefed<TestInterface> Constructor(const GlobalObject&,
                                                      uint32_t,
                                                      const Nullable<bool>&);
   static already_AddRefed<TestInterface> Constructor(const GlobalObject&,
                                                      TestInterface*);
   static already_AddRefed<TestInterface> Constructor(
-      const GlobalObject&, uint32_t, IndirectlyImplementedInterface&);
+      const GlobalObject&, uint32_t, TestInterface&);
 
   static already_AddRefed<TestInterface> Constructor(const GlobalObject&,
                                                      Date&);
   static already_AddRefed<TestInterface> Constructor(const GlobalObject&,
                                                      const ArrayBuffer&);
   static already_AddRefed<TestInterface> Constructor(const GlobalObject&,
                                                      const Uint8Array&);
   /*  static
@@ -337,31 +312,16 @@ class TestInterface : public nsISupports
       nsTArray<RefPtr<TestNonWrapperCacheInterface>>&);
   void ReceiveNullableNonWrapperCacheInterfaceSequence(
       nsTArray<RefPtr<TestNonWrapperCacheInterface>>&);
   void ReceiveNonWrapperCacheInterfaceNullableSequence(
       Nullable<nsTArray<RefPtr<TestNonWrapperCacheInterface>>>&);
   void ReceiveNullableNonWrapperCacheInterfaceNullableSequence(
       Nullable<nsTArray<RefPtr<TestNonWrapperCacheInterface>>>&);
 
-  already_AddRefed<IndirectlyImplementedInterface> ReceiveOther();
-  already_AddRefed<IndirectlyImplementedInterface> ReceiveNullableOther();
-  IndirectlyImplementedInterface* ReceiveWeakOther();
-  IndirectlyImplementedInterface* ReceiveWeakNullableOther();
-  void PassOther(IndirectlyImplementedInterface&);
-  void PassNullableOther(IndirectlyImplementedInterface*);
-  already_AddRefed<IndirectlyImplementedInterface> NonNullOther();
-  void SetNonNullOther(IndirectlyImplementedInterface&);
-  already_AddRefed<IndirectlyImplementedInterface> GetNullableOther();
-  void SetNullableOther(IndirectlyImplementedInterface*);
-  void PassOptionalOther(const Optional<IndirectlyImplementedInterface*>&);
-  void PassOptionalNonNullOther(
-      const Optional<NonNull<IndirectlyImplementedInterface>>&);
-  void PassOptionalOtherWithDefault(IndirectlyImplementedInterface*);
-
   already_AddRefed<TestExternalInterface> ReceiveExternal();
   already_AddRefed<TestExternalInterface> ReceiveNullableExternal();
   TestExternalInterface* ReceiveWeakExternal();
   TestExternalInterface* ReceiveWeakNullableExternal();
   void PassExternal(TestExternalInterface*);
   void PassNullableExternal(TestExternalInterface*);
   already_AddRefed<TestExternalInterface> NonNullExternal();
   void SetNonNullExternal(TestExternalInterface*);
@@ -382,20 +342,16 @@ class TestInterface : public nsISupports
   already_AddRefed<TestCallbackInterface> GetNullableCallbackInterface();
   void SetNullableCallbackInterface(TestCallbackInterface*);
   void PassOptionalCallbackInterface(
       const Optional<RefPtr<TestCallbackInterface>>&);
   void PassOptionalNonNullCallbackInterface(
       const Optional<OwningNonNull<TestCallbackInterface>>&);
   void PassOptionalCallbackInterfaceWithDefault(TestCallbackInterface*);
 
-  already_AddRefed<IndirectlyImplementedInterface>
-  ReceiveConsequentialInterface();
-  void PassConsequentialInterface(IndirectlyImplementedInterface&);
-
   // Sequence types
   void GetReadonlySequence(nsTArray<int32_t>&);
   void GetReadonlySequenceOfDictionaries(JSContext*, nsTArray<Dict>&);
   void GetReadonlyNullableSequenceOfDictionaries(JSContext*,
                                                  Nullable<nsTArray<Dict>>&);
   void GetReadonlyFrozenSequence(JSContext*, nsTArray<Dict>&);
   void GetReadonlyFrozenNullableSequence(JSContext*, Nullable<nsTArray<Dict>>&);
   void ReceiveSequence(nsTArray<int32_t>&);
@@ -1081,27 +1037,20 @@ class TestInterface : public nsISupports
   void SetDashed_attribute(int8_t);
   int8_t Dashed_attribute();
   void Dashed_method();
 
   bool NonEnumerableAttr() const;
   void SetNonEnumerableAttr(bool);
   void NonEnumerableMethod();
 
-  // Methods and properties imported via "implements"
-  bool ImplementedProperty();
-  void SetImplementedProperty(bool);
-  void ImplementedMethod();
-  bool ImplementedParentProperty();
-  void SetImplementedParentProperty(bool);
-  void ImplementedParentMethod();
-  bool IndirectlyImplementedProperty();
-  void SetIndirectlyImplementedProperty(bool);
-  void IndirectlyImplementedMethod();
-  uint32_t DiamondImplementedProperty();
+  // Methods and properties imported via "includes"
+  bool MixedInProperty();
+  void SetMixedInProperty(bool);
+  void MixedInMethod();
 
   // Test EnforceRange/Clamp
   void DontEnforceRangeOrClamp(int8_t);
   void DoEnforceRange(int8_t);
   void DoClamp(int8_t);
   void SetEnforcedByte(int8_t);
   int8_t EnforcedByte();
   void SetClampedByte(int8_t);
@@ -1232,19 +1181,16 @@ class TestInterface : public nsISupports
   void PassOptionalLong(Optional<int32_t>&) = delete;
   void PassOptionalLongLong(Optional<int64_t>&) = delete;
   void PassOptionalOctet(Optional<uint8_t>&) = delete;
   void PassOptionalUnsignedShort(Optional<uint16_t>&) = delete;
   void PassOptionalUnsignedLong(Optional<uint32_t>&) = delete;
   void PassOptionalUnsignedLongLong(Optional<uint64_t>&) = delete;
   void PassOptionalSelf(Optional<TestInterface*>&) = delete;
   void PassOptionalNonNullSelf(Optional<NonNull<TestInterface>>&) = delete;
-  void PassOptionalOther(Optional<IndirectlyImplementedInterface*>&);
-  void PassOptionalNonNullOther(
-      Optional<NonNull<IndirectlyImplementedInterface>>&);
   void PassOptionalExternal(Optional<TestExternalInterface*>&) = delete;
   void PassOptionalNonNullExternal(Optional<TestExternalInterface*>&) = delete;
   void PassOptionalSequence(Optional<Sequence<int32_t>>&) = delete;
   void PassOptionalNullableSequence(Optional<Nullable<Sequence<int32_t>>>&) =
       delete;
   void PassOptionalObjectSequence(
       Optional<Sequence<OwningNonNull<TestInterface>>>&) = delete;
   void PassOptionalArrayBuffer(Optional<ArrayBuffer>&) = delete;
@@ -1308,20 +1254,16 @@ class TestInterface : public nsISupports
   void PassVariadicObject(JSContext*, Sequence<JSObject*>&) = delete;
   void PassVariadicNullableObject(JSContext*, Sequence<JSObject*>&) = delete;
 
   // Ensure NonNull does not leak in
   void PassSelf(NonNull<TestInterface>&) = delete;
   void PassSelf(OwningNonNull<TestInterface>&) = delete;
   void PassSelf(const NonNull<TestInterface>&) = delete;
   void PassSelf(const OwningNonNull<TestInterface>&) = delete;
-  void PassOther(NonNull<IndirectlyImplementedInterface>&) = delete;
-  void PassOther(const NonNull<IndirectlyImplementedInterface>&) = delete;
-  void PassOther(OwningNonNull<IndirectlyImplementedInterface>&) = delete;
-  void PassOther(const OwningNonNull<IndirectlyImplementedInterface>&) = delete;
   void PassCallbackInterface(OwningNonNull<TestCallbackInterface>&) = delete;
   void PassCallbackInterface(const OwningNonNull<TestCallbackInterface>&) =
       delete;
   void PassCallbackInterface(NonNull<TestCallbackInterface>&) = delete;
   void PassCallbackInterface(const NonNull<TestCallbackInterface>&) = delete;
   void PassCallback(OwningNonNull<TestCallback>&) = delete;
   void PassCallback(const OwningNonNull<TestCallback>&) = delete;
   void PassCallback(NonNull<TestCallback>&) = delete;
@@ -1575,17 +1517,17 @@ class TestThrowingConstructorInterface :
       const GlobalObject&, ErrorResult&);
   static already_AddRefed<TestThrowingConstructorInterface> Constructor(
       const GlobalObject&, const nsAString&, ErrorResult&);
   static already_AddRefed<TestThrowingConstructorInterface> Constructor(
       const GlobalObject&, uint32_t, const Nullable<bool>&, ErrorResult&);
   static already_AddRefed<TestThrowingConstructorInterface> Constructor(
       const GlobalObject&, TestInterface*, ErrorResult&);
   static already_AddRefed<TestThrowingConstructorInterface> Constructor(
-      const GlobalObject&, uint32_t, IndirectlyImplementedInterface&,
+      const GlobalObject&, uint32_t, TestInterface&,
       ErrorResult&);
 
   static already_AddRefed<TestThrowingConstructorInterface> Constructor(
       const GlobalObject&, Date&, ErrorResult&);
   static already_AddRefed<TestThrowingConstructorInterface> Constructor(
       const GlobalObject&, const ArrayBuffer&, ErrorResult&);
   static already_AddRefed<TestThrowingConstructorInterface> Constructor(
       const GlobalObject&, const Uint8Array&, ErrorResult&);
--- a/dom/bindings/test/TestCodeGen.webidl
+++ b/dom/bindings/test/TestCodeGen.webidl
@@ -134,17 +134,17 @@ callback constructor TestExternalInterfa
 callback constructor TestCallbackInterfaceConstruction = TestCallbackInterface();
 callback constructor TestCallbackConstruction = TestCallback();
 callback constructor TestObjectConstruction = object();
 callback constructor TestTypedArrayConstruction = ArrayBuffer();
 callback constructor TestSequenceConstruction = sequence<boolean>();
 // If you add a new test callback, add it to the forceCallbackGeneration
 // method on TestInterface so it actually gets tested.
 
-TestInterface implements ImplementedInterface;
+TestInterface includes InterfaceMixin;
 
 // This interface is only for use in the constructor below
 interface OnlyForUseInConstructor {
 };
 
 [NamedConstructor=Test,
  NamedConstructor=Test(DOMString str),
  NamedConstructor=Test2(DictForConstructor dict, any any1, object obj1,
@@ -155,17 +155,17 @@ interface OnlyForUseInConstructor {
  NamedConstructor=Test5(record<DOMString, sequence<record<DOMString, record<DOMString, sequence<sequence<any>>>>>> arg1),
  NamedConstructor=Test6(sequence<record<ByteString, sequence<sequence<record<ByteString, record<USVString, any>>>>>> arg1),
  ]
 interface TestInterface {
   constructor();
   constructor(DOMString str);
   constructor(unsigned long num, boolean? boolArg);
   constructor(TestInterface? iface);
-  constructor(unsigned long arg1, IndirectlyImplementedInterface iface);
+  constructor(unsigned long arg1, TestInterface iface);
   constructor(Date arg1);
   constructor(ArrayBuffer arrayBuf);
   constructor(Uint8Array typedArr);
   // constructor(long arg1, long arg2, (TestInterface or OnlyForUseInConstructor) arg3);
 
   // Integer types
   // XXXbz add tests for throwing versions of all the integer stuff
   readonly attribute byte readonlyByte;
@@ -320,30 +320,16 @@ interface TestInterface {
   sequence<TestNonWrapperCacheInterface> receiveNonWrapperCacheInterfaceSequence();
   [NewObject]
   sequence<TestNonWrapperCacheInterface?> receiveNullableNonWrapperCacheInterfaceSequence();
   [NewObject]
   sequence<TestNonWrapperCacheInterface>? receiveNonWrapperCacheInterfaceNullableSequence();
   [NewObject]
   sequence<TestNonWrapperCacheInterface?>? receiveNullableNonWrapperCacheInterfaceNullableSequence();
 
-  // Non-castable interface types
-  IndirectlyImplementedInterface receiveOther();
-  IndirectlyImplementedInterface? receiveNullableOther();
-  IndirectlyImplementedInterface receiveWeakOther();
-  IndirectlyImplementedInterface? receiveWeakNullableOther();
-  void passOther(IndirectlyImplementedInterface arg);
-  void passNullableOther(IndirectlyImplementedInterface? arg);
-  attribute IndirectlyImplementedInterface nonNullOther;
-  attribute IndirectlyImplementedInterface? nullableOther;
-  // Optional arguments
-  void passOptionalOther(optional IndirectlyImplementedInterface? arg);
-  void passOptionalNonNullOther(optional IndirectlyImplementedInterface arg);
-  void passOptionalOtherWithDefault(optional IndirectlyImplementedInterface? arg = null);
-
   // External interface types
   TestExternalInterface receiveExternal();
   TestExternalInterface? receiveNullableExternal();
   TestExternalInterface receiveWeakExternal();
   TestExternalInterface? receiveWeakNullableExternal();
   void passExternal(TestExternalInterface arg);
   void passNullableExternal(TestExternalInterface? arg);
   attribute TestExternalInterface nonNullExternal;
@@ -362,20 +348,16 @@ interface TestInterface {
   void passNullableCallbackInterface(TestCallbackInterface? arg);
   attribute TestCallbackInterface nonNullCallbackInterface;
   attribute TestCallbackInterface? nullableCallbackInterface;
   // Optional arguments
   void passOptionalCallbackInterface(optional TestCallbackInterface? arg);
   void passOptionalNonNullCallbackInterface(optional TestCallbackInterface arg);
   void passOptionalCallbackInterfaceWithDefault(optional TestCallbackInterface? arg = null);
 
-  // Miscellaneous interface tests
-  IndirectlyImplementedInterface receiveConsequentialInterface();
-  void passConsequentialInterface(IndirectlyImplementedInterface arg);
-
   // Sequence types
   [Cached, Pure]
   readonly attribute sequence<long> readonlySequence;
   [Cached, Pure]
   readonly attribute sequence<Dict> readonlySequenceOfDictionaries;
   [Cached, Pure]
   readonly attribute sequence<Dict>? readonlyNullableSequenceOfDictionaries;
   [Cached, Pure, Frozen]
@@ -1041,64 +1023,22 @@ interface TestParentInterface {
 };
 
 interface TestChildInterface : TestParentInterface {
 };
 
 interface TestNonWrapperCacheInterface {
 };
 
-[NoInterfaceObject]
-interface ImplementedInterfaceParent {
-  void implementedParentMethod();
-  attribute boolean implementedParentProperty;
-
-  const long implementedParentConstant = 8;
-};
-
-ImplementedInterfaceParent implements IndirectlyImplementedInterface;
-
-[NoInterfaceObject]
-interface IndirectlyImplementedInterface {
-  void indirectlyImplementedMethod();
-  attribute boolean indirectlyImplementedProperty;
-
-  const long indirectlyImplementedConstant = 9;
-};
-
-[NoInterfaceObject]
-interface ImplementedInterface : ImplementedInterfaceParent {
-  void implementedMethod();
-  attribute boolean implementedProperty;
+interface mixin InterfaceMixin {
+  void mixedInMethod();
+  attribute boolean mixedInProperty;
 
-  const long implementedConstant = 5;
-};
-
-[NoInterfaceObject]
-interface DiamondImplements {
-  readonly attribute long diamondImplementedProperty;
-};
-[NoInterfaceObject]
-interface DiamondBranch1A {
-};
-[NoInterfaceObject]
-interface DiamondBranch1B {
+  const long mixedInConstant = 5;
 };
-[NoInterfaceObject]
-interface DiamondBranch2A : DiamondImplements {
-};
-[NoInterfaceObject]
-interface DiamondBranch2B : DiamondImplements {
-};
-TestInterface implements DiamondBranch1A;
-TestInterface implements DiamondBranch1B;
-TestInterface implements DiamondBranch2A;
-TestInterface implements DiamondBranch2B;
-DiamondBranch1A implements DiamondImplements;
-DiamondBranch1B implements DiamondImplements;
 
 dictionary Dict : ParentDict {
   TestEnum someEnum;
   long x;
   long a;
   long b = 8;
   long z = 9;
   [EnforceRange] unsigned long enforcedUnsignedLong;
@@ -1371,17 +1311,17 @@ interface TestThrowingConstructorInterfa
   constructor();
   [Throws]
   constructor(DOMString str);
   [Throws]
   constructor(unsigned long num, boolean? boolArg);
   [Throws]
   constructor(TestInterface? iface);
   [Throws]
-  constructor(unsigned long arg1, IndirectlyImplementedInterface iface);
+  constructor(unsigned long arg1, TestInterface iface);
   [Throws]
   constructor(Date arg1);
   [Throws]
   constructor(ArrayBuffer arrayBuf);
   [Throws]
   constructor(Uint8Array typedArr);
   // [Throws] constructor(long arg1, long arg2, (TestInterface or OnlyForUseInConstructor) arg3);
 };
--- a/dom/bindings/test/TestExampleGen.webidl
+++ b/dom/bindings/test/TestExampleGen.webidl
@@ -10,17 +10,17 @@
                            optional object obj3, optional object? obj4),
  NamedConstructor=Example2((long or record<DOMString, any>) arg1)
  ]
 interface TestExampleInterface {
   constructor();
   constructor(DOMString str);
   constructor(unsigned long num, boolean? boolArg);
   constructor(TestInterface? iface);
-  constructor(unsigned long arg1, IndirectlyImplementedInterface iface);
+  constructor(unsigned long arg1, TestInterface iface);
   constructor(Date arg1);
   constructor(ArrayBuffer arrayBuf);
   constructor(Uint8Array typedArr);
   // constructor(long arg1, long arg2, (TestInterface or OnlyForUseInConstructor) arg3);
 
   // Integer types
   // XXXbz add tests for throwing versions of all the integer stuff
   readonly attribute byte readonlyByte;
@@ -166,30 +166,16 @@ interface TestExampleInterface {
   sequence<TestNonWrapperCacheInterface> receiveNonWrapperCacheInterfaceSequence();
   [NewObject]
   sequence<TestNonWrapperCacheInterface?> receiveNullableNonWrapperCacheInterfaceSequence();
   [NewObject]
   sequence<TestNonWrapperCacheInterface>? receiveNonWrapperCacheInterfaceNullableSequence();
   [NewObject]
   sequence<TestNonWrapperCacheInterface?>? receiveNullableNonWrapperCacheInterfaceNullableSequence();
 
-  // Non-castable interface types
-  IndirectlyImplementedInterface receiveOther();
-  IndirectlyImplementedInterface? receiveNullableOther();
-  IndirectlyImplementedInterface receiveWeakOther();
-  IndirectlyImplementedInterface? receiveWeakNullableOther();
-  void passOther(IndirectlyImplementedInterface arg);
-  void passNullableOther(IndirectlyImplementedInterface? arg);
-  attribute IndirectlyImplementedInterface nonNullOther;
-  attribute IndirectlyImplementedInterface? nullableOther;
-  // Optional arguments
-  void passOptionalOther(optional IndirectlyImplementedInterface? arg);
-  void passOptionalNonNullOther(optional IndirectlyImplementedInterface arg);
-  void passOptionalOtherWithDefault(optional IndirectlyImplementedInterface? arg = null);
-
   // External interface types
   TestExternalInterface receiveExternal();
   TestExternalInterface? receiveNullableExternal();
   TestExternalInterface receiveWeakExternal();
   TestExternalInterface? receiveWeakNullableExternal();
   void passExternal(TestExternalInterface arg);
   void passNullableExternal(TestExternalInterface? arg);
   attribute TestExternalInterface nonNullExternal;
@@ -208,20 +194,16 @@ interface TestExampleInterface {
   void passNullableCallbackInterface(TestCallbackInterface? arg);
   attribute TestCallbackInterface nonNullCallbackInterface;
   attribute TestCallbackInterface? nullableCallbackInterface;
   // Optional arguments
   void passOptionalCallbackInterface(optional TestCallbackInterface? arg);
   void passOptionalNonNullCallbackInterface(optional TestCallbackInterface arg);
   void passOptionalCallbackInterfaceWithDefault(optional TestCallbackInterface? arg = null);
 
-  // Miscellaneous interface tests
-  IndirectlyImplementedInterface receiveConsequentialInterface();
-  void passConsequentialInterface(IndirectlyImplementedInterface arg);
-
   // Sequence types
   [Cached, Pure]
   readonly attribute sequence<long> readonlySequence;
   [Cached, Pure]
   readonly attribute sequence<Dict> readonlySequenceOfDictionaries;
   [Cached, Pure]
   readonly attribute sequence<Dict>? readonlyNullableSequenceOfDictionaries;
   [Cached, Pure, Frozen]
@@ -863,17 +845,17 @@ interface TestExampleThrowingConstructor
   constructor();
   [Throws]
   constructor(DOMString str);
   [Throws]
   constructor(unsigned long num, boolean? boolArg);
   [Throws]
   constructor(TestInterface? iface);
   [Throws]
-  constructor(unsigned long arg1, IndirectlyImplementedInterface iface);
+  constructor(unsigned long arg1, TestInterface iface);
   [Throws]
   constructor(Date arg1);
   [Throws]
   constructor(ArrayBuffer arrayBuf);
   [Throws]
   constructor(Uint8Array typedArr);
   // [Throws] constructor(long arg1, long arg2, (TestInterface or OnlyForUseInConstructor) arg3);
 };
--- a/dom/bindings/test/TestJSImplGen.webidl
+++ b/dom/bindings/test/TestJSImplGen.webidl
@@ -181,31 +181,16 @@ interface TestJSImplInterface {
   sequence<TestNonWrapperCacheInterface> receiveNonWrapperCacheInterfaceSequence();
   [NewObject]
   sequence<TestNonWrapperCacheInterface?> receiveNullableNonWrapperCacheInterfaceSequence();
   [NewObject]
   sequence<TestNonWrapperCacheInterface>? receiveNonWrapperCacheInterfaceNullableSequence();
   [NewObject]
   sequence<TestNonWrapperCacheInterface?>? receiveNullableNonWrapperCacheInterfaceNullableSequence();
 
-  // Non-castable interface types
-  IndirectlyImplementedInterface receiveOther();
-  IndirectlyImplementedInterface? receiveNullableOther();
-  IndirectlyImplementedInterface receiveWeakOther();
-  IndirectlyImplementedInterface? receiveWeakNullableOther();
-
-  void passOther(IndirectlyImplementedInterface arg);
-  void passNullableOther(IndirectlyImplementedInterface? arg);
-  attribute IndirectlyImplementedInterface nonNullOther;
-  attribute IndirectlyImplementedInterface? nullableOther;
-  // Optional arguments
-  void passOptionalOther(optional IndirectlyImplementedInterface? arg);
-  void passOptionalNonNullOther(optional IndirectlyImplementedInterface arg);
-  void passOptionalOtherWithDefault(optional IndirectlyImplementedInterface? arg = null);
-
   // External interface types
   TestExternalInterface receiveExternal();
   TestExternalInterface? receiveNullableExternal();
   TestExternalInterface receiveWeakExternal();
   TestExternalInterface? receiveWeakNullableExternal();
   void passExternal(TestExternalInterface arg);
   void passNullableExternal(TestExternalInterface? arg);
   attribute TestExternalInterface nonNullExternal;
@@ -224,20 +209,16 @@ interface TestJSImplInterface {
   void passNullableCallbackInterface(TestCallbackInterface? arg);
   attribute TestCallbackInterface nonNullCallbackInterface;
   attribute TestCallbackInterface? nullableCallbackInterface;
   // Optional arguments
   void passOptionalCallbackInterface(optional TestCallbackInterface? arg);
   void passOptionalNonNullCallbackInterface(optional TestCallbackInterface arg);
   void passOptionalCallbackInterfaceWithDefault(optional TestCallbackInterface? arg = null);
 
-  // Miscellaneous interface tests
-  IndirectlyImplementedInterface receiveConsequentialInterface();
-  void passConsequentialInterface(IndirectlyImplementedInterface arg);
-
   // Sequence types
   // [Cached] is not supported in JS-implemented WebIDL.
   //[Cached, Pure]
   //readonly attribute sequence<long> readonlySequence;
   //[Cached, Pure]
   //readonly attribute sequence<Dict> readonlySequenceOfDictionaries;
   //[Cached, Pure]
   //readonly attribute sequence<Dict>? readonlyNullableSequenceOfDictionaries;
--- a/tools/lint/file-whitespace.yml
+++ b/tools/lint/file-whitespace.yml
@@ -12,17 +12,16 @@ file-whitespace:
         - build/pymake/pymake/process.py
         - build/pymake/pymake/util.py
         - build/pymake/tests/runtests.py
         - dom/bindings/Codegen.py
         - dom/bindings/Configuration.py
         - dom/bindings/parser/WebIDL.py
         - dom/bindings/parser/tests/test_attributes_on_types.py
         - dom/bindings/parser/tests/test_extended_attributes.py
-        - dom/bindings/parser/tests/test_implements.py
         - dom/bindings/parser/tests/test_interface.py
         - dom/bindings/parser/tests/test_record.py
         - dom/bindings/parser/tests/test_securecontext_extended_attribute.py
         - dom/bindings/parser/tests/test_special_methods.py
         - dom/bindings/parser/tests/test_toJSON.py
         - dom/bindings/parser/tests/test_typedef.py
         - dom/encoding/encodings2arrays.py
         - dom/media/gtest/AudioGenerator.cpp