Erase raw types during canonicalization

MOE_MIGRATED_REVID=137061193
diff --git a/java/com/google/turbine/types/Canonicalize.java b/java/com/google/turbine/types/Canonicalize.java
index b7c9c68..f35779a 100644
--- a/java/com/google/turbine/types/Canonicalize.java
+++ b/java/com/google/turbine/types/Canonicalize.java
@@ -79,6 +79,9 @@
 
   /** Canonicalize a qualified class type, excluding type arguments. */
   private static ClassTy canon(Env<ClassSymbol, TypeBoundClass> env, ClassSymbol base, ClassTy ty) {
+    if (isRaw(env, ty)) {
+      return ClassTy.asNonParametricClassTy(ty.sym());
+    }
     // if the first name is a simple name resolved inside a nested class, add explicit qualifiers
     // for the enclosing declarations
     Iterator<ClassTy.SimpleClassTy> it = ty.classes.iterator();
@@ -95,6 +98,22 @@
     return canon;
   }
 
+  /**
+   * Qualified type names cannot be partially raw; if any elements are raw erase the entire type.
+   */
+  private static boolean isRaw(Env<ClassSymbol, TypeBoundClass> env, ClassTy ty) {
+    for (ClassTy.SimpleClassTy s : ty.classes.reverse()) {
+      TypeBoundClass info = env.get(s.sym());
+      if (s.targs().isEmpty() && !info.typeParameters().isEmpty()) {
+        return true;
+      }
+      if ((info.access() & TurbineFlag.ACC_STATIC) == TurbineFlag.ACC_STATIC) {
+        break;
+      }
+    }
+    return false;
+  }
+
   /** Given a base symbol to canonicalize, find any implicit enclosing instances. */
   private static Collection<ClassTy.SimpleClassTy> lexicalBase(
       Env<ClassSymbol, TypeBoundClass> env, ClassSymbol first, ClassSymbol owner) {
diff --git a/javatests/com/google/turbine/lower/LowerIntegrationTest.java b/javatests/com/google/turbine/lower/LowerIntegrationTest.java
index 0222688..a96fea8 100644
--- a/javatests/com/google/turbine/lower/LowerIntegrationTest.java
+++ b/javatests/com/google/turbine/lower/LowerIntegrationTest.java
@@ -224,6 +224,7 @@
       "cast_tail.test",
       "marker.test",
       "interface_method.test",
+      "raw_canon.test",
     };
     List<Object[]> tests =
         ImmutableList.copyOf(testCases).stream().map(x -> new Object[] {x}).collect(toList());
diff --git a/javatests/com/google/turbine/lower/testdata/raw_canon.test b/javatests/com/google/turbine/lower/testdata/raw_canon.test
new file mode 100644
index 0000000..a3ee24f
--- /dev/null
+++ b/javatests/com/google/turbine/lower/testdata/raw_canon.test
@@ -0,0 +1,8 @@
+=== Test.java ===
+class Test<T> {
+  class Inner<V> {
+    class InnerMost {}
+  }
+  void f(Inner i) {}
+  void f(Inner.InnerMost i) {}
+}