Skip to content

Commit dda2372

Browse files
committedMar 25, 2024
Auto merge of #122802 - estebank:unconstrained-generic-const, r=Nadrieril
Provide structured suggestion for unconstrained generic constant ``` error: unconstrained generic constant --> $DIR/const-argument-if-length.rs:18:10 | LL | pad: [u8; is_zst::<T>()], | ^^^^^^^^^^^^^^^^^^^ | help: try adding a `where` bound | LL | pub struct AtLeastByte<T: ?Sized> where [(); is_zst::<T>()]: { | ++++++++++++++++++++++++++ ``` Detect when the constant expression isn't `usize` and suggest casting: ``` error: unconstrained generic constant --> f300.rs:6:10 | 6 | bb::<{!N}>(); | ^^^^ -Ztrack-diagnostics: created at compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs:3539:36 | help: try adding a `where` bound | 5 | fn b<const N: bool>() where [(); {!N} as usize]: { | ++++++++++++++++++++++++++ ``` Fix #122395.
2 parents 42198bf + 6b24fdf commit dda2372

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+351
-111
lines changed
 

‎compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3536,12 +3536,39 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
35363536
let mut err =
35373537
self.dcx().struct_span_err(span, "unconstrained generic constant");
35383538
let const_span = self.tcx.def_span(uv.def);
3539+
3540+
let const_ty = self.tcx.type_of(uv.def).instantiate(self.tcx, uv.args);
3541+
let cast = if const_ty != self.tcx.types.usize { " as usize" } else { "" };
3542+
let msg = "try adding a `where` bound";
35393543
match self.tcx.sess.source_map().span_to_snippet(const_span) {
3540-
Ok(snippet) => err.help(format!(
3541-
"try adding a `where` bound using this expression: `where [(); {snippet}]:`"
3542-
)),
3543-
_ => err.help("consider adding a `where` bound using this expression"),
3544-
};
3544+
Ok(snippet) => {
3545+
let code = format!("[(); {snippet}{cast}]:");
3546+
let def_id = if let ObligationCauseCode::CompareImplItemObligation {
3547+
trait_item_def_id,
3548+
..
3549+
} = obligation.cause.code()
3550+
{
3551+
trait_item_def_id.as_local()
3552+
} else {
3553+
Some(obligation.cause.body_id)
3554+
};
3555+
if let Some(def_id) = def_id
3556+
&& let Some(generics) = self.tcx.hir().get_generics(def_id)
3557+
{
3558+
err.span_suggestion_verbose(
3559+
generics.tail_span_for_predicate_suggestion(),
3560+
msg,
3561+
format!("{} {code}", generics.add_where_or_trailing_comma()),
3562+
Applicability::MaybeIncorrect,
3563+
);
3564+
} else {
3565+
err.help(format!("{msg}: where {code}"));
3566+
};
3567+
}
3568+
_ => {
3569+
err.help(msg);
3570+
}
3571+
};
35453572
Ok(err)
35463573
}
35473574
ty::ConstKind::Expr(_) => {

‎tests/ui/const-generics/const-argument-if-length.full.stderr

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@ error: unconstrained generic constant
44
LL | pad: [u8; is_zst::<T>()],
55
| ^^^^^^^^^^^^^^^^^^^
66
|
7-
= help: try adding a `where` bound using this expression: `where [(); is_zst::<T>()]:`
7+
help: try adding a `where` bound
8+
|
9+
LL | pub struct AtLeastByte<T: ?Sized> where [(); is_zst::<T>()]: {
10+
| ++++++++++++++++++++++++++
811

912
error[E0277]: the size for values of type `T` cannot be known at compilation time
1013
--> $DIR/const-argument-if-length.rs:16:12

0 commit comments

Comments
 (0)
Please sign in to comment.