diff --git a/src/librustc/ty/item_path.rs b/src/librustc/ty/item_path.rs index d9a8deb80e4..288894f235b 100644 --- a/src/librustc/ty/item_path.rs +++ b/src/librustc/ty/item_path.rs @@ -3,7 +3,7 @@ use crate::hir::map::DefPathData; use crate::hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE}; use crate::ty::{self, DefIdTree, Ty, TyCtxt}; use crate::ty::print::PrintCx; -use crate::ty::subst::{Subst, Substs}; +use crate::ty::subst::{Subst, SubstsRef}; use crate::middle::cstore::{ExternCrate, ExternCrateSource}; use syntax::ast; use syntax::symbol::{keywords, Symbol}; @@ -79,7 +79,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { pub fn item_path_str_with_substs_and_ns( self, def_id: DefId, - substs: Option<&Substs<'tcx>>, + substs: Option>, ns: Namespace, ) -> String { debug!("item_path_str: def_id={:?}, substs={:?}, ns={:?}", def_id, substs, ns); @@ -116,7 +116,7 @@ impl PrintCx<'a, 'gcx, 'tcx, P> { pub fn default_print_item_path( &mut self, def_id: DefId, - substs: Option<&Substs<'tcx>>, + substs: Option>, ns: Namespace, ) -> P::Path { debug!("default_print_item_path: def_id={:?}, substs={:?}, ns={:?}", def_id, substs, ns); @@ -169,7 +169,7 @@ impl PrintCx<'a, 'gcx, 'tcx, P> { fn default_print_impl_path( &mut self, impl_def_id: DefId, - substs: Option<&Substs<'tcx>>, + substs: Option>, ns: Namespace, ) -> P::Path { debug!("default_print_impl_path: impl_def_id={:?}", impl_def_id); @@ -314,7 +314,7 @@ pub trait ItemPathPrinter: Sized { fn print_item_path( self: &mut PrintCx<'_, '_, 'tcx, Self>, def_id: DefId, - substs: Option<&Substs<'tcx>>, + substs: Option>, ns: Namespace, ) -> Self::Path { self.default_print_item_path(def_id, substs, ns) @@ -322,7 +322,7 @@ pub trait ItemPathPrinter: Sized { fn print_impl_path( self: &mut PrintCx<'_, '_, 'tcx, Self>, impl_def_id: DefId, - substs: Option<&Substs<'tcx>>, + substs: Option>, ns: Namespace, ) -> Self::Path { self.default_print_impl_path(impl_def_id, substs, ns) @@ -506,7 +506,7 @@ impl ItemPathPrinter for LocalPathPrinter { fn print_item_path( self: &mut PrintCx<'_, '_, 'tcx, Self>, def_id: DefId, - substs: Option<&Substs<'tcx>>, + substs: Option>, ns: Namespace, ) -> Self::Path { self.try_print_visible_item_path(def_id, ns) @@ -515,7 +515,7 @@ impl ItemPathPrinter for LocalPathPrinter { fn print_impl_path( self: &mut PrintCx<'_, '_, 'tcx, Self>, impl_def_id: DefId, - substs: Option<&Substs<'tcx>>, + substs: Option>, ns: Namespace, ) -> Self::Path { // Always use types for non-local impls, where types are always diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index bfdf34f3e37..307cee5d972 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -198,6 +198,8 @@ use crate::monomorphize::item::{MonoItemExt, DefPathBasedNames, InstantiationMod use rustc_data_structures::bit_set::GrowableBitSet; use rustc_data_structures::sync::{MTRef, MTLock, ParallelIterator, par_iter}; +use std::iter; + #[derive(PartialEq, Eq, Hash, Clone, Copy, Debug)] pub enum MonoItemCollectionMode { Eager, @@ -487,21 +489,33 @@ fn check_type_length_limit<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // We include the const length in the type length, as it's better // to be overly conservative. if type_length + const_length > type_length_limit { - // The instance name is already known to be too long for rustc. Use - // `{:.64}` to avoid blasting the user's terminal with thousands of - // lines of type-name. - let instance_name = instance.to_string(); - let msg = format!("reached the type-length limit while instantiating `{:.64}...`", - instance_name); - let mut diag = if let Some(hir_id) = tcx.hir().as_local_hir_id(instance.def_id()) { - tcx.sess.struct_span_fatal(tcx.hir().span_by_hir_id(hir_id), &msg) - } else { - tcx.sess.struct_fatal(&msg) - }; + // The instance name is already known to be too long for rustc. + // Show only the first and last 32 characters to avoid blasting + // the user's terminal with thousands of lines of type-name. + let shrink = |s: String, before: usize, after: usize| { + // An iterator of all byte positions including the end of the string. + let positions = || s.char_indices().map(|(i, _)| i).chain(iter::once(s.len())); + let shrunk = format!( + "{before}...{after}", + before = &s[..positions().nth(before).unwrap_or(s.len())], + after = &s[positions().rev().nth(after).unwrap_or(0)..], + ); + + // Only use the shrunk version if it's really shorter. + // This also avoids the case where before and after slices overlap. + if shrunk.len() < s.len() { + shrunk + } else { + s + } + }; + let msg = format!("reached the type-length limit while instantiating `{}`", + shrink(instance.to_string(), 32, 32)); + let mut diag = tcx.sess.struct_span_fatal(tcx.def_span(instance.def_id()), &msg); diag.note(&format!( "consider adding a `#![type_length_limit=\"{}\"]` attribute to your crate", - type_length_limit * 2)); + type_length)); diag.emit(); tcx.sess.abort_if_errors(); } diff --git a/src/test/ui/issues/issue-22638.stderr b/src/test/ui/issues/issue-22638.stderr index aff968f3618..b60e1c29ec0 100644 --- a/src/test/ui/issues/issue-22638.stderr +++ b/src/test/ui/issues/issue-22638.stderr @@ -8,7 +8,7 @@ LL | | a.matches(f) LL | | } | |_____^ | - = note: consider adding a `#![type_length_limit="40000000"]` attribute to your crate + = note: consider adding a `#![type_length_limit="26214380"]` attribute to your crate error: aborting due to previous error diff --git a/src/test/ui/issues/issue-37311-type-length-limit/issue-37311.stderr b/src/test/ui/issues/issue-37311-type-length-limit/issue-37311.stderr index c5432190412..aead415d23f 100644 --- a/src/test/ui/issues/issue-37311-type-length-limit/issue-37311.stderr +++ b/src/test/ui/issues/issue-37311-type-length-limit/issue-37311.stderr @@ -1,4 +1,4 @@ -error: reached the type-length limit while instantiating `<(&(&(&(&(&(&(&(&(&(&(&(&(&(&(&(&(&(&(&(), &()), &(&(), &())), &...` +error: reached the type-length limit while instantiating `<(&(&(&(&(&(&(&(&(&(&(&(&(&(&(&(...))))))))))))))) as Foo>::recurse` --> $DIR/issue-37311.rs:13:5 | LL | / fn recurse(&self) { @@ -6,7 +6,7 @@ LL | | (self, self).recurse(); LL | | } | |_____^ | - = note: consider adding a `#![type_length_limit="2097152"]` attribute to your crate + = note: consider adding a `#![type_length_limit="2097149"]` attribute to your crate error: aborting due to previous error diff --git a/src/test/ui/type_length_limit.rs b/src/test/ui/type_length_limit.rs index bb54669d37d..cd15f81a615 100644 --- a/src/test/ui/type_length_limit.rs +++ b/src/test/ui/type_length_limit.rs @@ -1,3 +1,5 @@ +// ignore-musl +// ignore-x86 // error-pattern: reached the type-length limit while instantiating // Test that the type length limit can be changed. diff --git a/src/test/ui/type_length_limit.stderr b/src/test/ui/type_length_limit.stderr index 910eca07594..9d07c86356b 100644 --- a/src/test/ui/type_length_limit.stderr +++ b/src/test/ui/type_length_limit.stderr @@ -1,6 +1,10 @@ -error: reached the type-length limit while instantiating `std::mem::drop::>` + --> $SRC_DIR/libcore/mem.rs:LL:COL | - = note: consider adding a `#![type_length_limit="512"]` attribute to your crate +LL | pub fn drop(_x: T) { } + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: consider adding a `#![type_length_limit="1094"]` attribute to your crate error: aborting due to previous error