diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 214973e308586..0eb2c19fe44dd 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -20,6 +20,7 @@ use ty::{TyParam, TyRawPtr, TyRef, TyNever, TyTuple}; use ty::{TyClosure, TyGenerator, TyProjection, TyAnon}; use ty::{TyDynamic, TyInt, TyUint, TyInfer}; use ty::{self, Ty, TyCtxt, TypeFoldable}; +use util::nodemap::FxHashSet; use std::cell::Cell; use std::fmt; @@ -32,310 +33,543 @@ use syntax::ast::CRATE_NODE_ID; use syntax::symbol::Symbol; use hir; -pub fn verbose() -> bool { - ty::tls::with(|tcx| tcx.sess.verbose()) +macro_rules! gen_display_debug_body { + ( $with:path ) => { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let mut cx = PrintContext::new(); + $with(self, f, &mut cx) + } + }; } - -pub fn identify_regions() -> bool { - ty::tls::with(|tcx| tcx.sess.opts.debugging_opts.identify_regions) +macro_rules! gen_display_debug { + ( ($($x:tt)+) $target:ty, display yes ) => { + impl<$($x)+> fmt::Display for $target { + gen_display_debug_body! { Print::print_display } + } + }; + ( () $target:ty, display yes ) => { + impl fmt::Display for $target { + gen_display_debug_body! { Print::print_display } + } + }; + ( ($($x:tt)+) $target:ty, debug yes ) => { + impl<$($x)+> fmt::Debug for $target { + gen_display_debug_body! { Print::print_debug } + } + }; + ( () $target:ty, debug yes ) => { + impl fmt::Debug for $target { + gen_display_debug_body! { Print::print_debug } + } + }; + ( $generic:tt $target:ty, $t:ident no ) => {}; } - -fn fn_sig(f: &mut fmt::Formatter, - inputs: &[Ty], - variadic: bool, - output: Ty) - -> fmt::Result { - write!(f, "(")?; - let mut inputs = inputs.iter(); - if let Some(&ty) = inputs.next() { - write!(f, "{}", ty)?; - for &ty in inputs { - write!(f, ", {}", ty)?; +macro_rules! gen_print_impl { + ( ($($x:tt)+) $target:ty, ($self:ident, $f:ident, $cx:ident) $disp:block $dbg:block ) => { + impl<$($x)+> Print for $target { + fn print(&$self, $f: &mut F, $cx: &mut PrintContext) -> fmt::Result { + if $cx.is_debug $dbg + else $disp + } } - if variadic { - write!(f, ", ...")?; + }; + ( () $target:ty, ($self:ident, $f:ident, $cx:ident) $disp:block $dbg:block ) => { + impl Print for $target { + fn print(&$self, $f: &mut F, $cx: &mut PrintContext) -> fmt::Result { + if $cx.is_debug $dbg + else $disp + } } + }; + ( $generic:tt $target:ty, + $vars:tt $gendisp:ident $disp:block $gendbg:ident $dbg:block ) => { + gen_print_impl! { $generic $target, $vars $disp $dbg } + gen_display_debug! { $generic $target, display $gendisp } + gen_display_debug! { $generic $target, debug $gendbg } } - write!(f, ")")?; - if !output.is_nil() { - write!(f, " -> {}", output)?; +} +macro_rules! define_print { + ( $generic:tt $target:ty, + $vars:tt { display $disp:block debug $dbg:block } ) => { + gen_print_impl! { $generic $target, $vars yes $disp yes $dbg } + }; + ( $generic:tt $target:ty, + $vars:tt { debug $dbg:block display $disp:block } ) => { + gen_print_impl! { $generic $target, $vars yes $disp yes $dbg } + }; + ( $generic:tt $target:ty, + $vars:tt { debug $dbg:block } ) => { + gen_print_impl! { $generic $target, $vars no { + bug!(concat!("display not implemented for ", stringify!($target))); + } yes $dbg } + }; + ( $generic:tt $target:ty, + ($self:ident, $f:ident, $cx:ident) { display $disp:block } ) => { + gen_print_impl! { $generic $target, ($self, $f, $cx) yes $disp no { + write!($f, "{:?}", $self) + } } + }; +} +macro_rules! define_print_multi { + ( [ $($generic:tt $target:ty),* ] $vars:tt $def:tt ) => { + $(define_print! { $generic $target, $vars $def })* + }; +} +macro_rules! print_inner { + ( $f:expr, $cx:expr, write ($($data:expr),+) ) => { + write!($f, $($data),+) + }; + ( $f:expr, $cx:expr, $kind:ident ($data:expr) ) => { + $data.$kind($f, $cx) + }; +} +macro_rules! print { + ( $f:expr, $cx:expr $(, $kind:ident $data:tt)+ ) => { + Ok(())$(.and_then(|_| print_inner!($f, $cx, $kind $data)))+ + }; +} + + +struct LateBoundRegionNameCollector(FxHashSet); +impl<'tcx> ty::fold::TypeVisitor<'tcx> for LateBoundRegionNameCollector { + fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool { + match *r { + ty::ReLateBound(_, ty::BrNamed(_, name)) => { + self.0.insert(name); + }, + _ => {}, + } + r.super_visit_with(self) } +} - Ok(()) +#[derive(Debug)] +pub struct PrintContext { + is_debug: bool, + is_verbose: bool, + identify_regions: bool, + used_region_names: Option>, + region_index: usize, + binder_depth: usize, +} +impl PrintContext { + fn new() -> Self { + ty::tls::with_opt(|tcx| { + let (is_verbose, identify_regions) = tcx.map( + |tcx| (tcx.sess.verbose(), tcx.sess.opts.debugging_opts.identify_regions) + ).unwrap_or((false, false)); + PrintContext { + is_debug: false, + is_verbose: is_verbose, + identify_regions: identify_regions, + used_region_names: None, + region_index: 0, + binder_depth: 0, + } + }) + } + fn prepare_late_bound_region_info<'tcx, T>(&mut self, value: &ty::Binder) + where T: TypeFoldable<'tcx> + { + let mut collector = LateBoundRegionNameCollector(FxHashSet()); + value.visit_with(&mut collector); + self.used_region_names = Some(collector.0); + self.region_index = 0; + } } -pub fn parameterized(f: &mut fmt::Formatter, - substs: &subst::Substs, - mut did: DefId, - projections: &[ty::ProjectionPredicate]) - -> fmt::Result { - let key = ty::tls::with(|tcx| tcx.def_key(did)); - let mut item_name = if let Some(name) = key.disambiguated_data.data.get_opt_name() { - Some(name) - } else { - did.index = key.parent.unwrap_or_else( - || bug!("finding type for {:?}, encountered def-id {:?} with no parent", - did, did)); - parameterized(f, substs, did, projections)?; - return write!(f, "::{}", key.disambiguated_data.data.as_interned_str()); - }; +pub trait Print { + fn print(&self, f: &mut F, cx: &mut PrintContext) -> fmt::Result; + fn print_to_string(&self, cx: &mut PrintContext) -> String { + let mut result = String::new(); + let _ = self.print(&mut result, cx); + result + } + fn print_display(&self, f: &mut F, cx: &mut PrintContext) -> fmt::Result { + let old_debug = cx.is_debug; + cx.is_debug = false; + let result = self.print(f, cx); + cx.is_debug = old_debug; + result + } + fn print_display_to_string(&self, cx: &mut PrintContext) -> String { + let mut result = String::new(); + let _ = self.print_display(&mut result, cx); + result + } + fn print_debug(&self, f: &mut F, cx: &mut PrintContext) -> fmt::Result { + let old_debug = cx.is_debug; + cx.is_debug = true; + let result = self.print(f, cx); + cx.is_debug = old_debug; + result + } + fn print_debug_to_string(&self, cx: &mut PrintContext) -> String { + let mut result = String::new(); + let _ = self.print_debug(&mut result, cx); + result + } +} - let mut verbose = false; - let mut num_supplied_defaults = 0; - let mut has_self = false; - let mut num_regions = 0; - let mut num_types = 0; - let mut is_value_path = false; - let fn_trait_kind = ty::tls::with(|tcx| { - // Unfortunately, some kinds of items (e.g., closures) don't have - // generics. So walk back up the find the closest parent that DOES - // have them. - let mut item_def_id = did; - loop { - let key = tcx.def_key(item_def_id); - match key.disambiguated_data.data { - DefPathData::TypeNs(_) => { - break; - } - DefPathData::ValueNs(_) | DefPathData::EnumVariant(_) => { - is_value_path = true; - break; - } - _ => { - // if we're making a symbol for something, there ought - // to be a value or type-def or something in there - // *somewhere* - item_def_id.index = key.parent.unwrap_or_else(|| { - bug!("finding type for {:?}, encountered def-id {:?} with no \ - parent", did, item_def_id); - }); - } +impl PrintContext { + fn fn_sig(&mut self, + f: &mut F, + inputs: &[Ty], + variadic: bool, + output: Ty) + -> fmt::Result { + write!(f, "(")?; + let mut inputs = inputs.iter(); + if let Some(&ty) = inputs.next() { + print!(f, self, print_display(ty))?; + for &ty in inputs { + print!(f, self, write(", "), print_display(ty))?; + } + if variadic { + write!(f, ", ...")?; } } - let mut generics = tcx.generics_of(item_def_id); - let mut path_def_id = did; - verbose = tcx.sess.verbose(); - has_self = generics.has_self; - - let mut child_types = 0; - if let Some(def_id) = generics.parent { - // Methods. - assert!(is_value_path); - child_types = generics.types.len(); - generics = tcx.generics_of(def_id); - num_regions = generics.regions.len(); - num_types = generics.types.len(); + write!(f, ")")?; + if !output.is_nil() { + print!(f, self, write(" -> "), print_display(output))?; + } - if has_self { - write!(f, "<{} as ", substs.type_at(0))?; - } + Ok(()) + } - path_def_id = def_id; + fn parameterized(&mut self, + f: &mut F, + substs: &subst::Substs, + mut did: DefId, + projections: &[ty::ProjectionPredicate]) + -> fmt::Result { + let key = ty::tls::with(|tcx| tcx.def_key(did)); + let mut item_name = if let Some(name) = key.disambiguated_data.data.get_opt_name() { + Some(name) } else { - item_name = None; + did.index = key.parent.unwrap_or_else( + || bug!("finding type for {:?}, encountered def-id {:?} with no parent", + did, did)); + self.parameterized(f, substs, did, projections)?; + return write!(f, "::{}", key.disambiguated_data.data.as_interned_str()); + }; - if is_value_path { - // Functions. - assert_eq!(has_self, false); - } else { - // Types and traits. + let verbose = self.is_verbose; + let mut num_supplied_defaults = 0; + let mut has_self = false; + let mut num_regions = 0; + let mut num_types = 0; + let mut is_value_path = false; + let fn_trait_kind = ty::tls::with(|tcx| { + // Unfortunately, some kinds of items (e.g., closures) don't have + // generics. So walk back up the find the closest parent that DOES + // have them. + let mut item_def_id = did; + loop { + let key = tcx.def_key(item_def_id); + match key.disambiguated_data.data { + DefPathData::TypeNs(_) => { + break; + } + DefPathData::ValueNs(_) | DefPathData::EnumVariant(_) => { + is_value_path = true; + break; + } + _ => { + // if we're making a symbol for something, there ought + // to be a value or type-def or something in there + // *somewhere* + item_def_id.index = key.parent.unwrap_or_else(|| { + bug!("finding type for {:?}, encountered def-id {:?} with no \ + parent", did, item_def_id); + }); + } + } + } + let mut generics = tcx.generics_of(item_def_id); + let mut path_def_id = did; + has_self = generics.has_self; + + let mut child_types = 0; + if let Some(def_id) = generics.parent { + // Methods. + assert!(is_value_path); + child_types = generics.types.len(); + generics = tcx.generics_of(def_id); num_regions = generics.regions.len(); num_types = generics.types.len(); + + if has_self { + print!(f, self, write("<"), print_display(substs.type_at(0)), write(" as "))?; + } + + path_def_id = def_id; + } else { + item_name = None; + + if is_value_path { + // Functions. + assert_eq!(has_self, false); + } else { + // Types and traits. + num_regions = generics.regions.len(); + num_types = generics.types.len(); + } } - } - if !verbose { - if generics.types.last().map_or(false, |def| def.has_default) { - if let Some(substs) = tcx.lift(&substs) { - let tps = substs.types().rev().skip(child_types); - for (def, actual) in generics.types.iter().rev().zip(tps) { - if !def.has_default { - break; - } - if tcx.type_of(def.def_id).subst(tcx, substs) != actual { - break; + if !verbose { + if generics.types.last().map_or(false, |def| def.has_default) { + if let Some(substs) = tcx.lift(&substs) { + let tps = substs.types().rev().skip(child_types); + for (def, actual) in generics.types.iter().rev().zip(tps) { + if !def.has_default { + break; + } + if tcx.type_of(def.def_id).subst(tcx, substs) != actual { + break; + } + num_supplied_defaults += 1; } - num_supplied_defaults += 1; } } } - } - write!(f, "{}", tcx.item_path_str(path_def_id))?; - Ok(tcx.lang_items().fn_trait_kind(path_def_id)) - })?; + print!(f, self, write("{}", tcx.item_path_str(path_def_id)))?; + Ok(tcx.lang_items().fn_trait_kind(path_def_id)) + })?; - if !verbose && fn_trait_kind.is_some() && projections.len() == 1 { - let projection_ty = projections[0].ty; - if let TyTuple(ref args, _) = substs.type_at(1).sty { - return fn_sig(f, args, false, projection_ty); + if !verbose && fn_trait_kind.is_some() && projections.len() == 1 { + let projection_ty = projections[0].ty; + if let TyTuple(ref args, _) = substs.type_at(1).sty { + return self.fn_sig(f, args, false, projection_ty); + } } - } - let empty = Cell::new(true); - let start_or_continue = |f: &mut fmt::Formatter, start: &str, cont: &str| { - if empty.get() { - empty.set(false); - write!(f, "{}", start) - } else { - write!(f, "{}", cont) - } - }; + let empty = Cell::new(true); + let start_or_continue = |f: &mut F, start: &str, cont: &str| { + if empty.get() { + empty.set(false); + write!(f, "{}", start) + } else { + write!(f, "{}", cont) + } + }; - let print_regions = |f: &mut fmt::Formatter, start: &str, skip, count| { - // Don't print any regions if they're all erased. - let regions = || substs.regions().skip(skip).take(count); - if regions().all(|r: ty::Region| *r == ty::ReErased) { - return Ok(()); - } + let print_regions = |f: &mut F, start: &str, skip, count| { + // Don't print any regions if they're all erased. + let regions = || substs.regions().skip(skip).take(count); + if regions().all(|r: ty::Region| *r == ty::ReErased) { + return Ok(()); + } - for region in regions() { - let region: ty::Region = region; - start_or_continue(f, start, ", ")?; - if verbose { - write!(f, "{:?}", region)?; - } else { - let s = region.to_string(); - if s.is_empty() { - // This happens when the value of the region - // parameter is not easily serialized. This may be - // because the user omitted it in the first place, - // or because it refers to some block in the code, - // etc. I'm not sure how best to serialize this. - write!(f, "'_")?; + for region in regions() { + let region: ty::Region = region; + start_or_continue(f, start, ", ")?; + if verbose { + write!(f, "{:?}", region)?; } else { - write!(f, "{}", s)?; + let s = region.to_string(); + if s.is_empty() { + // This happens when the value of the region + // parameter is not easily serialized. This may be + // because the user omitted it in the first place, + // or because it refers to some block in the code, + // etc. I'm not sure how best to serialize this. + write!(f, "'_")?; + } else { + write!(f, "{}", s)?; + } } } + + Ok(()) + }; + + print_regions(f, "<", 0, num_regions)?; + + let tps = substs.types().take(num_types - num_supplied_defaults) + .skip(has_self as usize); + + for ty in tps { + start_or_continue(f, "<", ", ")?; + ty.print_display(f, self)?; } - Ok(()) - }; + for projection in projections { + start_or_continue(f, "<", ", ")?; + ty::tls::with(|tcx| + print!(f, self, + write("{}=", + tcx.associated_item(projection.projection_ty.item_def_id).name), + print_display(projection.ty)) + )?; + } - print_regions(f, "<", 0, num_regions)?; + start_or_continue(f, "", ">")?; - let tps = substs.types().take(num_types - num_supplied_defaults) - .skip(has_self as usize); + // For values, also print their name and type parameters. + if is_value_path { + empty.set(true); - for ty in tps { - start_or_continue(f, "<", ", ")?; - write!(f, "{}", ty)?; - } + if has_self { + write!(f, ">")?; + } - for projection in projections { - start_or_continue(f, "<", ", ")?; - ty::tls::with(|tcx| - write!(f, "{}={}", - tcx.associated_item(projection.projection_ty.item_def_id).name, - projection.ty) - )?; - } + if let Some(item_name) = item_name { + write!(f, "::{}", item_name)?; + } - start_or_continue(f, "", ">")?; + print_regions(f, "::<", num_regions, usize::MAX)?; - // For values, also print their name and type parameters. - if is_value_path { - empty.set(true); + // FIXME: consider being smart with defaults here too + for ty in substs.types().skip(num_types) { + start_or_continue(f, "::<", ", ")?; + ty.print_display(f, self)?; + } - if has_self { - write!(f, ">")?; + start_or_continue(f, "", ">")?; } - if let Some(item_name) = item_name { - write!(f, "::{}", item_name)?; + Ok(()) + } + + fn in_binder<'a, 'gcx, 'tcx, T, U, F>(&mut self, + f: &mut F, + tcx: TyCtxt<'a, 'gcx, 'tcx>, + original: &ty::Binder, + lifted: Option>) -> fmt::Result + where T: Print, U: Print + TypeFoldable<'tcx>, F: fmt::Write + { + fn name_by_region_index(index: usize) -> Symbol { + match index { + 0 => Symbol::intern("'r"), + 1 => Symbol::intern("'s"), + i => Symbol::intern(&format!("'t{}", i-2)), + } } - print_regions(f, "::<", num_regions, usize::MAX)?; + // Replace any anonymous late-bound regions with named + // variants, using gensym'd identifiers, so that we can + // clearly differentiate between named and unnamed regions in + // the output. We'll probably want to tweak this over time to + // decide just how much information to give. + let value = if let Some(v) = lifted { + v + } else { + return original.0.print_display(f, self); + }; - // FIXME: consider being smart with defaults here too - for ty in substs.types().skip(num_types) { - start_or_continue(f, "::<", ", ")?; - write!(f, "{}", ty)?; + if self.binder_depth == 0 { + self.prepare_late_bound_region_info(&value); } - start_or_continue(f, "", ">")?; + let mut empty = true; + let mut start_or_continue = |f: &mut F, start: &str, cont: &str| { + if empty { + empty = false; + write!(f, "{}", start) + } else { + write!(f, "{}", cont) + } + }; + + let old_region_index = self.region_index; + let mut region_index = old_region_index; + let new_value = tcx.replace_late_bound_regions(&value, |br| { + let _ = start_or_continue(f, "for<", ", "); + let br = match br { + ty::BrNamed(_, name) => { + let _ = write!(f, "{}", name); + br + } + ty::BrAnon(_) | + ty::BrFresh(_) | + ty::BrEnv => { + let name = loop { + let name = name_by_region_index(region_index); + region_index += 1; + if !self.is_name_used(&name) { + break name; + } + }; + let _ = write!(f, "{}", name); + ty::BrNamed(tcx.hir.local_def_id(CRATE_NODE_ID), + name) + } + }; + tcx.mk_region(ty::ReLateBound(ty::DebruijnIndex::new(1), br)) + }).0; + start_or_continue(f, "", "> ")?; + + // Push current state to gcx, and restore after writing new_value. + self.binder_depth += 1; + self.region_index = region_index; + let result = new_value.print_display(f, self); + self.region_index = old_region_index; + self.binder_depth -= 1; + result } - Ok(()) + fn is_name_used(&self, name: &Symbol) -> bool { + match self.used_region_names { + Some(ref names) => names.contains(name), + None => false, + } + } } -fn in_binder<'a, 'gcx, 'tcx, T, U>(f: &mut fmt::Formatter, - tcx: TyCtxt<'a, 'gcx, 'tcx>, - original: &ty::Binder, - lifted: Option>) -> fmt::Result - where T: fmt::Display, U: fmt::Display + TypeFoldable<'tcx> -{ - // Replace any anonymous late-bound regions with named - // variants, using gensym'd identifiers, so that we can - // clearly differentiate between named and unnamed regions in - // the output. We'll probably want to tweak this over time to - // decide just how much information to give. - let value = if let Some(v) = lifted { - v - } else { - return write!(f, "{}", original.0); - }; +pub fn verbose() -> bool { + ty::tls::with(|tcx| tcx.sess.verbose()) +} - let mut empty = true; - let mut start_or_continue = |f: &mut fmt::Formatter, start: &str, cont: &str| { - if empty { - empty = false; - write!(f, "{}", start) - } else { - write!(f, "{}", cont) - } - }; +pub fn identify_regions() -> bool { + ty::tls::with(|tcx| tcx.sess.opts.debugging_opts.identify_regions) +} - let new_value = tcx.replace_late_bound_regions(&value, |br| { - let _ = start_or_continue(f, "for<", ", "); - let br = match br { - ty::BrNamed(_, name) => { - let _ = write!(f, "{}", name); - br - } - ty::BrAnon(_) | - ty::BrFresh(_) | - ty::BrEnv => { - let name = Symbol::intern("'r"); - let _ = write!(f, "{}", name); - ty::BrNamed(tcx.hir.local_def_id(CRATE_NODE_ID), - name) - } - }; - tcx.mk_region(ty::ReLateBound(ty::DebruijnIndex::new(1), br)) - }).0; +pub fn parameterized(f: &mut F, + substs: &subst::Substs, + did: DefId, + projections: &[ty::ProjectionPredicate]) + -> fmt::Result { + PrintContext::new().parameterized(f, substs, did, projections) +} - start_or_continue(f, "", "> ")?; - write!(f, "{}", new_value) + +impl<'a, T: Print> Print for &'a T { + fn print(&self, f: &mut F, cx: &mut PrintContext) -> fmt::Result { + (*self).print(f, cx) + } } -impl<'tcx> fmt::Display for &'tcx ty::Slice> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - // Generate the main trait ref, including associated types. - ty::tls::with(|tcx| { - // Use a type that can't appear in defaults of type parameters. - let dummy_self = tcx.mk_infer(ty::FreshTy(0)); - - if let Some(p) = self.principal() { - let principal = tcx.lift(&p).expect("could not lift TraitRef for printing") - .with_self_ty(tcx, dummy_self); - let projections = self.projection_bounds().map(|p| { - tcx.lift(&p) - .expect("could not lift projection for printing") - .with_self_ty(tcx, dummy_self) - }).collect::>(); - parameterized(f, principal.substs, principal.def_id, &projections)?; - } +define_print! { + ('tcx) &'tcx ty::Slice>, (self, f, cx) { + display { + // Generate the main trait ref, including associated types. + ty::tls::with(|tcx| { + // Use a type that can't appear in defaults of type parameters. + let dummy_self = tcx.mk_infer(ty::FreshTy(0)); + + if let Some(p) = self.principal() { + let principal = tcx.lift(&p).expect("could not lift TraitRef for printing") + .with_self_ty(tcx, dummy_self); + let projections = self.projection_bounds().map(|p| { + tcx.lift(&p) + .expect("could not lift projection for printing") + .with_self_ty(tcx, dummy_self) + }).collect::>(); + cx.parameterized(f, principal.substs, principal.def_id, &projections)?; + } - // Builtin bounds. - for did in self.auto_traits() { - write!(f, " + {}", tcx.item_path_str(did))?; - } + // Builtin bounds. + for did in self.auto_traits() { + write!(f, " + {}", tcx.item_path_str(did))?; + } - Ok(()) - })?; + Ok(()) + })?; - Ok(()) + Ok(()) + } } } @@ -357,42 +591,6 @@ impl fmt::Debug for ty::RegionParameterDef { } } -impl<'tcx> fmt::Debug for ty::TyS<'tcx> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", *self) - } -} - -impl<'tcx> fmt::Display for ty::TypeAndMut<'tcx> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}{}", - if self.mutbl == hir::MutMutable { "mut " } else { "" }, - self.ty) - } -} - -impl<'tcx> fmt::Debug for ty::TraitRef<'tcx> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - // when printing out the debug representation, we don't need - // to enumerate the `for<...>` etc because the debruijn index - // tells you everything you need to know. - write!(f, "<{:?} as {}>", self.self_ty(), *self) - } -} - -impl<'tcx> fmt::Debug for ty::ExistentialTraitRef<'tcx> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - ty::tls::with(|tcx| { - let dummy_self = tcx.mk_infer(ty::FreshTy(0)); - - let trait_ref = tcx.lift(&ty::Binder(*self)) - .expect("could not lift TraitRef for printing") - .with_self_ty(tcx, dummy_self).0; - parameterized(f, trait_ref.substs, trait_ref.def_id, &[]) - }) - } -} - impl fmt::Debug for ty::TraitDef { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { ty::tls::with(|tcx| { @@ -409,196 +607,226 @@ impl fmt::Debug for ty::AdtDef { } } -impl<'tcx> fmt::Debug for ty::adjustment::Adjustment<'tcx> { +impl<'tcx> fmt::Debug for ty::ClosureUpvar<'tcx> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{:?} -> {}", self.kind, self.target) + write!(f, "ClosureUpvar({:?},{:?})", + self.def, + self.ty) } } -impl<'tcx> fmt::Debug for ty::Predicate<'tcx> { +impl fmt::Debug for ty::UpvarId { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match *self { - ty::Predicate::Trait(ref a) => write!(f, "{:?}", a), - ty::Predicate::Equate(ref pair) => write!(f, "{:?}", pair), - ty::Predicate::Subtype(ref pair) => write!(f, "{:?}", pair), - ty::Predicate::RegionOutlives(ref pair) => write!(f, "{:?}", pair), - ty::Predicate::TypeOutlives(ref pair) => write!(f, "{:?}", pair), - ty::Predicate::Projection(ref pair) => write!(f, "{:?}", pair), - ty::Predicate::WellFormed(ty) => write!(f, "WF({:?})", ty), - ty::Predicate::ObjectSafe(trait_def_id) => { - write!(f, "ObjectSafe({:?})", trait_def_id) - } - ty::Predicate::ClosureKind(closure_def_id, kind) => { - write!(f, "ClosureKind({:?}, {:?})", closure_def_id, kind) - } - ty::Predicate::ConstEvaluatable(def_id, substs) => { - write!(f, "ConstEvaluatable({:?}, {:?})", def_id, substs) - } - } + write!(f, "UpvarId({:?};`{}`;{:?})", + self.var_id, + ty::tls::with(|tcx| tcx.hir.name(tcx.hir.hir_to_node_id(self.var_id))), + self.closure_expr_id) } } -impl fmt::Display for ty::BoundRegion { +impl<'tcx> fmt::Debug for ty::UpvarBorrow<'tcx> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - if verbose() { - return write!(f, "{:?}", *self); + write!(f, "UpvarBorrow({:?}, {:?})", + self.kind, self.region) + } +} + +define_print! { + ('tcx) ty::TypeAndMut<'tcx>, (self, f, cx) { + display { + print!(f, cx, + write("{}", if self.mutbl == hir::MutMutable { "mut " } else { "" }), + print(self.ty)) } + } +} - match *self { - BrNamed(_, name) => write!(f, "{}", name), - BrAnon(_) | BrFresh(_) | BrEnv => Ok(()) +define_print! { + ('tcx) ty::ExistentialTraitRef<'tcx>, (self, f, cx) { + debug { + ty::tls::with(|tcx| { + let dummy_self = tcx.mk_infer(ty::FreshTy(0)); + + let trait_ref = tcx.lift(&ty::Binder(*self)) + .expect("could not lift TraitRef for printing") + .with_self_ty(tcx, dummy_self).0; + cx.parameterized(f, trait_ref.substs, trait_ref.def_id, &[]) + }) } } } -impl fmt::Debug for ty::BoundRegion { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match *self { - BrAnon(n) => write!(f, "BrAnon({:?})", n), - BrFresh(n) => write!(f, "BrFresh({:?})", n), - BrNamed(did, name) => { - write!(f, "BrNamed({:?}:{:?}, {:?})", - did.krate, did.index, name) - } - BrEnv => "BrEnv".fmt(f), +define_print! { + ('tcx) ty::adjustment::Adjustment<'tcx>, (self, f, cx) { + debug { + print!(f, cx, write("{:?} -> ", self.kind), print(self.target)) } } } -impl fmt::Debug for ty::RegionKind { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match *self { - ty::ReEarlyBound(ref data) => { - write!(f, "ReEarlyBound({}, {})", - data.index, - data.name) +define_print! { + () ty::BoundRegion, (self, f, cx) { + display { + if cx.is_verbose { + return self.print_debug(f, cx); } - ty::ReLateBound(binder_id, ref bound_region) => { - write!(f, "ReLateBound({:?}, {:?})", - binder_id, - bound_region) + match *self { + BrNamed(_, name) => write!(f, "{}", name), + BrAnon(_) | BrFresh(_) | BrEnv => Ok(()) } + } + debug { + return match *self { + BrAnon(n) => write!(f, "BrAnon({:?})", n), + BrFresh(n) => write!(f, "BrFresh({:?})", n), + BrNamed(did, name) => { + write!(f, "BrNamed({:?}:{:?}, {:?})", + did.krate, did.index, name) + } + BrEnv => write!(f, "BrEnv"), + }; + } + } +} - ty::ReFree(ref fr) => write!(f, "{:?}", fr), - - ty::ReScope(id) => { - write!(f, "ReScope({:?})", id) +define_print! { + () ty::RegionKind, (self, f, cx) { + display { + if cx.is_verbose { + return self.print_debug(f, cx); } - ty::ReStatic => write!(f, "ReStatic"), - - ty::ReVar(ref vid) => { - write!(f, "{:?}", vid) + // These printouts are concise. They do not contain all the information + // the user might want to diagnose an error, but there is basically no way + // to fit that into a short string. Hence the recommendation to use + // `explain_region()` or `note_and_explain_region()`. + match *self { + ty::ReEarlyBound(ref data) => { + write!(f, "{}", data.name) + } + ty::ReLateBound(_, br) | + ty::ReFree(ty::FreeRegion { bound_region: br, .. }) | + ty::ReSkolemized(_, br) => { + write!(f, "{}", br) + } + ty::ReScope(scope) if cx.identify_regions => { + match scope.data() { + region::ScopeData::Node(id) => + write!(f, "'{}s", id.as_usize()), + region::ScopeData::CallSite(id) => + write!(f, "'{}cs", id.as_usize()), + region::ScopeData::Arguments(id) => + write!(f, "'{}as", id.as_usize()), + region::ScopeData::Destruction(id) => + write!(f, "'{}ds", id.as_usize()), + region::ScopeData::Remainder(BlockRemainder + { block, first_statement_index }) => + write!(f, "'{}_{}rs", block.as_usize(), first_statement_index.index()), + } + } + ty::ReVar(region_vid) if cx.identify_regions => { + write!(f, "'{}rv", region_vid.index) + } + ty::ReScope(_) | + ty::ReVar(_) | + ty::ReErased => Ok(()), + ty::ReStatic => write!(f, "'static"), + ty::ReEmpty => write!(f, "'"), } + } + debug { + match *self { + ty::ReEarlyBound(ref data) => { + write!(f, "ReEarlyBound({}, {})", + data.index, + data.name) + } - ty::ReSkolemized(id, ref bound_region) => { - write!(f, "ReSkolemized({}, {:?})", id.index, bound_region) - } + ty::ReLateBound(binder_id, ref bound_region) => { + write!(f, "ReLateBound({:?}, {:?})", + binder_id, + bound_region) + } - ty::ReEmpty => write!(f, "ReEmpty"), + ty::ReFree(ref fr) => write!(f, "{:?}", fr), - ty::ReErased => write!(f, "ReErased") - } - } -} + ty::ReScope(id) => { + write!(f, "ReScope({:?})", id) + } -impl<'tcx> fmt::Debug for ty::ClosureUpvar<'tcx> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "ClosureUpvar({:?},{:?})", - self.def, - self.ty) - } -} + ty::ReStatic => write!(f, "ReStatic"), -impl fmt::Display for ty::RegionKind { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - if verbose() { - return write!(f, "{:?}", *self); - } + ty::ReVar(ref vid) => { + write!(f, "{:?}", vid) + } - // These printouts are concise. They do not contain all the information - // the user might want to diagnose an error, but there is basically no way - // to fit that into a short string. Hence the recommendation to use - // `explain_region()` or `note_and_explain_region()`. - match *self { - ty::ReEarlyBound(ref data) => { - write!(f, "{}", data.name) - } - ty::ReLateBound(_, br) | - ty::ReFree(ty::FreeRegion { bound_region: br, .. }) | - ty::ReSkolemized(_, br) => { - write!(f, "{}", br) - } - ty::ReScope(scope) if identify_regions() => { - match scope.data() { - region::ScopeData::Node(id) => - write!(f, "'{}s", id.as_usize()), - region::ScopeData::CallSite(id) => - write!(f, "'{}cs", id.as_usize()), - region::ScopeData::Arguments(id) => - write!(f, "'{}as", id.as_usize()), - region::ScopeData::Destruction(id) => - write!(f, "'{}ds", id.as_usize()), - region::ScopeData::Remainder(BlockRemainder { block, first_statement_index }) => - write!(f, "'{}_{}rs", block.as_usize(), first_statement_index.index()), + ty::ReSkolemized(id, ref bound_region) => { + write!(f, "ReSkolemized({}, {:?})", id.index, bound_region) } + + ty::ReEmpty => write!(f, "ReEmpty"), + + ty::ReErased => write!(f, "ReErased") } - ty::ReVar(region_vid) if identify_regions() => { - write!(f, "'{}rv", region_vid.index) - } - ty::ReScope(_) | - ty::ReVar(_) | - ty::ReErased => Ok(()), - ty::ReStatic => write!(f, "'static"), - ty::ReEmpty => write!(f, "'"), } } } -impl fmt::Debug for ty::FreeRegion { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "ReFree({:?}, {:?})", - self.scope, self.bound_region) +define_print! { + () ty::FreeRegion, (self, f, cx) { + debug { + write!(f, "ReFree({:?}, {:?})", self.scope, self.bound_region) + } } } -impl fmt::Debug for ty::Variance { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.write_str(match *self { - ty::Covariant => "+", - ty::Contravariant => "-", - ty::Invariant => "o", - ty::Bivariant => "*", - }) +define_print! { + () ty::Variance, (self, f, cx) { + debug { + f.write_str(match *self { + ty::Covariant => "+", + ty::Contravariant => "-", + ty::Invariant => "o", + ty::Bivariant => "*", + }) + } } } -impl<'tcx> fmt::Debug for ty::GenericPredicates<'tcx> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "GenericPredicates({:?})", self.predicates) +define_print! { + ('tcx) ty::GenericPredicates<'tcx>, (self, f, cx) { + debug { + write!(f, "GenericPredicates({:?})", self.predicates) + } } } -impl<'tcx> fmt::Debug for ty::InstantiatedPredicates<'tcx> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "InstantiatedPredicates({:?})", - self.predicates) +define_print! { + ('tcx) ty::InstantiatedPredicates<'tcx>, (self, f, cx) { + debug { + write!(f, "InstantiatedPredicates({:?})", self.predicates) + } } } -impl<'tcx> fmt::Display for ty::FnSig<'tcx> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - if self.unsafety == hir::Unsafety::Unsafe { - write!(f, "unsafe ")?; - } +define_print! { + ('tcx) ty::FnSig<'tcx>, (self, f, cx) { + display { + if self.unsafety == hir::Unsafety::Unsafe { + write!(f, "unsafe ")?; + } - if self.abi != Abi::Rust { - write!(f, "extern {} ", self.abi)?; - } + if self.abi != Abi::Rust { + write!(f, "extern {} ", self.abi)?; + } - write!(f, "fn")?; - fn_sig(f, self.inputs(), self.variadic, self.output()) + write!(f, "fn")?; + cx.fn_sig(f, self.inputs(), self.variadic, self.output()) + } + debug { + write!(f, "({:?}; variadic: {})->{:?}", self.inputs(), self.variadic, self.output()) + } } } @@ -626,21 +854,27 @@ impl fmt::Debug for ty::RegionVid { } } -impl<'tcx> fmt::Debug for ty::FnSig<'tcx> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "({:?}; variadic: {})->{:?}", self.inputs(), self.variadic, self.output()) - } -} - -impl fmt::Debug for ty::InferTy { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match *self { - ty::TyVar(ref v) => v.fmt(f), - ty::IntVar(ref v) => v.fmt(f), - ty::FloatVar(ref v) => v.fmt(f), - ty::FreshTy(v) => write!(f, "FreshTy({:?})", v), - ty::FreshIntTy(v) => write!(f, "FreshIntTy({:?})", v), - ty::FreshFloatTy(v) => write!(f, "FreshFloatTy({:?})", v) +define_print! { + () ty::InferTy, (self, f, cx) { + display { + match *self { + ty::TyVar(_) => write!(f, "_"), + ty::IntVar(_) => write!(f, "{}", "{integer}"), + ty::FloatVar(_) => write!(f, "{}", "{float}"), + ty::FreshTy(v) => write!(f, "FreshTy({})", v), + ty::FreshIntTy(v) => write!(f, "FreshIntTy({})", v), + ty::FreshFloatTy(v) => write!(f, "FreshFloatTy({})", v) + } + } + debug { + match *self { + ty::TyVar(ref v) => write!(f, "{:?}", v), + ty::IntVar(ref v) => write!(f, "{:?}", v), + ty::FloatVar(ref v) => write!(f, "{:?}", v), + ty::FreshTy(v) => write!(f, "FreshTy({:?})", v), + ty::FreshIntTy(v) => write!(f, "FreshIntTy({:?})", v), + ty::FreshFloatTy(v) => write!(f, "FreshFloatTy({:?})", v) + } } } } @@ -665,406 +899,393 @@ impl fmt::Debug for ty::IntVarValue { } }*/ -impl<'tcx> fmt::Display for ty::Binder<&'tcx ty::Slice>> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - ty::tls::with(|tcx| in_binder(f, tcx, self, tcx.lift(self))) - } -} - -impl<'tcx> fmt::Display for ty::Binder> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - ty::tls::with(|tcx| in_binder(f, tcx, self, tcx.lift(self))) - } -} - -impl<'tcx> fmt::Display for ty::Binder> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - ty::tls::with(|tcx| in_binder(f, tcx, self, tcx.lift(self))) - } -} - -impl<'tcx> fmt::Display for ty::Binder> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - ty::tls::with(|tcx| in_binder(f, tcx, self, tcx.lift(self))) - } -} - -impl<'tcx> fmt::Display for ty::Binder> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - ty::tls::with(|tcx| in_binder(f, tcx, self, tcx.lift(self))) - } -} - -impl<'tcx> fmt::Display for ty::Binder> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - ty::tls::with(|tcx| in_binder(f, tcx, self, tcx.lift(self))) - } -} - -impl<'tcx> fmt::Display for ty::Binder> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - ty::tls::with(|tcx| in_binder(f, tcx, self, tcx.lift(self))) - } -} - -impl<'tcx> fmt::Display for ty::Binder, ty::Region<'tcx>>> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - ty::tls::with(|tcx| in_binder(f, tcx, self, tcx.lift(self))) - } -} - -impl<'tcx> fmt::Display for ty::Binder, - ty::Region<'tcx>>> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - ty::tls::with(|tcx| in_binder(f, tcx, self, tcx.lift(self))) +define_print_multi! { + [ + ('tcx) ty::Binder<&'tcx ty::Slice>>, + ('tcx) ty::Binder>, + ('tcx) ty::Binder>, + ('tcx) ty::Binder>, + ('tcx) ty::Binder>, + ('tcx) ty::Binder>, + ('tcx) ty::Binder>, + ('tcx) ty::Binder, ty::Region<'tcx>>>, + ('tcx) ty::Binder, ty::Region<'tcx>>> + ] + (self, f, cx) { + display { + ty::tls::with(|tcx| cx.in_binder(f, tcx, self, tcx.lift(self))) + } } } -impl<'tcx> fmt::Display for ty::TraitRef<'tcx> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - parameterized(f, self.substs, self.def_id, &[]) +define_print! { + ('tcx) ty::TraitRef<'tcx>, (self, f, cx) { + display { + cx.parameterized(f, self.substs, self.def_id, &[]) + } + debug { + // when printing out the debug representation, we don't need + // to enumerate the `for<...>` etc because the debruijn index + // tells you everything you need to know. + print!(f, cx, + write("<"), + print(self.self_ty()), + write(" as "))?; + cx.parameterized(f, self.substs, self.def_id, &[])?; + write!(f, ">") + } } } -impl<'tcx> fmt::Display for ty::GeneratorInterior<'tcx> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - self.witness.fmt(f) +define_print! { + ('tcx) ty::GeneratorInterior<'tcx>, (self, f, cx) { + display { + self.witness.print(f, cx) + } } } -impl<'tcx> fmt::Display for ty::TypeVariants<'tcx> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match *self { - TyBool => write!(f, "bool"), - TyChar => write!(f, "char"), - TyInt(t) => write!(f, "{}", t.ty_to_string()), - TyUint(t) => write!(f, "{}", t.ty_to_string()), - TyFloat(t) => write!(f, "{}", t.ty_to_string()), - TyRawPtr(ref tm) => { - write!(f, "*{} {}", match tm.mutbl { - hir::MutMutable => "mut", - hir::MutImmutable => "const", - }, tm.ty) - } - TyRef(r, ref tm) => { - write!(f, "&")?; - let s = r.to_string(); - write!(f, "{}", s)?; - if !s.is_empty() { - write!(f, " ")?; +define_print! { + ('tcx) ty::TypeVariants<'tcx>, (self, f, cx) { + display { + match *self { + TyBool => write!(f, "bool"), + TyChar => write!(f, "char"), + TyInt(t) => write!(f, "{}", t.ty_to_string()), + TyUint(t) => write!(f, "{}", t.ty_to_string()), + TyFloat(t) => write!(f, "{}", t.ty_to_string()), + TyRawPtr(ref tm) => { + write!(f, "*{} ", match tm.mutbl { + hir::MutMutable => "mut", + hir::MutImmutable => "const", + })?; + tm.ty.print(f, cx) } - write!(f, "{}", tm) - } - TyNever => write!(f, "!"), - TyTuple(ref tys, _) => { - write!(f, "(")?; - let mut tys = tys.iter(); - if let Some(&ty) = tys.next() { - write!(f, "{},", ty)?; + TyRef(r, ref tm) => { + write!(f, "&")?; + let s = r.print_to_string(cx); + write!(f, "{}", s)?; + if !s.is_empty() { + write!(f, " ")?; + } + tm.print(f, cx) + } + TyNever => write!(f, "!"), + TyTuple(ref tys, _) => { + write!(f, "(")?; + let mut tys = tys.iter(); if let Some(&ty) = tys.next() { - write!(f, " {}", ty)?; - for &ty in tys { - write!(f, ", {}", ty)?; + print!(f, cx, print(ty), write(","))?; + if let Some(&ty) = tys.next() { + print!(f, cx, write(" "), print(ty))?; + for &ty in tys { + print!(f, cx, write(", "), print(ty))?; + } } } + write!(f, ")") } - write!(f, ")") - } - TyFnDef(def_id, substs) => { - ty::tls::with(|tcx| { - let mut sig = tcx.fn_sig(def_id); - if let Some(substs) = tcx.lift(&substs) { - sig = sig.subst(tcx, substs); + TyFnDef(def_id, substs) => { + ty::tls::with(|tcx| { + let mut sig = tcx.fn_sig(def_id); + if let Some(substs) = tcx.lift(&substs) { + sig = sig.subst(tcx, substs); + } + print!(f, cx, print(sig), write(" {{")) + })?; + cx.parameterized(f, substs, def_id, &[])?; + write!(f, "}}") + } + TyFnPtr(ref bare_fn) => { + bare_fn.print(f, cx) + } + TyInfer(infer_ty) => write!(f, "{}", infer_ty), + TyError => write!(f, "[type error]"), + TyParam(ref param_ty) => write!(f, "{}", param_ty), + TyAdt(def, substs) => cx.parameterized(f, substs, def.did, &[]), + TyDynamic(data, r) => { + data.print(f, cx)?; + let r = r.print_to_string(cx); + if !r.is_empty() { + write!(f, " + {}", r) + } else { + Ok(()) } - write!(f, "{} {{", sig.0) - })?; - parameterized(f, substs, def_id, &[])?; - write!(f, "}}") - } - TyFnPtr(ref bare_fn) => { - write!(f, "{}", bare_fn.0) - } - TyInfer(infer_ty) => write!(f, "{}", infer_ty), - TyError => write!(f, "[type error]"), - TyParam(ref param_ty) => write!(f, "{}", param_ty), - TyAdt(def, substs) => parameterized(f, substs, def.did, &[]), - TyDynamic(data, r) => { - write!(f, "{}", data)?; - let r = r.to_string(); - if !r.is_empty() { - write!(f, " + {}", r) - } else { - Ok(()) } - } - TyProjection(ref data) => write!(f, "{}", data), - TyAnon(def_id, substs) => { - ty::tls::with(|tcx| { - // Grab the "TraitA + TraitB" from `impl TraitA + TraitB`, - // by looking up the projections associated with the def_id. - let predicates_of = tcx.predicates_of(def_id); - let substs = tcx.lift(&substs).unwrap_or_else(|| { - tcx.intern_substs(&[]) - }); - let bounds = predicates_of.instantiate(tcx, substs); - - let mut first = true; - let mut is_sized = false; - write!(f, "impl")?; - for predicate in bounds.predicates { - if let Some(trait_ref) = predicate.to_opt_poly_trait_ref() { - // Don't print +Sized, but rather +?Sized if absent. - if Some(trait_ref.def_id()) == tcx.lang_items().sized_trait() { - is_sized = true; - continue; + TyProjection(ref data) => data.print(f, cx), + TyAnon(def_id, substs) => { + ty::tls::with(|tcx| { + // Grab the "TraitA + TraitB" from `impl TraitA + TraitB`, + // by looking up the projections associated with the def_id. + let predicates_of = tcx.predicates_of(def_id); + let substs = tcx.lift(&substs).unwrap_or_else(|| { + tcx.intern_substs(&[]) + }); + let bounds = predicates_of.instantiate(tcx, substs); + + let mut first = true; + let mut is_sized = false; + write!(f, "impl")?; + for predicate in bounds.predicates { + if let Some(trait_ref) = predicate.to_opt_poly_trait_ref() { + // Don't print +Sized, but rather +?Sized if absent. + if Some(trait_ref.def_id()) == tcx.lang_items().sized_trait() { + is_sized = true; + continue; + } + + print!(f, cx, + write("{}", if first { " " } else { "+" }), + print(trait_ref))?; + first = false; } - - write!(f, "{}{}", if first { " " } else { "+" }, trait_ref)?; - first = false; } - } - if !is_sized { - write!(f, "{}?Sized", if first { " " } else { "+" })?; - } - Ok(()) - }) - } - TyStr => write!(f, "str"), - TyGenerator(did, substs, interior) => ty::tls::with(|tcx| { - let upvar_tys = substs.upvar_tys(did, tcx); - write!(f, "[generator")?; - - if let Some(node_id) = tcx.hir.as_local_node_id(did) { - write!(f, "@{:?}", tcx.hir.span(node_id))?; - let mut sep = " "; - tcx.with_freevars(node_id, |freevars| { - for (freevar, upvar_ty) in freevars.iter().zip(upvar_tys) { - write!(f, - "{}{}:{}", - sep, - tcx.hir.name(freevar.var_id()), - upvar_ty)?; - sep = ", "; + if !is_sized { + write!(f, "{}?Sized", if first { " " } else { "+" })?; } Ok(()) - })? - } else { - // cross-crate closure types should only be - // visible in trans bug reports, I imagine. - write!(f, "@{:?}", did)?; - let mut sep = " "; - for (index, upvar_ty) in upvar_tys.enumerate() { - write!(f, "{}{}:{}", sep, index, upvar_ty)?; - sep = ", "; - } + }) } + TyStr => write!(f, "str"), + TyGenerator(did, substs, interior) => ty::tls::with(|tcx| { + let upvar_tys = substs.upvar_tys(did, tcx); + write!(f, "[generator")?; - write!(f, " {}", interior)?; - - write!(f, "]") - }), - TyClosure(did, substs) => ty::tls::with(|tcx| { - let upvar_tys = substs.upvar_tys(did, tcx); - write!(f, "[closure")?; - - if let Some(node_id) = tcx.hir.as_local_node_id(did) { - if tcx.sess.opts.debugging_opts.span_free_formats { - write!(f, "@{:?}", node_id)?; - } else { + if let Some(node_id) = tcx.hir.as_local_node_id(did) { write!(f, "@{:?}", tcx.hir.span(node_id))?; - } - let mut sep = " "; - tcx.with_freevars(node_id, |freevars| { - for (freevar, upvar_ty) in freevars.iter().zip(upvar_tys) { - write!(f, - "{}{}:{}", - sep, - tcx.hir.name(freevar.var_id()), - upvar_ty)?; + let mut sep = " "; + tcx.with_freevars(node_id, |freevars| { + for (freevar, upvar_ty) in freevars.iter().zip(upvar_tys) { + print!(f, cx, + write("{}{}:", + sep, + tcx.hir.name(freevar.var_id())), + print(upvar_ty))?; + sep = ", "; + } + Ok(()) + })? + } else { + // cross-crate closure types should only be + // visible in trans bug reports, I imagine. + write!(f, "@{:?}", did)?; + let mut sep = " "; + for (index, upvar_ty) in upvar_tys.enumerate() { + print!(f, cx, + write("{}{}:", sep, index), + print(upvar_ty))?; sep = ", "; } - Ok(()) - })? - } else { - // cross-crate closure types should only be - // visible in trans bug reports, I imagine. - write!(f, "@{:?}", did)?; - let mut sep = " "; - for (index, upvar_ty) in upvar_tys.enumerate() { - write!(f, "{}{}:{}", sep, index, upvar_ty)?; - sep = ", "; } - } - write!(f, "]") - }), - TyArray(ty, sz) => { - write!(f, "[{}; ", ty)?; - match sz.val { - ConstVal::Integral(ConstInt::Usize(sz)) => { - write!(f, "{}", sz)?; - } - ConstVal::Unevaluated(_def_id, substs) => { - write!(f, "", &substs[..])?; + print!(f, cx, write(" "), print(interior), write("]")) + }), + TyClosure(did, substs) => ty::tls::with(|tcx| { + let upvar_tys = substs.upvar_tys(did, tcx); + write!(f, "[closure")?; + + if let Some(node_id) = tcx.hir.as_local_node_id(did) { + if tcx.sess.opts.debugging_opts.span_free_formats { + write!(f, "@{:?}", node_id)?; + } else { + write!(f, "@{:?}", tcx.hir.span(node_id))?; + } + let mut sep = " "; + tcx.with_freevars(node_id, |freevars| { + for (freevar, upvar_ty) in freevars.iter().zip(upvar_tys) { + print!(f, cx, + write("{}{}:", + sep, + tcx.hir.name(freevar.var_id())), + print(upvar_ty))?; + sep = ", "; + } + Ok(()) + })? + } else { + // cross-crate closure types should only be + // visible in trans bug reports, I imagine. + write!(f, "@{:?}", did)?; + let mut sep = " "; + for (index, upvar_ty) in upvar_tys.enumerate() { + print!(f, cx, + write("{}{}:", sep, index), + print(upvar_ty))?; + sep = ", "; + } } - _ => { - write!(f, "{:?}", sz)?; + + write!(f, "]") + }), + TyArray(ty, sz) => { + print!(f, cx, write("["), print(ty), write("; "))?; + match sz.val { + ConstVal::Integral(ConstInt::Usize(sz)) => { + write!(f, "{}", sz)?; + } + ConstVal::Unevaluated(_def_id, substs) => { + write!(f, "", &substs[..])?; + } + _ => { + write!(f, "{:?}", sz)?; + } } + write!(f, "]") + } + TySlice(ty) => { + print!(f, cx, write("["), print(ty), write("]")) } - write!(f, "]") } - TySlice(ty) => write!(f, "[{}]", ty) } } } -impl<'tcx> fmt::Display for ty::TyS<'tcx> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", self.sty) - } -} - -impl fmt::Debug for ty::UpvarId { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "UpvarId({:?};`{}`;{:?})", - self.var_id, - ty::tls::with(|tcx| tcx.hir.name(tcx.hir.hir_to_node_id(self.var_id))), - self.closure_expr_id) - } -} - -impl<'tcx> fmt::Debug for ty::UpvarBorrow<'tcx> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "UpvarBorrow({:?}, {:?})", - self.kind, self.region) - } -} - -impl fmt::Display for ty::InferTy { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let print_var_ids = verbose(); - match *self { - ty::TyVar(ref vid) if print_var_ids => write!(f, "{:?}", vid), - ty::IntVar(ref vid) if print_var_ids => write!(f, "{:?}", vid), - ty::FloatVar(ref vid) if print_var_ids => write!(f, "{:?}", vid), - ty::TyVar(_) => write!(f, "_"), - ty::IntVar(_) => write!(f, "{}", "{integer}"), - ty::FloatVar(_) => write!(f, "{}", "{float}"), - ty::FreshTy(v) => write!(f, "FreshTy({})", v), - ty::FreshIntTy(v) => write!(f, "FreshIntTy({})", v), - ty::FreshFloatTy(v) => write!(f, "FreshFloatTy({})", v) +define_print! { + ('tcx) ty::TyS<'tcx>, (self, f, cx) { + display { + self.sty.print(f, cx) + } + debug { + self.sty.print_display(f, cx) } } } -impl fmt::Display for ty::ParamTy { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", self.name) - } -} - -impl fmt::Debug for ty::ParamTy { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}/#{}", self, self.idx) - } -} - -impl<'tcx, T, U> fmt::Display for ty::OutlivesPredicate - where T: fmt::Display, U: fmt::Display -{ - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{} : {}", self.0, self.1) - } -} - -impl<'tcx> fmt::Display for ty::EquatePredicate<'tcx> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{} == {}", self.0, self.1) +define_print! { + () ty::ParamTy, (self, f, cx) { + display { + write!(f, "{}", self.name) + } + debug { + write!(f, "{}/#{}", self.name, self.idx) + } } } -impl<'tcx> fmt::Display for ty::SubtypePredicate<'tcx> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{} <: {}", self.a, self.b) +define_print! { + ('tcx, T: Print + fmt::Debug, U: Print + fmt::Debug) ty::OutlivesPredicate, + (self, f, cx) { + display { + print!(f, cx, print(self.0), write(" : "), print(self.1)) + } } } -impl<'tcx> fmt::Debug for ty::TraitPredicate<'tcx> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "TraitPredicate({:?})", - self.trait_ref) +define_print! { + ('tcx) ty::EquatePredicate<'tcx>, (self, f, cx) { + display { + print!(f, cx, print(self.0), write(" == "), print(self.1)) + } } } -impl<'tcx> fmt::Display for ty::TraitPredicate<'tcx> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}: {}", self.trait_ref.self_ty(), self.trait_ref) +define_print! { + ('tcx) ty::SubtypePredicate<'tcx>, (self, f, cx) { + display { + print!(f, cx, print(self.a), write(" <: "), print(self.b)) + } } } -impl<'tcx> fmt::Debug for ty::ProjectionPredicate<'tcx> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "ProjectionPredicate({:?}, {:?})", - self.projection_ty, - self.ty) +define_print! { + ('tcx) ty::TraitPredicate<'tcx>, (self, f, cx) { + debug { + write!(f, "TraitPredicate({:?})", + self.trait_ref) + } + display { + print!(f, cx, print(self.trait_ref.self_ty()), write(": "), print(self.trait_ref)) + } } } -impl<'tcx> fmt::Display for ty::ProjectionPredicate<'tcx> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{} == {}", - self.projection_ty, - self.ty) +define_print! { + ('tcx) ty::ProjectionPredicate<'tcx>, (self, f, cx) { + debug { + print!(f, cx, + write("ProjectionPredicate("), + print(self.projection_ty), + write(", "), + print(self.ty), + write(")")) + } + display { + print!(f, cx, print(self.projection_ty), write(" == "), print(self.ty)) + } } } -impl<'tcx> fmt::Display for ty::ProjectionTy<'tcx> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - // FIXME(tschottdorf): use something like - // parameterized(f, self.substs, self.item_def_id, &[]) - // (which currently ICEs). - let (trait_ref, item_name) = ty::tls::with(|tcx| - (self.trait_ref(tcx), tcx.associated_item(self.item_def_id).name) - ); - write!(f, "{:?}::{}", - trait_ref, - item_name) +define_print! { + ('tcx) ty::ProjectionTy<'tcx>, (self, f, cx) { + display { + // FIXME(tschottdorf): use something like + // parameterized(f, self.substs, self.item_def_id, &[]) + // (which currently ICEs). + let (trait_ref, item_name) = ty::tls::with(|tcx| + (self.trait_ref(tcx), tcx.associated_item(self.item_def_id).name) + ); + print!(f, cx, print_debug(trait_ref), write("::{}", item_name)) + } } } -impl fmt::Display for ty::ClosureKind { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match *self { - ty::ClosureKind::Fn => write!(f, "Fn"), - ty::ClosureKind::FnMut => write!(f, "FnMut"), - ty::ClosureKind::FnOnce => write!(f, "FnOnce"), +define_print! { + () ty::ClosureKind, (self, f, cx) { + display { + match *self { + ty::ClosureKind::Fn => write!(f, "Fn"), + ty::ClosureKind::FnMut => write!(f, "FnMut"), + ty::ClosureKind::FnOnce => write!(f, "FnOnce"), + } } } } -impl<'tcx> fmt::Display for ty::Predicate<'tcx> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match *self { - ty::Predicate::Trait(ref data) => write!(f, "{}", data), - ty::Predicate::Equate(ref predicate) => write!(f, "{}", predicate), - ty::Predicate::Subtype(ref predicate) => write!(f, "{}", predicate), - ty::Predicate::RegionOutlives(ref predicate) => write!(f, "{}", predicate), - ty::Predicate::TypeOutlives(ref predicate) => write!(f, "{}", predicate), - ty::Predicate::Projection(ref predicate) => write!(f, "{}", predicate), - ty::Predicate::WellFormed(ty) => write!(f, "{} well-formed", ty), - ty::Predicate::ObjectSafe(trait_def_id) => - ty::tls::with(|tcx| { - write!(f, "the trait `{}` is object-safe", tcx.item_path_str(trait_def_id)) - }), - ty::Predicate::ClosureKind(closure_def_id, kind) => - ty::tls::with(|tcx| { - write!(f, "the closure `{}` implements the trait `{}`", - tcx.item_path_str(closure_def_id), kind) - }), - ty::Predicate::ConstEvaluatable(def_id, substs) => { - write!(f, "the constant `")?; - parameterized(f, substs, def_id, &[])?; - write!(f, "` can be evaluated") +define_print! { + ('tcx) ty::Predicate<'tcx>, (self, f, cx) { + display { + match *self { + ty::Predicate::Trait(ref data) => data.print(f, cx), + ty::Predicate::Equate(ref predicate) => predicate.print(f, cx), + ty::Predicate::Subtype(ref predicate) => predicate.print(f, cx), + ty::Predicate::RegionOutlives(ref predicate) => predicate.print(f, cx), + ty::Predicate::TypeOutlives(ref predicate) => predicate.print(f, cx), + ty::Predicate::Projection(ref predicate) => predicate.print(f, cx), + ty::Predicate::WellFormed(ty) => print!(f, cx, print(ty), write(" well-formed")), + ty::Predicate::ObjectSafe(trait_def_id) => + ty::tls::with(|tcx| { + write!(f, "the trait `{}` is object-safe", tcx.item_path_str(trait_def_id)) + }), + ty::Predicate::ClosureKind(closure_def_id, kind) => + ty::tls::with(|tcx| { + write!(f, "the closure `{}` implements the trait `{}`", + tcx.item_path_str(closure_def_id), kind) + }), + ty::Predicate::ConstEvaluatable(def_id, substs) => { + write!(f, "the constant `")?; + cx.parameterized(f, substs, def_id, &[])?; + write!(f, "` can be evaluated") + } + } + } + debug { + match *self { + ty::Predicate::Trait(ref a) => a.print(f, cx), + ty::Predicate::Equate(ref pair) => pair.print(f, cx), + ty::Predicate::Subtype(ref pair) => pair.print(f, cx), + ty::Predicate::RegionOutlives(ref pair) => pair.print(f, cx), + ty::Predicate::TypeOutlives(ref pair) => pair.print(f, cx), + ty::Predicate::Projection(ref pair) => pair.print(f, cx), + ty::Predicate::WellFormed(ty) => ty.print(f, cx), + ty::Predicate::ObjectSafe(trait_def_id) => { + write!(f, "ObjectSafe({:?})", trait_def_id) + } + ty::Predicate::ClosureKind(closure_def_id, kind) => { + write!(f, "ClosureKind({:?}, {:?})", closure_def_id, kind) + } + ty::Predicate::ConstEvaluatable(def_id, substs) => { + write!(f, "ConstEvaluatable({:?}, {:?})", def_id, substs) + } } } } diff --git a/src/test/compile-fail/hygiene/impl_items.rs b/src/test/compile-fail/hygiene/impl_items.rs index 445aa62f2361e..cdba559445d19 100644 --- a/src/test/compile-fail/hygiene/impl_items.rs +++ b/src/test/compile-fail/hygiene/impl_items.rs @@ -19,7 +19,7 @@ mod foo { } pub macro m() { - let _: () = S.f(); //~ ERROR type `fn(&foo::S) {foo::S::f}` is private + let _: () = S.f(); //~ ERROR type `for<'r> fn(&'r foo::S) {foo::S::f}` is private } } diff --git a/src/test/compile-fail/issue-12997-2.rs b/src/test/compile-fail/issue-12997-2.rs index 276d7f7c9ed33..85d91bb2db202 100644 --- a/src/test/compile-fail/issue-12997-2.rs +++ b/src/test/compile-fail/issue-12997-2.rs @@ -15,6 +15,6 @@ #[bench] fn bar(x: isize) { } //~^ ERROR mismatched types -//~| expected type `fn(&mut __test::test::Bencher)` +//~| expected type `for<'r> fn(&'r mut __test::test::Bencher)` //~| found type `fn(isize) {bar}` //~| expected mutable reference, found isize diff --git a/src/test/compile-fail/private-inferred-type-3.rs b/src/test/compile-fail/private-inferred-type-3.rs index fdd9166ef2999..c0ba38b240202 100644 --- a/src/test/compile-fail/private-inferred-type-3.rs +++ b/src/test/compile-fail/private-inferred-type-3.rs @@ -15,7 +15,7 @@ // error-pattern:type `fn() {::method}` is private // error-pattern:type `fn(u8) -> ext::PrivTupleStruct {ext::PrivTupleStruct::{{constructor}}}` is pr // error-pattern:type `fn(u8) -> ext::PubTupleStruct {ext::PubTupleStruct::{{constructor}}}` is priv -// error-pattern:type `fn(&ext::Pub) {>::priv_method}` is private +// error-pattern:type `for<'r> fn(&'r ext::Pub) {>::priv_method}` is private #![feature(decl_macro)] diff --git a/src/test/compile-fail/private-inferred-type.rs b/src/test/compile-fail/private-inferred-type.rs index 973d467b11226..95e3732d61342 100644 --- a/src/test/compile-fail/private-inferred-type.rs +++ b/src/test/compile-fail/private-inferred-type.rs @@ -56,7 +56,7 @@ mod m { PubTupleStruct; //~^ ERROR type `fn(u8) -> m::PubTupleStruct {m::PubTupleStruct::{{constructor}}}` is privat Pub(0u8).priv_method(); - //~^ ERROR type `fn(&m::Pub) {>::priv_method}` is private + //~^ ERROR type `for<'r> fn(&'r m::Pub) {>::priv_method}` is private } trait Trait {} diff --git a/src/test/compile-fail/regions-fn-subtyping-return-static.rs b/src/test/compile-fail/regions-fn-subtyping-return-static.rs index ac7dd022c7c46..6be65a5e35905 100644 --- a/src/test/compile-fail/regions-fn-subtyping-return-static.rs +++ b/src/test/compile-fail/regions-fn-subtyping-return-static.rs @@ -58,8 +58,8 @@ fn supply_G() { want_G(bar); want_G(baz); //~^ ERROR mismatched types - //~| expected type `fn(&'cx S) -> &'static S` - //~| found type `fn(&S) -> &S {baz}` + //~| expected type `for<'cx> fn(&'cx S) -> &'static S` + //~| found type `for<'r> fn(&'r S) -> &'r S {baz}` //~| expected concrete lifetime, found bound lifetime parameter 'cx } diff --git a/src/test/mir-opt/validate_1.rs b/src/test/mir-opt/validate_1.rs index d2ca65775a44e..39f43e4e990cd 100644 --- a/src/test/mir-opt/validate_1.rs +++ b/src/test/mir-opt/validate_1.rs @@ -57,7 +57,7 @@ fn main() { // START rustc.node50.EraseRegions.after.mir // fn main::{{closure}}(_1: &ReErased [closure@NodeId(50)], _2: &ReErased mut i32) -> i32 { // bb0: { -// Validate(Acquire, [_1: &ReFree(DefId { krate: CrateNum(0), index: DefIndex(1:11) => validate_1[8cd8]::main[0]::{{closure}}[0] }, "BrEnv") [closure@NodeId(50)], _2: &ReFree(DefId { krate: CrateNum(0), index: DefIndex(1:11) => validate_1[8cd8]::main[0]::{{closure}}[0] }, BrAnon(1)) mut i32]); +// Validate(Acquire, [_1: &ReFree(DefId { krate: CrateNum(0), index: DefIndex(1:11) => validate_1[8cd8]::main[0]::{{closure}}[0] }, BrEnv) [closure@NodeId(50)], _2: &ReFree(DefId { krate: CrateNum(0), index: DefIndex(1:11) => validate_1[8cd8]::main[0]::{{closure}}[0] }, BrAnon(1)) mut i32]); // StorageLive(_3); // _3 = _2; // StorageLive(_4); diff --git a/src/test/mir-opt/validate_4.rs b/src/test/mir-opt/validate_4.rs index d240b51e222e1..b670d8094dd53 100644 --- a/src/test/mir-opt/validate_4.rs +++ b/src/test/mir-opt/validate_4.rs @@ -48,8 +48,8 @@ fn main() { // START rustc.node22.EraseRegions.after.mir // fn write_42::{{closure}}(_1: &ReErased [closure@NodeId(22)], _2: *mut i32) -> () { // bb0: { -// Validate(Acquire, [_1: &ReFree(DefId { krate: CrateNum(0), index: DefIndex(1:9) => validate_4[8cd8]::write_42[0]::{{closure}}[0] }, "BrEnv") [closure@NodeId(22)], _2: *mut i32]); -// Validate(Release, [_1: &ReFree(DefId { krate: CrateNum(0), index: DefIndex(1:9) => validate_4[8cd8]::write_42[0]::{{closure}}[0] }, "BrEnv") [closure@NodeId(22)], _2: *mut i32]); +// Validate(Acquire, [_1: &ReFree(DefId { krate: CrateNum(0), index: DefIndex(1:9) => validate_4[8cd8]::write_42[0]::{{closure}}[0] }, BrEnv) [closure@NodeId(22)], _2: *mut i32]); +// Validate(Release, [_1: &ReFree(DefId { krate: CrateNum(0), index: DefIndex(1:9) => validate_4[8cd8]::write_42[0]::{{closure}}[0] }, BrEnv) [closure@NodeId(22)], _2: *mut i32]); // StorageLive(_3); // _3 = _2; // (*_3) = const 23i32; @@ -74,8 +74,8 @@ fn main() { // START rustc.node60.EraseRegions.after.mir // fn main::{{closure}}(_1: &ReErased [closure@NodeId(60)], _2: &ReErased mut i32) -> bool { // bb0: { -// Validate(Acquire, [_1: &ReFree(DefId { krate: CrateNum(0), index: DefIndex(1:10) => validate_4[8cd8]::main[0]::{{closure}}[0] }, "BrEnv") [closure@NodeId(60)], _2: &ReFree(DefId { krate: CrateNum(0), index: DefIndex(1:10) => validate_4[8cd8]::main[0]::{{closure}}[0] }, BrAnon(1)) mut i32]); -// Validate(Release, [_1: &ReFree(DefId { krate: CrateNum(0), index: DefIndex(1:10) => validate_4[8cd8]::main[0]::{{closure}}[0] }, "BrEnv") [closure@NodeId(60)], _2: &ReFree(DefId { krate: CrateNum(0), index: DefIndex(1:10) => validate_4[8cd8]::main[0]::{{closure}}[0] }, BrAnon(1)) mut i32]); +// Validate(Acquire, [_1: &ReFree(DefId { krate: CrateNum(0), index: DefIndex(1:10) => validate_4[8cd8]::main[0]::{{closure}}[0] }, BrEnv) [closure@NodeId(60)], _2: &ReFree(DefId { krate: CrateNum(0), index: DefIndex(1:10) => validate_4[8cd8]::main[0]::{{closure}}[0] }, BrAnon(1)) mut i32]); +// Validate(Release, [_1: &ReFree(DefId { krate: CrateNum(0), index: DefIndex(1:10) => validate_4[8cd8]::main[0]::{{closure}}[0] }, BrEnv) [closure@NodeId(60)], _2: &ReFree(DefId { krate: CrateNum(0), index: DefIndex(1:10) => validate_4[8cd8]::main[0]::{{closure}}[0] }, BrAnon(1)) mut i32]); // StorageLive(_3); // _0 = const write_42(_4) -> bb1; // } diff --git a/src/test/mir-opt/validate_5.rs b/src/test/mir-opt/validate_5.rs index e1eeb2102d1a2..059d3adb407aa 100644 --- a/src/test/mir-opt/validate_5.rs +++ b/src/test/mir-opt/validate_5.rs @@ -45,7 +45,7 @@ fn main() { // START rustc.node46.EraseRegions.after.mir // fn main::{{closure}}(_1: &ReErased [closure@NodeId(46)], _2: &ReErased mut i32) -> bool { // bb0: { -// Validate(Acquire, [_1: &ReFree(DefId { krate: CrateNum(0), index: DefIndex(1:9) => validate_5[8cd8]::main[0]::{{closure}}[0] }, "BrEnv") [closure@NodeId(46)], _2: &ReFree(DefId { krate: CrateNum(0), index: DefIndex(1:9) => validate_5[8cd8]::main[0]::{{closure}}[0] }, BrAnon(1)) mut i32]); +// Validate(Acquire, [_1: &ReFree(DefId { krate: CrateNum(0), index: DefIndex(1:9) => validate_5[8cd8]::main[0]::{{closure}}[0] }, BrEnv) [closure@NodeId(46)], _2: &ReFree(DefId { krate: CrateNum(0), index: DefIndex(1:9) => validate_5[8cd8]::main[0]::{{closure}}[0] }, BrAnon(1)) mut i32]); // StorageLive(_3); // _3 = _2; // StorageLive(_4); diff --git a/src/test/pretty/issue-4264.pp b/src/test/pretty/issue-4264.pp index 14a499644df8b..02b8425d88bee 100644 --- a/src/test/pretty/issue-4264.pp +++ b/src/test/pretty/issue-4264.pp @@ -40,31 +40,31 @@ ((::fmt::format as - fn(std::fmt::Arguments<'_>) -> std::string::String {std::fmt::format})(((<::std::fmt::Arguments>::new_v1 - as - fn(&[&str], &[std::fmt::ArgumentV1<'_>]) -> std::fmt::Arguments<'_> {std::fmt::Arguments<'_>::new_v1})((&([("test" - as - &'static str)] - as - [&str; 1]) - as - &[&str; 1]), - (&(match (() - as - ()) - { - () - => - ([] - as - [std::fmt::ArgumentV1<'_>; 0]), - } - as - [std::fmt::ArgumentV1<'_>; 0]) - as - &[std::fmt::ArgumentV1<'_>; 0])) - as - std::fmt::Arguments<'_>)) + for<'r> fn(std::fmt::Arguments<'r>) -> std::string::String {std::fmt::format})(((<::std::fmt::Arguments>::new_v1 + as + fn(&[&str], &[std::fmt::ArgumentV1<'_>]) -> std::fmt::Arguments<'_> {std::fmt::Arguments<'_>::new_v1})((&([("test" + as + &'static str)] + as + [&str; 1]) + as + &[&str; 1]), + (&(match (() + as + ()) + { + () + => + ([] + as + [std::fmt::ArgumentV1<'_>; 0]), + } + as + [std::fmt::ArgumentV1<'_>; 0]) + as + &[std::fmt::ArgumentV1<'_>; 0])) + as + std::fmt::Arguments<'_>)) as std::string::String); } as ()) pub type Foo = [i32; (3 as usize)]; diff --git a/src/test/ui/anonymous-higher-ranked-lifetime.rs b/src/test/ui/anonymous-higher-ranked-lifetime.rs new file mode 100644 index 0000000000000..f2d04c16d99e1 --- /dev/null +++ b/src/test/ui/anonymous-higher-ranked-lifetime.rs @@ -0,0 +1,40 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn main() { + f1(|_: (), _: ()| {}); + f2(|_: (), _: ()| {}); + f3(|_: (), _: ()| {}); + f4(|_: (), _: ()| {}); + f5(|_: (), _: ()| {}); + g1(|_: (), _: ()| {}); + g2(|_: (), _: ()| {}); + g3(|_: (), _: ()| {}); + g4(|_: (), _: ()| {}); + h1(|_: (), _: (), _: (), _: ()| {}); + h2(|_: (), _: (), _: (), _: ()| {}); +} + +// Basic +fn f1(_: F) where F: Fn(&(), &()) {} +fn f2(_: F) where F: for<'a> Fn(&'a (), &()) {} +fn f3<'a, F>(_: F) where F: Fn(&'a (), &()) {} +fn f4(_: F) where F: for<'r> Fn(&(), &'r ()) {} +fn f5(_: F) where F: for<'r> Fn(&'r (), &'r ()) {} + +// Nested +fn g1(_: F) where F: Fn(&(), Box) {} +fn g2(_: F) where F: Fn(&(), fn(&())) {} +fn g3(_: F) where F: for<'s> Fn(&'s (), Box) {} +fn g4(_: F) where F: Fn(&(), for<'r> fn(&'r ())) {} + +// Mixed +fn h1(_: F) where F: Fn(&(), Box, &(), fn(&(), &())) {} +fn h2(_: F) where F: for<'t0> Fn(&(), Box, &'t0 (), fn(&(), &())) {} diff --git a/src/test/ui/anonymous-higher-ranked-lifetime.stderr b/src/test/ui/anonymous-higher-ranked-lifetime.stderr new file mode 100644 index 0000000000000..f962b7722036b --- /dev/null +++ b/src/test/ui/anonymous-higher-ranked-lifetime.stderr @@ -0,0 +1,112 @@ +error[E0631]: type mismatch in closure arguments + --> $DIR/anonymous-higher-ranked-lifetime.rs:12:5 + | +12 | f1(|_: (), _: ()| {}); + | ^^ ----------------- found signature of `fn((), ()) -> _` + | | + | expected signature of `for<'r, 's> fn(&'r (), &'s ()) -> _` + | + = note: required by `f1` + +error[E0631]: type mismatch in closure arguments + --> $DIR/anonymous-higher-ranked-lifetime.rs:13:5 + | +13 | f2(|_: (), _: ()| {}); + | ^^ ----------------- found signature of `fn((), ()) -> _` + | | + | expected signature of `for<'a, 'r> fn(&'a (), &'r ()) -> _` + | + = note: required by `f2` + +error[E0631]: type mismatch in closure arguments + --> $DIR/anonymous-higher-ranked-lifetime.rs:14:5 + | +14 | f3(|_: (), _: ()| {}); + | ^^ ----------------- found signature of `fn((), ()) -> _` + | | + | expected signature of `for<'r> fn(&(), &'r ()) -> _` + | + = note: required by `f3` + +error[E0631]: type mismatch in closure arguments + --> $DIR/anonymous-higher-ranked-lifetime.rs:15:5 + | +15 | f4(|_: (), _: ()| {}); + | ^^ ----------------- found signature of `fn((), ()) -> _` + | | + | expected signature of `for<'s, 'r> fn(&'s (), &'r ()) -> _` + | + = note: required by `f4` + +error[E0631]: type mismatch in closure arguments + --> $DIR/anonymous-higher-ranked-lifetime.rs:16:5 + | +16 | f5(|_: (), _: ()| {}); + | ^^ ----------------- found signature of `fn((), ()) -> _` + | | + | expected signature of `for<'r> fn(&'r (), &'r ()) -> _` + | + = note: required by `f5` + +error[E0631]: type mismatch in closure arguments + --> $DIR/anonymous-higher-ranked-lifetime.rs:17:5 + | +17 | g1(|_: (), _: ()| {}); + | ^^ ----------------- found signature of `fn((), ()) -> _` + | | + | expected signature of `for<'r> fn(&'r (), std::boxed::Box std::ops::Fn(&'s ()) + 'static>) -> _` + | + = note: required by `g1` + +error[E0631]: type mismatch in closure arguments + --> $DIR/anonymous-higher-ranked-lifetime.rs:18:5 + | +18 | g2(|_: (), _: ()| {}); + | ^^ ----------------- found signature of `fn((), ()) -> _` + | | + | expected signature of `for<'r> fn(&'r (), for<'s> fn(&'s ())) -> _` + | + = note: required by `g2` + +error[E0631]: type mismatch in closure arguments + --> $DIR/anonymous-higher-ranked-lifetime.rs:19:5 + | +19 | g3(|_: (), _: ()| {}); + | ^^ ----------------- found signature of `fn((), ()) -> _` + | | + | expected signature of `for<'s> fn(&'s (), std::boxed::Box std::ops::Fn(&'r ()) + 'static>) -> _` + | + = note: required by `g3` + +error[E0631]: type mismatch in closure arguments + --> $DIR/anonymous-higher-ranked-lifetime.rs:20:5 + | +20 | g4(|_: (), _: ()| {}); + | ^^ ----------------- found signature of `fn((), ()) -> _` + | | + | expected signature of `for<'s> fn(&'s (), for<'r> fn(&'r ())) -> _` + | + = note: required by `g4` + +error[E0631]: type mismatch in closure arguments + --> $DIR/anonymous-higher-ranked-lifetime.rs:21:5 + | +21 | h1(|_: (), _: (), _: (), _: ()| {}); + | ^^ ------------------------------- found signature of `fn((), (), (), ()) -> _` + | | + | expected signature of `for<'r, 's> fn(&'r (), std::boxed::Box std::ops::Fn(&'t0 ()) + 'static>, &'s (), for<'t0, 't1> fn(&'t0 (), &'t1 ())) -> _` + | + = note: required by `h1` + +error[E0631]: type mismatch in closure arguments + --> $DIR/anonymous-higher-ranked-lifetime.rs:22:5 + | +22 | h2(|_: (), _: (), _: (), _: ()| {}); + | ^^ ------------------------------- found signature of `fn((), (), (), ()) -> _` + | | + | expected signature of `for<'r, 't0> fn(&'r (), std::boxed::Box std::ops::Fn(&'s ()) + 'static>, &'t0 (), for<'s, 't1> fn(&'s (), &'t1 ())) -> _` + | + = note: required by `h2` + +error: aborting due to 11 previous errors + diff --git a/src/test/ui/regions-fn-subtyping-return-static.stderr b/src/test/ui/regions-fn-subtyping-return-static.stderr index 1598a8a40d2f0..4a97537223cf6 100644 --- a/src/test/ui/regions-fn-subtyping-return-static.stderr +++ b/src/test/ui/regions-fn-subtyping-return-static.stderr @@ -4,8 +4,8 @@ error[E0308]: mismatched types 51 | want_F(bar); //~ ERROR E0308 | ^^^ expected concrete lifetime, found bound lifetime parameter 'cx | - = note: expected type `fn(&'cx S) -> &'cx S` - found type `fn(&'a S) -> &S {bar::<'_>}` + = note: expected type `for<'cx> fn(&'cx S) -> &'cx S` + found type `for<'a> fn(&'a S) -> &S {bar::<'_>}` error: aborting due to previous error