-
-
Notifications
You must be signed in to change notification settings - Fork 14.1k
Description
Right now you just have to hope that whoever adds a new option to CodegenFnAttrFlags correctly updates all the places where it is relevant, e.g.
rust/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs
Lines 18 to 50 in c4dc70e
| let mut attrs = Cow::Borrowed(self.codegen_fn_attrs(instance_kind.def_id())); | |
| // Drop the `#[naked]` attribute on non-item `InstanceKind`s, like the shims that | |
| // are generated for indirect function calls. | |
| if !matches!(instance_kind, InstanceKind::Item(_)) { | |
| if attrs.flags.contains(CodegenFnAttrFlags::NAKED) { | |
| attrs.to_mut().flags.remove(CodegenFnAttrFlags::NAKED); | |
| } | |
| } | |
| // A shim created by `#[track_caller]` should not inherit any attributes | |
| // that modify the symbol name. Failing to remove these attributes from | |
| // the shim leads to errors like `symbol `foo` is already defined`. | |
| // | |
| // A `ClosureOnceShim` with the track_caller attribute does not have a symbol, | |
| // and therefore can be skipped here. | |
| if let InstanceKind::ReifyShim(_, _) = instance_kind | |
| && attrs.flags.contains(CodegenFnAttrFlags::TRACK_CALLER) | |
| { | |
| if attrs.flags.contains(CodegenFnAttrFlags::NO_MANGLE) { | |
| attrs.to_mut().flags.remove(CodegenFnAttrFlags::NO_MANGLE); | |
| } | |
| if attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL) { | |
| attrs.to_mut().flags.remove(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL); | |
| } | |
| if attrs.symbol_name.is_some() { | |
| attrs.to_mut().symbol_name = None; | |
| } | |
| } | |
| attrs |
This is quite fragile and I certainly wouldn't have caught this omission in review.
A way to prevent such bugs is by exhaustively matching on all options in such places, e.g.
rust/compiler/rustc_middle/src/ty/context.rs
Lines 632 to 638 in c4dc70e
| let (ty::FloatTy::F16 | ty::FloatTy::F32 | ty::FloatTy::F64 | ty::FloatTy::F128); | |
| let possible_floats = [ | |
| ty::SimplifiedType::Float(ty::FloatTy::F16), | |
| ty::SimplifiedType::Float(ty::FloatTy::F32), | |
| ty::SimplifiedType::Float(ty::FloatTy::F64), | |
| ty::SimplifiedType::Float(ty::FloatTy::F128), | |
| ]; |
rust/compiler/rustc_next_trait_solver/src/solve/mod.rs
Lines 72 to 81 in c4dc70e
| fn has_only_region_constraints<I: Interner>(response: ty::Canonical<I, Response<I>>) -> bool { | |
| let ExternalConstraintsData { | |
| region_constraints: _, | |
| ref opaque_types, | |
| ref normalization_nested_goals, | |
| } = *response.value.external_constraints; | |
| response.value.var_values.is_identity_modulo_regions() | |
| && opaque_types.is_empty() | |
| && normalization_nested_goals.is_empty() | |
| } |
Imo we should extend our bitflags macro to also emit an enum of all options to enable us to exhaustively match on them in cases where this is likely useful.