Rollup merge of #81503 - henryboisdequin:fix-const-fn-arr-err-msg, r=estebank
Suggest to create a new `const` item if the `fn` in the array is a `const fn` Fixes #73734. If the `fn` in the array repeat expression is a `const fn`, suggest creating a new `const` item. On nightly, suggest creating an inline `const` block. This PR also removes the `suggest_const_in_array_repeat_expressions` as it is no longer necessary. Example: ```rust fn main() { // Should not compile but hint to create a new const item (stable) or an inline const block (nightly) let strings: [String; 5] = [String::new(); 5]; println!("{:?}", strings); } ``` Gives this error: ``` error[E0277]: the trait bound `std::string::String: std::marker::Copy` is not satisfied --> $DIR/const-fn-in-vec.rs:3:32 | 2 | let strings: [String; 5] = [String::new(); 5]; | ^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `String` | = note: the `Copy` trait is required because the repeated element will be copied ``` With this change, this is the error message: ``` error[E0277]: the trait bound `String: Copy` is not satisfied --> $DIR/const-fn-in-vec.rs:3:32 | LL | let strings: [String; 5] = [String::new(); 5]; | ^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String` | = help: moving the function call to a new `const` item will resolve the error ```
This commit is contained in:
@@ -1231,3 +1231,38 @@ pub fn promote_candidates<'tcx>(
|
||||
|
||||
promotions
|
||||
}
|
||||
|
||||
/// This function returns `true` if the function being called in the array
|
||||
/// repeat expression is a `const` function.
|
||||
crate fn is_const_fn_in_array_repeat_expression<'tcx>(
|
||||
ccx: &ConstCx<'_, 'tcx>,
|
||||
place: &Place<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
) -> bool {
|
||||
match place.as_local() {
|
||||
// rule out cases such as: `let my_var = some_fn(); [my_var; N]`
|
||||
Some(local) if body.local_decls[local].is_user_variable() => return false,
|
||||
None => return false,
|
||||
_ => {}
|
||||
}
|
||||
|
||||
for block in body.basic_blocks() {
|
||||
if let Some(Terminator { kind: TerminatorKind::Call { func, destination, .. }, .. }) =
|
||||
&block.terminator
|
||||
{
|
||||
if let Operand::Constant(box Constant { literal: ty::Const { ty, .. }, .. }) = func {
|
||||
if let ty::FnDef(def_id, _) = *ty.kind() {
|
||||
if let Some((destination_place, _)) = destination {
|
||||
if destination_place == place {
|
||||
if is_const_fn(ccx.tcx, def_id) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user