Skip to content

Commit 17d2e3b

Browse files
committed
Better handling for exponential-sized types in misc places
Mostly to fix ui/issues/issue-37311-type-length-limit/issue-37311.rs. Most parts of the compiler can handle deeply nested types with a lot of duplicates just fine, but some parts still attempt to naively traverse type tree. Before such problems were caught by type length limit check, but now these places will have to be changed to handle duplicated types gracefully.
1 parent 2f32961 commit 17d2e3b

File tree

12 files changed

+89
-41
lines changed

12 files changed

+89
-41
lines changed

compiler/rustc_infer/src/infer/combine.rs

+13-2
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ use super::unify_key::replace_if_possible;
3131
use super::unify_key::{ConstVarValue, ConstVariableValue};
3232
use super::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
3333
use super::{InferCtxt, MiscVariable, TypeTrace};
34+
use rustc_data_structures::fx::FxHashMap;
3435

3536
use crate::traits::{Obligation, PredicateObligations};
3637

@@ -379,6 +380,7 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
379380
needs_wf: false,
380381
root_ty: ty,
381382
param_env: self.param_env,
383+
cache: FxHashMap::default(),
382384
};
383385

384386
let ty = match generalize.relate(ty, ty) {
@@ -438,6 +440,8 @@ struct Generalizer<'cx, 'tcx> {
438440
root_ty: Ty<'tcx>,
439441

440442
param_env: ty::ParamEnv<'tcx>,
443+
444+
cache: FxHashMap<(Ty<'tcx>, Ty<'tcx>), RelateResult<'tcx, Ty<'tcx>>>,
441445
}
442446

443447
/// Result from a generalization operation. This includes
@@ -535,13 +539,17 @@ impl TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
535539
fn tys(&mut self, t: Ty<'tcx>, t2: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
536540
assert_eq!(t, t2); // we are abusing TypeRelation here; both LHS and RHS ought to be ==
537541

542+
let cache_key = (t, t2);
543+
if let Some(result) = self.cache.get(&cache_key) {
544+
return result.clone();
545+
}
538546
debug!("generalize: t={:?}", t);
539547

540548
// Check to see whether the type we are generalizing references
541549
// any other type variable related to `vid` via
542550
// subtyping. This is basically our "occurs check", preventing
543551
// us from creating infinitely sized types.
544-
match *t.kind() {
552+
let result = match *t.kind() {
545553
ty::Infer(ty::TyVar(vid)) => {
546554
let vid = self.infcx.inner.borrow_mut().type_variables().root_var(vid);
547555
let sub_vid = self.infcx.inner.borrow_mut().type_variables().sub_root_var(vid);
@@ -598,7 +606,10 @@ impl TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
598606
Ok(t)
599607
}
600608
_ => relate::super_relate_tys(self, t, t),
601-
}
609+
};
610+
611+
self.cache.insert(cache_key, result.clone());
612+
return result;
602613
}
603614

604615
fn regions(

compiler/rustc_middle/src/ty/print/mod.rs

+23-7
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use crate::ty::{self, DefIdTree, Ty, TyCtxt};
44
use rustc_data_structures::fx::FxHashSet;
55
use rustc_hir::def_id::{CrateNum, DefId};
66
use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData};
7+
use rustc_middle::ty::walk::MiniSet;
78

89
// `pretty` is a separate module only for organization.
910
mod pretty;
@@ -263,21 +264,33 @@ pub trait Printer<'tcx>: Sized {
263264
/// function tries to find a "characteristic `DefId`" for a
264265
/// type. It's just a heuristic so it makes some questionable
265266
/// decisions and we may want to adjust it later.
266-
pub fn characteristic_def_id_of_type(ty: Ty<'_>) -> Option<DefId> {
267+
///
268+
/// Visited set is needed in to avoid full iteration over
269+
/// deeply nested tuples that have no DefId.
270+
fn characteristic_def_id_of_type_cached<'a>(
271+
ty: Ty<'a>,
272+
visited: &mut MiniSet<Ty<'a>>,
273+
) -> Option<DefId> {
267274
match *ty.kind() {
268275
ty::Adt(adt_def, _) => Some(adt_def.did),
269276

270277
ty::Dynamic(data, ..) => data.principal_def_id(),
271278

272-
ty::Array(subty, _) | ty::Slice(subty) => characteristic_def_id_of_type(subty),
279+
ty::Array(subty, _) | ty::Slice(subty) => {
280+
characteristic_def_id_of_type_cached(subty, visited)
281+
}
273282

274-
ty::RawPtr(mt) => characteristic_def_id_of_type(mt.ty),
283+
ty::RawPtr(mt) => characteristic_def_id_of_type_cached(mt.ty, visited),
275284

276-
ty::Ref(_, ty, _) => characteristic_def_id_of_type(ty),
285+
ty::Ref(_, ty, _) => characteristic_def_id_of_type_cached(ty, visited),
277286

278-
ty::Tuple(ref tys) => {
279-
tys.iter().find_map(|ty| characteristic_def_id_of_type(ty.expect_ty()))
280-
}
287+
ty::Tuple(ref tys) => tys.iter().find_map(|ty| {
288+
let ty = ty.expect_ty();
289+
if visited.insert(ty) {
290+
return characteristic_def_id_of_type_cached(ty, visited);
291+
}
292+
return None;
293+
}),
281294

282295
ty::FnDef(def_id, _)
283296
| ty::Closure(def_id, _)
@@ -302,6 +315,9 @@ pub fn characteristic_def_id_of_type(ty: Ty<'_>) -> Option<DefId> {
302315
| ty::Float(_) => None,
303316
}
304317
}
318+
pub fn characteristic_def_id_of_type(ty: Ty<'_>) -> Option<DefId> {
319+
characteristic_def_id_of_type_cached(ty, &mut MiniSet::new())
320+
}
305321

306322
impl<'tcx, P: Printer<'tcx>> Print<'tcx, P> for ty::RegionKind {
307323
type Output = P::Region;

compiler/rustc_middle/src/ty/print/pretty.rs

+10-2
Original file line numberDiff line numberDiff line change
@@ -1264,6 +1264,7 @@ pub struct FmtPrinterData<'a, 'tcx, F> {
12641264
used_region_names: FxHashSet<Symbol>,
12651265
region_index: usize,
12661266
binder_depth: usize,
1267+
printed_type_count: usize,
12671268

12681269
pub region_highlight_mode: RegionHighlightMode,
12691270

@@ -1294,6 +1295,7 @@ impl<F> FmtPrinter<'a, 'tcx, F> {
12941295
used_region_names: Default::default(),
12951296
region_index: 0,
12961297
binder_depth: 0,
1298+
printed_type_count: 0,
12971299
region_highlight_mode: RegionHighlightMode::default(),
12981300
name_resolver: None,
12991301
}))
@@ -1411,8 +1413,14 @@ impl<F: fmt::Write> Printer<'tcx> for FmtPrinter<'_, 'tcx, F> {
14111413
self.pretty_print_region(region)
14121414
}
14131415

1414-
fn print_type(self, ty: Ty<'tcx>) -> Result<Self::Type, Self::Error> {
1415-
self.pretty_print_type(ty)
1416+
fn print_type(mut self, ty: Ty<'tcx>) -> Result<Self::Type, Self::Error> {
1417+
if self.tcx.sess.type_length_limit().value_within_limit(self.printed_type_count) {
1418+
self.printed_type_count += 1;
1419+
self.pretty_print_type(ty)
1420+
} else {
1421+
write!(self, "...")?;
1422+
Ok(self)
1423+
}
14161424
}
14171425

14181426
fn print_dyn_existential(

compiler/rustc_mir/src/monomorphize/collector.rs

+28-19
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,29 @@ fn record_accesses<'a, 'tcx: 'a>(
418418
inlining_map.lock_mut().record_accesses(caller, &accesses);
419419
}
420420

421+
// Shrinks string by keeping prefix and suffix of given sizes.
422+
fn shrink(s: String, before: usize, after: usize) -> String {
423+
// An iterator of all byte positions including the end of the string.
424+
let positions = || s.char_indices().map(|(i, _)| i).chain(iter::once(s.len()));
425+
426+
let shrunk = format!(
427+
"{before}...{after}",
428+
before = &s[..positions().nth(before).unwrap_or(s.len())],
429+
after = &s[positions().rev().nth(after).unwrap_or(0)..],
430+
);
431+
432+
// Only use the shrunk version if it's really shorter.
433+
// This also avoids the case where before and after slices overlap.
434+
if shrunk.len() < s.len() { shrunk } else { s }
435+
}
436+
437+
// Format instance name that is already known to be too long for rustc.
438+
// Show only the first and last 32 characters to avoid blasting
439+
// the user's terminal with thousands of lines of type-name.
440+
fn shrunk_instance_name(instance: &Instance<'tcx>) -> String {
441+
shrink(instance.to_string(), 32, 32)
442+
}
443+
421444
fn check_recursion_limit<'tcx>(
422445
tcx: TyCtxt<'tcx>,
423446
instance: Instance<'tcx>,
@@ -440,7 +463,10 @@ fn check_recursion_limit<'tcx>(
440463
// more than the recursion limit is assumed to be causing an
441464
// infinite expansion.
442465
if !tcx.sess.recursion_limit().value_within_limit(adjusted_recursion_depth) {
443-
let error = format!("reached the recursion limit while instantiating `{}`", instance);
466+
let error = format!(
467+
"reached the recursion limit while instantiating `{}`",
468+
shrunk_instance_name(&instance),
469+
);
444470
let mut err = tcx.sess.struct_span_fatal(span, &error);
445471
err.span_note(
446472
tcx.def_span(def_id),
@@ -474,26 +500,9 @@ fn check_type_length_limit<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) {
474500
//
475501
// Bail out in these cases to avoid that bad user experience.
476502
if !tcx.sess.type_length_limit().value_within_limit(type_length) {
477-
// The instance name is already known to be too long for rustc.
478-
// Show only the first and last 32 characters to avoid blasting
479-
// the user's terminal with thousands of lines of type-name.
480-
let shrink = |s: String, before: usize, after: usize| {
481-
// An iterator of all byte positions including the end of the string.
482-
let positions = || s.char_indices().map(|(i, _)| i).chain(iter::once(s.len()));
483-
484-
let shrunk = format!(
485-
"{before}...{after}",
486-
before = &s[..positions().nth(before).unwrap_or(s.len())],
487-
after = &s[positions().rev().nth(after).unwrap_or(0)..],
488-
);
489-
490-
// Only use the shrunk version if it's really shorter.
491-
// This also avoids the case where before and after slices overlap.
492-
if shrunk.len() < s.len() { shrunk } else { s }
493-
};
494503
let msg = format!(
495504
"reached the type-length limit while instantiating `{}`",
496-
shrink(instance.to_string(), 32, 32)
505+
shrunk_instance_name(&instance),
497506
);
498507
let mut diag = tcx.sess.struct_span_fatal(tcx.def_span(instance.def_id()), &msg);
499508
diag.note(&format!(

src/test/ui/infinite/infinite-instantiation.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error: reached the recursion limit while instantiating `function::<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<usize>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`
1+
error: reached the recursion limit while instantiating `function::<Option<Option<Option<...>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`
22
--> $DIR/infinite-instantiation.rs:21:9
33
|
44
LL | function(counter - 1, t.to_option());

src/test/ui/issues/issue-37311-type-length-limit/issue-37311.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ trait Foo {
1212

1313
impl<T> Foo for T {
1414
#[allow(unconditional_recursion)]
15-
fn recurse(&self) { //~ ERROR reached the type-length limit
16-
(self, self).recurse();
15+
fn recurse(&self) {
16+
(self, self).recurse(); //~ ERROR reached the recursion limit
1717
}
1818
}
1919

Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
1-
error: reached the type-length limit while instantiating `<(&(&(&(&(&(&(&(&(&(&(&(&(&(&(&(...))))))))))))))) as Foo>::recurse`
1+
error: reached the recursion limit while instantiating `<(&(&(&(&(&(&(&(&(&(&(&(&(&(&(&(.....), ...), ...) as Foo>::recurse`
2+
--> $DIR/issue-37311.rs:16:9
3+
|
4+
LL | (self, self).recurse();
5+
| ^^^^^^^^^^^^^^^^^^^^^^
6+
|
7+
note: `<T as Foo>::recurse` defined here
28
--> $DIR/issue-37311.rs:15:5
39
|
410
LL | fn recurse(&self) {
511
| ^^^^^^^^^^^^^^^^^
6-
|
7-
= note: consider adding a `#![type_length_limit="2097149"]` attribute to your crate
812

913
error: aborting due to previous error
1014

src/test/ui/issues/issue-67552.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error: reached the recursion limit while instantiating `rec::<&mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut Empty>`
1+
error: reached the recursion limit while instantiating `rec::<&mut &mut &mut &mut &mut &... &mut &mut &mut &mut &mut Empty>`
22
--> $DIR/issue-67552.rs:27:9
33
|
44
LL | rec(identity(&mut it))

src/test/ui/issues/issue-8727.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ LL | generic::<Option<T>>();
99
= note: `#[warn(unconditional_recursion)]` on by default
1010
= help: a `loop` may express intention better if this is on purpose
1111

12-
error: reached the recursion limit while instantiating `generic::<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<Option<i32>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`
12+
error: reached the recursion limit while instantiating `generic::<Option<Option<Option<O...>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`
1313
--> $DIR/issue-8727.rs:7:5
1414
|
1515
LL | generic::<Option<T>>();

src/test/ui/recursion/issue-38591-non-regular-dropck-recursion.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error: reached the recursion limit while instantiating `drop_in_place::<S<fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(u32))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))>> - shim(Some(S<fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(u32))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))>))`
1+
error: reached the recursion limit while instantiating `drop_in_place::<S<fn(fn(fn(fn(fn...)))))))))))))))))))))))))))))>))`
22
--> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
33
|
44
LL | / pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {

src/test/ui/recursion/recursion.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error: reached the recursion limit while instantiating `test::<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Cons<Nil>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`
1+
error: reached the recursion limit while instantiating `test::<Cons<Cons<Cons<Cons<Cons<...>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`
22
--> $DIR/recursion.rs:17:11
33
|
44
LL | _ => {test (n-1, i+1, Cons {head:2*i+1, tail:first}, Cons{head:i*i, tail:second})}

src/test/ui/type_length_limit.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error: reached the type-length limit while instantiating `std::mem::drop::<Option<((((((G,... G), (G, G, G), (G, G, G))))))>>`
1+
error: reached the type-length limit while instantiating `std::mem::drop::<Option<((((...,....., ...), ..., ...), ..., ...)>>`
22
--> $SRC_DIR/core/src/mem/mod.rs:LL:COL
33
|
44
LL | pub fn drop<T>(_x: T) {}

0 commit comments

Comments
 (0)