Skip to content

GCI: At their def site, actually wfcheck the where-clause & always eval free lifetime-generic constants #136429

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 30 additions & 3 deletions compiler/rustc_hir_analysis/src/check/wfcheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -306,9 +306,7 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) -> Result<()
hir::ItemKind::Static(ty, ..) => {
check_item_type(tcx, def_id, ty.span, UnsizedHandling::Forbid)
}
hir::ItemKind::Const(ty, ..) => {
check_item_type(tcx, def_id, ty.span, UnsizedHandling::Forbid)
}
hir::ItemKind::Const(ty, ..) => check_const_item(tcx, def_id, ty.span, item.span),
hir::ItemKind::Struct(_, hir_generics) => {
let res = check_type_defn(tcx, item, false);
check_variances_for_type_defn(tcx, item, hir_generics);
Expand Down Expand Up @@ -1280,6 +1278,7 @@ enum UnsizedHandling {
AllowIfForeignTail,
}

// FIXME(fmease): Rename to check_static_item once LTAs don't use it anymore (#136432)
fn check_item_type(
tcx: TyCtxt<'_>,
item_id: LocalDefId,
Expand Down Expand Up @@ -1338,6 +1337,34 @@ fn check_item_type(
})
}

fn check_const_item(
tcx: TyCtxt<'_>,
def_id: LocalDefId,
ty_span: Span,
item_span: Span,
) -> Result<(), ErrorGuaranteed> {
enter_wf_checking_ctxt(tcx, ty_span, def_id, |wfcx| {
let ty = tcx.type_of(def_id).instantiate_identity();
let ty = wfcx.normalize(ty_span, Some(WellFormedLoc::Ty(def_id)), ty);

wfcx.register_wf_obligation(ty_span, Some(WellFormedLoc::Ty(def_id)), ty.into());
wfcx.register_bound(
traits::ObligationCause::new(
ty_span,
wfcx.body_def_id,
ObligationCauseCode::WellFormed(None),
),
wfcx.param_env,
ty,
tcx.require_lang_item(LangItem::Sized, None),
);

check_where_clauses(wfcx, item_span, def_id);

Ok(())
})
}

#[instrument(level = "debug", skip(tcx, hir_self_ty, hir_trait_ref))]
fn check_impl<'tcx>(
tcx: TyCtxt<'tcx>,
Expand Down
10 changes: 3 additions & 7 deletions compiler/rustc_hir_analysis/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,8 @@ use rustc_abi::ExternAbi;
use rustc_hir as hir;
use rustc_hir::def::DefKind;
use rustc_middle::middle;
use rustc_middle::mir::interpret::GlobalId;
use rustc_middle::query::Providers;
use rustc_middle::ty::{self, Const, Ty, TyCtxt};
use rustc_middle::ty::{Const, Ty, TyCtxt};
use rustc_span::{ErrorGuaranteed, Span};
use rustc_trait_selection::traits;

Expand Down Expand Up @@ -172,11 +171,8 @@ pub fn check_crate(tcx: TyCtxt<'_>) {
let def_kind = tcx.def_kind(item_def_id);
match def_kind {
DefKind::Static { .. } => tcx.ensure_ok().eval_static_initializer(item_def_id),
DefKind::Const if tcx.generics_of(item_def_id).is_empty() => {
let instance = ty::Instance::new(item_def_id.into(), ty::GenericArgs::empty());
let cid = GlobalId { instance, promoted: None };
let typing_env = ty::TypingEnv::fully_monomorphized();
tcx.ensure_ok().eval_to_const_value_raw(typing_env.as_query_input(cid));
DefKind::Const if !tcx.generics_of(item_def_id).requires_monomorphization(tcx) => {
tcx.ensure_ok().const_eval_poly(item_def_id.into())
}
_ => (),
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/mir/interpret/queries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ impl<'tcx> TyCtxtEnsureOk<'tcx> {
// into `const_eval` which will return `ErrorHandled::TooGeneric` if any of them are
// encountered.
let args = GenericArgs::identity_for_item(self.tcx, def_id);
let instance = ty::Instance::new(def_id, self.tcx.erase_regions(args));
let instance = ty::Instance::new(def_id, args);
let cid = GlobalId { instance, promoted: None };
let typing_env = ty::TypingEnv::post_analysis(self.tcx, def_id);
// Const-eval shouldn't depend on lifetimes at all, so we can erase them, which should
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/generic-const-items/def-site-eval.fail.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error[E0080]: evaluation of `_::<'_>` failed
--> $DIR/def-site-eval.rs:14:20
--> $DIR/def-site-eval.rs:13:20
|
LL | const _<'_a>: () = panic!();
| ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/def-site-eval.rs:14:20
| ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/def-site-eval.rs:13:20
|
= note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)

Expand Down
1 change: 0 additions & 1 deletion tests/ui/generic-const-items/def-site-eval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
#![allow(incomplete_features)]

//@ revisions: fail pass
//@[fail] build-fail (we require monomorphization)
//@[pass] build-pass (we require monomorphization)

const _<_T>: () = panic!();
Expand Down
9 changes: 9 additions & 0 deletions tests/ui/generic-const-items/def-site-predicates-wf.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
//! Ensure that we check the predicates for well-formedness at the definition site.
#![feature(generic_const_items)]
#![allow(incomplete_features)]

const _: () = ()
where
Vec<str>: Sized; //~ ERROR the size for values of type `str` cannot be known at compilation time

fn main() {}
13 changes: 13 additions & 0 deletions tests/ui/generic-const-items/def-site-predicates-wf.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
error[E0277]: the size for values of type `str` cannot be known at compilation time
--> $DIR/def-site-predicates-wf.rs:7:15
|
LL | Vec<str>: Sized;
| ^^^^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `str`
note: required by an implicit `Sized` bound in `Vec`
--> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0277`.
Loading