Skip to content

Commit d3c605a

Browse files
authored
Rollup merge of rust-lang#136429 - fmease:gci-fix-def-site-checks, r=BoxyUwU
GCI: At their def site, actually wfcheck the where-clause & always eval free lifetime-generic constants * 1st commit: Partially addresses [rust-lang#136204](rust-lang#136204) by turning const eval errors from post to pre-mono for free lifetime-generic constants. * As the linked issue/comment states, on master there's a difference between `const _: () = panic!();` (pre-mono error) and `const _<'a>: () = panic!();` (post-mono error) which feels wrong. * With this PR, both become pre-mono ones! * 2nd commit: Oof, yeah, I missed that in the initial impl! This doesn't fully address rust-lang#136204 because I still haven't figured out how & where to properly & best suppress const eval of free constants whose predicates don't hold at the def site. The motivating example is `const _UNUSED: () = () where for<'_delay> String: Copy;` which can also be found over at the tracking issue rust-lang#113521. r? compiler-errors or reassign
2 parents ebe9b00 + 9f12748 commit d3c605a

File tree

8 files changed

+64
-38
lines changed

8 files changed

+64
-38
lines changed

compiler/rustc_hir_analysis/src/check/wfcheck.rs

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -298,11 +298,9 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) -> Result<()
298298
check_item_fn(tcx, def_id, ident, item.span, sig.decl)
299299
}
300300
hir::ItemKind::Static(_, ty, ..) => {
301-
check_item_type(tcx, def_id, ty.span, UnsizedHandling::Forbid)
302-
}
303-
hir::ItemKind::Const(_, ty, ..) => {
304-
check_item_type(tcx, def_id, ty.span, UnsizedHandling::Forbid)
301+
check_static_item(tcx, def_id, ty.span, UnsizedHandling::Forbid)
305302
}
303+
hir::ItemKind::Const(_, ty, ..) => check_const_item(tcx, def_id, ty.span, item.span),
306304
hir::ItemKind::Struct(_, _, hir_generics) => {
307305
let res = check_type_defn(tcx, item, false);
308306
check_variances_for_type_defn(tcx, item, hir_generics);
@@ -366,7 +364,7 @@ fn check_foreign_item<'tcx>(
366364
check_item_fn(tcx, def_id, item.ident, item.span, sig.decl)
367365
}
368366
hir::ForeignItemKind::Static(ty, ..) => {
369-
check_item_type(tcx, def_id, ty.span, UnsizedHandling::AllowIfForeignTail)
367+
check_static_item(tcx, def_id, ty.span, UnsizedHandling::AllowIfForeignTail)
370368
}
371369
hir::ForeignItemKind::Type => Ok(()),
372370
}
@@ -1331,14 +1329,13 @@ enum UnsizedHandling {
13311329
AllowIfForeignTail,
13321330
}
13331331

1334-
fn check_item_type(
1332+
#[instrument(level = "debug", skip(tcx, ty_span, unsized_handling))]
1333+
fn check_static_item(
13351334
tcx: TyCtxt<'_>,
13361335
item_id: LocalDefId,
13371336
ty_span: Span,
13381337
unsized_handling: UnsizedHandling,
13391338
) -> Result<(), ErrorGuaranteed> {
1340-
debug!("check_item_type: {:?}", item_id);
1341-
13421339
enter_wf_checking_ctxt(tcx, ty_span, item_id, |wfcx| {
13431340
let ty = tcx.type_of(item_id).instantiate_identity();
13441341
let item_ty = wfcx.deeply_normalize(ty_span, Some(WellFormedLoc::Ty(item_id)), ty);
@@ -1388,6 +1385,34 @@ fn check_item_type(
13881385
})
13891386
}
13901387

1388+
fn check_const_item(
1389+
tcx: TyCtxt<'_>,
1390+
def_id: LocalDefId,
1391+
ty_span: Span,
1392+
item_span: Span,
1393+
) -> Result<(), ErrorGuaranteed> {
1394+
enter_wf_checking_ctxt(tcx, ty_span, def_id, |wfcx| {
1395+
let ty = tcx.type_of(def_id).instantiate_identity();
1396+
let ty = wfcx.deeply_normalize(ty_span, Some(WellFormedLoc::Ty(def_id)), ty);
1397+
1398+
wfcx.register_wf_obligation(ty_span, Some(WellFormedLoc::Ty(def_id)), ty.into());
1399+
wfcx.register_bound(
1400+
traits::ObligationCause::new(
1401+
ty_span,
1402+
wfcx.body_def_id,
1403+
ObligationCauseCode::SizedConstOrStatic,
1404+
),
1405+
wfcx.param_env,
1406+
ty,
1407+
tcx.require_lang_item(LangItem::Sized, None),
1408+
);
1409+
1410+
check_where_clauses(wfcx, item_span, def_id);
1411+
1412+
Ok(())
1413+
})
1414+
}
1415+
13911416
#[instrument(level = "debug", skip(tcx, hir_self_ty, hir_trait_ref))]
13921417
fn check_impl<'tcx>(
13931418
tcx: TyCtxt<'tcx>,

compiler/rustc_hir_analysis/src/lib.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,9 @@ pub fn check_crate(tcx: TyCtxt<'_>) {
203203
tcx.ensure_ok().eval_static_initializer(item_def_id);
204204
check::maybe_check_static_with_link_section(tcx, item_def_id);
205205
}
206-
DefKind::Const if tcx.generics_of(item_def_id).is_empty() => {
206+
DefKind::Const if !tcx.generics_of(item_def_id).own_requires_monomorphization() => {
207+
// FIXME(generic_const_items): Passing empty instead of identity args is fishy but
208+
// seems to be fine for now. Revisit this!
207209
let instance = ty::Instance::new_raw(item_def_id.into(), ty::GenericArgs::empty());
208210
let cid = GlobalId { instance, promoted: None };
209211
let typing_env = ty::TypingEnv::fully_monomorphized();

compiler/rustc_middle/src/mir/interpret/queries.rs

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ use super::{
99
ReportedErrorInfo,
1010
};
1111
use crate::mir;
12-
use crate::query::TyCtxtEnsureOk;
1312
use crate::ty::{self, GenericArgs, TyCtxt, TypeVisitableExt};
1413

1514
impl<'tcx> TyCtxt<'tcx> {
@@ -197,24 +196,3 @@ impl<'tcx> TyCtxt<'tcx> {
197196
}
198197
}
199198
}
200-
201-
impl<'tcx> TyCtxtEnsureOk<'tcx> {
202-
/// Evaluates a constant without providing any generic parameters. This is useful to evaluate consts
203-
/// that can't take any generic arguments like const items or enum discriminants. If a
204-
/// generic parameter is used within the constant `ErrorHandled::TooGeneric` will be returned.
205-
#[instrument(skip(self), level = "debug")]
206-
pub fn const_eval_poly(self, def_id: DefId) {
207-
// In some situations def_id will have generic parameters within scope, but they aren't allowed
208-
// to be used. So we can't use `Instance::mono`, instead we feed unresolved generic parameters
209-
// into `const_eval` which will return `ErrorHandled::TooGeneric` if any of them are
210-
// encountered.
211-
let args = GenericArgs::identity_for_item(self.tcx, def_id);
212-
let instance = ty::Instance::new_raw(def_id, self.tcx.erase_regions(args));
213-
let cid = GlobalId { instance, promoted: None };
214-
let typing_env = ty::TypingEnv::post_analysis(self.tcx, def_id);
215-
// Const-eval shouldn't depend on lifetimes at all, so we can erase them, which should
216-
// improve caching of queries.
217-
let inputs = self.tcx.erase_regions(typing_env.as_query_input(cid));
218-
self.eval_to_const_value_raw(inputs)
219-
}
220-
}

compiler/rustc_monomorphize/src/collector.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1483,7 +1483,7 @@ impl<'v> RootCollector<'_, 'v> {
14831483

14841484
// But even just declaring them must collect the items they refer to
14851485
// unless their generics require monomorphization.
1486-
if !self.tcx.generics_of(id.owner_id).requires_monomorphization(self.tcx)
1486+
if !self.tcx.generics_of(id.owner_id).own_requires_monomorphization()
14871487
&& let Ok(val) = self.tcx.const_eval_poly(id.owner_id.to_def_id())
14881488
{
14891489
collect_const_value(self.tcx, val, self.output);

tests/ui/generic-const-items/def-site-eval.fail.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
error[E0080]: evaluation of `_::<'_>` failed
2-
--> $DIR/def-site-eval.rs:14:20
1+
error[E0080]: evaluation of constant value failed
2+
--> $DIR/def-site-eval.rs:13:20
33
|
44
LL | const _<'_a>: () = panic!();
55
| ^^^^^^^^ evaluation panicked: explicit panic
Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,15 @@
11
//! Test that we only evaluate free const items (their def site to be clear)
22
//! whose generics don't require monomorphization.
33
#![feature(generic_const_items)]
4-
#![allow(incomplete_features)]
4+
#![expect(incomplete_features)]
55

66
//@ revisions: fail pass
7-
//@[fail] build-fail (we require monomorphization)
8-
//@[pass] build-pass (we require monomorphization)
7+
//@[pass] check-pass
98

109
const _<_T>: () = panic!();
1110
const _<const _N: usize>: () = panic!();
1211

1312
#[cfg(fail)]
14-
const _<'_a>: () = panic!(); //[fail]~ ERROR evaluation of `_::<'_>` failed
13+
const _<'_a>: () = panic!(); //[fail]~ ERROR evaluation of constant value failed
1514

1615
fn main() {}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
//! Ensure that we check the predicates for well-formedness at the definition site.
2+
#![feature(generic_const_items)]
3+
#![expect(incomplete_features)]
4+
5+
const _: () = ()
6+
where
7+
Vec<str>: Sized; //~ ERROR the size for values of type `str` cannot be known at compilation time
8+
9+
fn main() {}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
error[E0277]: the size for values of type `str` cannot be known at compilation time
2+
--> $DIR/def-site-predicates-wf.rs:7:15
3+
|
4+
LL | Vec<str>: Sized;
5+
| ^^^^^ doesn't have a size known at compile-time
6+
|
7+
= help: the trait `Sized` is not implemented for `str`
8+
note: required by an implicit `Sized` bound in `Vec`
9+
--> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
10+
11+
error: aborting due to 1 previous error
12+
13+
For more information about this error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)