// RUN: %testDafnyForEachResolver --expect-exit-code=2 "%s"


// Here is the example reported in issue #125 to cause a crash in Dafny.
// The crash has been fixed.  However, the semantics is not what is suggested
// in a comment in that bug report.  The semantics suggested there said
// that the opened AMA.T would take precedence over AMA2.T in AbstractModuleC.
// That seems weird, even though it would allow Foo(t:T) to type check in
// AbstractModuleC just like it does in AbstractModuleB.  In the semantics
// now implemented, the two opened imports AMA and AMA2 in AbstractModuleC
// have equal standing.  This means that (the inherited) Foo(t:T) in
// AbstractModuleC refers to T ambiguously.
//
// This file tests resolution errors.  The file Bug125more.dfy tests
// verification on similar (bug resolution-correct) examples.

abstract module AbstractModuleA
{
  type T
}

abstract module AbstractModuleB
{
  import opened AMA : AbstractModuleA

  method Foo(t:T)  // resolution error when inherited in AbstractModuleC: T is ambiguous
}

abstract module AbstractModuleC refines AbstractModuleB
{
  import opened AMA2 : AbstractModuleA
}

// Here is another test example:

module LibA {
  class G {
    static ghost function f(x:int) : bool {
      x >= 10
    }
  }

  ghost function g() : bool {
     true
  }
}

module LibB {
  class G {
    static ghost function f(x:int) : bool {
      x < 10
    }
  }

  ghost function g() : bool {
     false
  }
}

module R {
  import opened LibA
}

module S refines R {
  import opened LibB
  method m() {
    assert g();  // resolution error: ambiguous reference to LibA.g / LibB.g
  }

  method m1() {
   assert G.f(20);  // resolution error: ambiguous reference to LibA.G / LibB.G
  }
}

module V {
  import opened LibA
  ghost function g(): int { 4 }
}

module W refines V {
  ghost function g(): int { 5 }  // refinement error: cannot provide a new body for the inherited g()
}
