@@ -361,6 +361,7 @@ fn collect_items_rec<'a, 'tcx: 'a>(scx: &SharedCrateContext<'a, 'tcx>,
361361 recursion_depth_reset = Some ( check_recursion_limit ( scx. tcx ( ) ,
362362 instance,
363363 recursion_depths) ) ;
364+ check_type_length_limit ( scx. tcx ( ) , instance) ;
364365
365366 // Scan the MIR in order to find function calls, closures, and
366367 // drop-glue
@@ -432,6 +433,40 @@ fn check_recursion_limit<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
432433 ( instance. def , recursion_depth)
433434}
434435
436+ fn check_type_length_limit < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
437+ instance : Instance < ' tcx > )
438+ {
439+ let type_length = instance. substs . types ( ) . flat_map ( |ty| ty. walk ( ) ) . count ( ) ;
440+ debug ! ( " => type length={}" , type_length) ;
441+
442+ // Rust code can easily create exponentially-long types using only a
443+ // polynomial recursion depth. Even with the default recursion
444+ // depth, you can easily get cases that take >2^60 steps to run,
445+ // which means that rustc basically hangs.
446+ //
447+ // Bail out in these cases to avoid that bad user experience.
448+ let type_length_limit = tcx. sess . type_length_limit . get ( ) ;
449+ if type_length > type_length_limit {
450+ // The instance name is already known to be too long for rustc. Use
451+ // `{:.64}` to avoid blasting the user's terminal with thousands of
452+ // lines of type-name.
453+ let instance_name = instance. to_string ( ) ;
454+ let msg = format ! ( "reached the type-length limit while instantiating `{:.64}...`" ,
455+ instance_name) ;
456+ let mut diag = if let Some ( node_id) = tcx. map . as_local_node_id ( instance. def ) {
457+ tcx. sess . struct_span_fatal ( tcx. map . span ( node_id) , & msg)
458+ } else {
459+ tcx. sess . struct_fatal ( & msg)
460+ } ;
461+
462+ diag. note ( & format ! (
463+ "consider adding a `#![type_length_limit=\" {}\" ]` attribute to your crate" ,
464+ type_length_limit* 2 ) ) ;
465+ diag. emit ( ) ;
466+ tcx. sess . abort_if_errors ( ) ;
467+ }
468+ }
469+
435470struct MirNeighborCollector < ' a , ' tcx : ' a > {
436471 scx : & ' a SharedCrateContext < ' a , ' tcx > ,
437472 mir : & ' a mir:: Mir < ' tcx > ,
0 commit comments