Skip to content

Commit

Permalink
Narrow clones in upgrade_type.
Browse files Browse the repository at this point in the history
  • Loading branch information
jimblandy committed Jun 21, 2024
1 parent 8543e79 commit e9af0fb
Showing 1 changed file with 42 additions and 31 deletions.
73 changes: 42 additions & 31 deletions naga/src/front/atomic_upgrade.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ use crate::{GlobalVariable, Handle, Module, Type, TypeInner};
pub enum Error {
#[error("encountered an unsupported expression")]
Unsupported,
#[error("upgrading structs of more than one member is not yet implemented")]
MultiMemberStruct,
#[error("encountered unsupported global initializer in an atomic variable")]
GlobalInitUnsupported,
}
Expand Down Expand Up @@ -103,9 +105,7 @@ impl<'a> UpgradeState<'a> {
let padding = self.inc_padding();
padding.trace("upgrading type: ", ty);

let r#type = self.module.types[ty].clone();

let inner = match r#type.inner.clone() {
let inner = match self.module.types[ty].inner {
TypeInner::Scalar(scalar) => {
log::trace!("{padding}hit the scalar leaf, replacing with an atomic");
TypeInner::Atomic(scalar)
Expand All @@ -119,44 +119,55 @@ impl<'a> UpgradeState<'a> {
size,
stride,
},
TypeInner::Struct { mut members, span } => TypeInner::Struct {
members: {
// In the future we should have to figure out which member needs
// upgrading, but for now we'll only cover the single-member case
if members.len() == 1 {
members[0].ty = self.upgrade_type(members[0].ty)?;
}
members
},
span,
},
TypeInner::Struct { ref members, span } => {
// In the future we should have to figure out which member needs
// upgrading, but for now we'll only cover the single-member
// case.
let &[crate::StructMember {
ref name,
ty,
ref binding,
offset,
}] = &members[..]
else {
return Err(Error::MultiMemberStruct);
};

// Take our own clones of these values now, so that
// `upgrade_type` can mutate the module.
let name = name.clone();
let binding = binding.clone();
let upgraded_member_type = self.upgrade_type(ty)?;
TypeInner::Struct {
members: vec![crate::StructMember {
name,
ty: upgraded_member_type,
binding,
offset,
}],
span,
}
}
TypeInner::BindingArray { base, size } => TypeInner::BindingArray {
base: self.upgrade_type(base)?,
size,
},
n => n,
_ => return Ok(ty),
};

// Now that we've upgraded any subtypes, re-borrow a reference to our
// type and update its `inner`.
let r#type = &self.module.types[ty];
let span = self.module.types.get_span(ty);
let new_type = Type {
name: r#type.name.clone(),
inner,
};
let new_ty = if let Some(prev_ty) = self.module.types.get(&new_type) {
padding.trace("type exists: ", prev_ty);
prev_ty
} else {
padding.debug("ty: ", ty);
padding.debug("from: ", &r#type);
padding.debug("to: ", &new_type);

let new_ty = self
.module
.types
.insert(new_type, self.module.types.get_span(ty));
padding.debug("new ty: ", new_ty);
new_ty
};
Ok(new_ty)
padding.debug("ty: ", ty);
padding.debug("from: ", r#type);
padding.debug("to: ", &new_type);
let new_handle = self.module.types.insert(new_type, span);
Ok(new_handle)
}

fn upgrade_global_variable(&mut self, handle: Handle<GlobalVariable>) -> Result<(), Error> {
Expand Down

0 comments on commit e9af0fb

Please sign in to comment.