Skip to content

Commit

Permalink
Auto merge of rust-lang#125507 - compiler-errors:type-length-limit, r…
Browse files Browse the repository at this point in the history
…=lcnr

Re-implement a type-size based limit

r? lcnr

This PR reintroduces the type length limit added in rust-lang#37789, which was accidentally made practically useless by the caching changes to `Ty::walk` in rust-lang#72412, which caused the `walk` function to no longer walk over identical elements.

Hitting this length limit is not fatal unless we are in codegen -- so it shouldn't affect passes like the mir inliner which creates potentially very large types (which we observed, for example, when the new trait solver compiles `itertools` in `--release` mode).

This also increases the type length limit from `1048576 == 2 ** 20` to `2 ** 24`, which covers all of the code that can be reached with craterbot-check. Individual crates can increase the length limit further if desired.

Perf regression is mild and I think we should accept it -- reinstating this limit is important for the new trait solver and to make sure we don't accidentally hit more type-size related regressions in the future.

Fixes rust-lang#125460
  • Loading branch information
bors committed Jul 3, 2024
2 parents 2db4ff4 + b1059cc commit c872a14
Show file tree
Hide file tree
Showing 54 changed files with 358 additions and 266 deletions.
2 changes: 1 addition & 1 deletion compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3733,7 +3733,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
if tcx.is_diagnostic_item(sym::deref_method, method_did) {
let deref_target =
tcx.get_diagnostic_item(sym::deref_target).and_then(|deref_target| {
Instance::resolve(tcx, self.param_env, deref_target, method_args)
Instance::try_resolve(tcx, self.param_env, deref_target, method_args)
.transpose()
});
if let Some(Ok(instance)) = deref_target {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_borrowck/src/diagnostics/region_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -949,7 +949,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
return;
}

if let Ok(Some(instance)) = ty::Instance::resolve(
if let Ok(Some(instance)) = ty::Instance::try_resolve(
tcx,
self.param_env,
*fn_did,
Expand Down
11 changes: 8 additions & 3 deletions compiler/rustc_codegen_cranelift/src/abi/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -371,9 +371,14 @@ pub(crate) fn codegen_terminator_call<'tcx>(

// Handle special calls like intrinsics and empty drop glue.
let instance = if let ty::FnDef(def_id, fn_args) = *func.layout().ty.kind() {
let instance =
ty::Instance::expect_resolve(fx.tcx, ty::ParamEnv::reveal_all(), def_id, fn_args)
.polymorphize(fx.tcx);
let instance = ty::Instance::expect_resolve(
fx.tcx,
ty::ParamEnv::reveal_all(),
def_id,
fn_args,
source_info.span,
)
.polymorphize(fx.tcx);

if is_call_from_compiler_builtins_to_upstream_monomorphization(fx.tcx, instance) {
if target.is_some() {
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_codegen_cranelift/src/main_shim.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use rustc_middle::ty::AssocKind;
use rustc_middle::ty::GenericArg;
use rustc_session::config::{sigpipe, EntryFnType};
use rustc_span::symbol::Ident;
use rustc_span::DUMMY_SP;

use crate::prelude::*;

Expand Down Expand Up @@ -119,6 +120,7 @@ pub(crate) fn maybe_create_entry_wrapper(
ParamEnv::reveal_all(),
report.def_id,
tcx.mk_args(&[GenericArg::from(main_ret_ty)]),
DUMMY_SP,
)
.polymorphize(tcx);

Expand All @@ -144,6 +146,7 @@ pub(crate) fn maybe_create_entry_wrapper(
ParamEnv::reveal_all(),
start_def_id,
tcx.mk_args(&[main_ret_ty.into()]),
DUMMY_SP,
)
.polymorphize(tcx);
let start_func_id = import_function(tcx, m, start_instance);
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_codegen_gcc/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use rustc_middle::ty::layout::{
};
use rustc_middle::ty::{self, Instance, ParamEnv, PolyExistentialTraitRef, Ty, TyCtxt};
use rustc_session::Session;
use rustc_span::{source_map::respan, Span};
use rustc_span::{source_map::respan, Span, DUMMY_SP};
use rustc_target::abi::{
call::FnAbi, HasDataLayout, PointeeInfo, Size, TargetDataLayout, VariantIdx,
};
Expand Down Expand Up @@ -479,6 +479,7 @@ impl<'gcc, 'tcx> MiscMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
ty::ParamEnv::reveal_all(),
def_id,
ty::List::empty(),
DUMMY_SP,
);

let symbol_name = tcx.symbol_name(instance).name;
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_codegen_llvm/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ use rustc_session::config::{BranchProtection, CFGuard, CFProtection};
use rustc_session::config::{CrateType, DebugInfo, PAuthKey, PacRet};
use rustc_session::Session;
use rustc_span::source_map::Spanned;
use rustc_span::Span;
use rustc_span::{Span, DUMMY_SP};
use rustc_target::abi::{call::FnAbi, HasDataLayout, TargetDataLayout, VariantIdx};
use rustc_target::spec::{HasTargetSpec, RelocModel, Target, TlsModel};
use smallvec::SmallVec;
Expand Down Expand Up @@ -580,6 +580,7 @@ impl<'ll, 'tcx> MiscMethods<'tcx> for CodegenCx<'ll, 'tcx> {
ty::ParamEnv::reveal_all(),
def_id,
ty::List::empty(),
DUMMY_SP,
)),
_ => {
let name = name.unwrap_or("rust_eh_personality");
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_codegen_ssa/src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ use rustc_middle::ty::{self, Instance, Ty, TyCtxt};
use rustc_session::config::{self, CrateType, EntryFnType, OptLevel, OutputType};
use rustc_session::Session;
use rustc_span::symbol::sym;
use rustc_span::Symbol;
use rustc_span::{Symbol, DUMMY_SP};
use rustc_target::abi::FIRST_VARIANT;

use std::cmp;
Expand Down Expand Up @@ -467,6 +467,7 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
ty::ParamEnv::reveal_all(),
start_def_id,
cx.tcx().mk_args(&[main_ret_ty.into()]),
DUMMY_SP,
);
let start_fn = cx.get_fn_addr(start_instance);

Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_codegen_ssa/src/mir/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -842,6 +842,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
ty::ParamEnv::reveal_all(),
def_id,
args,
fn_span,
)
.polymorphize(bx.tcx()),
),
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_const_eval/src/check_consts/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -768,7 +768,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
is_trait = true;

if let Ok(Some(instance)) =
Instance::resolve(tcx, param_env, callee, fn_args)
Instance::try_resolve(tcx, param_env, callee, fn_args)
&& let InstanceKind::Item(def) = instance.def
{
// Resolve a trait method call to its concrete implementation, which may be in a
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_const_eval/src/const_eval/machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,7 @@ impl<'tcx> CompileTimeInterpCx<'tcx> {
ty::ParamEnv::reveal_all(),
const_def_id,
instance.args,
self.cur_span(),
);

return Ok(Some(new_instance));
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_const_eval/src/interpret/eval_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -618,7 +618,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
trace!("resolve: {:?}, {:#?}", def, args);
trace!("param_env: {:#?}", self.param_env);
trace!("args: {:#?}", args);
match ty::Instance::resolve(*self.tcx, self.param_env, def, args) {
match ty::Instance::try_resolve(*self.tcx, self.param_env, def, args) {
Ok(Some(instance)) => Ok(instance),
Ok(None) => throw_inval!(TooGeneric),

Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_const_eval/src/interpret/terminator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -883,13 +883,13 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
ty::ExistentialTraitRef::erase_self_ty(tcx, virtual_trait_ref);
let concrete_trait_ref = existential_trait_ref.with_self_ty(tcx, dyn_ty);

let concrete_method = Instance::resolve_for_vtable(
let concrete_method = Instance::expect_resolve_for_vtable(
tcx,
self.param_env,
def_id,
instance.args.rebase_onto(tcx, trait_def_id, concrete_trait_ref.args),
)
.unwrap();
self.cur_span(),
);
assert_eq!(fn_inst, concrete_method);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -534,7 +534,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
let tcx = self.tcx();

// Find the method being called.
let Ok(Some(instance)) = ty::Instance::resolve(
let Ok(Some(instance)) = ty::Instance::try_resolve(
tcx,
ctxt.param_env,
ctxt.assoc_item.def_id,
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_lint/src/internal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ declare_lint_pass!(QueryStability => [POTENTIAL_QUERY_INSTABILITY]);
impl LateLintPass<'_> for QueryStability {
fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
let Some((span, def_id, args)) = typeck_results_of_method_fn(cx, expr) else { return };
if let Ok(Some(instance)) = ty::Instance::resolve(cx.tcx, cx.param_env, def_id, args) {
if let Ok(Some(instance)) = ty::Instance::try_resolve(cx.tcx, cx.param_env, def_id, args) {
let def_id = instance.def_id();
if cx.tcx.has_attr(def_id, sym::rustc_lint_query_instability) {
cx.emit_span_lint(
Expand Down Expand Up @@ -393,7 +393,7 @@ impl LateLintPass<'_> for Diagnostics {
};

// Is the callee marked with `#[rustc_lint_diagnostics]`?
let has_attr = ty::Instance::resolve(cx.tcx, cx.param_env, def_id, fn_gen_args)
let has_attr = ty::Instance::try_resolve(cx.tcx, cx.param_env, def_id, fn_gen_args)
.ok()
.flatten()
.is_some_and(|inst| cx.tcx.has_attr(inst.def_id(), sym::rustc_lint_diagnostics));
Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_lint/src/noop_method_call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,9 @@ impl<'tcx> LateLintPass<'tcx> for NoopMethodCall {
.tcx
.normalize_erasing_regions(cx.param_env, cx.typeck_results().node_args(expr.hir_id));
// Resolve the trait method instance.
let Ok(Some(i)) = ty::Instance::resolve(cx.tcx, cx.param_env, did, args) else { return };
let Ok(Some(i)) = ty::Instance::try_resolve(cx.tcx, cx.param_env, did, args) else {
return;
};
// (Re)check that it implements the noop diagnostic.
let Some(name) = cx.tcx.get_diagnostic_name(i.def_id()) else { return };
if !matches!(
Expand Down
6 changes: 6 additions & 0 deletions compiler/rustc_middle/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ middle_cannot_be_normalized =
middle_conflict_types =
this expression supplies two conflicting concrete types for the same opaque type
middle_consider_type_length_limit =
consider adding a `#![type_length_limit="{$type_length}"]` attribute to your crate
middle_const_eval_non_int =
constant evaluation of enum discriminant resulted in non-integer
Expand Down Expand Up @@ -94,8 +97,11 @@ middle_strict_coherence_needs_negative_coherence =
to use `strict_coherence` on this trait, the `with_negative_coherence` feature must be enabled
.label = due to this attribute
middle_type_length_limit = reached the type-length limit while instantiating `{$shrunk}`
middle_unknown_layout =
the type `{$ty}` has an unknown layout
middle_values_too_big =
values of the type `{$ty}` are too big for the current architecture
middle_written_to_path = the full type name has been written to '{$path}'
14 changes: 14 additions & 0 deletions compiler/rustc_middle/src/error.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::fmt;
use std::path::PathBuf;

use rustc_errors::{codes::*, DiagArgName, DiagArgValue, DiagMessage};
use rustc_macros::{Diagnostic, Subdiagnostic};
Expand Down Expand Up @@ -149,3 +150,16 @@ pub struct ErroneousConstant {

/// Used by `rustc_const_eval`
pub use crate::fluent_generated::middle_adjust_for_foreign_abi_error;

#[derive(Diagnostic)]
#[diag(middle_type_length_limit)]
#[help(middle_consider_type_length_limit)]
pub struct TypeLengthLimit {
#[primary_span]
pub span: Span,
pub shrunk: String,
#[note(middle_written_to_path)]
pub was_written: Option<()>,
pub path: PathBuf,
pub type_length: usize,
}
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/middle/limits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ pub fn provide(providers: &mut Providers) {
tcx.hir().krate_attrs(),
tcx.sess,
sym::type_length_limit,
1048576,
2usize.pow(24),
),
}
}
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_middle/src/mir/interpret/queries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ impl<'tcx> TyCtxt<'tcx> {
bug!("did not expect inference variables here");
}

match ty::Instance::resolve(
match ty::Instance::try_resolve(
self, param_env,
// FIXME: maybe have a separate version for resolving mir::UnevaluatedConst?
ct.def, ct.args,
Expand Down Expand Up @@ -106,7 +106,7 @@ impl<'tcx> TyCtxt<'tcx> {
bug!("did not expect inference variables here");
}

match ty::Instance::resolve(self, param_env, ct.def, ct.args) {
match ty::Instance::try_resolve(self, param_env, ct.def, ct.args) {
Ok(Some(instance)) => {
let cid = GlobalId { instance, promoted: None };
self.const_eval_global_id_for_typeck(param_env, cid, span).inspect(|_| {
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_middle/src/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2197,8 +2197,8 @@ rustc_queries! {
/// * `Err(ErrorGuaranteed)` when the `Instance` resolution process
/// couldn't complete due to errors elsewhere - this is distinct
/// from `Ok(None)` to avoid misleading diagnostics when an error
/// has already been/will be emitted, for the original cause
query resolve_instance(
/// has already been/will be emitted, for the original cause.
query resolve_instance_raw(
key: ty::ParamEnvAnd<'tcx, (DefId, GenericArgsRef<'tcx>)>
) -> Result<Option<ty::Instance<'tcx>>, ErrorGuaranteed> {
desc { "resolving instance `{}`", ty::Instance::new(key.value.0, key.value.1) }
Expand Down
Loading

0 comments on commit c872a14

Please sign in to comment.