Skip to content

Commit f9326cd

Browse files
committed
Check that impls of #[type_const] consts also have the attr
1 parent 82b6d72 commit f9326cd

File tree

8 files changed

+105
-28
lines changed

8 files changed

+105
-28
lines changed

compiler/rustc_hir_analysis/src/check/compare_impl_item.rs

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@ use hir::def_id::{DefId, DefIdMap, LocalDefId};
66
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
77
use rustc_errors::codes::*;
88
use rustc_errors::{Applicability, ErrorGuaranteed, MultiSpan, pluralize, struct_span_code_err};
9+
use rustc_hir::attrs::AttributeKind;
910
use rustc_hir::def::{DefKind, Res};
1011
use rustc_hir::intravisit::VisitorExt;
11-
use rustc_hir::{self as hir, AmbigArg, GenericParamKind, ImplItemKind, intravisit};
12+
use rustc_hir::{self as hir, AmbigArg, GenericParamKind, ImplItemKind, find_attr, intravisit};
1213
use rustc_infer::infer::{self, BoundRegionConversionTime, InferCtxt, TyCtxtInferExt};
1314
use rustc_infer::traits::util;
1415
use rustc_middle::ty::error::{ExpectedFound, TypeError};
@@ -1984,12 +1985,46 @@ fn compare_impl_const<'tcx>(
19841985
trait_const_item: ty::AssocItem,
19851986
impl_trait_ref: ty::TraitRef<'tcx>,
19861987
) -> Result<(), ErrorGuaranteed> {
1988+
compare_type_const(tcx, impl_const_item, trait_const_item)?;
19871989
compare_number_of_generics(tcx, impl_const_item, trait_const_item, false)?;
19881990
compare_generic_param_kinds(tcx, impl_const_item, trait_const_item, false)?;
19891991
check_region_bounds_on_impl_item(tcx, impl_const_item, trait_const_item, false)?;
19901992
compare_const_predicate_entailment(tcx, impl_const_item, trait_const_item, impl_trait_ref)
19911993
}
19921994

1995+
fn compare_type_const<'tcx>(
1996+
tcx: TyCtxt<'tcx>,
1997+
impl_const_item: ty::AssocItem,
1998+
trait_const_item: ty::AssocItem,
1999+
) -> Result<(), ErrorGuaranteed> {
2000+
let impl_is_type_const =
2001+
find_attr!(tcx.get_all_attrs(impl_const_item.def_id), AttributeKind::TypeConst(_));
2002+
let trait_type_const_span = find_attr!(
2003+
tcx.get_all_attrs(trait_const_item.def_id),
2004+
AttributeKind::TypeConst(sp) => *sp
2005+
);
2006+
2007+
if let Some(trait_type_const_span) = trait_type_const_span
2008+
&& !impl_is_type_const
2009+
{
2010+
return Err(tcx
2011+
.dcx()
2012+
.struct_span_err(
2013+
tcx.def_span(impl_const_item.def_id),
2014+
"implementation of `#[type_const]` const must be marked with `#[type_const]`",
2015+
)
2016+
.with_span_note(
2017+
MultiSpan::from_spans(vec![
2018+
tcx.def_span(trait_const_item.def_id),
2019+
trait_type_const_span,
2020+
]),
2021+
"trait declaration of const is marked with `#[type_const]`",
2022+
)
2023+
.emit());
2024+
}
2025+
Ok(())
2026+
}
2027+
19932028
/// The equivalent of [compare_method_predicate_entailment], but for associated constants
19942029
/// instead of associated functions.
19952030
// FIXME(generic_const_items): If possible extract the common parts of `compare_{type,const}_predicate_entailment`.

compiler/rustc_hir_analysis/src/collect.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1562,8 +1562,12 @@ fn const_of_item<'tcx>(
15621562
};
15631563
let ct_arg = match ct_rhs {
15641564
hir::ConstItemRhs::TypeConst(ct_arg) => ct_arg,
1565-
hir::ConstItemRhs::Body(body_id) => {
1566-
bug!("cannot call const_of_item on a non-type_const {body_id:?}")
1565+
hir::ConstItemRhs::Body(_) => {
1566+
let e = tcx.dcx().span_delayed_bug(
1567+
tcx.def_span(def_id),
1568+
"cannot call const_of_item on a non-type_const",
1569+
);
1570+
return ty::EarlyBinder::bind(Const::new_error(tcx, e));
15671571
}
15681572
};
15691573
let icx = ItemCtxt::new(tcx, def_id);

tests/crashes/140729.rs

Lines changed: 0 additions & 11 deletions
This file was deleted.

tests/crashes/140860.rs

Lines changed: 0 additions & 10 deletions
This file was deleted.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Regression test for #140729
2+
3+
#![expect(incomplete_features)]
4+
#![feature(min_generic_const_args)]
5+
6+
const C: usize = 0;
7+
pub struct A<const M: usize> {}
8+
impl A<C> {
9+
fn fun1() {}
10+
//~^ ERROR duplicate definitions with name `fun1`
11+
}
12+
impl A {
13+
//~^ ERROR missing generics for struct `A`
14+
fn fun1() {}
15+
}
16+
17+
fn main() {}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
error[E0107]: missing generics for struct `A`
2+
--> $DIR/const-arg-coherence-conflicting-methods.rs:12:6
3+
|
4+
LL | impl A {
5+
| ^ expected 1 generic argument
6+
|
7+
note: struct defined here, with 1 generic parameter: `M`
8+
--> $DIR/const-arg-coherence-conflicting-methods.rs:7:12
9+
|
10+
LL | pub struct A<const M: usize> {}
11+
| ^ --------------
12+
help: add missing generic argument
13+
|
14+
LL | impl A<M> {
15+
| +++
16+
17+
error[E0592]: duplicate definitions with name `fun1`
18+
--> $DIR/const-arg-coherence-conflicting-methods.rs:9:5
19+
|
20+
LL | fn fun1() {}
21+
| ^^^^^^^^^ duplicate definitions for `fun1`
22+
...
23+
LL | fn fun1() {}
24+
| --------- other definition for `fun1`
25+
26+
error: aborting due to 2 previous errors
27+
28+
Some errors have detailed explanations: E0107, E0592.
29+
For more information about an error, try `rustc --explain E0107`.

tests/crashes/mgca/type_const-only-in-trait.rs renamed to tests/ui/const-generics/mgca/type_const-only-in-trait.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
1-
//@ known-bug: #132980
2-
// Move this test to tests/ui/const-generics/mgca/type_const-only-in-trait.rs
3-
// once fixed.
4-
51
#![expect(incomplete_features)]
62
#![feature(associated_const_equality, min_generic_const_args)]
73

@@ -14,6 +10,7 @@ struct BadS;
1410

1511
impl GoodTr for BadS {
1612
const NUM: usize = 42;
13+
//~^ ERROR implementation of `#[type_const]` const must be marked with `#[type_const]`
1714
}
1815

1916
fn accept_good_tr<const N: usize, T: GoodTr<NUM = { N }>>(_x: &T) {}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
error: implementation of `#[type_const]` const must be marked with `#[type_const]`
2+
--> $DIR/type_const-only-in-trait.rs:12:5
3+
|
4+
LL | const NUM: usize = 42;
5+
| ^^^^^^^^^^^^^^^^
6+
|
7+
note: trait declaration of const is marked with `#[type_const]`
8+
--> $DIR/type_const-only-in-trait.rs:5:5
9+
|
10+
LL | #[type_const]
11+
| ^^^^^^^^^^^^^
12+
LL | const NUM: usize;
13+
| ^^^^^^^^^^^^^^^^
14+
15+
error: aborting due to 1 previous error
16+

0 commit comments

Comments
 (0)