Rename all type UnwrapXXX() methods

Give them sensible names.
Make them act consistently.
Remove those that were not used.

Change-Id: Ib043a4093cfae9f81630643e1a0e4eae7bca2440
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/50305
Commit-Queue: Ben Clayton <bclayton@google.com>
Reviewed-by: James Price <jrprice@google.com>
Reviewed-by: Antonio Maiorano <amaiorano@google.com>
diff --git a/src/ast/alias_test.cc b/src/ast/alias_test.cc
index 3699aaf..751b9b2 100644
--- a/src/ast/alias_test.cc
+++ b/src/ast/alias_test.cc
@@ -80,41 +80,6 @@
   EXPECT_EQ(at->FriendlyName(Symbols()), "Particle");
 }
 
-TEST_F(AstAliasTest, UnwrapIfNeeded_Alias) {
-  auto* u32 = create<U32>();
-  auto* a = create<Alias>(Sym("a_type"), u32);
-  EXPECT_EQ(a->symbol(), Symbol(1, ID()));
-  EXPECT_EQ(a->type(), u32);
-  EXPECT_EQ(a->UnwrapIfNeeded(), u32);
-  EXPECT_EQ(u32->UnwrapIfNeeded(), u32);
-}
-
-TEST_F(AstAliasTest, UnwrapIfNeeded_AccessControl) {
-  auto* u32 = create<U32>();
-  auto* ac = create<AccessControl>(AccessControl::kReadOnly, u32);
-  EXPECT_EQ(ac->type(), u32);
-  EXPECT_EQ(ac->UnwrapIfNeeded(), u32);
-}
-
-TEST_F(AstAliasTest, UnwrapIfNeeded_MultiLevel) {
-  auto* u32 = create<U32>();
-  auto* a = create<Alias>(Sym("a_type"), u32);
-  auto* aa = create<Alias>(Sym("aa_type"), a);
-
-  EXPECT_EQ(aa->symbol(), Symbol(2, ID()));
-  EXPECT_EQ(aa->type(), a);
-  EXPECT_EQ(aa->UnwrapIfNeeded(), u32);
-}
-
-TEST_F(AstAliasTest, UnwrapIfNeeded_MultiLevel_AliasAccessControl) {
-  auto* u32 = create<U32>();
-  auto* a = create<Alias>(Sym("a_type"), u32);
-
-  auto* ac = create<AccessControl>(AccessControl::kReadWrite, a);
-  EXPECT_EQ(ac->type(), a);
-  EXPECT_EQ(ac->UnwrapIfNeeded(), u32);
-}
-
 TEST_F(AstAliasTest, UnwrapAll_TwiceAliasPointerTwiceAlias) {
   auto* u32 = create<U32>();
   auto* a = create<Alias>(Sym("a_type"), u32);
@@ -128,31 +93,6 @@
   EXPECT_EQ(aapaa->UnwrapAll(), u32);
 }
 
-TEST_F(AstAliasTest, UnwrapAll_SecondConsecutivePointerBlocksUnrapping) {
-  auto* u32 = create<U32>();
-  auto* a = create<Alias>(Sym("a_type"), u32);
-  auto* aa = create<Alias>(Sym("aa_type"), a);
-
-  auto* paa = create<Pointer>(aa, StorageClass::kUniform);
-  auto* ppaa = create<Pointer>(paa, StorageClass::kUniform);
-  auto* appaa = create<Alias>(Sym("appaa_type"), ppaa);
-  EXPECT_EQ(appaa->UnwrapAll(), paa);
-}
-
-TEST_F(AstAliasTest, UnwrapAll_SecondNonConsecutivePointerBlocksUnrapping) {
-  auto* u32 = create<U32>();
-  auto* a = create<Alias>(Sym("a_type"), u32);
-  auto* aa = create<Alias>(Sym("aa_type"), a);
-  auto* paa = create<Pointer>(aa, StorageClass::kUniform);
-
-  auto* apaa = create<Alias>(Sym("apaa_type"), paa);
-  auto* aapaa = create<Alias>(Sym("aapaa_type"), apaa);
-  auto* paapaa = create<Pointer>(aapaa, StorageClass::kUniform);
-  auto* apaapaa = create<Alias>(Sym("apaapaa_type"), paapaa);
-
-  EXPECT_EQ(apaapaa->UnwrapAll(), paa);
-}
-
 TEST_F(AstAliasTest, UnwrapAll_AccessControlPointer) {
   auto* u32 = create<U32>();
   auto* a = create<AccessControl>(AccessControl::kReadOnly, u32);
@@ -170,14 +110,6 @@
   EXPECT_EQ(a->UnwrapAll(), u32);
 }
 
-TEST_F(AstAliasTest, UnwrapAliasIfNeeded) {
-  auto* f32 = create<F32>();
-  auto* alias1 = create<Alias>(Sym("alias1"), f32);
-  auto* alias2 = create<Alias>(Sym("alias2"), alias1);
-  auto* alias3 = create<Alias>(Sym("alias3"), alias2);
-  EXPECT_EQ(alias3->UnwrapAliasIfNeeded(), f32);
-}
-
 }  // namespace
 }  // namespace ast
 }  // namespace tint
diff --git a/src/ast/ast_type.cc b/src/ast/ast_type.cc
index 766b7a5..a9ea9d1 100644
--- a/src/ast/ast_type.cc
+++ b/src/ast/ast_type.cc
@@ -38,37 +38,20 @@
 
 Type::~Type() = default;
 
-Type* Type::UnwrapPtrIfNeeded() {
-  if (auto* ptr = As<Pointer>()) {
-    return ptr->type();
-  }
-  return this;
-}
-
-Type* Type::UnwrapAliasIfNeeded() {
-  Type* unwrapped = this;
-  while (auto* ptr = unwrapped->As<Alias>()) {
-    unwrapped = ptr->type();
-  }
-  return unwrapped;
-}
-
-Type* Type::UnwrapIfNeeded() {
-  auto* where = this;
+Type* Type::UnwrapAll() {
+  auto* type = this;
   while (true) {
-    if (auto* alias = where->As<Alias>()) {
-      where = alias->type();
-    } else if (auto* access = where->As<AccessControl>()) {
-      where = access->type();
+    if (auto* alias = type->As<Alias>()) {
+      type = alias->type();
+    } else if (auto* access = type->As<AccessControl>()) {
+      type = access->type();
+    } else if (auto* ptr = type->As<Pointer>()) {
+      type = ptr->type();
     } else {
       break;
     }
   }
-  return where;
-}
-
-Type* Type::UnwrapAll() {
-  return UnwrapIfNeeded()->UnwrapPtrIfNeeded()->UnwrapIfNeeded();
+  return type;
 }
 
 bool Type::is_scalar() const {
diff --git a/src/ast/type.h b/src/ast/type.h
index d41daeb..73f44dc 100644
--- a/src/ast/type.h
+++ b/src/ast/type.h
@@ -43,49 +43,10 @@
   /// declared in WGSL.
   virtual std::string FriendlyName(const SymbolTable& symbols) const = 0;
 
-  /// @returns the pointee type if this is a pointer, `this` otherwise
-  Type* UnwrapPtrIfNeeded();
-
-  /// @returns the most deeply nested aliased type if this is an alias, `this`
-  /// otherwise
-  const Type* UnwrapAliasIfNeeded() const {
-    return const_cast<Type*>(this)->UnwrapAliasIfNeeded();
-  }
-
-  /// @returns the most deeply nested aliased type if this is an alias, `this`
-  /// otherwise
-  Type* UnwrapAliasIfNeeded();
-
-  /// Removes all levels of aliasing and access control.
-  /// This is just enough to assist with WGSL translation
-  /// in that you want see through one level of pointer to get from an
-  /// identifier-like expression as an l-value to its corresponding r-value,
-  /// plus see through the wrappers on either side.
-  /// @returns the completely unaliased type.
-  Type* UnwrapIfNeeded();
-
-  /// Removes all levels of aliasing and access control.
-  /// This is just enough to assist with WGSL translation
-  /// in that you want see through one level of pointer to get from an
-  /// identifier-like expression as an l-value to its corresponding r-value,
-  /// plus see through the wrappers on either side.
-  /// @returns the completely unaliased type.
-  const Type* UnwrapIfNeeded() const {
-    return const_cast<Type*>(this)->UnwrapIfNeeded();
-  }
-
-  /// Returns the type found after:
-  /// - removing all layers of aliasing and access control if they exist, then
-  /// - removing the pointer, if it exists, then
-  /// - removing all further layers of aliasing or access control, if they exist
-  /// @returns the unwrapped type
+  /// @returns the type with all aliasing, access control and pointers removed
   Type* UnwrapAll();
 
-  /// Returns the type found after:
-  /// - removing all layers of aliasing and access control if they exist, then
-  /// - removing the pointer, if it exists, then
-  /// - removing all further layers of aliasing or access control, if they exist
-  /// @returns the unwrapped type
+  /// @returns the type with all aliasing, access control and pointers removed
   const Type* UnwrapAll() const { return const_cast<Type*>(this)->UnwrapAll(); }
 
   /// @returns true if this type is a scalar
diff --git a/src/inspector/inspector.cc b/src/inspector/inspector.cc
index f1100dc..845be85 100644
--- a/src/inspector/inspector.cc
+++ b/src/inspector/inspector.cc
@@ -387,7 +387,7 @@
     auto* var = ruv.first;
     auto binding_info = ruv.second;
 
-    auto* unwrapped_type = var->Type()->UnwrapIfNeeded();
+    auto* unwrapped_type = var->Type()->UnwrapAccess();
     auto* str = unwrapped_type->As<sem::Struct>();
     if (str == nullptr) {
       continue;
@@ -509,7 +509,7 @@
     entry.bind_group = binding_info.group->value();
     entry.binding = binding_info.binding->value();
 
-    auto* texture_type = var->Type()->UnwrapIfNeeded()->As<sem::Texture>();
+    auto* texture_type = var->Type()->UnwrapAccess()->As<sem::Texture>();
     entry.dim = TypeTextureDimensionToResourceBindingTextureDimension(
         texture_type->dim());
 
@@ -602,7 +602,7 @@
       continue;
     }
 
-    auto* str = var->Type()->UnwrapIfNeeded()->As<sem::Struct>();
+    auto* str = var->Type()->UnwrapAccess()->As<sem::Struct>();
     if (!str) {
       continue;
     }
@@ -646,18 +646,15 @@
     entry.bind_group = binding_info.group->value();
     entry.binding = binding_info.binding->value();
 
-    auto* texture_type = var->Type()->UnwrapIfNeeded()->As<sem::Texture>();
+    auto* texture_type = var->Type()->UnwrapAccess()->As<sem::Texture>();
     entry.dim = TypeTextureDimensionToResourceBindingTextureDimension(
         texture_type->dim());
 
     const sem::Type* base_type = nullptr;
     if (multisampled_only) {
-      base_type = texture_type->As<sem::MultisampledTexture>()
-                      ->type()
-                      ->UnwrapIfNeeded();
+      base_type = texture_type->As<sem::MultisampledTexture>()->type();
     } else {
-      base_type =
-          texture_type->As<sem::SampledTexture>()->type()->UnwrapIfNeeded();
+      base_type = texture_type->As<sem::SampledTexture>()->type();
     }
     entry.sampled_kind = BaseTypeToSampledKind(base_type);
 
@@ -697,12 +694,11 @@
     entry.bind_group = binding_info.group->value();
     entry.binding = binding_info.binding->value();
 
-    auto* texture_type =
-        var->Type()->UnwrapIfNeeded()->As<sem::StorageTexture>();
+    auto* texture_type = var->Type()->UnwrapAccess()->As<sem::StorageTexture>();
     entry.dim = TypeTextureDimensionToResourceBindingTextureDimension(
         texture_type->dim());
 
-    auto* base_type = texture_type->type()->UnwrapIfNeeded();
+    auto* base_type = texture_type->type();
     entry.sampled_kind = BaseTypeToSampledKind(base_type);
     entry.image_format = TypeImageFormatToResourceBindingImageFormat(
         texture_type->image_format());
diff --git a/src/reader/spirv/parser_impl.cc b/src/reader/spirv/parser_impl.cc
index b1392a0..582638e 100644
--- a/src/reader/spirv/parser_impl.cc
+++ b/src/reader/spirv/parser_impl.cc
@@ -1472,7 +1472,7 @@
   }
 
   auto source = GetSourceForInst(inst);
-  auto* ast_type = original_ast_type->UnwrapIfNeeded();
+  auto* ast_type = original_ast_type->UnwrapAliasAndAccess();
 
   // TODO(dneto): Note: NullConstant for int, uint, float map to a regular 0.
   // So canonicalization should map that way too.
@@ -1548,7 +1548,7 @@
   }
 
   auto* original_type = type;
-  type = type->UnwrapIfNeeded();
+  type = type->UnwrapAliasAndAccess();
 
   if (type->Is<Bool>()) {
     return create<ast::ScalarConstructorExpression>(
diff --git a/src/reader/spirv/parser_type.cc b/src/reader/spirv/parser_type.cc
index 4f2ca5a..feabc24 100644
--- a/src/reader/spirv/parser_type.cc
+++ b/src/reader/spirv/parser_type.cc
@@ -305,37 +305,50 @@
       storage_textures_;
 };
 
-const Type* Type::UnwrapPtrIfNeeded() const {
-  if (auto* ptr = As<Pointer>()) {
-    return ptr->type;
+const Type* Type::UnwrapPtr() const {
+  const Type* type = this;
+  while (auto* ptr = type->As<Pointer>()) {
+    type = ptr->type;
   }
-  return this;
+  return type;
 }
 
-const Type* Type::UnwrapAliasIfNeeded() const {
-  const Type* unwrapped = this;
-  while (auto* ptr = unwrapped->As<Alias>()) {
-    unwrapped = ptr->type;
+const Type* Type::UnwrapAlias() const {
+  const Type* type = this;
+  while (auto* alias = type->As<Alias>()) {
+    type = alias->type;
   }
-  return unwrapped;
+  return type;
 }
 
-const Type* Type::UnwrapIfNeeded() const {
-  auto* where = this;
+const Type* Type::UnwrapAliasAndAccess() const {
+  auto* type = this;
   while (true) {
-    if (auto* alias = where->As<Alias>()) {
-      where = alias->type;
-    } else if (auto* access = where->As<AccessControl>()) {
-      where = access->type;
+    if (auto* alias = type->As<Alias>()) {
+      type = alias->type;
+    } else if (auto* access = type->As<AccessControl>()) {
+      type = access->type;
     } else {
       break;
     }
   }
-  return where;
+  return type;
 }
 
 const Type* Type::UnwrapAll() const {
-  return UnwrapIfNeeded()->UnwrapPtrIfNeeded()->UnwrapIfNeeded();
+  auto* type = this;
+  while (true) {
+    if (auto* alias = type->As<Alias>()) {
+      type = alias->type;
+    } else if (auto* access = type->As<AccessControl>()) {
+      type = access->type;
+    } else if (auto* ptr = type->As<Pointer>()) {
+      type = ptr->type;
+    } else {
+      break;
+    }
+  }
+  return type;
 }
 
 bool Type::IsFloatScalar() const {
diff --git a/src/reader/spirv/parser_type.h b/src/reader/spirv/parser_type.h
index c3ca2bd..1dc65be 100644
--- a/src/reader/spirv/parser_type.h
+++ b/src/reader/spirv/parser_type.h
@@ -45,26 +45,17 @@
   /// @returns the constructed ast::Type node for the given type
   virtual ast::Type* Build(ProgramBuilder& b) const = 0;
 
-  /// @returns the pointee type if this is a pointer, `this` otherwise
-  const Type* UnwrapPtrIfNeeded() const;
-
-  /// @returns the most deeply nested aliased type if this is an alias, `this`
+  /// @returns the inner most pointee type if this is a pointer, `this`
   /// otherwise
-  const Type* UnwrapAliasIfNeeded() const;
+  const Type* UnwrapPtr() const;
 
-  /// Removes all levels of aliasing and access control.
-  /// This is just enough to assist with WGSL translation
-  /// in that you want see through one level of pointer to get from an
-  /// identifier-like expression as an l-value to its corresponding r-value,
-  /// plus see through the wrappers on either side.
-  /// @returns the completely unaliased type.
-  const Type* UnwrapIfNeeded() const;
+  /// @returns the inner most aliased type if this is an alias, `this` otherwise
+  const Type* UnwrapAlias() const;
 
-  /// Returns the type found after:
-  /// - removing all layers of aliasing and access control if they exist, then
-  /// - removing the pointer, if it exists, then
-  /// - removing all further layers of aliasing or access control, if they exist
-  /// @returns the unwrapped type
+  /// @returns the type with all aliasing and access control removed
+  const Type* UnwrapAliasAndAccess() const;
+
+  /// @returns the type with all aliasing, access control and pointers removed
   const Type* UnwrapAll() const;
 
   /// @returns true if this type is a float scalar
diff --git a/src/resolver/resolver.cc b/src/resolver/resolver.cc
index 8f40076..cfda9a5 100644
--- a/src/resolver/resolver.cc
+++ b/src/resolver/resolver.cc
@@ -174,7 +174,7 @@
 
 // https://gpuweb.github.io/gpuweb/wgsl.html#storable-types
 bool Resolver::IsStorable(const sem::Type* type) {
-  type = type->UnwrapIfNeeded();
+  type = type->UnwrapAccess();
   if (type->is_scalar() || type->Is<sem::Vector>() || type->Is<sem::Matrix>()) {
     return true;
   }
@@ -194,7 +194,7 @@
 
 // https://gpuweb.github.io/gpuweb/wgsl.html#host-shareable-types
 bool Resolver::IsHostShareable(const sem::Type* type) {
-  type = type->UnwrapIfNeeded();
+  type = type->UnwrapAccess();
   if (type->IsAnyOf<sem::I32, sem::U32, sem::F32>()) {
     return true;
   }
@@ -224,9 +224,9 @@
   // This will need to be fixed after WGSL agrees the behavior of pointers /
   // references.
   // Check:
-  if (lhs->UnwrapIfNeeded() != rhs->UnwrapIfNeeded()) {
+  if (lhs->UnwrapAccess() != rhs->UnwrapAccess()) {
     // Try RHS dereference
-    if (lhs->UnwrapIfNeeded() != rhs->UnwrapAll()) {
+    if (lhs->UnwrapAccess() != rhs->UnwrapAll()) {
       return false;
     }
   }
@@ -1636,7 +1636,7 @@
   }
 
   auto* res = TypeOf(expr->structure());
-  auto* data_type = res->UnwrapPtrIfNeeded()->UnwrapIfNeeded();
+  auto* data_type = res->UnwrapAll();
 
   sem::Type* ret = nullptr;
   std::vector<uint32_t> swizzle;
@@ -1926,7 +1926,7 @@
   if (expr->IsAnd() || expr->IsOr() || expr->IsXor() || expr->IsShiftLeft() ||
       expr->IsShiftRight() || expr->IsAdd() || expr->IsSubtract() ||
       expr->IsDivide() || expr->IsModulo()) {
-    SetType(expr, TypeOf(expr->lhs())->UnwrapPtrIfNeeded());
+    SetType(expr, TypeOf(expr->lhs())->UnwrapPtr());
     return true;
   }
   // Result type is a scalar or vector of boolean type
@@ -1999,7 +1999,7 @@
     return false;
   }
 
-  auto* result_type = TypeOf(expr->expr())->UnwrapPtrIfNeeded();
+  auto* result_type = TypeOf(expr->expr())->UnwrapPtr();
   SetType(expr, result_type);
   return true;
 }
@@ -2039,7 +2039,7 @@
     // If the variable has no type, infer it from the rhs
     if (type == nullptr) {
       type_name = TypeNameOf(ctor);
-      type = rhs_type->UnwrapPtrIfNeeded();
+      type = rhs_type->UnwrapPtr();
     }
 
     if (!IsValidAssignment(type, rhs_type)) {
@@ -2726,7 +2726,7 @@
   }
 
   // lhs must be a pointer or a constant
-  auto* lhs_result_type = TypeOf(lhs)->UnwrapIfNeeded();
+  auto* lhs_result_type = TypeOf(lhs)->UnwrapAccess();
   if (!lhs_result_type->Is<sem::Pointer>()) {
     // In case lhs is a constant identifier, output a nicer message as it's
     // likely to be a common programmer error.
@@ -2768,7 +2768,7 @@
 bool Resolver::ApplyStorageClassUsageToType(ast::StorageClass sc,
                                             sem::Type* ty,
                                             const Source& usage) {
-  ty = const_cast<sem::Type*>(ty->UnwrapIfNeeded());
+  ty = const_cast<sem::Type*>(ty->UnwrapAccess());
 
   if (auto* str = ty->As<sem::Struct>()) {
     if (str->StorageClassUsage().count(sc)) {
diff --git a/src/resolver/type_validation_test.cc b/src/resolver/type_validation_test.cc
index f671925..82a231e 100644
--- a/src/resolver/type_validation_test.cc
+++ b/src/resolver/type_validation_test.cc
@@ -521,7 +521,7 @@
 
   EXPECT_TRUE(r()->Resolve()) << r()->error();
 
-  auto* got = TypeOf(expr)->UnwrapPtrIfNeeded();
+  auto* got = TypeOf(expr)->UnwrapPtr();
   auto* expected = params.create_sem_type(ty);
 
   EXPECT_EQ(got, expected) << "got:      " << FriendlyName(got) << "\n"
diff --git a/src/sem/expression.cc b/src/sem/expression.cc
index 83d16d7..74fb0c2 100644
--- a/src/sem/expression.cc
+++ b/src/sem/expression.cc
@@ -22,9 +22,7 @@
 Expression::Expression(ast::Expression* declaration,
                        const sem::Type* type,
                        Statement* statement)
-    : declaration_(declaration),
-      type_(type->UnwrapIfNeeded()),
-      statement_(statement) {
+    : declaration_(declaration), type_(type), statement_(statement) {
   TINT_ASSERT(type_);
 }
 
diff --git a/src/sem/function.cc b/src/sem/function.cc
index 9e31545..5a5a151 100644
--- a/src/sem/function.cc
+++ b/src/sem/function.cc
@@ -138,7 +138,7 @@
   VariableBindings ret;
 
   for (auto* var : ReferencedModuleVariables()) {
-    auto* unwrapped_type = var->Type()->UnwrapIfNeeded();
+    auto* unwrapped_type = var->Type()->UnwrapAccess();
     auto* storage_texture = unwrapped_type->As<sem::StorageTexture>();
     if (storage_texture == nullptr) {
       continue;
@@ -155,7 +155,7 @@
   VariableBindings ret;
 
   for (auto* var : ReferencedModuleVariables()) {
-    auto* unwrapped_type = var->Type()->UnwrapIfNeeded();
+    auto* unwrapped_type = var->Type()->UnwrapAccess();
     auto* storage_texture = unwrapped_type->As<sem::DepthTexture>();
     if (storage_texture == nullptr) {
       continue;
@@ -182,7 +182,7 @@
   VariableBindings ret;
 
   for (auto* var : ReferencedModuleVariables()) {
-    auto* unwrapped_type = var->Type()->UnwrapIfNeeded();
+    auto* unwrapped_type = var->Type()->UnwrapAccess();
     auto* sampler = unwrapped_type->As<sem::Sampler>();
     if (sampler == nullptr || sampler->kind() != kind) {
       continue;
@@ -200,7 +200,7 @@
   VariableBindings ret;
 
   for (auto* var : ReferencedModuleVariables()) {
-    auto* unwrapped_type = var->Type()->UnwrapIfNeeded();
+    auto* unwrapped_type = var->Type()->UnwrapAccess();
     auto* texture = unwrapped_type->As<sem::Texture>();
     if (texture == nullptr) {
       continue;
diff --git a/src/sem/type.cc b/src/sem/type.cc
index e730e72..cd0f5c4 100644
--- a/src/sem/type.cc
+++ b/src/sem/type.cc
@@ -36,7 +36,7 @@
 
 Type::~Type() = default;
 
-const Type* Type::UnwrapPtrIfNeeded() const {
+const Type* Type::UnwrapPtr() const {
   auto* type = this;
   while (auto* ptr = type->As<sem::Pointer>()) {
     type = ptr->type();
@@ -44,7 +44,7 @@
   return type;
 }
 
-const Type* Type::UnwrapIfNeeded() const {
+const Type* Type::UnwrapAccess() const {
   auto* type = this;
   while (auto* access = type->As<sem::AccessControl>()) {
     type = access->type();
@@ -57,14 +57,13 @@
   while (true) {
     if (auto* ptr = type->As<sem::Pointer>()) {
       type = ptr->type();
-      continue;
-    }
-    if (auto* access = type->As<sem::AccessControl>()) {
+    } else if (auto* access = type->As<sem::AccessControl>()) {
       type = access->type();
-      continue;
+    } else {
+      break;
     }
-    return type;
   }
+  return type;
 }
 
 bool Type::is_scalar() const {
diff --git a/src/sem/type.h b/src/sem/type.h
index f4a7835..76a64e1 100644
--- a/src/sem/type.h
+++ b/src/sem/type.h
@@ -45,19 +45,16 @@
   /// declared in WGSL.
   virtual std::string FriendlyName(const SymbolTable& symbols) const = 0;
 
-  /// @returns the pointee type if this is a pointer, `this` otherwise
-  const Type* UnwrapPtrIfNeeded() const;
+  /// @returns the inner most pointee type if this is a pointer, `this`
+  /// otherwise
+  const Type* UnwrapPtr() const;
 
-  /// Removes all levels of access control.
-  /// This is just enough to assist with WGSL translation
-  /// in that you want see through one level of pointer to get from an
-  /// identifier-like expression as an l-value to its corresponding r-value,
-  /// plus see through the wrappers on either side.
-  /// @returns the completely unaliased type.
-  const Type* UnwrapIfNeeded() const;
+  /// @returns the inner most type if this is an access control, `this`
+  /// otherwise
+  const Type* UnwrapAccess() const;
 
   /// Returns the type found after removing all layers of access control and
-  /// pointer.
+  /// pointer
   /// @returns the unwrapped type
   const Type* UnwrapAll() const;
 
diff --git a/src/transform/decompose_storage_access.cc b/src/transform/decompose_storage_access.cc
index cc1c4a2..2f9f07a 100644
--- a/src/transform/decompose_storage_access.cc
+++ b/src/transform/decompose_storage_access.cc
@@ -746,7 +746,7 @@
 
     auto* buf = access.var->Declaration();
     auto* offset = access.offset->Build(ctx);
-    auto* buf_ty = access.var->Type()->UnwrapPtrIfNeeded();
+    auto* buf_ty = access.var->Type()->UnwrapPtr();
     auto* el_ty = access.type->UnwrapAll();
     auto* insert_after = ConstructedTypeOf(access.var->Type());
     Symbol func = state.LoadFunc(ctx, insert_after, buf_ty, el_ty);
@@ -760,7 +760,7 @@
   for (auto& store : state.stores) {
     auto* buf = store.target.var->Declaration();
     auto* offset = store.target.offset->Build(ctx);
-    auto* buf_ty = store.target.var->Type()->UnwrapPtrIfNeeded();
+    auto* buf_ty = store.target.var->Type()->UnwrapPtr();
     auto* el_ty = store.target.type->UnwrapAll();
     auto* value = store.assignment->rhs();
     auto* insert_after = ConstructedTypeOf(store.target.var->Type());
diff --git a/src/writer/append_vector.cc b/src/writer/append_vector.cc
index f080887..9e64ac4 100644
--- a/src/writer/append_vector.cc
+++ b/src/writer/append_vector.cc
@@ -41,7 +41,7 @@
   uint32_t packed_size;
   const sem::Type* packed_el_sem_ty;
   auto* vector_sem = b->Sem().Get(vector);
-  auto* vector_ty = vector_sem->Type()->UnwrapPtrIfNeeded();
+  auto* vector_ty = vector_sem->Type()->UnwrapPtr();
   if (auto* vec = vector_ty->As<sem::Vector>()) {
     packed_size = vec->size() + 1;
     packed_el_sem_ty = vec->type();
@@ -72,7 +72,7 @@
   } else {
     packed.emplace_back(vector);
   }
-  if (packed_el_sem_ty != b->TypeOf(scalar)->UnwrapPtrIfNeeded()) {
+  if (packed_el_sem_ty != b->TypeOf(scalar)->UnwrapPtr()) {
     // Cast scalar to the vector element type
     auto* scalar_cast = b->Construct(packed_el_ty, scalar);
     b->Sem().Add(scalar_cast, b->create<sem::Expression>(
diff --git a/src/writer/hlsl/generator_impl.cc b/src/writer/hlsl/generator_impl.cc
index a98e6e5..30edeb4 100644
--- a/src/writer/hlsl/generator_impl.cc
+++ b/src/writer/hlsl/generator_impl.cc
@@ -1697,7 +1697,7 @@
       continue;  // Global already emitted
     }
 
-    auto* type = var->Type()->UnwrapIfNeeded();
+    auto* type = var->Type()->UnwrapAccess();
     if (auto* strct = type->As<sem::Struct>()) {
       out << "ConstantBuffer<"
           << builder_.Symbols().NameFor(strct->Declaration()->name()) << "> "
diff --git a/src/writer/spirv/builder.cc b/src/writer/spirv/builder.cc
index ee09323..377ed2c 100644
--- a/src/writer/spirv/builder.cc
+++ b/src/writer/spirv/builder.cc
@@ -627,7 +627,7 @@
 
   // TODO(dsinclair) We could detect if the constructor is fully const and emit
   // an initializer value for the variable instead of doing the OpLoad.
-  auto null_id = GenerateConstantNullIfNeeded(type->UnwrapPtrIfNeeded());
+  auto null_id = GenerateConstantNullIfNeeded(type->UnwrapPtr());
   if (null_id == 0) {
     return 0;
   }
@@ -953,7 +953,7 @@
       }
 
       info->source_id = GenerateLoadIfNeeded(expr_type, extract_id);
-      info->source_type = expr_type->UnwrapPtrIfNeeded();
+      info->source_type = expr_type->UnwrapPtr();
       info->access_chain_indices.clear();
     }
 
@@ -1130,7 +1130,7 @@
     return id;
   }
 
-  auto type_id = GenerateTypeIfNeeded(type->UnwrapPtrIfNeeded());
+  auto type_id = GenerateTypeIfNeeded(type->UnwrapPtr());
   auto result = result_op();
   auto result_id = result.to_i();
   if (!push_function_inst(spv::Op::OpLoad,
@@ -1271,7 +1271,7 @@
 
   // Generate the zero initializer if there are no values provided.
   if (values.empty()) {
-    return GenerateConstantNullIfNeeded(result_type->UnwrapPtrIfNeeded());
+    return GenerateConstantNullIfNeeded(result_type->UnwrapPtr());
   }
 
   std::ostringstream out;
@@ -1326,7 +1326,7 @@
       return 0;
     }
 
-    auto* value_type = TypeOf(e)->UnwrapPtrIfNeeded();
+    auto* value_type = TypeOf(e)->UnwrapPtr();
     // If the result and value types are the same we can just use the object.
     // If the result is not a vector then we should have validated that the
     // value type is a correctly sized vector so we can just use it directly.
@@ -1443,7 +1443,7 @@
   }
   val_id = GenerateLoadIfNeeded(TypeOf(from_expr), val_id);
 
-  auto* from_type = TypeOf(from_expr)->UnwrapPtrIfNeeded();
+  auto* from_type = TypeOf(from_expr)->UnwrapPtr();
 
   spv::Op op = spv::Op::OpNop;
   if ((from_type->Is<sem::I32>() && to_type->Is<sem::F32>()) ||
@@ -2578,8 +2578,8 @@
   val_id = GenerateLoadIfNeeded(TypeOf(expr->expr()), val_id);
 
   // Bitcast does not allow same types, just emit a CopyObject
-  auto* to_type = TypeOf(expr)->UnwrapPtrIfNeeded();
-  auto* from_type = TypeOf(expr->expr())->UnwrapPtrIfNeeded();
+  auto* to_type = TypeOf(expr)->UnwrapPtr();
+  auto* from_type = TypeOf(expr->expr())->UnwrapPtr();
   if (to_type->type_name() == from_type->type_name()) {
     if (!push_function_inst(
             spv::Op::OpCopyObject,
@@ -2931,7 +2931,7 @@
   }
 
   if (auto* ac = type->As<sem::AccessControl>()) {
-    if (!ac->type()->UnwrapIfNeeded()->Is<sem::Struct>()) {
+    if (!ac->type()->UnwrapAccess()->Is<sem::Struct>()) {
       return GenerateTypeIfNeeded(ac->type());
     }
   }
@@ -2945,7 +2945,7 @@
   auto id = result.to_i();
   if (auto* ac = type->As<sem::AccessControl>()) {
     // The non-struct case was handled above.
-    auto* subtype = ac->type()->UnwrapIfNeeded();
+    auto* subtype = ac->UnwrapAccess();
     if (!GenerateStructType(subtype->As<sem::Struct>(), ac->access_control(),
                             result)) {
       return 0;