diff --git a/src/qptr/analyze.rs b/src/qptr/analyze.rs index 5c38d126..f1f1e23c 100644 --- a/src/qptr/analyze.rs +++ b/src/qptr/analyze.rs @@ -379,8 +379,11 @@ impl UsageMerger<'_> { MergeResult { merged: a.kind.clone(), error: Some(AnalysisError(Diag::bug([ - format!("merge_mem: unimplemented non-intra-element merging into stride={a_stride} (") - .into(), + format!( + "merge_mem: unimplemented \ + non-intra-element merging into stride={a_stride} (" + ) + .into(), QPtrUsage::Memory(a).into(), " vs ".into(), QPtrUsage::Memory(b).into(), @@ -1019,12 +1022,16 @@ impl<'a> InferUsage<'a> { QPtrUsage::Handles(_) => { return Err(AnalysisError(Diag::bug([format!( "Offset({offset}): cannot offset Handles" - ).into()]))); + ) + .into()]))); } QPtrUsage::Memory(usage) => usage, }; let offset = u32::try_from(offset).ok().ok_or_else(|| { - AnalysisError(Diag::bug([format!("Offset({offset}): negative offset").into()])) + AnalysisError(Diag::bug([format!( + "Offset({offset}): negative offset" + ) + .into()])) })?; // FIXME(eddyb) these should be normalized @@ -1037,9 +1044,16 @@ impl<'a> InferUsage<'a> { Ok(QPtrUsage::Memory(QPtrMemUsage { max_size: usage .max_size - .map(|max_size| offset.checked_add(max_size).ok_or_else(|| { - AnalysisError(Diag::bug([format!("Offset({offset}): size overflow ({offset}+{max_size})").into()])) - })).transpose()?, + .map(|max_size| { + offset.checked_add(max_size).ok_or_else(|| { + AnalysisError(Diag::bug([format!( + "Offset({offset}): size overflow \ + ({offset}+{max_size})" + ) + .into()])) + }) + }) + .transpose()?, // FIXME(eddyb) allocating `Rc>` // to represent the one-element case, seems // quite wasteful when it's likely consumed. @@ -1059,19 +1073,25 @@ impl<'a> InferUsage<'a> { .and_then(|usage| { let usage = match usage { QPtrUsage::Handles(_) => { - return Err(AnalysisError(Diag::bug(["DynOffset: cannot offset Handles".into()]))); + return Err(AnalysisError(Diag::bug([ + "DynOffset: cannot offset Handles".into(), + ]))); } QPtrUsage::Memory(usage) => usage, }; match usage.max_size { None => { - return Err(AnalysisError(Diag::bug(["DynOffset: unsized element".into()]))); + return Err(AnalysisError(Diag::bug([ + "DynOffset: unsized element".into(), + ]))); } // FIXME(eddyb) support this by "folding" // the usage onto itself (i.e. applying // `%= stride` on all offsets inside). Some(max_size) if max_size > stride.get() => { - return Err(AnalysisError(Diag::bug(["DynOffset: element max_size exceeds stride".into()]))); + return Err(AnalysisError(Diag::bug([ + "DynOffset: element max_size exceeds stride".into(), + ]))); } Some(_) => {} } @@ -1082,19 +1102,22 @@ impl<'a> InferUsage<'a> { .as_ref() .map(|index_bounds| { if index_bounds.start < 0 || index_bounds.end < 0 { - return Err(AnalysisError( - Diag::bug([ - "DynOffset: potentially negative offset" - .into(), - ]) - )); + return Err(AnalysisError(Diag::bug([ + "DynOffset: potentially negative offset" + .into(), + ]))); } - let index_bounds_end = u32::try_from(index_bounds.end).unwrap(); - index_bounds_end.checked_mul(stride.get()).ok_or_else(|| { - AnalysisError(Diag::bug([ - format!("DynOffset: size overflow ({index_bounds_end}*{stride})").into(), - ])) - }) + let index_bounds_end = + u32::try_from(index_bounds.end).unwrap(); + index_bounds_end + .checked_mul(stride.get()) + .ok_or_else(|| { + AnalysisError(Diag::bug([format!( + "DynOffset: size overflow \ + ({index_bounds_end}*{stride})" + ) + .into()])) + }) }) .transpose()?, kind: QPtrMemUsageKind::DynOffsetBase { @@ -1165,50 +1188,65 @@ impl<'a> InferUsage<'a> { self.layout_cache .layout_of(ty) .map_err(|LayoutError(e)| AnalysisError(e)) - .and_then(|layout| match layout { - TypeLayout::Handle(handle) => { - let handle = match handle { - shapes::Handle::Opaque(ty) => { - shapes::Handle::Opaque(ty) - } - // NOTE(eddyb) this error is important, - // as the `Block` annotation on the - // buffer type means the type is *not* - // usable anywhere inside buffer data, - // since it would conflict with our - // own `Block`-annotated wrapper. - shapes::Handle::Buffer(..) => { - return Err(AnalysisError(Diag::bug(["ToSpvPtrInput: whole Buffer ambiguous (handle vs buffer data)".into()]) - )); - } - }; - Ok(QPtrUsage::Handles(handle)) - } - // NOTE(eddyb) because we can't represent - // the original type, in the same way we - // use `QPtrMemUsageKind::StrictlyTyped` - // for non-handles, we can't guarantee - // a generated type that matches the - // desired `pointee` type. - TypeLayout::HandleArray(..) => { - Err(AnalysisError(Diag::bug(["ToSpvPtrInput: whole handle array unrepresentable".into()]) - )) - } - TypeLayout::Concrete(concrete) => { - Ok(QPtrUsage::Memory(QPtrMemUsage { - max_size: if concrete - .mem_layout - .dyn_unit_stride - .is_some() - { - None - } else { - Some( - concrete.mem_layout.fixed_base.size, - ) - }, - kind: QPtrMemUsageKind::StrictlyTyped(ty), - })) + .and_then(|layout| { + match layout { + TypeLayout::Handle(handle) => { + let handle = match handle { + shapes::Handle::Opaque(ty) => { + shapes::Handle::Opaque(ty) + } + // NOTE(eddyb) this error is important, + // as the `Block` annotation on the + // buffer type means the type is *not* + // usable anywhere inside buffer data, + // since it would conflict with our + // own `Block`-annotated wrapper. + shapes::Handle::Buffer(..) => { + return Err(AnalysisError( + Diag::bug(["ToSpvPtrInput: \ + whole Buffer ambiguous \ + (handle vs buffer data)" + .into()]), + )); + } + }; + Ok(QPtrUsage::Handles(handle)) + } + // NOTE(eddyb) because we can't represent + // the original type, in the same way we + // use `QPtrMemUsageKind::StrictlyTyped` + // for non-handles, we can't guarantee + // a generated type that matches the + // desired `pointee` type. + TypeLayout::HandleArray(..) => { + Err(AnalysisError(Diag::bug([ + "ToSpvPtrInput: \ + whole handle array \ + unrepresentable" + .into(), + ]))) + } + TypeLayout::Concrete(concrete) => { + Ok(QPtrUsage::Memory(QPtrMemUsage { + max_size: if concrete + .mem_layout + .dyn_unit_stride + .is_some() + { + None + } else { + Some( + concrete + .mem_layout + .fixed_base + .size, + ) + }, + kind: QPtrMemUsageKind::StrictlyTyped( + ty, + ), + })) + } } }), ); diff --git a/src/qptr/layout.rs b/src/qptr/layout.rs index c5e081ba..cbc407b1 100644 --- a/src/qptr/layout.rs +++ b/src/qptr/layout.rs @@ -475,7 +475,8 @@ impl<'a> LayoutCache<'a> { } Ordering::Greater => { return Err(LayoutError(Diag::bug([ - "structs with explicit offsets must provide them for all fields" + "structs with explicit offsets \ + must provide them for all fields" .into(), ]))); } diff --git a/src/qptr/lift.rs b/src/qptr/lift.rs index 0b0668c1..c4af4e2f 100644 --- a/src/qptr/lift.rs +++ b/src/qptr/lift.rs @@ -603,9 +603,11 @@ impl LiftToSpvPtrInstsInFunc<'_> { // FIXME(eddyb) this could include the chosen indices, // and maybe the current type and/or layout. return Err(LiftError(Diag::bug([format!( - "offset {offset} not found in type layout, after {} access chain indices", + "offset {offset} not found in type layout, \ + after {} access chain indices", access_chain_inputs.len() - 1 - ).into()]))); + ) + .into()]))); } (Some(idx), Some(_)) => { // FIXME(eddyb) !!! this can also be illegal overlap diff --git a/src/spv/lower.rs b/src/spv/lower.rs index 12d5c080..a2902c4a 100644 --- a/src/spv/lower.rs +++ b/src/spv/lower.rs @@ -1675,20 +1675,14 @@ impl Module { Ok((ExportKey::LinkName(name), exportee)) } - Export::EntryPoint { - func_id, - imms, - interface_ids, - } => { + Export::EntryPoint { func_id, imms, interface_ids } => { let func = match id_defs.get(&func_id) { Some(&IdDef::Func(func)) => Ok(func), Some(id_def) => Err(id_def.descr(&cx)), None => Err(format!("unknown ID %{func_id}")), } .map_err(|descr| { - invalid(&format!( - "unsupported use of {descr} as the `OpEntryPoint` target" - )) + invalid(&format!("unsupported use of {descr} as the `OpEntryPoint` target")) })?; let interface_global_vars = interface_ids .into_iter() @@ -1703,16 +1697,14 @@ impl Module { .map(|result| { result.map_err(|descr| { invalid(&format!( - "unsupported use of {descr} as an `OpEntryPoint` interface variable" + "unsupported use of {descr} as an \ + `OpEntryPoint` interface variable" )) }) }) .collect::>()?; Ok(( - ExportKey::SpvEntryPoint { - imms, - interface_global_vars, - }, + ExportKey::SpvEntryPoint { imms, interface_global_vars }, Exportee::Func(func), )) } diff --git a/src/spv/spec.rs b/src/spv/spec.rs index b11b7b67..ef59ee6d 100644 --- a/src/spv/spec.rs +++ b/src/spv/spec.rs @@ -683,10 +683,7 @@ impl Spec { .unwrap(); } - Enumerant { - req_params, - rest_params, - } + Enumerant { req_params, rest_params } }; let def = match o.category { @@ -732,7 +729,8 @@ impl Spec { // Only allow aliases that do not meaningfully differ. assert!( prev_enumerant == new_enumerant, - "{} bits {} and {} share a bit index but differ in definition", + "{} bits {} and {} share a bit index \ + but differ in definition", o.kind, prev_name, new_name, @@ -757,10 +755,7 @@ impl Spec { storage: bits, }; - OperandKindDef::BitEnum { - empty_name: empty_name.unwrap_or("None"), - bits, - } + OperandKindDef::BitEnum { empty_name: empty_name.unwrap_or("None"), bits } } raw::OperandKindCategory::ValueEnum => { assert!(o.bases.is_none()); @@ -768,10 +763,7 @@ impl Spec { let enumerants = o.enumerants.as_ref().unwrap(); let variants = indexed::KhrSegmentedVec::from_in_order_iter( enumerants.iter().map(|e| { - ( - e.value.try_into().unwrap(), - (e.enumerant, enumerant_from_raw(e)), - ) + (e.value.try_into().unwrap(), (e.enumerant, enumerant_from_raw(e))) }), // `merge_duplicates` closure: |(prev_name, prev_enumerant), (new_name, new_enumerant)| { @@ -784,10 +776,7 @@ impl Spec { new_name, ); - ( - preferred_name_between_dups(prev_name, new_name), - new_enumerant, - ) + (preferred_name_between_dups(prev_name, new_name), new_enumerant) }, );