diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index 4034055d04155..aa678ba788a5b 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -625,7 +625,7 @@ define_dep_nodes!( <'tcx> [eval_always] CollectAndPartitionTranslationItems, [] ExportName(DefId), [] ContainsExternIndicator(DefId), - [] IsTranslatedFunction(DefId), + [] IsTranslatedItem(DefId), [] CodegenUnit(InternedString), [] CompileCodegenUnit(InternedString), [input] OutputFilenames, diff --git a/src/librustc/dep_graph/graph.rs b/src/librustc/dep_graph/graph.rs index 55ec8adb5fbf3..b77431e806a6d 100644 --- a/src/librustc/dep_graph/graph.rs +++ b/src/librustc/dep_graph/graph.rs @@ -74,7 +74,7 @@ struct DepGraphData { /// nodes and edges as well as all fingerprints of nodes that have them. previous: PreviousDepGraph, - colors: RefCell>, + colors: RefCell, /// When we load, there may be `.o` files, cached mir, or other such /// things available to us. If we find that they are not dirty, we @@ -97,8 +97,10 @@ impl DepGraph { // Pre-allocate the fingerprints array. We over-allocate a little so // that we hopefully don't have to re-allocate during this compilation // session. + let prev_graph_node_count = prev_graph.node_count(); + let fingerprints = IndexVec::from_elem_n(Fingerprint::ZERO, - (prev_graph.node_count() * 115) / 100); + (prev_graph_node_count * 115) / 100); DepGraph { data: Some(Rc::new(DepGraphData { previous_work_products: RefCell::new(FxHashMap()), @@ -106,7 +108,7 @@ impl DepGraph { dep_node_debug: RefCell::new(FxHashMap()), current: RefCell::new(CurrentDepGraph::new()), previous: prev_graph, - colors: RefCell::new(FxHashMap()), + colors: RefCell::new(DepNodeColorMap::new(prev_graph_node_count)), loaded_from_cache: RefCell::new(FxHashMap()), })), fingerprints: Rc::new(RefCell::new(fingerprints)), @@ -213,8 +215,6 @@ impl DepGraph { R: HashStable, { if let Some(ref data) = self.data { - debug_assert!(!data.colors.borrow().contains_key(&key)); - push(&data.current, key); if cfg!(debug_assertions) { profq_msg(ProfileQueriesMsg::TaskBegin(key.clone())) @@ -254,19 +254,21 @@ impl DepGraph { } // Determine the color of the new DepNode. - { - let prev_fingerprint = data.previous.fingerprint_of(&key); + if let Some(prev_index) = data.previous.node_to_index_opt(&key) { + let prev_fingerprint = data.previous.fingerprint_by_index(prev_index); - let color = if Some(current_fingerprint) == prev_fingerprint { + let color = if current_fingerprint == prev_fingerprint { DepNodeColor::Green(dep_node_index) } else { DepNodeColor::Red }; - let old_value = data.colors.borrow_mut().insert(key, color); - debug_assert!(old_value.is_none(), + let mut colors = data.colors.borrow_mut(); + debug_assert!(colors.get(prev_index).is_none(), "DepGraph::with_task() - Duplicate DepNodeColor \ insertion for {:?}", key); + + colors.insert(prev_index, color); } (result, dep_node_index) @@ -281,9 +283,11 @@ impl DepGraph { let mut fingerprints = self.fingerprints.borrow_mut(); let dep_node_index = DepNodeIndex::new(fingerprints.len()); fingerprints.push(fingerprint); + debug_assert!(fingerprints[dep_node_index] == fingerprint, "DepGraph::with_task() - Assigned fingerprint to \ unexpected index for {:?}", key); + (result, dep_node_index) } else { (task(cx, arg), DepNodeIndex::INVALID) @@ -356,6 +360,15 @@ impl DepGraph { .unwrap() } + #[inline] + pub fn dep_node_exists(&self, dep_node: &DepNode) -> bool { + if let Some(ref data) = self.data { + data.current.borrow_mut().node_to_node_index.contains_key(dep_node) + } else { + false + } + } + #[inline] pub fn fingerprint_of(&self, dep_node_index: DepNodeIndex) -> Fingerprint { match self.fingerprints.borrow().get(dep_node_index) { @@ -495,7 +508,17 @@ impl DepGraph { } pub fn node_color(&self, dep_node: &DepNode) -> Option { - self.data.as_ref().and_then(|data| data.colors.borrow().get(dep_node).cloned()) + if let Some(ref data) = self.data { + if let Some(prev_index) = data.previous.node_to_index_opt(dep_node) { + return data.colors.borrow().get(prev_index) + } else { + // This is a node that did not exist in the previous compilation + // session, so we consider it to be red. + return Some(DepNodeColor::Red) + } + } + + None } pub fn try_mark_green<'tcx>(&self, @@ -505,7 +528,6 @@ impl DepGraph { debug!("try_mark_green({:?}) - BEGIN", dep_node); let data = self.data.as_ref().unwrap(); - debug_assert!(!data.colors.borrow().contains_key(dep_node)); debug_assert!(!data.current.borrow().node_to_node_index.contains_key(dep_node)); if dep_node.kind.is_input() { @@ -535,19 +557,22 @@ impl DepGraph { } }; + debug_assert!(data.colors.borrow().get(prev_dep_node_index).is_none()); + let mut current_deps = Vec::new(); for &dep_dep_node_index in prev_deps { - let dep_dep_node = &data.previous.index_to_node(dep_dep_node_index); + let dep_dep_node_color = data.colors.borrow().get(dep_dep_node_index); - let dep_dep_node_color = data.colors.borrow().get(dep_dep_node).cloned(); match dep_dep_node_color { Some(DepNodeColor::Green(node_index)) => { // This dependency has been marked as green before, we are // still fine and can continue with checking the other // dependencies. debug!("try_mark_green({:?}) --- found dependency {:?} to \ - be immediately green", dep_node, dep_dep_node); + be immediately green", + dep_node, + data.previous.index_to_node(dep_dep_node_index)); current_deps.push(node_index); } Some(DepNodeColor::Red) => { @@ -556,10 +581,14 @@ impl DepGraph { // mark the DepNode as green and also don't need to bother // with checking any of the other dependencies. debug!("try_mark_green({:?}) - END - dependency {:?} was \ - immediately red", dep_node, dep_dep_node); + immediately red", + dep_node, + data.previous.index_to_node(dep_dep_node_index)); return None } None => { + let dep_dep_node = &data.previous.index_to_node(dep_dep_node_index); + // We don't know the state of this dependency. If it isn't // an input node, let's try to mark it green recursively. if !dep_dep_node.kind.is_input() { @@ -601,10 +630,8 @@ impl DepGraph { debug!("try_mark_green({:?}) --- trying to force \ dependency {:?}", dep_node, dep_dep_node); if ::ty::maps::force_from_dep_node(tcx, dep_dep_node) { - let dep_dep_node_color = data.colors - .borrow() - .get(dep_dep_node) - .cloned(); + let dep_dep_node_color = data.colors.borrow().get(dep_dep_node_index); + match dep_dep_node_color { Some(DepNodeColor::Green(node_index)) => { debug!("try_mark_green({:?}) --- managed to \ @@ -681,26 +708,21 @@ impl DepGraph { } // ... and finally storing a "Green" entry in the color map. - let old_color = data.colors - .borrow_mut() - .insert(*dep_node, DepNodeColor::Green(dep_node_index)); - debug_assert!(old_color.is_none(), + let mut colors = data.colors.borrow_mut(); + debug_assert!(colors.get(prev_dep_node_index).is_none(), "DepGraph::try_mark_green() - Duplicate DepNodeColor \ insertion for {:?}", dep_node); + colors.insert(prev_dep_node_index, DepNodeColor::Green(dep_node_index)); + debug!("try_mark_green({:?}) - END - successfully marked as green", dep_node); Some(dep_node_index) } - // Used in various assertions - pub fn is_green(&self, dep_node_index: DepNodeIndex) -> bool { - let dep_node = self.data.as_ref().unwrap().current.borrow().nodes[dep_node_index]; - self.data.as_ref().unwrap().colors.borrow().get(&dep_node).map(|&color| { - match color { - DepNodeColor::Red => false, - DepNodeColor::Green(_) => true, - } - }).unwrap_or(false) + // Returns true if the given node has been marked as green during the + // current compilation session. Used in various assertions + pub fn is_green(&self, dep_node: &DepNode) -> bool { + self.node_color(dep_node).map(|c| c.is_green()).unwrap_or(false) } // This method loads all on-disk cacheable query results into memory, so @@ -714,20 +736,25 @@ impl DepGraph { pub fn exec_cache_promotions<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) { let green_nodes: Vec = { let data = self.data.as_ref().unwrap(); - data.colors.borrow().iter().filter_map(|(dep_node, color)| match color { - DepNodeColor::Green(_) => { - if dep_node.cache_on_disk(tcx) { - Some(*dep_node) - } else { + let colors = data.colors.borrow(); + colors.values.indices().filter_map(|prev_index| { + match colors.get(prev_index) { + Some(DepNodeColor::Green(_)) => { + let dep_node = data.previous.index_to_node(prev_index); + if dep_node.cache_on_disk(tcx) { + Some(dep_node) + } else { + None + } + } + None | + Some(DepNodeColor::Red) => { + // We can skip red nodes because a node can only be marked + // as red if the query result was recomputed and thus is + // already in memory. None } } - DepNodeColor::Red => { - // We can skip red nodes because a node can only be marked - // as red if the query result was recomputed and thus is - // already in memory. - None - } }).collect() }; @@ -1052,3 +1079,36 @@ enum OpenTask { node: DepNode, }, } + +// A data structure that stores Option values as a contiguous +// array, using one u32 per entry. +struct DepNodeColorMap { + values: IndexVec, +} + +const COMPRESSED_NONE: u32 = 0; +const COMPRESSED_RED: u32 = 1; +const COMPRESSED_FIRST_GREEN: u32 = 2; + +impl DepNodeColorMap { + fn new(size: usize) -> DepNodeColorMap { + DepNodeColorMap { + values: IndexVec::from_elem_n(COMPRESSED_NONE, size) + } + } + + fn get(&self, index: SerializedDepNodeIndex) -> Option { + match self.values[index] { + COMPRESSED_NONE => None, + COMPRESSED_RED => Some(DepNodeColor::Red), + value => Some(DepNodeColor::Green(DepNodeIndex(value - COMPRESSED_FIRST_GREEN))) + } + } + + fn insert(&mut self, index: SerializedDepNodeIndex, color: DepNodeColor) { + self.values[index] = match color { + DepNodeColor::Red => COMPRESSED_RED, + DepNodeColor::Green(index) => index.0 + COMPRESSED_FIRST_GREEN, + } + } +} diff --git a/src/librustc/dep_graph/prev.rs b/src/librustc/dep_graph/prev.rs index 50e1ee88a4614..504b60e763e23 100644 --- a/src/librustc/dep_graph/prev.rs +++ b/src/librustc/dep_graph/prev.rs @@ -49,6 +49,11 @@ impl PreviousDepGraph { self.index[dep_node] } + #[inline] + pub fn node_to_index_opt(&self, dep_node: &DepNode) -> Option { + self.index.get(dep_node).cloned() + } + #[inline] pub fn fingerprint_of(&self, dep_node: &DepNode) -> Option { self.index diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index b6b3e8955351c..3799bdada888e 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -22,6 +22,7 @@ use hir::def_id::{CRATE_DEF_INDEX, DefId, LocalDefId, DefIndexAddressSpace}; use syntax::abi::Abi; use syntax::ast::{self, Name, NodeId, CRATE_NODE_ID}; use syntax::codemap::Spanned; +use syntax::ext::base::MacroKind; use syntax_pos::Span; use hir::*; @@ -32,6 +33,7 @@ use util::nodemap::{DefIdMap, FxHashMap}; use arena::TypedArena; use std::cell::RefCell; use std::io; +use ty::TyCtxt; pub mod blocks; mod collector; @@ -39,6 +41,7 @@ mod def_collector; pub mod definitions; mod hir_id_validator; + pub const ITEM_LIKE_SPACE: DefIndexAddressSpace = DefIndexAddressSpace::Low; pub const REGULAR_SPACE: DefIndexAddressSpace = DefIndexAddressSpace::High; @@ -373,6 +376,92 @@ impl<'hir> Map<'hir> { self.definitions.as_local_node_id(def_id.to_def_id()).unwrap() } + pub fn describe_def(&self, node_id: NodeId) -> Option { + let node = if let Some(node) = self.find(node_id) { + node + } else { + return None + }; + + match node { + NodeItem(item) => { + let def_id = || { + self.local_def_id(item.id) + }; + + match item.node { + ItemStatic(_, m, _) => Some(Def::Static(def_id(), + m == MutMutable)), + ItemConst(..) => Some(Def::Const(def_id())), + ItemFn(..) => Some(Def::Fn(def_id())), + ItemMod(..) => Some(Def::Mod(def_id())), + ItemGlobalAsm(..) => Some(Def::GlobalAsm(def_id())), + ItemTy(..) => Some(Def::TyAlias(def_id())), + ItemEnum(..) => Some(Def::Enum(def_id())), + ItemStruct(..) => Some(Def::Struct(def_id())), + ItemUnion(..) => Some(Def::Union(def_id())), + ItemTrait(..) => Some(Def::Trait(def_id())), + ItemTraitAlias(..) => { + bug!("trait aliases are not yet implemented (see issue #41517)") + }, + ItemExternCrate(_) | + ItemUse(..) | + ItemForeignMod(..) | + ItemImpl(..) => None, + } + } + NodeForeignItem(item) => { + let def_id = self.local_def_id(item.id); + match item.node { + ForeignItemFn(..) => Some(Def::Fn(def_id)), + ForeignItemStatic(_, m) => Some(Def::Static(def_id, m)), + ForeignItemType => Some(Def::TyForeign(def_id)), + } + } + NodeTraitItem(item) => { + let def_id = self.local_def_id(item.id); + match item.node { + TraitItemKind::Const(..) => Some(Def::AssociatedConst(def_id)), + TraitItemKind::Method(..) => Some(Def::Method(def_id)), + TraitItemKind::Type(..) => Some(Def::AssociatedTy(def_id)), + } + } + NodeImplItem(item) => { + let def_id = self.local_def_id(item.id); + match item.node { + ImplItemKind::Const(..) => Some(Def::AssociatedConst(def_id)), + ImplItemKind::Method(..) => Some(Def::Method(def_id)), + ImplItemKind::Type(..) => Some(Def::AssociatedTy(def_id)), + } + } + NodeVariant(variant) => { + let def_id = self.local_def_id(variant.node.data.id()); + Some(Def::Variant(def_id)) + } + NodeField(_) | + NodeExpr(_) | + NodeStmt(_) | + NodeTy(_) | + NodeTraitRef(_) | + NodePat(_) | + NodeBinding(_) | + NodeStructCtor(_) | + NodeLifetime(_) | + NodeVisibility(_) | + NodeBlock(_) => None, + NodeLocal(local) => { + Some(Def::Local(local.id)) + } + NodeMacroDef(macro_def) => { + Some(Def::Macro(self.local_def_id(macro_def.id), + MacroKind::Bang)) + } + NodeTyParam(param) => { + Some(Def::TyParam(self.local_def_id(param.id))) + } + } + } + fn entry_count(&self) -> usize { self.map.len() } @@ -1275,3 +1364,12 @@ fn node_id_to_string(map: &Map, id: NodeId, include_id: bool) -> String { } } } + +pub fn describe_def(tcx: TyCtxt, def_id: DefId) -> Option { + if let Some(node_id) = tcx.hir.as_local_node_id(def_id) { + tcx.hir.describe_def(node_id) + } else { + bug!("Calling local describe_def query provider for upstream DefId: {:?}", + def_id) + } +} diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index bc03f7ead8187..0fa1b95d8e777 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -43,6 +43,7 @@ use syntax::tokenstream::TokenStream; use syntax::util::ThinVec; use syntax::util::parser::ExprPrecedence; use ty::AdtKind; +use ty::maps::Providers; use rustc_data_structures::indexed_vec; @@ -2204,3 +2205,8 @@ pub type TraitMap = NodeMap>; // Map from the NodeId of a glob import to a list of items which are actually // imported. pub type GlobMap = NodeMap>; + + +pub fn provide(providers: &mut Providers) { + providers.describe_def = map::describe_def; +} diff --git a/src/librustc/mir/mono.rs b/src/librustc/mir/mono.rs index 49e5c0dc21f9e..7f8f2e9b90603 100644 --- a/src/librustc/mir/mono.rs +++ b/src/librustc/mir/mono.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use hir::def_id::DefId; use syntax::ast::NodeId; use syntax::symbol::InternedString; use ty::{Instance, TyCtxt}; @@ -21,7 +22,7 @@ use std::hash::Hash; #[derive(PartialEq, Eq, Clone, Copy, Debug, Hash)] pub enum MonoItem<'tcx> { Fn(Instance<'tcx>), - Static(NodeId), + Static(DefId), GlobalAsm(NodeId), } @@ -50,7 +51,9 @@ impl<'tcx> HashStable> for MonoItem<'tcx> { MonoItem::Fn(ref instance) => { instance.hash_stable(hcx, hasher); } - MonoItem::Static(node_id) | + MonoItem::Static(def_id) => { + def_id.hash_stable(hcx, hasher); + } MonoItem::GlobalAsm(node_id) => { hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| { node_id.hash_stable(hcx, hasher); diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 12d8d6f3d7481..118d4ddd4457b 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -756,7 +756,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { }).collect(), ref sty => vec![ArgKind::Arg("_".to_owned(), format!("{}", sty))], }; - if found.len()== expected.len() { + if found.len() == expected.len() { self.report_closure_arg_mismatch(span, found_span, found_trait_ref, @@ -874,6 +874,19 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { _ => ArgKind::Arg("_".to_owned(), "_".to_owned()) }).collect::>()) } + hir::map::NodeVariant(&hir::Variant { + span, + node: hir::Variant_ { + data: hir::VariantData::Tuple(ref fields, _), + .. + }, + .. + }) => { + (self.tcx.sess.codemap().def_span(span), + fields.iter().map(|field| { + ArgKind::Arg(format!("{}", field.name), "_".to_string()) + }).collect::>()) + } _ => panic!("non-FnLike node found: {:?}", node), } } diff --git a/src/librustc/ty/maps/mod.rs b/src/librustc/ty/maps/mod.rs index 21ffe6b895e72..be1d255afa191 100644 --- a/src/librustc/ty/maps/mod.rs +++ b/src/librustc/ty/maps/mod.rs @@ -349,7 +349,7 @@ define_maps! { <'tcx> [] fn export_name: ExportName(DefId) -> Option, [] fn contains_extern_indicator: ContainsExternIndicator(DefId) -> bool, [] fn symbol_export_level: GetSymbolExportLevel(DefId) -> SymbolExportLevel, - [] fn is_translated_function: IsTranslatedFunction(DefId) -> bool, + [] fn is_translated_item: IsTranslatedItem(DefId) -> bool, [] fn codegen_unit: CodegenUnit(InternedString) -> Arc>, [] fn compile_codegen_unit: CompileCodegenUnit(InternedString) -> Stats, [] fn output_filenames: output_filenames_node(CrateNum) diff --git a/src/librustc/ty/maps/on_disk_cache.rs b/src/librustc/ty/maps/on_disk_cache.rs index 56ed0f9106f30..17b44f6959f2f 100644 --- a/src/librustc/ty/maps/on_disk_cache.rs +++ b/src/librustc/ty/maps/on_disk_cache.rs @@ -347,22 +347,21 @@ impl<'sess> OnDiskCache<'sess> { return None }; - let mut cnum_map = self.cnum_map.borrow_mut(); - if cnum_map.is_none() { + // Initialize the cnum_map if it is not initialized yet. + if self.cnum_map.borrow().is_none() { + let mut cnum_map = self.cnum_map.borrow_mut(); *cnum_map = Some(Self::compute_cnum_map(tcx, &self.prev_cnums[..])); } - - let mut synthetic_expansion_infos = self.synthetic_expansion_infos.borrow_mut(); - let mut file_index_to_file = self.file_index_to_file.borrow_mut(); + let cnum_map = self.cnum_map.borrow(); let mut decoder = CacheDecoder { tcx, opaque: opaque::Decoder::new(&self.serialized_data[..], pos.to_usize()), codemap: self.codemap, cnum_map: cnum_map.as_ref().unwrap(), - file_index_to_file: &mut file_index_to_file, + file_index_to_file: &self.file_index_to_file, file_index_to_stable_id: &self.file_index_to_stable_id, - synthetic_expansion_infos: &mut synthetic_expansion_infos, + synthetic_expansion_infos: &self.synthetic_expansion_infos, }; match decode_tagged(&mut decoder, dep_node_index) { @@ -421,21 +420,21 @@ struct CacheDecoder<'a, 'tcx: 'a, 'x> { opaque: opaque::Decoder<'x>, codemap: &'x CodeMap, cnum_map: &'x IndexVec>, - synthetic_expansion_infos: &'x mut FxHashMap, - file_index_to_file: &'x mut FxHashMap>, + synthetic_expansion_infos: &'x RefCell>, + file_index_to_file: &'x RefCell>>, file_index_to_stable_id: &'x FxHashMap, } impl<'a, 'tcx, 'x> CacheDecoder<'a, 'tcx, 'x> { - fn file_index_to_file(&mut self, index: FileMapIndex) -> Rc { + fn file_index_to_file(&self, index: FileMapIndex) -> Rc { let CacheDecoder { - ref mut file_index_to_file, + ref file_index_to_file, ref file_index_to_stable_id, ref codemap, .. } = *self; - file_index_to_file.entry(index).or_insert_with(|| { + file_index_to_file.borrow_mut().entry(index).or_insert_with(|| { let stable_id = file_index_to_stable_id[&index]; codemap.filemap_by_stable_id(stable_id) .expect("Failed to lookup FileMap in new context.") @@ -572,19 +571,24 @@ impl<'a, 'tcx, 'x> SpecializedDecoder for CacheDecoder<'a, 'tcx, 'x> { let pos = AbsoluteBytePos::new(self.opaque.position()); let expn_info: ExpnInfo = Decodable::decode(self)?; let ctxt = SyntaxContext::allocate_directly(expn_info); - self.synthetic_expansion_infos.insert(pos, ctxt); + self.synthetic_expansion_infos.borrow_mut().insert(pos, ctxt); ctxt } TAG_EXPANSION_INFO_SHORTHAND => { let pos = AbsoluteBytePos::decode(self)?; - if let Some(ctxt) = self.synthetic_expansion_infos.get(&pos).cloned() { + let cached_ctxt = self.synthetic_expansion_infos + .borrow() + .get(&pos) + .cloned(); + + if let Some(ctxt) = cached_ctxt { ctxt } else { let expn_info = self.with_position(pos.to_usize(), |this| { ExpnInfo::decode(this) })?; let ctxt = SyntaxContext::allocate_directly(expn_info); - self.synthetic_expansion_infos.insert(pos, ctxt); + self.synthetic_expansion_infos.borrow_mut().insert(pos, ctxt); ctxt } } diff --git a/src/librustc/ty/maps/plumbing.rs b/src/librustc/ty/maps/plumbing.rs index f02c7cbd0ea3e..b654b6bc42a12 100644 --- a/src/librustc/ty/maps/plumbing.rs +++ b/src/librustc/ty/maps/plumbing.rs @@ -84,7 +84,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { let span = self.sess.codemap().def_span(span); let mut err = struct_span_err!(self.sess, span, E0391, - "unsupported cyclic reference between types/traits detected"); + "cyclic dependency detected"); err.span_label(span, "cyclic reference"); err.span_note(self.sess.codemap().def_span(stack[0].0), @@ -147,7 +147,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } match self.dep_graph.try_mark_green(self.global_tcx(), &dep_node) { Some(dep_node_index) => { - debug_assert!(self.dep_graph.is_green(dep_node_index)); + debug_assert!(self.dep_graph.is_green(&dep_node)); self.dep_graph.read_index(dep_node_index); Some(dep_node_index) } @@ -403,7 +403,7 @@ macro_rules! define_maps { dep_node: &DepNode) -> Result<$V, CycleError<'a, $tcx>> { - debug_assert!(tcx.dep_graph.is_green(dep_node_index)); + debug_assert!(tcx.dep_graph.is_green(dep_node)); // First we try to load the result from the on-disk cache let result = if Self::cache_on_disk(key) && @@ -491,7 +491,7 @@ macro_rules! define_maps { span: Span, dep_node: DepNode) -> Result<($V, DepNodeIndex), CycleError<'a, $tcx>> { - debug_assert!(tcx.dep_graph.node_color(&dep_node).is_none()); + debug_assert!(!tcx.dep_graph.dep_node_exists(&dep_node)); profq_msg!(tcx, ProfileQueriesMsg::ProviderBegin); let res = tcx.cycle_check(span, Query::$name(key), || { @@ -929,7 +929,7 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>, DepKind::ContainsExternIndicator => { force!(contains_extern_indicator, def_id!()); } - DepKind::IsTranslatedFunction => { force!(is_translated_function, def_id!()); } + DepKind::IsTranslatedItem => { force!(is_translated_item, def_id!()); } DepKind::OutputFilenames => { force!(output_filenames, LOCAL_CRATE); } DepKind::TargetFeaturesWhitelist => { force!(target_features_whitelist, LOCAL_CRATE); } diff --git a/src/librustc_data_structures/bitslice.rs b/src/librustc_data_structures/bitslice.rs index 7665bfd5b1117..2678861be0634 100644 --- a/src/librustc_data_structures/bitslice.rs +++ b/src/librustc_data_structures/bitslice.rs @@ -24,6 +24,7 @@ pub trait BitSlice { impl BitSlice for [Word] { /// Clears bit at `idx` to 0; returns true iff this changed `self.` + #[inline] fn clear_bit(&mut self, idx: usize) -> bool { let words = self; debug!("clear_bit: words={} idx={}", @@ -37,6 +38,7 @@ impl BitSlice for [Word] { } /// Sets bit at `idx` to 1; returns true iff this changed `self.` + #[inline] fn set_bit(&mut self, idx: usize) -> bool { let words = self; debug!("set_bit: words={} idx={}", @@ -50,6 +52,7 @@ impl BitSlice for [Word] { } /// Extracts value of bit at `idx` in `self`. + #[inline] fn get_bit(&self, idx: usize) -> bool { let words = self; let BitLookup { word, bit_mask, .. } = bit_lookup(idx); diff --git a/src/librustc_data_structures/indexed_vec.rs b/src/librustc_data_structures/indexed_vec.rs index 3e94b3f4d302a..11c2bd7368760 100644 --- a/src/librustc_data_structures/indexed_vec.rs +++ b/src/librustc_data_structures/indexed_vec.rs @@ -29,12 +29,16 @@ pub trait Idx: Copy + 'static + Eq + Debug { } impl Idx for usize { + #[inline] fn new(idx: usize) -> Self { idx } + #[inline] fn index(self) -> usize { self } } impl Idx for u32 { + #[inline] fn new(idx: usize) -> Self { assert!(idx <= u32::MAX as usize); idx as u32 } + #[inline] fn index(self) -> usize { self as usize } } @@ -73,11 +77,13 @@ macro_rules! newtype_index { pub struct $type($($pub)* u32); impl Idx for $type { + #[inline] fn new(value: usize) -> Self { assert!(value < ($max) as usize); $type(value as u32) } + #[inline] fn index(self) -> usize { self.0 as usize } diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index eb67c9ce4b7d8..b03108ed807da 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -36,7 +36,7 @@ use rustc_typeck as typeck; use rustc_privacy; use rustc_plugin::registry::Registry; use rustc_plugin as plugin; -use rustc_passes::{self, ast_validation, loops, consts, static_recursion, hir_stats}; +use rustc_passes::{self, ast_validation, loops, consts, hir_stats}; use rustc_const_eval::{self, check_match}; use super::Compilation; @@ -818,7 +818,8 @@ pub fn phase_2_configure_and_expand_inner<'a, F>(sess: &'a Session, &mut resolver, sess.opts.test, krate, - sess.diagnostic()) + sess.diagnostic(), + &sess.features.borrow()) }); // If we're actually rustdoc then there's no need to actually compile @@ -931,6 +932,7 @@ pub fn phase_2_configure_and_expand_inner<'a, F>(sess: &'a Session, } pub fn default_provide(providers: &mut ty::maps::Providers) { + hir::provide(providers); borrowck::provide(providers); mir::provide(providers); reachable::provide(providers); @@ -990,10 +992,6 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(trans: &TransCrate, "loop checking", || loops::check_crate(sess, &hir_map)); - time(time_passes, - "static item recursion checking", - || static_recursion::check_crate(sess, &hir_map))?; - let mut local_providers = ty::maps::Providers::default(); default_provide(&mut local_providers); trans.provide(&mut local_providers); diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs index 7ca8d0bdd500b..d57b8e78f18a9 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs @@ -1585,6 +1585,12 @@ impl MirPass for TypeckMir { let id = tcx.hir.as_local_node_id(def_id).unwrap(); debug!("run_pass: {:?}", def_id); + // When NLL is enabled, the borrow checker runs the typeck + // itself, so we don't need this MIR pass anymore. + if tcx.sess.nll() { + return; + } + if tcx.sess.err_count() > 0 { // compiling a broken program can obviously result in a // broken MIR, so try not to report duplicate errors. diff --git a/src/librustc_mir/dataflow/move_paths/builder.rs b/src/librustc_mir/dataflow/move_paths/builder.rs index 635d99e7737a9..d6f419f6cfb41 100644 --- a/src/librustc_mir/dataflow/move_paths/builder.rs +++ b/src/librustc_mir/dataflow/move_paths/builder.rs @@ -353,9 +353,12 @@ impl<'b, 'a, 'gcx, 'tcx> Gatherer<'b, 'a, 'gcx, 'tcx> { self.gather_move(&Place::Local(RETURN_PLACE)); } - TerminatorKind::Assert { .. } | - TerminatorKind::SwitchInt { .. } => { - // branching terminators - these don't move anything + TerminatorKind::Assert { ref cond, .. } => { + self.gather_operand(cond); + } + + TerminatorKind::SwitchInt { ref discr, .. } => { + self.gather_operand(discr); } TerminatorKind::Yield { ref value, .. } => { diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index a80dfaef0dab1..eb4ba21489c3d 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -368,8 +368,7 @@ fn collect_items_rec<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>, let recursion_depth_reset; match starting_point { - MonoItem::Static(node_id) => { - let def_id = tcx.hir.local_def_id(node_id); + MonoItem::Static(def_id) => { let instance = Instance::mono(tcx, def_id); // Sanity check whether this ended up being collected accidentally @@ -652,8 +651,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> { let tcx = self.tcx; let instance = Instance::mono(tcx, static_.def_id); if should_monomorphize_locally(tcx, &instance) { - let node_id = tcx.hir.as_local_node_id(static_.def_id).unwrap(); - self.output.push(MonoItem::Static(node_id)); + self.output.push(MonoItem::Static(static_.def_id)); } self.super_static(static_, context, location); @@ -946,10 +944,10 @@ impl<'b, 'a, 'v> ItemLikeVisitor<'v> for RootCollector<'b, 'a, 'v> { self.output.push(MonoItem::GlobalAsm(item.id)); } hir::ItemStatic(..) => { + let def_id = self.tcx.hir.local_def_id(item.id); debug!("RootCollector: ItemStatic({})", - def_id_to_string(self.tcx, - self.tcx.hir.local_def_id(item.id))); - self.output.push(MonoItem::Static(item.id)); + def_id_to_string(self.tcx, def_id)); + self.output.push(MonoItem::Static(def_id)); } hir::ItemConst(..) => { // const items only generate mono items if they are diff --git a/src/librustc_mir/monomorphize/item.rs b/src/librustc_mir/monomorphize/item.rs index a5078187a57e3..549919a2c8919 100644 --- a/src/librustc_mir/monomorphize/item.rs +++ b/src/librustc_mir/monomorphize/item.rs @@ -97,8 +97,7 @@ pub trait MonoItemExt<'a, 'tcx>: fmt::Debug { fn symbol_name(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> ty::SymbolName { match *self.as_mono_item() { MonoItem::Fn(instance) => tcx.symbol_name(instance), - MonoItem::Static(node_id) => { - let def_id = tcx.hir.local_def_id(node_id); + MonoItem::Static(def_id) => { tcx.symbol_name(Instance::mono(tcx, def_id)) } MonoItem::GlobalAsm(node_id) => { @@ -159,7 +158,7 @@ pub trait MonoItemExt<'a, 'tcx>: fmt::Debug { fn explicit_linkage(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Option { let def_id = match *self.as_mono_item() { MonoItem::Fn(ref instance) => instance.def_id(), - MonoItem::Static(node_id) => tcx.hir.local_def_id(node_id), + MonoItem::Static(def_id) => def_id, MonoItem::GlobalAsm(..) => return None, }; @@ -209,7 +208,7 @@ pub trait MonoItemExt<'a, 'tcx>: fmt::Debug { debug!("is_instantiable({:?})", self); let (def_id, substs) = match *self.as_mono_item() { MonoItem::Fn(ref instance) => (instance.def_id(), instance.substs), - MonoItem::Static(node_id) => (tcx.hir.local_def_id(node_id), Substs::empty()), + MonoItem::Static(def_id) => (def_id, Substs::empty()), // global asm never has predicates MonoItem::GlobalAsm(..) => return true }; @@ -218,14 +217,11 @@ pub trait MonoItemExt<'a, 'tcx>: fmt::Debug { } fn to_string(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> String { - let hir_map = &tcx.hir; - return match *self.as_mono_item() { MonoItem::Fn(instance) => { to_string_internal(tcx, "fn ", instance) }, - MonoItem::Static(node_id) => { - let def_id = hir_map.local_def_id(node_id); + MonoItem::Static(def_id) => { let instance = Instance::new(def_id, tcx.intern_substs(&[])); to_string_internal(tcx, "static ", instance) }, @@ -251,7 +247,9 @@ pub trait MonoItemExt<'a, 'tcx>: fmt::Debug { MonoItem::Fn(Instance { def, .. }) => { tcx.hir.as_local_node_id(def.def_id()) } - MonoItem::Static(node_id) | + MonoItem::Static(def_id) => { + tcx.hir.as_local_node_id(def_id) + } MonoItem::GlobalAsm(node_id) => { Some(node_id) } diff --git a/src/librustc_mir/monomorphize/partitioning.rs b/src/librustc_mir/monomorphize/partitioning.rs index e9471cdb4f949..2b558e71483c6 100644 --- a/src/librustc_mir/monomorphize/partitioning.rs +++ b/src/librustc_mir/monomorphize/partitioning.rs @@ -180,7 +180,9 @@ pub trait CodegenUnitExt<'tcx> { } } } - MonoItem::Static(node_id) | + MonoItem::Static(def_id) => { + tcx.hir.as_local_node_id(def_id) + } MonoItem::GlobalAsm(node_id) => { Some(node_id) } @@ -382,7 +384,15 @@ fn place_root_translation_items<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>, }; (Linkage::External, visibility) } - MonoItem::Static(node_id) | + MonoItem::Static(def_id) => { + let visibility = if tcx.is_exported_symbol(def_id) { + can_be_internalized = false; + default_visibility(def_id) + } else { + Visibility::Hidden + }; + (Linkage::External, visibility) + } MonoItem::GlobalAsm(node_id) => { let def_id = tcx.hir.local_def_id(node_id); let visibility = if tcx.is_exported_symbol(def_id) { @@ -643,7 +653,7 @@ fn characteristic_def_id_of_trans_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, Some(def_id) } - MonoItem::Static(node_id) | + MonoItem::Static(def_id) => Some(def_id), MonoItem::GlobalAsm(node_id) => Some(tcx.hir.local_def_id(node_id)), } } diff --git a/src/librustc_mir/transform/check_unsafety.rs b/src/librustc_mir/transform/check_unsafety.rs index bbc7803b84d8e..3524255e03772 100644 --- a/src/librustc_mir/transform/check_unsafety.rs +++ b/src/librustc_mir/transform/check_unsafety.rs @@ -386,10 +386,13 @@ fn is_enclosed(tcx: TyCtxt, if used_unsafe.contains(&parent_id) { Some(("block".to_string(), parent_id)) } else if let Some(hir::map::NodeItem(&hir::Item { - node: hir::ItemFn(_, hir::Unsafety::Unsafe, _, _, _, _), + node: hir::ItemFn(_, fn_unsafety, _, _, _, _), .. })) = tcx.hir.find(parent_id) { - Some(("fn".to_string(), parent_id)) + match fn_unsafety { + hir::Unsafety::Unsafe => Some(("fn".to_string(), parent_id)), + hir::Unsafety::Normal => None, + } } else { is_enclosed(tcx, used_unsafe, parent_id) } diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_passes/ast_validation.rs index bb6dbe632e316..a5dd8f1558e43 100644 --- a/src/librustc_passes/ast_validation.rs +++ b/src/librustc_passes/ast_validation.rs @@ -419,6 +419,141 @@ impl<'a> Visitor<'a> for AstValidator<'a> { } } +// Bans nested `impl Trait`, e.g. `impl Into`. +// Nested `impl Trait` _is_ allowed in associated type position, +// e.g `impl Iterator` +struct NestedImplTraitVisitor<'a> { + session: &'a Session, + outer_impl_trait: Option, +} + +impl<'a> NestedImplTraitVisitor<'a> { + fn with_impl_trait(&mut self, outer_impl_trait: Option, f: F) + where F: FnOnce(&mut NestedImplTraitVisitor<'a>) + { + let old_outer_impl_trait = self.outer_impl_trait; + self.outer_impl_trait = outer_impl_trait; + f(self); + self.outer_impl_trait = old_outer_impl_trait; + } +} + + +impl<'a> Visitor<'a> for NestedImplTraitVisitor<'a> { + fn visit_ty(&mut self, t: &'a Ty) { + if let TyKind::ImplTrait(_) = t.node { + if let Some(outer_impl_trait) = self.outer_impl_trait { + struct_span_err!(self.session, t.span, E0666, + "nested `impl Trait` is not allowed") + .span_label(outer_impl_trait, "outer `impl Trait`") + .span_label(t.span, "nested `impl Trait` here") + .emit(); + + } + self.with_impl_trait(Some(t.span), |this| visit::walk_ty(this, t)); + } else { + visit::walk_ty(self, t); + } + } + fn visit_path_parameters(&mut self, _: Span, path_parameters: &'a PathParameters) { + match *path_parameters { + PathParameters::AngleBracketed(ref params) => { + for type_ in ¶ms.types { + self.visit_ty(type_); + } + for type_binding in ¶ms.bindings { + // Type bindings such as `Item=impl Debug` in `Iterator` + // are allowed to contain nested `impl Trait`. + self.with_impl_trait(None, |this| visit::walk_ty(this, &type_binding.ty)); + } + } + PathParameters::Parenthesized(ref params) => { + for type_ in ¶ms.inputs { + self.visit_ty(type_); + } + if let Some(ref type_) = params.output { + // `-> Foo` syntax is essentially an associated type binding, + // so it is also allowed to contain nested `impl Trait`. + self.with_impl_trait(None, |this| visit::walk_ty(this, type_)); + } + } + } + } +} + +// Bans `impl Trait` in path projections like `::Item` or `Foo::Bar`. +struct ImplTraitProjectionVisitor<'a> { + session: &'a Session, + is_banned: bool, +} + +impl<'a> ImplTraitProjectionVisitor<'a> { + fn with_ban(&mut self, f: F) + where F: FnOnce(&mut ImplTraitProjectionVisitor<'a>) + { + let old_is_banned = self.is_banned; + self.is_banned = true; + f(self); + self.is_banned = old_is_banned; + } +} + +impl<'a> Visitor<'a> for ImplTraitProjectionVisitor<'a> { + fn visit_ty(&mut self, t: &'a Ty) { + match t.node { + TyKind::ImplTrait(_) => { + if self.is_banned { + struct_span_err!(self.session, t.span, E0667, + "`impl Trait` is not allowed in path parameters") + .emit(); + } + } + TyKind::Path(ref qself, ref path) => { + // We allow these: + // - `Option` + // - `option::Option` + // - `option::Option::Foo + // + // But not these: + // - `::Foo` + // - `option::Option::Foo`. + // + // To implement this, we disallow `impl Trait` from `qself` + // (for cases like `::Foo>`) + // but we allow `impl Trait` in `PathParameters` + // iff there are no more PathSegments. + if let Some(ref qself) = *qself { + // `impl Trait` in `qself` is always illegal + self.with_ban(|this| this.visit_ty(&qself.ty)); + } + + for (i, segment) in path.segments.iter().enumerate() { + // Allow `impl Trait` iff we're on the final path segment + if i == (path.segments.len() - 1) { + visit::walk_path_segment(self, path.span, segment); + } else { + self.with_ban(|this| + visit::walk_path_segment(this, path.span, segment)); + } + } + } + _ => visit::walk_ty(self, t), + } + } +} + pub fn check_crate(session: &Session, krate: &Crate) { + visit::walk_crate( + &mut NestedImplTraitVisitor { + session, + outer_impl_trait: None, + }, krate); + + visit::walk_crate( + &mut ImplTraitProjectionVisitor { + session, + is_banned: false, + }, krate); + visit::walk_crate(&mut AstValidator { session: session }, krate) } diff --git a/src/librustc_passes/diagnostics.rs b/src/librustc_passes/diagnostics.rs index 743f7b7326e9e..184fab778c601 100644 --- a/src/librustc_passes/diagnostics.rs +++ b/src/librustc_passes/diagnostics.rs @@ -128,22 +128,6 @@ impl !Enterprise for Foo { } Please note that negative impls are only allowed for auto traits. "##, -E0265: r##" -This error indicates that a static or constant references itself. -All statics and constants need to resolve to a value in an acyclic manner. - -For example, neither of the following can be sensibly compiled: - -```compile_fail,E0265 -const X: u32 = X; -``` - -```compile_fail,E0265 -const X: u32 = Y; -const Y: u32 = X; -``` -"##, - E0267: r##" This error indicates the use of a loop keyword (`break` or `continue`) inside a closure but outside of any loop. Erroneous code example: @@ -320,4 +304,6 @@ register_diagnostics! { E0567, // auto traits can not have generic parameters E0568, // auto traits can not have super traits E0642, // patterns aren't allowed in methods without bodies + E0666, // nested `impl Trait` is illegal + E0667, // `impl Trait` in projections } diff --git a/src/librustc_passes/lib.rs b/src/librustc_passes/lib.rs index 7db1f5665fbe5..6b9f407cbdb4d 100644 --- a/src/librustc_passes/lib.rs +++ b/src/librustc_passes/lib.rs @@ -42,7 +42,6 @@ pub mod consts; pub mod hir_stats; pub mod loops; mod mir_stats; -pub mod static_recursion; __build_diagnostic_array! { librustc_passes, DIAGNOSTICS } diff --git a/src/librustc_passes/static_recursion.rs b/src/librustc_passes/static_recursion.rs deleted file mode 100644 index 987243b523473..0000000000000 --- a/src/librustc_passes/static_recursion.rs +++ /dev/null @@ -1,280 +0,0 @@ -// Copyright 2014 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. - -// This compiler pass detects constants that refer to themselves -// recursively. - -use rustc::hir::map as hir_map; -use rustc::session::Session; -use rustc::hir::def::{Def, CtorKind}; -use rustc::util::common::ErrorReported; -use rustc::util::nodemap::{NodeMap, NodeSet}; - -use syntax::ast; -use syntax_pos::Span; -use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap}; -use rustc::hir; - -struct CheckCrateVisitor<'a, 'hir: 'a> { - sess: &'a Session, - hir_map: &'a hir_map::Map<'hir>, - // `discriminant_map` is a cache that associates the `NodeId`s of local - // variant definitions with the discriminant expression that applies to - // each one. If the variant uses the default values (starting from `0`), - // then `None` is stored. - discriminant_map: NodeMap>, - detected_recursive_ids: NodeSet, -} - -impl<'a, 'hir: 'a> Visitor<'hir> for CheckCrateVisitor<'a, 'hir> { - fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'hir> { - NestedVisitorMap::None - } - - fn visit_item(&mut self, it: &'hir hir::Item) { - match it.node { - hir::ItemStatic(..) | - hir::ItemConst(..) => { - let mut recursion_visitor = CheckItemRecursionVisitor::new(self); - recursion_visitor.visit_item(it); - } - hir::ItemEnum(ref enum_def, ref generics) => { - // We could process the whole enum, but handling the variants - // with discriminant expressions one by one gives more specific, - // less redundant output. - for variant in &enum_def.variants { - if let Some(_) = variant.node.disr_expr { - let mut recursion_visitor = CheckItemRecursionVisitor::new(self); - recursion_visitor.populate_enum_discriminants(enum_def); - recursion_visitor.visit_variant(variant, generics, it.id); - } - } - } - _ => {} - } - intravisit::walk_item(self, it) - } - - fn visit_trait_item(&mut self, ti: &'hir hir::TraitItem) { - match ti.node { - hir::TraitItemKind::Const(_, ref default) => { - if let Some(_) = *default { - let mut recursion_visitor = CheckItemRecursionVisitor::new(self); - recursion_visitor.visit_trait_item(ti); - } - } - _ => {} - } - intravisit::walk_trait_item(self, ti) - } - - fn visit_impl_item(&mut self, ii: &'hir hir::ImplItem) { - match ii.node { - hir::ImplItemKind::Const(..) => { - let mut recursion_visitor = CheckItemRecursionVisitor::new(self); - recursion_visitor.visit_impl_item(ii); - } - _ => {} - } - intravisit::walk_impl_item(self, ii) - } -} - -pub fn check_crate<'hir>(sess: &Session, hir_map: &hir_map::Map<'hir>) - -> Result<(), ErrorReported> -{ - let mut visitor = CheckCrateVisitor { - sess, - hir_map, - discriminant_map: NodeMap(), - detected_recursive_ids: NodeSet(), - }; - sess.track_errors(|| { - // FIXME(#37712) could use ItemLikeVisitor if trait items were item-like - hir_map.krate().visit_all_item_likes(&mut visitor.as_deep_visitor()); - }) -} - -struct CheckItemRecursionVisitor<'a, 'b: 'a, 'hir: 'b> { - sess: &'b Session, - hir_map: &'b hir_map::Map<'hir>, - discriminant_map: &'a mut NodeMap>, - idstack: Vec, - detected_recursive_ids: &'a mut NodeSet, -} - -impl<'a, 'b: 'a, 'hir: 'b> CheckItemRecursionVisitor<'a, 'b, 'hir> { - fn new(v: &'a mut CheckCrateVisitor<'b, 'hir>) -> Self { - CheckItemRecursionVisitor { - sess: v.sess, - hir_map: v.hir_map, - discriminant_map: &mut v.discriminant_map, - idstack: Vec::new(), - detected_recursive_ids: &mut v.detected_recursive_ids, - } - } - fn with_item_id_pushed(&mut self, id: ast::NodeId, f: F, span: Span) - where F: Fn(&mut Self) - { - if self.idstack.iter().any(|&x| x == id) { - if self.detected_recursive_ids.contains(&id) { - return; - } - self.detected_recursive_ids.insert(id); - let any_static = self.idstack.iter().any(|&x| { - if let hir_map::NodeItem(item) = self.hir_map.get(x) { - if let hir::ItemStatic(..) = item.node { - true - } else { - false - } - } else { - false - } - }); - if !any_static { - struct_span_err!(self.sess, span, E0265, "recursive constant") - .span_label(span, "recursion not allowed in constant") - .emit(); - } - return; - } - self.idstack.push(id); - f(self); - self.idstack.pop(); - } - // If a variant has an expression specifying its discriminant, then it needs - // to be checked just like a static or constant. However, if there are more - // variants with no explicitly specified discriminant, those variants will - // increment the same expression to get their values. - // - // So for every variant, we need to track whether there is an expression - // somewhere in the enum definition that controls its discriminant. We do - // this by starting from the end and searching backward. - fn populate_enum_discriminants(&mut self, enum_definition: &'hir hir::EnumDef) { - // Get the map, and return if we already processed this enum or if it - // has no variants. - match enum_definition.variants.first() { - None => { - return; - } - Some(variant) if self.discriminant_map.contains_key(&variant.node.data.id()) => { - return; - } - _ => {} - } - - // Go through all the variants. - let mut variant_stack: Vec = Vec::new(); - for variant in enum_definition.variants.iter().rev() { - variant_stack.push(variant.node.data.id()); - // When we find an expression, every variant currently on the stack - // is affected by that expression. - if let Some(expr) = variant.node.disr_expr { - for id in &variant_stack { - self.discriminant_map.insert(*id, Some(expr)); - } - variant_stack.clear() - } - } - // If we are at the top, that always starts at 0, so any variant on the - // stack has a default value and does not need to be checked. - for id in &variant_stack { - self.discriminant_map.insert(*id, None); - } - } -} - -impl<'a, 'b: 'a, 'hir: 'b> Visitor<'hir> for CheckItemRecursionVisitor<'a, 'b, 'hir> { - fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'hir> { - NestedVisitorMap::OnlyBodies(&self.hir_map) - } - fn visit_item(&mut self, it: &'hir hir::Item) { - self.with_item_id_pushed(it.id, |v| intravisit::walk_item(v, it), it.span); - } - - fn visit_enum_def(&mut self, - enum_definition: &'hir hir::EnumDef, - generics: &'hir hir::Generics, - item_id: ast::NodeId, - _: Span) { - self.populate_enum_discriminants(enum_definition); - intravisit::walk_enum_def(self, enum_definition, generics, item_id); - } - - fn visit_variant(&mut self, - variant: &'hir hir::Variant, - _: &'hir hir::Generics, - _: ast::NodeId) { - let variant_id = variant.node.data.id(); - let maybe_expr = *self.discriminant_map.get(&variant_id).unwrap_or_else(|| { - span_bug!(variant.span, - "`check_static_recursion` attempted to visit \ - variant with unknown discriminant") - }); - // If `maybe_expr` is `None`, that's because no discriminant is - // specified that affects this variant. Thus, no risk of recursion. - if let Some(expr) = maybe_expr { - let expr = &self.hir_map.body(expr).value; - self.with_item_id_pushed(expr.id, |v| intravisit::walk_expr(v, expr), expr.span); - } - } - - fn visit_trait_item(&mut self, ti: &'hir hir::TraitItem) { - self.with_item_id_pushed(ti.id, |v| intravisit::walk_trait_item(v, ti), ti.span); - } - - fn visit_impl_item(&mut self, ii: &'hir hir::ImplItem) { - self.with_item_id_pushed(ii.id, |v| intravisit::walk_impl_item(v, ii), ii.span); - } - - fn visit_path(&mut self, path: &'hir hir::Path, _: ast::NodeId) { - match path.def { - Def::Static(def_id, _) | - Def::AssociatedConst(def_id) | - Def::Const(def_id) => { - if let Some(node_id) = self.hir_map.as_local_node_id(def_id) { - match self.hir_map.get(node_id) { - hir_map::NodeItem(item) => self.visit_item(item), - hir_map::NodeTraitItem(item) => self.visit_trait_item(item), - hir_map::NodeImplItem(item) => self.visit_impl_item(item), - hir_map::NodeForeignItem(_) => {} - _ => { - span_bug!(path.span, - "expected item, found {}", - self.hir_map.node_to_string(node_id)); - } - } - } - } - // For variants, we only want to check expressions that - // affect the specific variant used, but we need to check - // the whole enum definition to see what expression that - // might be (if any). - Def::VariantCtor(variant_id, CtorKind::Const) => { - if let Some(variant_id) = self.hir_map.as_local_node_id(variant_id) { - let variant = self.hir_map.expect_variant(variant_id); - let enum_id = self.hir_map.get_parent(variant_id); - let enum_item = self.hir_map.expect_item(enum_id); - if let hir::ItemEnum(ref enum_def, ref generics) = enum_item.node { - self.populate_enum_discriminants(enum_def); - self.visit_variant(variant, generics, enum_id); - } else { - span_bug!(path.span, - "`check_static_recursion` found \ - non-enum in Def::VariantCtor"); - } - } - } - _ => (), - } - intravisit::walk_path(self, path); - } -} diff --git a/src/librustc_save_analysis/span_utils.rs b/src/librustc_save_analysis/span_utils.rs index 25e81e6f326e1..d5a58c08cbe5a 100644 --- a/src/librustc_save_analysis/span_utils.rs +++ b/src/librustc_save_analysis/span_utils.rs @@ -115,7 +115,7 @@ impl<'a> SpanUtils<'a> { // We keep track of the following two counts - the depth of nesting of // angle brackets, and the depth of nesting of square brackets. For the // angle bracket count, we only count tokens which occur outside of any - // square brackets (i.e. bracket_count == 0). The intutition here is + // square brackets (i.e. bracket_count == 0). The intuition here is // that we want to count angle brackets in the type, but not any which // could be in expression context (because these could mean 'less than', // etc.). @@ -151,18 +151,20 @@ impl<'a> SpanUtils<'a> { } prev = next; } - if angle_count != 0 || bracket_count != 0 { - let loc = self.sess.codemap().lookup_char_pos(span.lo()); - span_bug!( - span, - "Mis-counted brackets when breaking path? Parsing '{}' \ - in {}, line {}", - self.snippet(span), - loc.file.name, - loc.line - ); + #[cfg(debug_assertions)] { + if angle_count != 0 || bracket_count != 0 { + let loc = self.sess.codemap().lookup_char_pos(span.lo()); + span_bug!( + span, + "Mis-counted brackets when breaking path? Parsing '{}' \ + in {}, line {}", + self.snippet(span), + loc.file.name, + loc.line + ); + } } - if result.is_none() && prev.tok.is_ident() && angle_count == 0 { + if result.is_none() && prev.tok.is_ident() { return Some(prev.sp); } result diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index 466a86e7ea558..c0785f5393716 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -1004,6 +1004,7 @@ fn collect_and_partition_translation_items<'a, 'tcx>( let translation_items: DefIdSet = items.iter().filter_map(|trans_item| { match *trans_item { MonoItem::Fn(ref instance) => Some(instance.def_id()), + MonoItem::Static(def_id) => Some(def_id), _ => None, } }).collect(); @@ -1107,7 +1108,7 @@ impl CrateInfo { } } -fn is_translated_function(tcx: TyCtxt, id: DefId) -> bool { +fn is_translated_item(tcx: TyCtxt, id: DefId) -> bool { let (all_trans_items, _) = tcx.collect_and_partition_translation_items(LOCAL_CRATE); all_trans_items.contains(&id) @@ -1222,7 +1223,7 @@ pub fn provide(providers: &mut Providers) { providers.collect_and_partition_translation_items = collect_and_partition_translation_items; - providers.is_translated_function = is_translated_function; + providers.is_translated_item = is_translated_item; providers.codegen_unit = |tcx, name| { let (_, all) = tcx.collect_and_partition_translation_items(LOCAL_CRATE); diff --git a/src/librustc_trans/callee.rs b/src/librustc_trans/callee.rs index c3d5e08c73e7e..8c40aa6a2acba 100644 --- a/src/librustc_trans/callee.rs +++ b/src/librustc_trans/callee.rs @@ -149,7 +149,7 @@ pub fn get_fn<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, unsafe { llvm::LLVMRustSetLinkage(llfn, llvm::Linkage::ExternalLinkage); - if cx.tcx.is_translated_function(instance_def_id) { + if cx.tcx.is_translated_item(instance_def_id) { if instance_def_id.is_local() { if !cx.tcx.is_exported_symbol(instance_def_id) { llvm::LLVMRustSetVisibility(llfn, llvm::Visibility::Hidden); diff --git a/src/librustc_trans/consts.rs b/src/librustc_trans/consts.rs index d5b33d837c5bd..1608c4a87bf5c 100644 --- a/src/librustc_trans/consts.rs +++ b/src/librustc_trans/consts.rs @@ -16,7 +16,7 @@ use rustc::hir::map as hir_map; use rustc::middle::const_val::ConstEvalErr; use debuginfo; use base; -use monomorphize::{MonoItem, MonoItemExt}; +use monomorphize::MonoItem; use common::{CodegenCx, val_ty}; use declare; use monomorphize::Instance; @@ -110,7 +110,17 @@ pub fn get_static(cx: &CodegenCx, def_id: DefId) -> ValueRef { return g; } + let defined_in_current_codegen_unit = cx.codegen_unit + .items() + .contains_key(&MonoItem::Static(def_id)); + assert!(!defined_in_current_codegen_unit, + "consts::get_static() should always hit the cache for \ + statics defined in the same CGU, but did not for `{:?}`", + def_id); + let ty = instance.ty(cx.tcx); + let sym = cx.tcx.symbol_name(instance); + let g = if let Some(id) = cx.tcx.hir.as_local_node_id(def_id) { let llty = cx.layout_of(ty).llvm_type(cx); @@ -118,13 +128,6 @@ pub fn get_static(cx: &CodegenCx, def_id: DefId) -> ValueRef { hir_map::NodeItem(&hir::Item { ref attrs, span, node: hir::ItemStatic(..), .. }) => { - let sym = MonoItem::Static(id).symbol_name(cx.tcx); - - let defined_in_current_codegen_unit = cx.codegen_unit - .items() - .contains_key(&MonoItem::Static(id)); - assert!(!defined_in_current_codegen_unit); - if declare::get_declared_value(cx, &sym[..]).is_some() { span_bug!(span, "trans: Conflicting symbol names for static?"); } @@ -143,7 +146,7 @@ pub fn get_static(cx: &CodegenCx, def_id: DefId) -> ValueRef { hir_map::NodeForeignItem(&hir::ForeignItem { ref attrs, span, node: hir::ForeignItemStatic(..), .. }) => { - let sym = cx.tcx.symbol_name(instance); + let g = if let Some(name) = attr::first_attr_value_str_by_name(&attrs, "linkage") { // If this is a static with a linkage specified, then we need to handle @@ -203,8 +206,6 @@ pub fn get_static(cx: &CodegenCx, def_id: DefId) -> ValueRef { g } else { - let sym = cx.tcx.symbol_name(instance); - // FIXME(nagisa): perhaps the map of externs could be offloaded to llvm somehow? // FIXME(nagisa): investigate whether it can be changed into define_global let g = declare::declare_global(cx, &sym, cx.layout_of(ty).llvm_type(cx)); @@ -225,8 +226,15 @@ pub fn get_static(cx: &CodegenCx, def_id: DefId) -> ValueRef { // statically in the final application, we always mark such symbols as 'dllimport'. // If final linkage happens to be static, we rely on compiler-emitted __imp_ stubs to // make things work. - unsafe { - llvm::LLVMSetDLLStorageClass(g, llvm::DLLStorageClass::DllImport); + // + // However, in some scenarios we defer emission of statics to downstream + // crates, so there are cases where a static with an upstream DefId + // is actually present in the current crate. We can find out via the + // is_translated_item query. + if !cx.tcx.is_translated_item(def_id) { + unsafe { + llvm::LLVMSetDLLStorageClass(g, llvm::DLLStorageClass::DllImport); + } } } g @@ -245,12 +253,11 @@ pub fn get_static(cx: &CodegenCx, def_id: DefId) -> ValueRef { } pub fn trans_static<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, - m: hir::Mutability, - id: ast::NodeId, + def_id: DefId, + is_mutable: bool, attrs: &[ast::Attribute]) -> Result> { unsafe { - let def_id = cx.tcx.hir.local_def_id(id); let g = get_static(cx, def_id); let v = ::mir::trans_static_initializer(cx, def_id)?; @@ -298,13 +305,13 @@ pub fn trans_static<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, // As an optimization, all shared statics which do not have interior // mutability are placed into read-only memory. - if m != hir::MutMutable { + if !is_mutable { if cx.type_is_freeze(ty) { llvm::LLVMSetGlobalConstant(g, llvm::True); } } - debuginfo::create_global_var_metadata(cx, id, g); + debuginfo::create_global_var_metadata(cx, def_id, g); if attr::contains_name(attrs, "thread_local") { llvm::set_thread_local_mode(g, cx.tls_model); diff --git a/src/librustc_trans/debuginfo/metadata.rs b/src/librustc_trans/debuginfo/metadata.rs index 62ba91840d95e..2c430d03c968e 100644 --- a/src/librustc_trans/debuginfo/metadata.rs +++ b/src/librustc_trans/debuginfo/metadata.rs @@ -14,7 +14,7 @@ use self::EnumDiscriminantInfo::*; use super::utils::{debug_context, DIB, span_start, get_namespace_for_item, create_DIArray, is_node_local_to_unit}; -use super::namespace::mangled_name_of_item; +use super::namespace::mangled_name_of_instance; use super::type_names::compute_debuginfo_type_name; use super::{CrateDebugContext}; use abi; @@ -1634,19 +1634,18 @@ fn create_union_stub<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, /// /// Adds the created metadata nodes directly to the crate's IR. pub fn create_global_var_metadata(cx: &CodegenCx, - node_id: ast::NodeId, + def_id: DefId, global: ValueRef) { if cx.dbg_cx.is_none() { return; } let tcx = cx.tcx; - let node_def_id = tcx.hir.local_def_id(node_id); - let no_mangle = attr::contains_name(&tcx.get_attrs(node_def_id), "no_mangle"); + let no_mangle = attr::contains_name(&tcx.get_attrs(def_id), "no_mangle"); // We may want to remove the namespace scope if we're in an extern block, see: // https://github.com/rust-lang/rust/pull/46457#issuecomment-351750952 - let var_scope = get_namespace_for_item(cx, node_def_id); - let span = cx.tcx.def_span(node_def_id); + let var_scope = get_namespace_for_item(cx, def_id); + let span = cx.tcx.def_span(def_id); let (file_metadata, line_number) = if span != syntax_pos::DUMMY_SP { let loc = span_start(cx, span); @@ -1655,15 +1654,15 @@ pub fn create_global_var_metadata(cx: &CodegenCx, (unknown_file_metadata(cx), UNKNOWN_LINE_NUMBER) }; - let is_local_to_unit = is_node_local_to_unit(cx, node_id); - let variable_type = Instance::mono(cx.tcx, node_def_id).ty(cx.tcx); + let is_local_to_unit = is_node_local_to_unit(cx, def_id); + let variable_type = Instance::mono(cx.tcx, def_id).ty(cx.tcx); let type_metadata = type_metadata(cx, variable_type, span); - let var_name = tcx.item_name(node_def_id).to_string(); + let var_name = tcx.item_name(def_id).to_string(); let var_name = CString::new(var_name).unwrap(); let linkage_name = if no_mangle { None } else { - let linkage_name = mangled_name_of_item(cx, node_id); + let linkage_name = mangled_name_of_instance(cx, Instance::mono(tcx, def_id)); Some(CString::new(linkage_name.to_string()).unwrap()) }; diff --git a/src/librustc_trans/debuginfo/mod.rs b/src/librustc_trans/debuginfo/mod.rs index 9071eb776d529..16279f31836a9 100644 --- a/src/librustc_trans/debuginfo/mod.rs +++ b/src/librustc_trans/debuginfo/mod.rs @@ -254,14 +254,14 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, let linkage_name = mangled_name_of_instance(cx, instance); let scope_line = span_start(cx, span).line; - - let local_id = cx.tcx.hir.as_local_node_id(instance.def_id()); - let is_local_to_unit = local_id.map_or(false, |id| is_node_local_to_unit(cx, id)); + let is_local_to_unit = is_node_local_to_unit(cx, def_id); let function_name = CString::new(name).unwrap(); let linkage_name = CString::new(linkage_name.to_string()).unwrap(); let mut flags = DIFlags::FlagPrototyped; + + let local_id = cx.tcx.hir.as_local_node_id(def_id); match *cx.sess().entry_fn.borrow() { Some((id, _)) => { if local_id == Some(id) { diff --git a/src/librustc_trans/debuginfo/namespace.rs b/src/librustc_trans/debuginfo/namespace.rs index 46067a4330396..891bf649c388a 100644 --- a/src/librustc_trans/debuginfo/namespace.rs +++ b/src/librustc_trans/debuginfo/namespace.rs @@ -14,7 +14,6 @@ use super::metadata::{unknown_file_metadata, UNKNOWN_LINE_NUMBER}; use super::utils::{DIB, debug_context}; use monomorphize::Instance; use rustc::ty; -use syntax::ast; use llvm; use llvm::debuginfo::DIScope; @@ -33,16 +32,6 @@ pub fn mangled_name_of_instance<'a, 'tcx>( tcx.symbol_name(instance) } -pub fn mangled_name_of_item<'a, 'tcx>( - cx: &CodegenCx<'a, 'tcx>, - node_id: ast::NodeId, -) -> ty::SymbolName { - let tcx = cx.tcx; - let node_def_id = tcx.hir.local_def_id(node_id); - let instance = Instance::mono(tcx, node_def_id); - tcx.symbol_name(instance) -} - pub fn item_namespace(cx: &CodegenCx, def_id: DefId) -> DIScope { if let Some(&scope) = debug_context(cx).namespace_map.borrow().get(&def_id) { return scope; diff --git a/src/librustc_trans/debuginfo/utils.rs b/src/librustc_trans/debuginfo/utils.rs index c571b84b8e9ed..9559cd4d9ea2d 100644 --- a/src/librustc_trans/debuginfo/utils.rs +++ b/src/librustc_trans/debuginfo/utils.rs @@ -21,9 +21,8 @@ use llvm::debuginfo::{DIScope, DIBuilderRef, DIDescriptor, DIArray}; use common::{CodegenCx}; use syntax_pos::{self, Span}; -use syntax::ast; -pub fn is_node_local_to_unit(cx: &CodegenCx, node_id: ast::NodeId) -> bool +pub fn is_node_local_to_unit(cx: &CodegenCx, def_id: DefId) -> bool { // The is_local_to_unit flag indicates whether a function is local to the // current compilation unit (i.e. if it is *static* in the C-sense). The @@ -33,7 +32,6 @@ pub fn is_node_local_to_unit(cx: &CodegenCx, node_id: ast::NodeId) -> bool // visible). It might better to use the `exported_items` set from // `driver::CrateAnalysis` in the future, but (atm) this set is not // available in the translation pass. - let def_id = cx.tcx.hir.local_def_id(node_id); !cx.tcx.is_exported_symbol(def_id) } diff --git a/src/librustc_trans/trans_item.rs b/src/librustc_trans/trans_item.rs index 5eb6679fe252c..91c1097fc7f8a 100644 --- a/src/librustc_trans/trans_item.rs +++ b/src/librustc_trans/trans_item.rs @@ -24,10 +24,11 @@ use llvm; use monomorphize::Instance; use type_of::LayoutLlvmExt; use rustc::hir; +use rustc::hir::def::Def; +use rustc::hir::def_id::DefId; use rustc::mir::mono::{Linkage, Visibility}; use rustc::ty::TypeFoldable; use rustc::ty::layout::LayoutOf; -use syntax::ast; use syntax::attr; use std::fmt; @@ -44,19 +45,25 @@ pub trait MonoItemExt<'a, 'tcx>: fmt::Debug + BaseMonoItemExt<'a, 'tcx> { cx.codegen_unit.name()); match *self.as_mono_item() { - MonoItem::Static(node_id) => { + MonoItem::Static(def_id) => { let tcx = cx.tcx; - let item = tcx.hir.expect_item(node_id); - if let hir::ItemStatic(_, m, _) = item.node { - match consts::trans_static(&cx, m, item.id, &item.attrs) { - Ok(_) => { /* Cool, everything's alright. */ }, - Err(err) => { - err.report(tcx, item.span, "static"); - } - }; - } else { - span_bug!(item.span, "Mismatch between hir::Item type and TransItem type") - } + let is_mutable = match tcx.describe_def(def_id) { + Some(Def::Static(_, is_mutable)) => is_mutable, + Some(other) => { + bug!("Expected Def::Static, found {:?}", other) + } + None => { + bug!("Expected Def::Static for {:?}, found nothing", def_id) + } + }; + let attrs = tcx.get_attrs(def_id); + + match consts::trans_static(&cx, def_id, is_mutable, &attrs) { + Ok(_) => { /* Cool, everything's alright. */ }, + Err(err) => { + err.report(tcx, tcx.def_span(def_id), "static"); + } + }; } MonoItem::GlobalAsm(node_id) => { let item = cx.tcx.hir.expect_item(node_id); @@ -91,8 +98,8 @@ pub trait MonoItemExt<'a, 'tcx>: fmt::Debug + BaseMonoItemExt<'a, 'tcx> { debug!("symbol {}", &symbol_name); match *self.as_mono_item() { - MonoItem::Static(node_id) => { - predefine_static(cx, node_id, linkage, visibility, &symbol_name); + MonoItem::Static(def_id) => { + predefine_static(cx, def_id, linkage, visibility, &symbol_name); } MonoItem::Fn(instance) => { predefine_fn(cx, instance, linkage, visibility, &symbol_name); @@ -126,17 +133,16 @@ pub trait MonoItemExt<'a, 'tcx>: fmt::Debug + BaseMonoItemExt<'a, 'tcx> { impl<'a, 'tcx> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> {} fn predefine_static<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, - node_id: ast::NodeId, + def_id: DefId, linkage: Linkage, visibility: Visibility, symbol_name: &str) { - let def_id = cx.tcx.hir.local_def_id(node_id); let instance = Instance::mono(cx.tcx, def_id); let ty = instance.ty(cx.tcx); let llty = cx.layout_of(ty).llvm_type(cx); let g = declare::define_global(cx, symbol_name, llty).unwrap_or_else(|| { - cx.sess().span_fatal(cx.tcx.hir.span(node_id), + cx.sess().span_fatal(cx.tcx.def_span(def_id), &format!("symbol `{}` is already defined", symbol_name)) }); diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 854cefcb59725..d7d856fe3ad06 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -500,11 +500,6 @@ mod memchr; // The runtime entry point and a few unstable public functions used by the // compiler pub mod rt; -// The trait to support returning arbitrary types in the main function -mod termination; - -#[unstable(feature = "termination_trait", issue = "43301")] -pub use self::termination::Termination; // Include a number of private modules that exist solely to provide // the rustdoc documentation for primitive types. Using `include!` diff --git a/src/libstd/process.rs b/src/libstd/process.rs index 9b2f815b71383..e25599b8bd871 100644 --- a/src/libstd/process.rs +++ b/src/libstd/process.rs @@ -1392,6 +1392,73 @@ pub fn id() -> u32 { ::sys::os::getpid() } +#[cfg(target_arch = "wasm32")] +mod exit { + pub const SUCCESS: i32 = 0; + pub const FAILURE: i32 = 1; +} +#[cfg(not(target_arch = "wasm32"))] +mod exit { + use libc; + pub const SUCCESS: i32 = libc::EXIT_SUCCESS; + pub const FAILURE: i32 = libc::EXIT_FAILURE; +} + +/// A trait for implementing arbitrary return types in the `main` function. +/// +/// The c-main function only supports to return integers as return type. +/// So, every type implementing the `Termination` trait has to be converted +/// to an integer. +/// +/// The default implementations are returning `libc::EXIT_SUCCESS` to indicate +/// a successful execution. In case of a failure, `libc::EXIT_FAILURE` is returned. +#[cfg_attr(not(test), lang = "termination")] +#[unstable(feature = "termination_trait_lib", issue = "43301")] +#[rustc_on_unimplemented = + "`main` can only return types that implement {Termination}, not `{Self}`"] +pub trait Termination { + /// Is called to get the representation of the value as status code. + /// This status code is returned to the operating system. + fn report(self) -> i32; +} + +#[unstable(feature = "termination_trait_lib", issue = "43301")] +impl Termination for () { + fn report(self) -> i32 { exit::SUCCESS } +} + +#[unstable(feature = "termination_trait_lib", issue = "43301")] +impl Termination for Result { + fn report(self) -> i32 { + match self { + Ok(val) => val.report(), + Err(err) => { + eprintln!("Error: {:?}", err); + exit::FAILURE + } + } + } +} + +#[unstable(feature = "termination_trait_lib", issue = "43301")] +impl Termination for ! { + fn report(self) -> i32 { unreachable!(); } +} + +#[unstable(feature = "termination_trait_lib", issue = "43301")] +impl Termination for bool { + fn report(self) -> i32 { + if self { exit::SUCCESS } else { exit::FAILURE } + } +} + +#[unstable(feature = "termination_trait_lib", issue = "43301")] +impl Termination for i32 { + fn report(self) -> i32 { + self + } +} + #[cfg(all(test, not(any(target_os = "cloudabi", target_os = "emscripten"))))] mod tests { use io::prelude::*; diff --git a/src/libstd/rt.rs b/src/libstd/rt.rs index 9dbaf784f89e0..e1392762a59dc 100644 --- a/src/libstd/rt.rs +++ b/src/libstd/rt.rs @@ -68,7 +68,7 @@ fn lang_start_internal(main: &(Fn() -> i32 + Sync + ::panic::RefUnwindSafe), #[cfg(not(test))] #[lang = "start"] -fn lang_start +fn lang_start (main: fn() -> T, argc: isize, argv: *const *const u8) -> isize { lang_start_internal(&move || main().report(), argc, argv) diff --git a/src/libstd/termination.rs b/src/libstd/termination.rs deleted file mode 100644 index dc7fa53aab632..0000000000000 --- a/src/libstd/termination.rs +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright 2017 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. - -use fmt::Debug; -#[cfg(target_arch = "wasm32")] -mod exit { - pub const SUCCESS: i32 = 0; - pub const FAILURE: i32 = 1; -} -#[cfg(not(target_arch = "wasm32"))] -mod exit { - use libc; - pub const SUCCESS: i32 = libc::EXIT_SUCCESS; - pub const FAILURE: i32 = libc::EXIT_FAILURE; -} - -/// A trait for implementing arbitrary return types in the `main` function. -/// -/// The c-main function only supports to return integers as return type. -/// So, every type implementing the `Termination` trait has to be converted -/// to an integer. -/// -/// The default implementations are returning `libc::EXIT_SUCCESS` to indicate -/// a successful execution. In case of a failure, `libc::EXIT_FAILURE` is returned. -#[cfg_attr(not(test), lang = "termination")] -#[unstable(feature = "termination_trait", issue = "43301")] -#[rustc_on_unimplemented = - "`main` can only return types that implement {Termination}, not `{Self}`"] -pub trait Termination { - /// Is called to get the representation of the value as status code. - /// This status code is returned to the operating system. - fn report(self) -> i32; -} - -#[unstable(feature = "termination_trait", issue = "43301")] -impl Termination for () { - fn report(self) -> i32 { exit::SUCCESS } -} - -#[unstable(feature = "termination_trait", issue = "43301")] -impl Termination for Result { - fn report(self) -> i32 { - match self { - Ok(val) => val.report(), - Err(err) => { - eprintln!("Error: {:?}", err); - exit::FAILURE - } - } - } -} - -#[unstable(feature = "termination_trait", issue = "43301")] -impl Termination for ! { - fn report(self) -> i32 { unreachable!(); } -} - -#[unstable(feature = "termination_trait", issue = "43301")] -impl Termination for bool { - fn report(self) -> i32 { - if self { exit::SUCCESS } else { exit::FAILURE } - } -} - -#[unstable(feature = "termination_trait", issue = "43301")] -impl Termination for i32 { - fn report(self) -> i32 { - self - } -} diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index 7681f55bd8ccb..b88e064e7e56d 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -319,14 +319,8 @@ impl<'a> AstBuilder for ExtCtxt<'a> { types: Vec>, bindings: Vec ) -> ast::Path { - use syntax::parse::token; - let last_identifier = idents.pop().unwrap(); let mut segments: Vec = Vec::new(); - if global && - !idents.first().map_or(false, |&ident| token::Ident(ident).is_path_segment_keyword()) { - segments.push(ast::PathSegment::crate_root(span)); - } segments.extend(idents.into_iter().map(|i| ast::PathSegment::from_ident(i, span))); let parameters = if !lifetimes.is_empty() || !types.is_empty() || !bindings.is_empty() { @@ -335,7 +329,9 @@ impl<'a> AstBuilder for ExtCtxt<'a> { None }; segments.push(ast::PathSegment { identifier: last_identifier, span, parameters }); - ast::Path { span, segments } + let path = ast::Path { span, segments }; + + if global { path.default_to_global() } else { path } } /// Constructs a qualified path. diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index f7cebed5f62cd..ba24d7f914be1 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -432,9 +432,6 @@ declare_features! ( // `foo.rs` as an alternative to `foo/mod.rs` (active, non_modrs_mods, "1.24.0", Some(44660)), - // Nested `impl Trait` - (active, nested_impl_trait, "1.24.0", Some(34511)), - // Termination trait in main (RFC 1937) (active, termination_trait, "1.24.0", Some(43301)), @@ -1352,73 +1349,8 @@ fn contains_novel_literal(item: &ast::MetaItem) -> bool { } } -// Bans nested `impl Trait`, e.g. `impl Into`. -// Nested `impl Trait` _is_ allowed in associated type position, -// e.g `impl Iterator` -struct NestedImplTraitVisitor<'a> { - context: &'a Context<'a>, - is_in_impl_trait: bool, -} - -impl<'a> NestedImplTraitVisitor<'a> { - fn with_impl_trait(&mut self, is_in_impl_trait: bool, f: F) - where F: FnOnce(&mut NestedImplTraitVisitor<'a>) - { - let old_is_in_impl_trait = self.is_in_impl_trait; - self.is_in_impl_trait = is_in_impl_trait; - f(self); - self.is_in_impl_trait = old_is_in_impl_trait; - } -} - - -impl<'a> Visitor<'a> for NestedImplTraitVisitor<'a> { - fn visit_ty(&mut self, t: &'a ast::Ty) { - if let ast::TyKind::ImplTrait(_) = t.node { - if self.is_in_impl_trait { - gate_feature_post!(&self, nested_impl_trait, t.span, - "nested `impl Trait` is experimental" - ); - } - self.with_impl_trait(true, |this| visit::walk_ty(this, t)); - } else { - visit::walk_ty(self, t); - } - } - fn visit_path_parameters(&mut self, _: Span, path_parameters: &'a ast::PathParameters) { - match *path_parameters { - ast::PathParameters::AngleBracketed(ref params) => { - for type_ in ¶ms.types { - self.visit_ty(type_); - } - for type_binding in ¶ms.bindings { - // Type bindings such as `Item=impl Debug` in `Iterator` - // are allowed to contain nested `impl Trait`. - self.with_impl_trait(false, |this| visit::walk_ty(this, &type_binding.ty)); - } - } - ast::PathParameters::Parenthesized(ref params) => { - for type_ in ¶ms.inputs { - self.visit_ty(type_); - } - if let Some(ref type_) = params.output { - // `-> Foo` syntax is essentially an associated type binding, - // so it is also allowed to contain nested `impl Trait`. - self.with_impl_trait(false, |this| visit::walk_ty(this, type_)); - } - } - } - } -} - impl<'a> PostExpansionVisitor<'a> { - fn whole_crate_feature_gates(&mut self, krate: &ast::Crate) { - visit::walk_crate( - &mut NestedImplTraitVisitor { - context: self.context, - is_in_impl_trait: false, - }, krate); - + fn whole_crate_feature_gates(&mut self, _krate: &ast::Crate) { for &(ident, span) in &*self.context.parse_sess.non_modrs_mods.borrow() { if !span.allows_unstable() { let cx = &self.context; diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 1a33de8442982..efc191f24ac6f 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -6482,6 +6482,8 @@ impl<'a> Parser<'a> { && self.look_ahead(1, |t| *t != token::OpenDelim(token::Brace)) { // UNSAFE FUNCTION ITEM self.bump(); // `unsafe` + // `{` is also expected after `unsafe`, in case of error, include it in the diagnostic + self.check(&token::OpenDelim(token::Brace)); let abi = if self.eat_keyword(keywords::Extern) { self.parse_opt_abi()?.unwrap_or(Abi::C) } else { diff --git a/src/libsyntax/test.rs b/src/libsyntax/test.rs index 7b119c576db58..e732ac3a635ba 100644 --- a/src/libsyntax/test.rs +++ b/src/libsyntax/test.rs @@ -32,6 +32,7 @@ use ext::build::AstBuilder; use ext::expand::ExpansionConfig; use ext::hygiene::{Mark, SyntaxContext}; use fold::Folder; +use feature_gate::Features; use util::move_map::MoveMap; use fold; use parse::{token, ParseSess}; @@ -63,6 +64,7 @@ struct TestCtxt<'a> { reexport_test_harness_main: Option, is_libtest: bool, ctxt: SyntaxContext, + features: &'a Features, // top-level re-export submodule, filled out after folding is finished toplevel_reexport: Option, @@ -74,7 +76,8 @@ pub fn modify_for_testing(sess: &ParseSess, resolver: &mut Resolver, should_test: bool, krate: ast::Crate, - span_diagnostic: &errors::Handler) -> ast::Crate { + span_diagnostic: &errors::Handler, + features: &Features) -> ast::Crate { // Check for #[reexport_test_harness_main = "some_name"] which // creates a `use some_name = __test::main;`. This needs to be // unconditional, so that the attribute is still marked as used in @@ -84,7 +87,8 @@ pub fn modify_for_testing(sess: &ParseSess, "reexport_test_harness_main"); if should_test { - generate_test_harness(sess, resolver, reexport_test_harness_main, krate, span_diagnostic) + generate_test_harness(sess, resolver, reexport_test_harness_main, + krate, span_diagnostic, features) } else { krate } @@ -265,16 +269,20 @@ fn generate_test_harness(sess: &ParseSess, resolver: &mut Resolver, reexport_test_harness_main: Option, krate: ast::Crate, - sd: &errors::Handler) -> ast::Crate { + sd: &errors::Handler, + features: &Features) -> ast::Crate { // Remove the entry points let mut cleaner = EntryPointCleaner { depth: 0 }; let krate = cleaner.fold_crate(krate); let mark = Mark::fresh(Mark::root()); + let mut econfig = ExpansionConfig::default("test".to_string()); + econfig.features = Some(features); + let cx = TestCtxt { span_diagnostic: sd, - ext_cx: ExtCtxt::new(sess, ExpansionConfig::default("test".to_string()), resolver), + ext_cx: ExtCtxt::new(sess, econfig, resolver), path: Vec::new(), testfns: Vec::new(), reexport_test_harness_main, @@ -282,6 +290,7 @@ fn generate_test_harness(sess: &ParseSess, is_libtest: attr::find_crate_name(&krate.attrs).map(|s| s == "test").unwrap_or(false), toplevel_reexport: None, ctxt: SyntaxContext::empty().apply_mark(mark), + features, }; mark.set_expn_info(ExpnInfo { @@ -318,71 +327,105 @@ enum HasTestSignature { fn is_test_fn(cx: &TestCtxt, i: &ast::Item) -> bool { let has_test_attr = attr::contains_name(&i.attrs, "test"); - fn has_test_signature(i: &ast::Item) -> HasTestSignature { + fn has_test_signature(cx: &TestCtxt, i: &ast::Item) -> HasTestSignature { match i.node { - ast::ItemKind::Fn(ref decl, _, _, _, ref generics, _) => { - let no_output = match decl.output { - ast::FunctionRetTy::Default(..) => true, - ast::FunctionRetTy::Ty(ref t) if t.node == ast::TyKind::Tup(vec![]) => true, - _ => false - }; - if decl.inputs.is_empty() - && no_output - && !generics.is_parameterized() { - Yes - } else { - No + ast::ItemKind::Fn(ref decl, _, _, _, ref generics, _) => { + // If the termination trait is active, the compiler will check that the output + // type implements the `Termination` trait as `libtest` enforces that. + let output_matches = if cx.features.termination_trait { + true + } else { + let no_output = match decl.output { + ast::FunctionRetTy::Default(..) => true, + ast::FunctionRetTy::Ty(ref t) if t.node == ast::TyKind::Tup(vec![]) => true, + _ => false + }; + + no_output && !generics.is_parameterized() + }; + + if decl.inputs.is_empty() && output_matches { + Yes + } else { + No + } } - } - _ => NotEvenAFunction, + _ => NotEvenAFunction, } } - if has_test_attr { + let has_test_signature = if has_test_attr { let diag = cx.span_diagnostic; - match has_test_signature(i) { - Yes => {}, - No => diag.span_err(i.span, "functions used as tests must have signature fn() -> ()"), - NotEvenAFunction => diag.span_err(i.span, - "only functions may be used as tests"), + match has_test_signature(cx, i) { + Yes => true, + No => { + if cx.features.termination_trait { + diag.span_err(i.span, "functions used as tests can not have any arguments"); + } else { + diag.span_err(i.span, "functions used as tests must have signature fn() -> ()"); + } + false + }, + NotEvenAFunction => { + diag.span_err(i.span, "only functions may be used as tests"); + false + }, } - } + } else { + false + }; - has_test_attr && has_test_signature(i) == Yes + has_test_attr && has_test_signature } fn is_bench_fn(cx: &TestCtxt, i: &ast::Item) -> bool { let has_bench_attr = attr::contains_name(&i.attrs, "bench"); - fn has_test_signature(i: &ast::Item) -> bool { + fn has_bench_signature(cx: &TestCtxt, i: &ast::Item) -> bool { match i.node { ast::ItemKind::Fn(ref decl, _, _, _, ref generics, _) => { let input_cnt = decl.inputs.len(); - let no_output = match decl.output { - ast::FunctionRetTy::Default(..) => true, - ast::FunctionRetTy::Ty(ref t) if t.node == ast::TyKind::Tup(vec![]) => true, - _ => false + + // If the termination trait is active, the compiler will check that the output + // type implements the `Termination` trait as `libtest` enforces that. + let output_matches = if cx.features.termination_trait { + true + } else { + let no_output = match decl.output { + ast::FunctionRetTy::Default(..) => true, + ast::FunctionRetTy::Ty(ref t) if t.node == ast::TyKind::Tup(vec![]) => true, + _ => false + }; + let tparm_cnt = generics.params.iter() + .filter(|param| param.is_type_param()) + .count(); + + no_output && tparm_cnt == 0 }; - let tparm_cnt = generics.params.iter() - .filter(|param| param.is_type_param()) - .count(); // NB: inadequate check, but we're running // well before resolve, can't get too deep. - input_cnt == 1 - && no_output && tparm_cnt == 0 + input_cnt == 1 && output_matches } _ => false } } - if has_bench_attr && !has_test_signature(i) { + let has_bench_signature = has_bench_signature(cx, i); + + if has_bench_attr && !has_bench_signature { let diag = cx.span_diagnostic; - diag.span_err(i.span, "functions used as benches must have signature \ - `fn(&mut Bencher) -> ()`"); + + if cx.features.termination_trait { + diag.span_err(i.span, "functions used as benches must have signature \ + `fn(&mut Bencher) -> impl Termination`"); + } else { + diag.span_err(i.span, "functions used as benches must have signature \ + `fn(&mut Bencher) -> ()`"); + } } - has_bench_attr && has_test_signature(i) + has_bench_attr && has_bench_signature } fn is_ignored(i: &ast::Item) -> bool { @@ -690,9 +733,12 @@ fn mk_test_desc_and_fn_rec(cx: &TestCtxt, test: &Test) -> P { field("should_panic", fail_expr), field("allow_fail", allow_fail_expr)]); - - let mut visible_path = match cx.toplevel_reexport { - Some(id) => vec![id], + let mut visible_path = vec![]; + if cx.features.extern_absolute_paths { + visible_path.push(keywords::Crate.ident()); + } + match cx.toplevel_reexport { + Some(id) => visible_path.push(id), None => { let diag = cx.span_diagnostic; diag.bug("expected to find top-level re-export name, but found None"); @@ -700,9 +746,64 @@ fn mk_test_desc_and_fn_rec(cx: &TestCtxt, test: &Test) -> P { }; visible_path.extend(path); - let fn_expr = ecx.expr_path(ecx.path_global(span, visible_path)); + // Rather than directly give the test function to the test + // harness, we create a wrapper like one of the following: + // + // || test::assert_test_result(real_function()) // for test + // |b| test::assert_test_result(real_function(b)) // for bench + // + // this will coerce into a fn pointer that is specialized to the + // actual return type of `real_function` (Typically `()`, but not always). + let fn_expr = { + // construct `real_function()` (this will be inserted into the overall expr) + let real_function_expr = ecx.expr_path(ecx.path_global(span, visible_path)); + // construct path `test::assert_test_result` + let assert_test_result = test_path("assert_test_result"); + if test.bench { + // construct `|b| {..}` + let b_ident = Ident::with_empty_ctxt(Symbol::gensym("b")); + let b_expr = ecx.expr_ident(span, b_ident); + ecx.lambda( + span, + vec![b_ident], + // construct `assert_test_result(..)` + ecx.expr_call( + span, + ecx.expr_path(assert_test_result), + vec![ + // construct `real_function(b)` + ecx.expr_call( + span, + real_function_expr, + vec![b_expr], + ) + ], + ), + ) + } else { + // construct `|| {..}` + ecx.lambda( + span, + vec![], + // construct `assert_test_result(..)` + ecx.expr_call( + span, + ecx.expr_path(assert_test_result), + vec![ + // construct `real_function()` + ecx.expr_call( + span, + real_function_expr, + vec![], + ) + ], + ), + ) + } + }; let variant_name = if test.bench { "StaticBenchFn" } else { "StaticTestFn" }; + // self::test::$variant_name($fn_expr) let testfn_expr = ecx.expr_call(span, ecx.expr_path(test_path(variant_name)), vec![fn_expr]); diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs index 9ea5f39b71fee..82077bc4cd482 100644 --- a/src/libtest/lib.rs +++ b/src/libtest/lib.rs @@ -40,6 +40,7 @@ #![feature(set_stdio)] #![feature(panic_unwind)] #![feature(staged_api)] +#![feature(termination_trait_lib)] extern crate getopts; extern crate term; @@ -67,6 +68,7 @@ use std::io::prelude::*; use std::io; use std::iter::repeat; use std::path::PathBuf; +use std::process::Termination; use std::sync::mpsc::{channel, Sender}; use std::sync::{Arc, Mutex}; use std::thread; @@ -81,8 +83,8 @@ const QUIET_MODE_MAX_COLUMN: usize = 100; // insert a '\n' after 100 tests in qu pub mod test { pub use {Bencher, TestName, TestResult, TestDesc, TestDescAndFn, TestOpts, TrFailed, TrFailedMsg, TrIgnored, TrOk, Metric, MetricMap, StaticTestFn, StaticTestName, - DynTestName, DynTestFn, run_test, test_main, test_main_static, filter_tests, - parse_opts, StaticBenchFn, ShouldPanic, Options}; + DynTestName, DynTestFn, assert_test_result, run_test, test_main, test_main_static, + filter_tests, parse_opts, StaticBenchFn, ShouldPanic, Options}; } pub mod stats; @@ -322,6 +324,13 @@ pub fn test_main_static(tests: &[TestDescAndFn]) { test_main(&args, owned_tests, Options::new()) } +/// Invoked when unit tests terminate. Should panic if the unit +/// test is considered a failure. By default, invokes `report()` +/// and checks for a `0` result. +pub fn assert_test_result(result: T) { + assert_eq!(result.report(), 0); +} + #[derive(Copy, Clone, Debug)] pub enum ColorConfig { AutoColor, diff --git a/src/test/compile-fail/borrowck/two-phase-nonrecv-autoref.rs b/src/test/compile-fail/borrowck/two-phase-nonrecv-autoref.rs index 795d45a776db5..c425ed554a6f8 100644 --- a/src/test/compile-fail/borrowck/two-phase-nonrecv-autoref.rs +++ b/src/test/compile-fail/borrowck/two-phase-nonrecv-autoref.rs @@ -105,14 +105,10 @@ fn overloaded_call_traits() { //[lxl]~^^^ ERROR use of moved value: `*f` //[nll]~^^^^ ERROR cannot move a value of type //[nll]~^^^^^ ERROR cannot move a value of type - //[nll]~^^^^^^ ERROR cannot move a value of type - //[nll]~^^^^^^^ ERROR cannot move a value of type - //[nll]~^^^^^^^^ ERROR use of moved value: `*f` - //[g2p]~^^^^^^^^^ ERROR cannot move a value of type - //[g2p]~^^^^^^^^^^ ERROR cannot move a value of type - //[g2p]~^^^^^^^^^^^ ERROR cannot move a value of type - //[g2p]~^^^^^^^^^^^^ ERROR cannot move a value of type - //[g2p]~^^^^^^^^^^^^^ ERROR use of moved value: `*f` + //[nll]~^^^^^^ ERROR use of moved value: `*f` + //[g2p]~^^^^^^^ ERROR cannot move a value of type + //[g2p]~^^^^^^^^ ERROR cannot move a value of type + //[g2p]~^^^^^^^^^ ERROR use of moved value: `*f` } twice_ten_sm(&mut |x| x + 1); diff --git a/src/test/compile-fail/coherence-inherited-assoc-ty-cycle-err.rs b/src/test/compile-fail/coherence-inherited-assoc-ty-cycle-err.rs index 5d7f33967402c..2f4d82e2ef514 100644 --- a/src/test/compile-fail/coherence-inherited-assoc-ty-cycle-err.rs +++ b/src/test/compile-fail/coherence-inherited-assoc-ty-cycle-err.rs @@ -17,7 +17,7 @@ #![feature(specialization)] trait Trait { type Assoc; } -//~^ unsupported cyclic reference between types/traits detected [E0391] +//~^ cyclic dependency detected [E0391] impl Trait for Vec { type Assoc = (); diff --git a/src/test/compile-fail/const-size_of-cycle.rs b/src/test/compile-fail/const-size_of-cycle.rs index cbeafdfe6acc9..6218dcbf5f2c5 100644 --- a/src/test/compile-fail/const-size_of-cycle.rs +++ b/src/test/compile-fail/const-size_of-cycle.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// error-pattern: unsupported cyclic reference between types/traits detected +// error-pattern: cyclic dependency detected #![feature(const_fn)] diff --git a/src/test/compile-fail/cycle-projection-based-on-where-clause.rs b/src/test/compile-fail/cycle-projection-based-on-where-clause.rs index 7af2f11bd2815..ee4722c010f16 100644 --- a/src/test/compile-fail/cycle-projection-based-on-where-clause.rs +++ b/src/test/compile-fail/cycle-projection-based-on-where-clause.rs @@ -25,7 +25,7 @@ trait Trait { type Item; } struct A where T : Trait, T : Add - //~^ ERROR unsupported cyclic reference between types/traits detected + //~^ ERROR cyclic dependency detected //~| ERROR associated type `Item` not found for `T` { data: T diff --git a/src/test/compile-fail/cycle-trait-default-type-trait.rs b/src/test/compile-fail/cycle-trait-default-type-trait.rs index e6caeb34a8c8f..88672088bcb4c 100644 --- a/src/test/compile-fail/cycle-trait-default-type-trait.rs +++ b/src/test/compile-fail/cycle-trait-default-type-trait.rs @@ -12,7 +12,7 @@ // again references the trait. trait Foo> { - //~^ ERROR unsupported cyclic reference + //~^ ERROR cyclic dependency detected } fn main() { } diff --git a/src/test/compile-fail/cycle-trait-supertrait-direct.rs b/src/test/compile-fail/cycle-trait-supertrait-direct.rs index ef3fead18f6aa..626567ccc0ead 100644 --- a/src/test/compile-fail/cycle-trait-supertrait-direct.rs +++ b/src/test/compile-fail/cycle-trait-supertrait-direct.rs @@ -11,7 +11,7 @@ // Test a supertrait cycle where a trait extends itself. trait Chromosome: Chromosome { - //~^ ERROR unsupported cyclic reference + //~^ ERROR cyclic dependency detected } fn main() { } diff --git a/src/test/compile-fail/impl-trait/where-allowed.rs b/src/test/compile-fail/impl-trait/where-allowed.rs index a9fe1e04664e9..52c5471681df3 100644 --- a/src/test/compile-fail/impl-trait/where-allowed.rs +++ b/src/test/compile-fail/impl-trait/where-allowed.rs @@ -10,7 +10,7 @@ //! A simple test for testing many permutations of allowedness of //! impl Trait -#![feature(conservative_impl_trait, nested_impl_trait, universal_impl_trait, dyn_trait)] +#![feature(conservative_impl_trait, universal_impl_trait, dyn_trait)] use std::fmt::Debug; // Allowed @@ -60,6 +60,7 @@ fn in_dyn_Fn_return_in_return() -> &'static dyn Fn() -> impl Debug { panic!() } // Disallowed fn in_impl_Fn_parameter_in_parameters(_: &impl Fn(impl Debug)) { panic!() } //~^ ERROR `impl Trait` not allowed outside of function and inherent method return types +//~^^ ERROR nested `impl Trait` is not allowed // Disallowed fn in_impl_Fn_return_in_parameters(_: &impl Fn() -> impl Debug) { panic!() } @@ -68,6 +69,7 @@ fn in_impl_Fn_return_in_parameters(_: &impl Fn() -> impl Debug) { panic!() } // Disallowed fn in_impl_Fn_parameter_in_return() -> &'static impl Fn(impl Debug) { panic!() } //~^ ERROR `impl Trait` not allowed outside of function and inherent method return types +//~^^ ERROR nested `impl Trait` is not allowed // Disallowed fn in_impl_Fn_return_in_return() -> &'static impl Fn() -> impl Debug { panic!() } diff --git a/src/test/compile-fail/infinite-vec-type-recursion.rs b/src/test/compile-fail/infinite-vec-type-recursion.rs index e5120840f7672..25d0590db1b75 100644 --- a/src/test/compile-fail/infinite-vec-type-recursion.rs +++ b/src/test/compile-fail/infinite-vec-type-recursion.rs @@ -9,6 +9,6 @@ // except according to those terms. type x = Vec; -//~^ ERROR unsupported cyclic reference +//~^ ERROR cyclic dependency detected fn main() { let b: x = Vec::new(); } diff --git a/src/test/compile-fail/issue-12997-2.rs b/src/test/compile-fail/issue-12997-2.rs index 85d91bb2db202..8d3df68577bab 100644 --- a/src/test/compile-fail/issue-12997-2.rs +++ b/src/test/compile-fail/issue-12997-2.rs @@ -15,6 +15,3 @@ #[bench] fn bar(x: isize) { } //~^ ERROR mismatched types -//~| 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/issue-17252.rs b/src/test/compile-fail/issue-17252.rs index 0c04e295e1458..1c3e6890c8e2e 100644 --- a/src/test/compile-fail/issue-17252.rs +++ b/src/test/compile-fail/issue-17252.rs @@ -8,12 +8,12 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -const FOO: usize = FOO; //~ ERROR recursive constant +const FOO: usize = FOO; //~ ERROR E0391 fn main() { let _x: [u8; FOO]; // caused stack overflow prior to fix let _y: usize = 1 + { - const BAR: usize = BAR; //~ ERROR recursive constant + const BAR: usize = BAR; let _z: [u8; BAR]; // caused stack overflow prior to fix 1 }; diff --git a/src/test/compile-fail/issue-20772.rs b/src/test/compile-fail/issue-20772.rs index 7ae4250d4203b..88395e5f1eafa 100644 --- a/src/test/compile-fail/issue-20772.rs +++ b/src/test/compile-fail/issue-20772.rs @@ -9,7 +9,7 @@ // except according to those terms. trait T : Iterator -//~^ ERROR unsupported cyclic reference between types/traits detected +//~^ ERROR cyclic dependency detected //~| ERROR associated type `Item` not found for `Self` {} diff --git a/src/test/compile-fail/issue-20825.rs b/src/test/compile-fail/issue-20825.rs index 7d082a3148f76..aeb798b382875 100644 --- a/src/test/compile-fail/issue-20825.rs +++ b/src/test/compile-fail/issue-20825.rs @@ -13,7 +13,7 @@ pub trait Subscriber { } pub trait Processor: Subscriber { - //~^ ERROR unsupported cyclic reference between types/traits detected [E0391] + //~^ ERROR cyclic dependency detected [E0391] type Input; } diff --git a/src/test/compile-fail/issue-21177.rs b/src/test/compile-fail/issue-21177.rs index f49b71953835b..40c95b98f1264 100644 --- a/src/test/compile-fail/issue-21177.rs +++ b/src/test/compile-fail/issue-21177.rs @@ -14,7 +14,7 @@ trait Trait { } fn foo>() { } -//~^ ERROR unsupported cyclic reference between types/traits detected +//~^ ERROR cyclic dependency detected //~| ERROR associated type `B` not found for `T` fn main() { } diff --git a/src/test/compile-fail/issue-22673.rs b/src/test/compile-fail/issue-22673.rs index 442e6bcda5a09..fde2d001542b8 100644 --- a/src/test/compile-fail/issue-22673.rs +++ b/src/test/compile-fail/issue-22673.rs @@ -9,7 +9,7 @@ // except according to those terms. trait Expr : PartialEq { - //~^ ERROR: unsupported cyclic reference between types/traits detected + //~^ ERROR: cyclic dependency detected type Item; } diff --git a/src/test/compile-fail/issue-26548.rs b/src/test/compile-fail/issue-26548.rs index 39c6e97268f98..16a650cc6d886 100644 --- a/src/test/compile-fail/issue-26548.rs +++ b/src/test/compile-fail/issue-26548.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// error-pattern: unsupported cyclic reference between types/traits detected +// error-pattern: cyclic dependency detected // note-pattern: the cycle begins when computing layout of // note-pattern: ...which then requires computing layout of // note-pattern: ...which then again requires computing layout of diff --git a/src/test/compile-fail/issue-34373.rs b/src/test/compile-fail/issue-34373.rs index 7bbc680197e84..b18e05af47c97 100644 --- a/src/test/compile-fail/issue-34373.rs +++ b/src/test/compile-fail/issue-34373.rs @@ -15,7 +15,7 @@ trait Trait { } pub struct Foo>>; -type DefaultFoo = Foo; //~ ERROR unsupported cyclic reference +type DefaultFoo = Foo; //~ ERROR cyclic dependency detected fn main() { } diff --git a/src/test/compile-fail/issue-44415.rs b/src/test/compile-fail/issue-44415.rs index 3b7089f497526..930a427e9a5e0 100644 --- a/src/test/compile-fail/issue-44415.rs +++ b/src/test/compile-fail/issue-44415.rs @@ -15,7 +15,7 @@ use std::intrinsics; struct Foo { bytes: [u8; unsafe { intrinsics::size_of::() }], - //~^ ERROR unsupported cyclic reference between types/traits detected + //~^ ERROR cyclic dependency detected x: usize, } diff --git a/src/test/compile-fail/issue-48131.rs b/src/test/compile-fail/issue-48131.rs new file mode 100644 index 0000000000000..9eb567a5d3eb0 --- /dev/null +++ b/src/test/compile-fail/issue-48131.rs @@ -0,0 +1,39 @@ +// Copyright 2018 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. + +// This note is annotated because the purpose of the test +// is to ensure that certain other notes are not generated. +#![deny(unused_unsafe)] //~ NOTE + +// (test that no note is generated on this unsafe fn) +pub unsafe fn a() { + fn inner() { + unsafe { /* unnecessary */ } //~ ERROR unnecessary `unsafe` + //~^ NOTE + } + + inner() +} + +pub fn b() { + // (test that no note is generated on this unsafe block) + unsafe { + fn inner() { + unsafe { /* unnecessary */ } //~ ERROR unnecessary `unsafe` + //~^ NOTE + } + + let () = ::std::mem::uninitialized(); + + inner() + } +} + +fn main() {} diff --git a/src/test/compile-fail/resolve-self-in-impl.rs b/src/test/compile-fail/resolve-self-in-impl.rs index 55ae37404a9fa..7210c857125d6 100644 --- a/src/test/compile-fail/resolve-self-in-impl.rs +++ b/src/test/compile-fail/resolve-self-in-impl.rs @@ -21,10 +21,10 @@ impl Tr for S where Self: Copy {} // OK impl Tr for S where S: Copy {} // OK impl Tr for S where Self::A: Copy {} // OK -impl Tr for Self {} //~ ERROR unsupported cyclic reference between types/traits detected -impl Tr for S {} //~ ERROR unsupported cyclic reference between types/traits detected -impl Self {} //~ ERROR unsupported cyclic reference between types/traits detected -impl S {} //~ ERROR unsupported cyclic reference between types/traits detected -impl Tr for S {} //~ ERROR unsupported cyclic reference between types/traits detected +impl Tr for Self {} //~ ERROR cyclic dependency detected +impl Tr for S {} //~ ERROR cyclic dependency detected +impl Self {} //~ ERROR cyclic dependency detected +impl S {} //~ ERROR cyclic dependency detected +impl Tr for S {} //~ ERROR cyclic dependency detected fn main() {} diff --git a/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-wrong-type.rs b/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-wrong-type.rs index a63162cf73d1c..93e2561adf753 100644 --- a/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-wrong-type.rs +++ b/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-wrong-type.rs @@ -10,6 +10,6 @@ #![feature(termination_trait)] fn main() -> char { -//~^ ERROR: the trait bound `char: std::Termination` is not satisfied +//~^ ERROR: the trait bound `char: std::process::Termination` is not satisfied ' ' } diff --git a/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-not-satisfied.rs b/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-not-satisfied.rs index 788c38c55be0a..e87e0ceebf1b1 100644 --- a/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-not-satisfied.rs +++ b/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-not-satisfied.rs @@ -12,6 +12,6 @@ struct ReturnType {} -fn main() -> ReturnType { //~ ERROR `ReturnType: std::Termination` is not satisfied +fn main() -> ReturnType { //~ ERROR `ReturnType: std::process::Termination` is not satisfied ReturnType {} } diff --git a/src/test/run-pass/termination-trait-for-result-box-error_ok.rs b/src/test/run-fail/rfc-1937-termination-trait/termination-trait-for-never.rs similarity index 76% rename from src/test/run-pass/termination-trait-for-result-box-error_ok.rs rename to src/test/run-fail/rfc-1937-termination-trait/termination-trait-for-never.rs index 269ac451cf4d8..c1dd44a91765e 100644 --- a/src/test/run-pass/termination-trait-for-result-box-error_ok.rs +++ b/src/test/run-fail/rfc-1937-termination-trait/termination-trait-for-never.rs @@ -1,4 +1,4 @@ -// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -10,8 +10,8 @@ #![feature(termination_trait)] -use std::io::Error; +// error-pattern:oh, dear -fn main() -> Result<(), Box> { - Ok(()) +fn main() -> ! { + panic!("oh, dear"); } diff --git a/src/test/run-pass/impl-trait/lifetimes.rs b/src/test/run-pass/impl-trait/lifetimes.rs index 213a46ded8e76..2d5dfb045dbac 100644 --- a/src/test/run-pass/impl-trait/lifetimes.rs +++ b/src/test/run-pass/impl-trait/lifetimes.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(conservative_impl_trait, underscore_lifetimes, universal_impl_trait, nested_impl_trait)] +#![feature(conservative_impl_trait, underscore_lifetimes, universal_impl_trait)] #![allow(warnings)] use std::fmt::Debug; @@ -63,12 +63,11 @@ fn pass_through_elision_with_fn_ptr(x: &fn(&u32) -> &u32) -> impl Into<&fn(&u32) fn pass_through_elision_with_fn_path &u32>( x: &T -) -> impl Into<&impl Fn(&u32) -> &u32> { x } +) -> &impl Fn(&u32) -> &u32 { x } -fn foo(x: &impl Debug) -> impl Into<&impl Debug> { x } -fn foo_explicit_lifetime<'a>(x: &'a impl Debug) -> impl Into<&'a impl Debug> { x } -fn foo_no_outer_impl(x: &impl Debug) -> &impl Debug { x } -fn foo_explicit_arg(x: &T) -> impl Into<&impl Debug> { x } +fn foo(x: &impl Debug) -> &impl Debug { x } +fn foo_explicit_lifetime<'a>(x: &'a impl Debug) -> &'a impl Debug { x } +fn foo_explicit_arg(x: &T) -> &impl Debug { x } fn mixed_lifetimes<'a>() -> impl for<'b: 'a> Fn(&'b u32) { |_| () } fn mixed_as_static() -> impl Fn(&'static u32) { mixed_lifetimes() } diff --git a/src/test/run-pass/rfc-1937-termination-trait/termination-trait-in-test.rs b/src/test/run-pass/rfc-1937-termination-trait/termination-trait-in-test.rs new file mode 100644 index 0000000000000..494500d522abe --- /dev/null +++ b/src/test/run-pass/rfc-1937-termination-trait/termination-trait-in-test.rs @@ -0,0 +1,43 @@ +// Copyright 2017 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. + +// compile-flags: --test + +#![feature(termination_trait)] +#![feature(test)] + +extern crate test; +use std::num::ParseIntError; +use test::Bencher; + +#[test] +fn is_a_num() -> Result<(), ParseIntError> { + let _: u32 = "22".parse()?; + Ok(()) +} + +#[test] +#[should_panic] +fn not_a_num() -> Result<(), ParseIntError> { + let _: u32 = "abc".parse()?; + Ok(()) +} + +#[bench] +fn test_a_positive_bench(_: &mut Bencher) -> Result<(), ParseIntError> { + Ok(()) +} + +#[bench] +#[should_panic] +fn test_a_neg_bench(_: &mut Bencher) -> Result<(), ParseIntError> { + let _: u32 = "abc".parse()?; + Ok(()) +} diff --git a/src/test/run-pass/rfc-2126-extern-absolute-paths/test.rs b/src/test/run-pass/rfc-2126-extern-absolute-paths/test.rs new file mode 100644 index 0000000000000..796f652d6b57b --- /dev/null +++ b/src/test/run-pass/rfc-2126-extern-absolute-paths/test.rs @@ -0,0 +1,21 @@ +// Copyright 2017 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. + +// Check that `#[test]` works with extern-absolute-paths enabled. +// +// Regression test for #47075. + +// compile-flags: --test + +#![feature(extern_absolute_paths)] + +#[test] +fn test() { +} diff --git a/src/test/ui/cycle-trait-supertrait-indirect.rs b/src/test/ui/cycle-trait-supertrait-indirect.rs index c3b0276bcf9cb..447505e886f81 100644 --- a/src/test/ui/cycle-trait-supertrait-indirect.rs +++ b/src/test/ui/cycle-trait-supertrait-indirect.rs @@ -18,7 +18,7 @@ trait B: C { } trait C: B { } - //~^ ERROR unsupported cyclic reference + //~^ ERROR cyclic dependency detected //~| cyclic reference fn main() { } diff --git a/src/test/ui/cycle-trait-supertrait-indirect.stderr b/src/test/ui/cycle-trait-supertrait-indirect.stderr index 107644037a9ca..a01565546462d 100644 --- a/src/test/ui/cycle-trait-supertrait-indirect.stderr +++ b/src/test/ui/cycle-trait-supertrait-indirect.stderr @@ -1,4 +1,4 @@ -error[E0391]: unsupported cyclic reference between types/traits detected +error[E0391]: cyclic dependency detected --> $DIR/cycle-trait-supertrait-indirect.rs:20:1 | 20 | trait C: B { } diff --git a/src/test/ui/error-codes/E0657.rs b/src/test/ui/error-codes/E0657.rs index 4595e413081a5..31b3acd86ef55 100644 --- a/src/test/ui/error-codes/E0657.rs +++ b/src/test/ui/error-codes/E0657.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. #![allow(warnings)] -#![feature(conservative_impl_trait, nested_impl_trait)] +#![feature(conservative_impl_trait)] trait Id {} trait Lt<'a> {} @@ -17,7 +17,7 @@ impl<'a> Lt<'a> for () {} impl Id for T {} fn free_fn_capture_hrtb_in_impl_trait() - -> impl for<'a> Id> + -> Box Id>> //~^ ERROR `impl Trait` can only capture lifetimes bound at the fn or impl level [E0657] { () @@ -26,7 +26,7 @@ fn free_fn_capture_hrtb_in_impl_trait() struct Foo; impl Foo { fn impl_fn_capture_hrtb_in_impl_trait() - -> impl for<'a> Id> + -> Box Id>> //~^ ERROR `impl Trait` can only capture lifetimes bound at the fn or impl level { () diff --git a/src/test/ui/error-codes/E0657.stderr b/src/test/ui/error-codes/E0657.stderr index d3b53d37a30a0..e039d645fa6db 100644 --- a/src/test/ui/error-codes/E0657.stderr +++ b/src/test/ui/error-codes/E0657.stderr @@ -1,14 +1,14 @@ error[E0657]: `impl Trait` can only capture lifetimes bound at the fn or impl level - --> $DIR/E0657.rs:20:32 + --> $DIR/E0657.rs:20:31 | -20 | -> impl for<'a> Id> - | ^^ +20 | -> Box Id>> + | ^^ error[E0657]: `impl Trait` can only capture lifetimes bound at the fn or impl level - --> $DIR/E0657.rs:29:36 + --> $DIR/E0657.rs:29:35 | -29 | -> impl for<'a> Id> - | ^^ +29 | -> Box Id>> + | ^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/impl-trait/auto-trait-leak.rs b/src/test/ui/impl-trait/auto-trait-leak.rs index 705390e3b969c..5a6aac43ec770 100644 --- a/src/test/ui/impl-trait/auto-trait-leak.rs +++ b/src/test/ui/impl-trait/auto-trait-leak.rs @@ -42,7 +42,7 @@ fn after() -> impl Fn(i32) { // independently resolved and only require the concrete // return type, which can't depend on the obligation. fn cycle1() -> impl Clone { - //~^ ERROR unsupported cyclic reference between types/traits detected + //~^ ERROR cyclic dependency detected //~| cyclic reference send(cycle2().clone()); diff --git a/src/test/ui/impl-trait/auto-trait-leak.stderr b/src/test/ui/impl-trait/auto-trait-leak.stderr index 838a3002e3aa7..d6e31ba1e1f9c 100644 --- a/src/test/ui/impl-trait/auto-trait-leak.stderr +++ b/src/test/ui/impl-trait/auto-trait-leak.stderr @@ -28,7 +28,7 @@ note: required by `send` 24 | fn send(_: T) {} | ^^^^^^^^^^^^^^^^^^^^^^ -error[E0391]: unsupported cyclic reference between types/traits detected +error[E0391]: cyclic dependency detected --> $DIR/auto-trait-leak.rs:44:1 | 44 | fn cycle1() -> impl Clone { diff --git a/src/test/ui/impl_trait_projections.rs b/src/test/ui/impl_trait_projections.rs new file mode 100644 index 0000000000000..f69a78b1450f1 --- /dev/null +++ b/src/test/ui/impl_trait_projections.rs @@ -0,0 +1,50 @@ +// Copyright 2018 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. +#![feature(dyn_trait, conservative_impl_trait, universal_impl_trait)] + +use std::fmt::Debug; +use std::option; + +fn parametrized_type_is_allowed() -> Option { + Some(5i32) +} + +fn path_parametrized_type_is_allowed() -> option::Option { + Some(5i32) +} + +fn projection_is_disallowed(x: impl Iterator) -> ::Item { +//~^ ERROR `impl Trait` is not allowed in path parameters +//~^^ ERROR ambiguous associated type + x.next().unwrap() +} + +fn projection_with_named_trait_is_disallowed(x: impl Iterator) + -> ::Item +//~^ ERROR `impl Trait` is not allowed in path parameters +{ + x.next().unwrap() +} + +fn projection_with_named_trait_inside_path_is_disallowed() + -> <::std::ops::Range as Iterator>::Item +//~^ ERROR `impl Trait` is not allowed in path parameters +{ + (1i32..100).next().unwrap() +} + +fn projection_from_impl_trait_inside_dyn_trait_is_disallowed() + -> as Iterator>::Item +//~^ ERROR `impl Trait` is not allowed in path parameters +{ + panic!() +} + +fn main() {} diff --git a/src/test/ui/impl_trait_projections.stderr b/src/test/ui/impl_trait_projections.stderr new file mode 100644 index 0000000000000..08de0eb99a307 --- /dev/null +++ b/src/test/ui/impl_trait_projections.stderr @@ -0,0 +1,34 @@ +error[E0667]: `impl Trait` is not allowed in path parameters + --> $DIR/impl_trait_projections.rs:23:51 + | +23 | fn projection_is_disallowed(x: impl Iterator) -> ::Item { + | ^^^^^^^^^^^^^ + +error[E0667]: `impl Trait` is not allowed in path parameters + --> $DIR/impl_trait_projections.rs:30:9 + | +30 | -> ::Item + | ^^^^^^^^^^^^^ + +error[E0667]: `impl Trait` is not allowed in path parameters + --> $DIR/impl_trait_projections.rs:37:27 + | +37 | -> <::std::ops::Range as Iterator>::Item + | ^^^^^^^^^^ + +error[E0667]: `impl Trait` is not allowed in path parameters + --> $DIR/impl_trait_projections.rs:44:29 + | +44 | -> as Iterator>::Item + | ^^^^^^^^^^ + +error[E0223]: ambiguous associated type + --> $DIR/impl_trait_projections.rs:23:50 + | +23 | fn projection_is_disallowed(x: impl Iterator) -> ::Item { + | ^^^^^^^^^^^^^^^^^^^^^ ambiguous associated type + | + = note: specify the type using the syntax `::Item` + +error: aborting due to 5 previous errors + diff --git a/src/test/ui/issue-12511.rs b/src/test/ui/issue-12511.rs index e1335c7d558e1..e4d6076868717 100644 --- a/src/test/ui/issue-12511.rs +++ b/src/test/ui/issue-12511.rs @@ -12,7 +12,7 @@ trait t1 : t2 { } trait t2 : t1 { -//~^ ERROR unsupported cyclic reference between types/traits detected +//~^ ERROR cyclic dependency detected //~| cyclic reference } diff --git a/src/test/ui/issue-12511.stderr b/src/test/ui/issue-12511.stderr index cbf005a70b028..aec828a90d1a7 100644 --- a/src/test/ui/issue-12511.stderr +++ b/src/test/ui/issue-12511.stderr @@ -1,4 +1,4 @@ -error[E0391]: unsupported cyclic reference between types/traits detected +error[E0391]: cyclic dependency detected --> $DIR/issue-12511.rs:14:1 | 14 | trait t2 : t1 { diff --git a/src/test/ui/issue-23302.rs b/src/test/ui/issue-23302-1.rs similarity index 71% rename from src/test/ui/issue-23302.rs rename to src/test/ui/issue-23302-1.rs index 2d93ab0c30c8f..10a538301162c 100644 --- a/src/test/ui/issue-23302.rs +++ b/src/test/ui/issue-23302-1.rs @@ -11,18 +11,7 @@ // Check that an enum with recursion in the discriminant throws // the appropriate error (rather than, say, blowing the stack). enum X { - A = X::A as isize, //~ ERROR E0265 + A = X::A as isize, //~ ERROR E0391 } -// Since `Y::B` here defaults to `Y::A+1`, this is also a -// recursive definition. -enum Y { - A = Y::B as isize, //~ ERROR E0265 - B, -} - -const A: i32 = B; //~ ERROR E0265 - -const B: i32 = A; //~ ERROR E0265 - fn main() { } diff --git a/src/test/ui/issue-23302-1.stderr b/src/test/ui/issue-23302-1.stderr new file mode 100644 index 0000000000000..0658c07fb1dbe --- /dev/null +++ b/src/test/ui/issue-23302-1.stderr @@ -0,0 +1,15 @@ +error[E0391]: cyclic dependency detected + --> $DIR/issue-23302-1.rs:14:9 + | +14 | A = X::A as isize, //~ ERROR E0391 + | ^^^^^^^^^^^^^ cyclic reference + | +note: the cycle begins when const-evaluating `X::A::{{initializer}}`... + --> $DIR/issue-23302-1.rs:14:5 + | +14 | A = X::A as isize, //~ ERROR E0391 + | ^^^^^^^^^^^^^^^^^ + = note: ...which then again requires const-evaluating `X::A::{{initializer}}`, completing the cycle. + +error: aborting due to previous error + diff --git a/src/test/ui/issue-23302-2.rs b/src/test/ui/issue-23302-2.rs new file mode 100644 index 0000000000000..d1af19eb579f5 --- /dev/null +++ b/src/test/ui/issue-23302-2.rs @@ -0,0 +1,18 @@ +// 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. + +// Since `Y::B` here defaults to `Y::A+1`, this is also a +// recursive definition. +enum Y { + A = Y::B as isize, //~ ERROR E0391 + B, +} + +fn main() { } diff --git a/src/test/ui/issue-23302-2.stderr b/src/test/ui/issue-23302-2.stderr new file mode 100644 index 0000000000000..c4a1c4f80c82c --- /dev/null +++ b/src/test/ui/issue-23302-2.stderr @@ -0,0 +1,15 @@ +error[E0391]: cyclic dependency detected + --> $DIR/issue-23302-2.rs:14:9 + | +14 | A = Y::B as isize, //~ ERROR E0391 + | ^^^^^^^^^^^^^ cyclic reference + | +note: the cycle begins when const-evaluating `Y::A::{{initializer}}`... + --> $DIR/issue-23302-2.rs:14:5 + | +14 | A = Y::B as isize, //~ ERROR E0391 + | ^^^^^^^^^^^^^^^^^ + = note: ...which then again requires const-evaluating `Y::A::{{initializer}}`, completing the cycle. + +error: aborting due to previous error + diff --git a/src/test/compile-fail/const-recursive.rs b/src/test/ui/issue-23302-3.rs similarity index 69% rename from src/test/compile-fail/const-recursive.rs rename to src/test/ui/issue-23302-3.rs index 7c05a817243b4..1d750b09025b9 100644 --- a/src/test/compile-fail/const-recursive.rs +++ b/src/test/ui/issue-23302-3.rs @@ -1,4 +1,4 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// 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. // @@ -8,8 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -const a: isize = b; //~ ERROR recursive constant -const b: isize = a; //~ ERROR recursive constant +const A: i32 = B; //~ ERROR E0391 -fn main() { -} +const B: i32 = A; + +fn main() { } diff --git a/src/test/ui/issue-23302-3.stderr b/src/test/ui/issue-23302-3.stderr new file mode 100644 index 0000000000000..76f543cff7913 --- /dev/null +++ b/src/test/ui/issue-23302-3.stderr @@ -0,0 +1,20 @@ +error[E0391]: cyclic dependency detected + --> $DIR/issue-23302-3.rs:11:16 + | +11 | const A: i32 = B; //~ ERROR E0391 + | ^ cyclic reference + | +note: the cycle begins when processing `B`... + --> $DIR/issue-23302-3.rs:13:1 + | +13 | const B: i32 = A; + | ^^^^^^^^^^^^^^^^^ +note: ...which then requires processing `A`... + --> $DIR/issue-23302-3.rs:13:16 + | +13 | const B: i32 = A; + | ^ + = note: ...which then again requires processing `B`, completing the cycle. + +error: aborting due to previous error + diff --git a/src/test/ui/issue-23302.stderr b/src/test/ui/issue-23302.stderr deleted file mode 100644 index 4e93809fac374..0000000000000 --- a/src/test/ui/issue-23302.stderr +++ /dev/null @@ -1,26 +0,0 @@ -error[E0265]: recursive constant - --> $DIR/issue-23302.rs:14:9 - | -14 | A = X::A as isize, //~ ERROR E0265 - | ^^^^^^^^^^^^^ recursion not allowed in constant - -error[E0265]: recursive constant - --> $DIR/issue-23302.rs:20:9 - | -20 | A = Y::B as isize, //~ ERROR E0265 - | ^^^^^^^^^^^^^ recursion not allowed in constant - -error[E0265]: recursive constant - --> $DIR/issue-23302.rs:24:1 - | -24 | const A: i32 = B; //~ ERROR E0265 - | ^^^^^^^^^^^^^^^^^ recursion not allowed in constant - -error[E0265]: recursive constant - --> $DIR/issue-23302.rs:26:1 - | -26 | const B: i32 = A; //~ ERROR E0265 - | ^^^^^^^^^^^^^^^^^ recursion not allowed in constant - -error: aborting due to 4 previous errors - diff --git a/src/test/ui/issue-36163.rs b/src/test/ui/issue-36163.rs index 2337f82afa49f..4c74d9d9173d8 100644 --- a/src/test/ui/issue-36163.rs +++ b/src/test/ui/issue-36163.rs @@ -8,16 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -const A: i32 = Foo::B; //~ ERROR E0265 +const A: isize = Foo::B as isize; enum Foo { - B = A, //~ ERROR E0265 + B = A, //~ ERROR E0391 } -enum Bar { - C = Bar::C, //~ ERROR E0265 -} - -const D: i32 = A; - fn main() {} diff --git a/src/test/ui/issue-36163.stderr b/src/test/ui/issue-36163.stderr index 5a107d88f2e4f..d0337fc32b03e 100644 --- a/src/test/ui/issue-36163.stderr +++ b/src/test/ui/issue-36163.stderr @@ -1,20 +1,20 @@ -error[E0265]: recursive constant - --> $DIR/issue-36163.rs:11:1 - | -11 | const A: i32 = Foo::B; //~ ERROR E0265 - | ^^^^^^^^^^^^^^^^^^^^^^ recursion not allowed in constant - -error[E0265]: recursive constant +error[E0391]: cyclic dependency detected --> $DIR/issue-36163.rs:14:9 | -14 | B = A, //~ ERROR E0265 - | ^ recursion not allowed in constant - -error[E0265]: recursive constant - --> $DIR/issue-36163.rs:18:9 +14 | B = A, //~ ERROR E0391 + | ^ cyclic reference + | +note: the cycle begins when const-evaluating `Foo::B::{{initializer}}`... + --> $DIR/issue-36163.rs:14:5 + | +14 | B = A, //~ ERROR E0391 + | ^^^^^ +note: ...which then requires const-evaluating `A`... + --> $DIR/issue-36163.rs:14:9 | -18 | C = Bar::C, //~ ERROR E0265 - | ^^^^^^ recursion not allowed in constant +14 | B = A, //~ ERROR E0391 + | ^ + = note: ...which then again requires const-evaluating `Foo::B::{{initializer}}`, completing the cycle. -error: aborting due to 3 previous errors +error: aborting due to previous error diff --git a/src/test/ui/issue-47706.rs b/src/test/ui/issue-47706.rs index 24a0f66f5b1c4..9c521dd647963 100644 --- a/src/test/ui/issue-47706.rs +++ b/src/test/ui/issue-47706.rs @@ -22,3 +22,18 @@ impl Foo { } //~^^ ERROR function is expected to take 1 argument, but it takes 2 arguments [E0593] } + +enum Qux { + Bar(i32), +} + +fn foo(f: F) +where + F: Fn(), +{ +} + +fn main() { + foo(Qux::Bar); +} +//~^^ ERROR function is expected to take 0 arguments, but it takes 1 argument [E0593] diff --git a/src/test/ui/issue-47706.stderr b/src/test/ui/issue-47706.stderr index 0916dc64292e3..e197c09062d1c 100644 --- a/src/test/ui/issue-47706.stderr +++ b/src/test/ui/issue-47706.stderr @@ -1,5 +1,3 @@ -error[E0601]: main function not found - error[E0593]: function is expected to take 1 argument, but it takes 2 arguments --> $DIR/issue-47706.rs:21:18 | @@ -9,5 +7,24 @@ error[E0593]: function is expected to take 1 argument, but it takes 2 arguments 21 | self.foo.map(Foo::new) | ^^^ expected function that takes 1 argument +error[E0593]: function is expected to take 0 arguments, but it takes 1 argument + --> $DIR/issue-47706.rs:37:5 + | +27 | Bar(i32), + | -------- takes 1 argument +... +37 | foo(Qux::Bar); + | ^^^ expected function that takes 0 arguments + | +note: required by `foo` + --> $DIR/issue-47706.rs:30:1 + | +30 | / fn foo(f: F) +31 | | where +32 | | F: Fn(), +33 | | { +34 | | } + | |_^ + error: aborting due to 2 previous errors diff --git a/src/test/compile-fail/feature-gate-nested_impl_trait.rs b/src/test/ui/nested_impl_trait.rs similarity index 80% rename from src/test/compile-fail/feature-gate-nested_impl_trait.rs rename to src/test/ui/nested_impl_trait.rs index 7c35263d05dd7..f6302c0f3b3e2 100644 --- a/src/test/compile-fail/feature-gate-nested_impl_trait.rs +++ b/src/test/ui/nested_impl_trait.rs @@ -14,18 +14,19 @@ use std::fmt::Debug; fn fine(x: impl Into) -> impl Into { x } fn bad_in_ret_position(x: impl Into) -> impl Into { x } -//~^ ERROR nested `impl Trait` is experimental +//~^ ERROR nested `impl Trait` is not allowed fn bad_in_fn_syntax(x: fn() -> impl Into) {} -//~^ ERROR nested `impl Trait` is experimental +//~^ ERROR nested `impl Trait` is not allowed +//~^^ `impl Trait` not allowed fn bad_in_arg_position(_: impl Into) { } -//~^ ERROR nested `impl Trait` is experimental +//~^ ERROR nested `impl Trait` is not allowed struct X; impl X { fn bad(x: impl Into) -> impl Into { x } - //~^ ERROR nested `impl Trait` is experimental + //~^ ERROR nested `impl Trait` is not allowed } fn allowed_in_assoc_type() -> impl Iterator { @@ -33,6 +34,7 @@ fn allowed_in_assoc_type() -> impl Iterator { } fn allowed_in_ret_type() -> impl Fn() -> impl Into { +//~^ `impl Trait` not allowed || 5 } diff --git a/src/test/ui/nested_impl_trait.stderr b/src/test/ui/nested_impl_trait.stderr new file mode 100644 index 0000000000000..094926120cdee --- /dev/null +++ b/src/test/ui/nested_impl_trait.stderr @@ -0,0 +1,50 @@ +error[E0666]: nested `impl Trait` is not allowed + --> $DIR/nested_impl_trait.rs:16:56 + | +16 | fn bad_in_ret_position(x: impl Into) -> impl Into { x } + | ----------^^^^^^^^^^- + | | | + | | nested `impl Trait` here + | outer `impl Trait` + +error[E0666]: nested `impl Trait` is not allowed + --> $DIR/nested_impl_trait.rs:19:42 + | +19 | fn bad_in_fn_syntax(x: fn() -> impl Into) {} + | ----------^^^^^^^^^^- + | | | + | | nested `impl Trait` here + | outer `impl Trait` + +error[E0666]: nested `impl Trait` is not allowed + --> $DIR/nested_impl_trait.rs:23:37 + | +23 | fn bad_in_arg_position(_: impl Into) { } + | ----------^^^^^^^^^^- + | | | + | | nested `impl Trait` here + | outer `impl Trait` + +error[E0666]: nested `impl Trait` is not allowed + --> $DIR/nested_impl_trait.rs:28:44 + | +28 | fn bad(x: impl Into) -> impl Into { x } + | ----------^^^^^^^^^^- + | | | + | | nested `impl Trait` here + | outer `impl Trait` + +error[E0562]: `impl Trait` not allowed outside of function and inherent method return types + --> $DIR/nested_impl_trait.rs:19:32 + | +19 | fn bad_in_fn_syntax(x: fn() -> impl Into) {} + | ^^^^^^^^^^^^^^^^^^^^^ + +error[E0562]: `impl Trait` not allowed outside of function and inherent method return types + --> $DIR/nested_impl_trait.rs:36:42 + | +36 | fn allowed_in_ret_type() -> impl Fn() -> impl Into { + | ^^^^^^^^^^^^^^ + +error: aborting due to 6 previous errors + diff --git a/src/test/ui/nll/ty-outlives/projection-no-regions-closure.stderr b/src/test/ui/nll/ty-outlives/projection-no-regions-closure.stderr index b2e98b7c2f6a4..30669dc4c2f8c 100644 --- a/src/test/ui/nll/ty-outlives/projection-no-regions-closure.stderr +++ b/src/test/ui/nll/ty-outlives/projection-no-regions-closure.stderr @@ -25,53 +25,6 @@ note: External requirements = note: number of external vids: 3 = note: where ::Item: '_#2r -note: External requirements - --> $DIR/projection-no-regions-closure.rs:46:23 - | -46 | with_signature(x, |mut y| Box::new(y.next())) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: defining type: DefId(0/1:18 ~ projection_no_regions_closure[317d]::correct_region[0]::{{closure}}[0]) with closure substs [ - '_#1r, - T, - i32, - extern "rust-call" fn((std::boxed::Box,)) -> std::boxed::Box - ] - = note: number of external vids: 3 - = note: where ::Item: '_#2r - -note: External requirements - --> $DIR/projection-no-regions-closure.rs:54:23 - | -54 | with_signature(x, |mut y| Box::new(y.next())) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: defining type: DefId(0/1:22 ~ projection_no_regions_closure[317d]::wrong_region[0]::{{closure}}[0]) with closure substs [ - '_#1r, - '_#2r, - T, - i32, - extern "rust-call" fn((std::boxed::Box,)) -> std::boxed::Box - ] - = note: number of external vids: 4 - = note: where ::Item: '_#3r - -note: External requirements - --> $DIR/projection-no-regions-closure.rs:65:23 - | -65 | with_signature(x, |mut y| Box::new(y.next())) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: defining type: DefId(0/1:26 ~ projection_no_regions_closure[317d]::outlives_region[0]::{{closure}}[0]) with closure substs [ - '_#1r, - '_#2r, - T, - i32, - extern "rust-call" fn((std::boxed::Box,)) -> std::boxed::Box - ] - = note: number of external vids: 4 - = note: where ::Item: '_#3r - error[E0309]: the associated type `::Item` may not live long enough --> $DIR/projection-no-regions-closure.rs:36:23 | @@ -97,6 +50,21 @@ note: No external requirements T ] +note: External requirements + --> $DIR/projection-no-regions-closure.rs:46:23 + | +46 | with_signature(x, |mut y| Box::new(y.next())) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: defining type: DefId(0/1:18 ~ projection_no_regions_closure[317d]::correct_region[0]::{{closure}}[0]) with closure substs [ + '_#1r, + T, + i32, + extern "rust-call" fn((std::boxed::Box,)) -> std::boxed::Box + ] + = note: number of external vids: 3 + = note: where ::Item: '_#2r + note: No external requirements --> $DIR/projection-no-regions-closure.rs:42:1 | @@ -113,6 +81,22 @@ note: No external requirements T ] +note: External requirements + --> $DIR/projection-no-regions-closure.rs:54:23 + | +54 | with_signature(x, |mut y| Box::new(y.next())) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: defining type: DefId(0/1:22 ~ projection_no_regions_closure[317d]::wrong_region[0]::{{closure}}[0]) with closure substs [ + '_#1r, + '_#2r, + T, + i32, + extern "rust-call" fn((std::boxed::Box,)) -> std::boxed::Box + ] + = note: number of external vids: 4 + = note: where ::Item: '_#3r + error[E0309]: the associated type `::Item` may not live long enough --> $DIR/projection-no-regions-closure.rs:54:23 | @@ -139,6 +123,22 @@ note: No external requirements T ] +note: External requirements + --> $DIR/projection-no-regions-closure.rs:65:23 + | +65 | with_signature(x, |mut y| Box::new(y.next())) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: defining type: DefId(0/1:26 ~ projection_no_regions_closure[317d]::outlives_region[0]::{{closure}}[0]) with closure substs [ + '_#1r, + '_#2r, + T, + i32, + extern "rust-call" fn((std::boxed::Box,)) -> std::boxed::Box + ] + = note: number of external vids: 4 + = note: where ::Item: '_#3r + note: No external requirements --> $DIR/projection-no-regions-closure.rs:60:1 | diff --git a/src/test/ui/nll/ty-outlives/projection-one-region-closure.stderr b/src/test/ui/nll/ty-outlives/projection-one-region-closure.stderr index bfe408342a868..946c1a8f37235 100644 --- a/src/test/ui/nll/ty-outlives/projection-one-region-closure.stderr +++ b/src/test/ui/nll/ty-outlives/projection-one-region-closure.stderr @@ -32,57 +32,6 @@ note: External requirements = note: where T: '_#2r = note: where '_#1r: '_#2r -note: External requirements - --> $DIR/projection-one-region-closure.rs:68:29 - | -68 | with_signature(cell, t, |cell, t| require(cell, t)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: defining type: DefId(0/1:23 ~ projection_one_region_closure[317d]::no_relationships_early[0]::{{closure}}[0]) with closure substs [ - '_#1r, - '_#2r, - T, - i32, - extern "rust-call" fn((std::cell::Cell<&'_#3r ()>, T)) - ] - = note: number of external vids: 4 - = note: where T: '_#3r - = note: where '_#2r: '_#3r - -note: External requirements - --> $DIR/projection-one-region-closure.rs:90:29 - | -90 | with_signature(cell, t, |cell, t| require(cell, t)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: defining type: DefId(0/1:27 ~ projection_one_region_closure[317d]::projection_outlives[0]::{{closure}}[0]) with closure substs [ - '_#1r, - '_#2r, - T, - i32, - extern "rust-call" fn((std::cell::Cell<&'_#3r ()>, T)) - ] - = note: number of external vids: 4 - = note: where T: '_#3r - = note: where '_#2r: '_#3r - -note: External requirements - --> $DIR/projection-one-region-closure.rs:103:29 - | -103 | with_signature(cell, t, |cell, t| require(cell, t)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: defining type: DefId(0/1:31 ~ projection_one_region_closure[317d]::elements_outlive[0]::{{closure}}[0]) with closure substs [ - '_#1r, - '_#2r, - T, - i32, - extern "rust-call" fn((std::cell::Cell<&'_#3r ()>, T)) - ] - = note: number of external vids: 4 - = note: where T: '_#3r - = note: where '_#2r: '_#3r - error[E0309]: the parameter type `T` may not live long enough --> $DIR/projection-one-region-closure.rs:56:29 | @@ -114,6 +63,23 @@ note: No external requirements T ] +note: External requirements + --> $DIR/projection-one-region-closure.rs:68:29 + | +68 | with_signature(cell, t, |cell, t| require(cell, t)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: defining type: DefId(0/1:23 ~ projection_one_region_closure[317d]::no_relationships_early[0]::{{closure}}[0]) with closure substs [ + '_#1r, + '_#2r, + T, + i32, + extern "rust-call" fn((std::cell::Cell<&'_#3r ()>, T)) + ] + = note: number of external vids: 4 + = note: where T: '_#3r + = note: where '_#2r: '_#3r + error[E0309]: the parameter type `T` may not live long enough --> $DIR/projection-one-region-closure.rs:68:29 | @@ -146,6 +112,23 @@ note: No external requirements T ] +note: External requirements + --> $DIR/projection-one-region-closure.rs:90:29 + | +90 | with_signature(cell, t, |cell, t| require(cell, t)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: defining type: DefId(0/1:27 ~ projection_one_region_closure[317d]::projection_outlives[0]::{{closure}}[0]) with closure substs [ + '_#1r, + '_#2r, + T, + i32, + extern "rust-call" fn((std::cell::Cell<&'_#3r ()>, T)) + ] + = note: number of external vids: 4 + = note: where T: '_#3r + = note: where '_#2r: '_#3r + error[E0309]: the parameter type `T` may not live long enough --> $DIR/projection-one-region-closure.rs:90:29 | @@ -178,6 +161,23 @@ note: No external requirements T ] +note: External requirements + --> $DIR/projection-one-region-closure.rs:103:29 + | +103 | with_signature(cell, t, |cell, t| require(cell, t)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: defining type: DefId(0/1:31 ~ projection_one_region_closure[317d]::elements_outlive[0]::{{closure}}[0]) with closure substs [ + '_#1r, + '_#2r, + T, + i32, + extern "rust-call" fn((std::cell::Cell<&'_#3r ()>, T)) + ] + = note: number of external vids: 4 + = note: where T: '_#3r + = note: where '_#2r: '_#3r + note: No external requirements --> $DIR/projection-one-region-closure.rs:97:1 | diff --git a/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.stderr b/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.stderr index 6cb54170d7a90..b26fa96fe6389 100644 --- a/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.stderr +++ b/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.stderr @@ -31,69 +31,6 @@ note: External requirements = note: number of external vids: 3 = note: where '_#1r: '_#2r -note: External requirements - --> $DIR/projection-one-region-trait-bound-closure.rs:59:29 - | -59 | with_signature(cell, t, |cell, t| require(cell, t)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: defining type: DefId(0/1:23 ~ projection_one_region_trait_bound_closure[317d]::no_relationships_early[0]::{{closure}}[0]) with closure substs [ - '_#1r, - '_#2r, - T, - i32, - extern "rust-call" fn((std::cell::Cell<&'_#3r ()>, T)) - ] - = note: number of external vids: 4 - = note: where '_#2r: '_#3r - -note: External requirements - --> $DIR/projection-one-region-trait-bound-closure.rs:80:29 - | -80 | with_signature(cell, t, |cell, t| require(cell, t)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: defining type: DefId(0/1:27 ~ projection_one_region_trait_bound_closure[317d]::projection_outlives[0]::{{closure}}[0]) with closure substs [ - '_#1r, - '_#2r, - T, - i32, - extern "rust-call" fn((std::cell::Cell<&'_#3r ()>, T)) - ] - = note: number of external vids: 4 - = note: where '_#2r: '_#3r - -note: External requirements - --> $DIR/projection-one-region-trait-bound-closure.rs:91:29 - | -91 | with_signature(cell, t, |cell, t| require(cell, t)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: defining type: DefId(0/1:31 ~ projection_one_region_trait_bound_closure[317d]::elements_outlive[0]::{{closure}}[0]) with closure substs [ - '_#1r, - '_#2r, - T, - i32, - extern "rust-call" fn((std::cell::Cell<&'_#3r ()>, T)) - ] - = note: number of external vids: 4 - = note: where '_#2r: '_#3r - -note: External requirements - --> $DIR/projection-one-region-trait-bound-closure.rs:103:29 - | -103 | with_signature(cell, t, |cell, t| require(cell, t)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: defining type: DefId(0/1:34 ~ projection_one_region_trait_bound_closure[317d]::one_region[0]::{{closure}}[0]) with closure substs [ - '_#1r, - T, - i32, - extern "rust-call" fn((std::cell::Cell<&'_#2r ()>, T)) - ] - = note: number of external vids: 3 - = note: where '_#1r: '_#2r - error: free region `ReEarlyBound(0, 'b)` does not outlive free region `ReFree(DefId(0/0:8 ~ projection_one_region_trait_bound_closure[317d]::no_relationships_late[0]), BrNamed(crate0:DefIndex(1:16), 'a))` --> $DIR/projection-one-region-trait-bound-closure.rs:48:20 | @@ -117,6 +54,22 @@ note: No external requirements T ] +note: External requirements + --> $DIR/projection-one-region-trait-bound-closure.rs:59:29 + | +59 | with_signature(cell, t, |cell, t| require(cell, t)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: defining type: DefId(0/1:23 ~ projection_one_region_trait_bound_closure[317d]::no_relationships_early[0]::{{closure}}[0]) with closure substs [ + '_#1r, + '_#2r, + T, + i32, + extern "rust-call" fn((std::cell::Cell<&'_#3r ()>, T)) + ] + = note: number of external vids: 4 + = note: where '_#2r: '_#3r + error: free region `ReEarlyBound(1, 'b)` does not outlive free region `ReEarlyBound(0, 'a)` --> $DIR/projection-one-region-trait-bound-closure.rs:59:20 | @@ -141,6 +94,22 @@ note: No external requirements T ] +note: External requirements + --> $DIR/projection-one-region-trait-bound-closure.rs:80:29 + | +80 | with_signature(cell, t, |cell, t| require(cell, t)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: defining type: DefId(0/1:27 ~ projection_one_region_trait_bound_closure[317d]::projection_outlives[0]::{{closure}}[0]) with closure substs [ + '_#1r, + '_#2r, + T, + i32, + extern "rust-call" fn((std::cell::Cell<&'_#3r ()>, T)) + ] + = note: number of external vids: 4 + = note: where '_#2r: '_#3r + error: free region `ReEarlyBound(1, 'b)` does not outlive free region `ReEarlyBound(0, 'a)` --> $DIR/projection-one-region-trait-bound-closure.rs:80:20 | @@ -165,6 +134,22 @@ note: No external requirements T ] +note: External requirements + --> $DIR/projection-one-region-trait-bound-closure.rs:91:29 + | +91 | with_signature(cell, t, |cell, t| require(cell, t)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: defining type: DefId(0/1:31 ~ projection_one_region_trait_bound_closure[317d]::elements_outlive[0]::{{closure}}[0]) with closure substs [ + '_#1r, + '_#2r, + T, + i32, + extern "rust-call" fn((std::cell::Cell<&'_#3r ()>, T)) + ] + = note: number of external vids: 4 + = note: where '_#2r: '_#3r + note: No external requirements --> $DIR/projection-one-region-trait-bound-closure.rs:86:1 | @@ -183,6 +168,21 @@ note: No external requirements T ] +note: External requirements + --> $DIR/projection-one-region-trait-bound-closure.rs:103:29 + | +103 | with_signature(cell, t, |cell, t| require(cell, t)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: defining type: DefId(0/1:34 ~ projection_one_region_trait_bound_closure[317d]::one_region[0]::{{closure}}[0]) with closure substs [ + '_#1r, + T, + i32, + extern "rust-call" fn((std::cell::Cell<&'_#2r ()>, T)) + ] + = note: number of external vids: 3 + = note: where '_#1r: '_#2r + note: No external requirements --> $DIR/projection-one-region-trait-bound-closure.rs:95:1 | diff --git a/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-static-closure.stderr b/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-static-closure.stderr index 986676d28d920..98b033b6a0672 100644 --- a/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-static-closure.stderr +++ b/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-static-closure.stderr @@ -12,40 +12,28 @@ note: No external requirements ] note: No external requirements - --> $DIR/projection-one-region-trait-bound-static-closure.rs:56:29 - | -56 | with_signature(cell, t, |cell, t| require(cell, t)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: defining type: DefId(0/1:23 ~ projection_one_region_trait_bound_static_closure[317d]::no_relationships_early[0]::{{closure}}[0]) with closure substs [ - '_#1r, - '_#2r, - T, - i32, - extern "rust-call" fn((std::cell::Cell<&'_#3r ()>, T)) - ] - -note: No external requirements - --> $DIR/projection-one-region-trait-bound-static-closure.rs:75:29 + --> $DIR/projection-one-region-trait-bound-static-closure.rs:43:1 | -75 | with_signature(cell, t, |cell, t| require(cell, t)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +43 | / fn no_relationships_late<'a, 'b, T>(cell: Cell<&'a ()>, t: T) +44 | | where +45 | | T: Anything<'b>, +46 | | { +47 | | with_signature(cell, t, |cell, t| require(cell, t)); +48 | | } + | |_^ | - = note: defining type: DefId(0/1:27 ~ projection_one_region_trait_bound_static_closure[317d]::projection_outlives[0]::{{closure}}[0]) with closure substs [ + = note: defining type: DefId(0/0:8 ~ projection_one_region_trait_bound_static_closure[317d]::no_relationships_late[0]) with substs [ '_#1r, - '_#2r, - T, - i32, - extern "rust-call" fn((std::cell::Cell<&'_#3r ()>, T)) + T ] note: No external requirements - --> $DIR/projection-one-region-trait-bound-static-closure.rs:84:29 + --> $DIR/projection-one-region-trait-bound-static-closure.rs:56:29 | -84 | with_signature(cell, t, |cell, t| require(cell, t)); +56 | with_signature(cell, t, |cell, t| require(cell, t)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: defining type: DefId(0/1:31 ~ projection_one_region_trait_bound_static_closure[317d]::elements_outlive[0]::{{closure}}[0]) with closure substs [ + = note: defining type: DefId(0/1:23 ~ projection_one_region_trait_bound_static_closure[317d]::no_relationships_early[0]::{{closure}}[0]) with closure substs [ '_#1r, '_#2r, T, @@ -53,35 +41,6 @@ note: No external requirements extern "rust-call" fn((std::cell::Cell<&'_#3r ()>, T)) ] -note: No external requirements - --> $DIR/projection-one-region-trait-bound-static-closure.rs:96:29 - | -96 | with_signature(cell, t, |cell, t| require(cell, t)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: defining type: DefId(0/1:34 ~ projection_one_region_trait_bound_static_closure[317d]::one_region[0]::{{closure}}[0]) with closure substs [ - '_#1r, - T, - i32, - extern "rust-call" fn((std::cell::Cell<&'_#2r ()>, T)) - ] - -note: No external requirements - --> $DIR/projection-one-region-trait-bound-static-closure.rs:43:1 - | -43 | / fn no_relationships_late<'a, 'b, T>(cell: Cell<&'a ()>, t: T) -44 | | where -45 | | T: Anything<'b>, -46 | | { -47 | | with_signature(cell, t, |cell, t| require(cell, t)); -48 | | } - | |_^ - | - = note: defining type: DefId(0/0:8 ~ projection_one_region_trait_bound_static_closure[317d]::no_relationships_late[0]) with substs [ - '_#1r, - T - ] - note: No external requirements --> $DIR/projection-one-region-trait-bound-static-closure.rs:51:1 | @@ -100,6 +59,20 @@ note: No external requirements T ] +note: No external requirements + --> $DIR/projection-one-region-trait-bound-static-closure.rs:75:29 + | +75 | with_signature(cell, t, |cell, t| require(cell, t)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: defining type: DefId(0/1:27 ~ projection_one_region_trait_bound_static_closure[317d]::projection_outlives[0]::{{closure}}[0]) with closure substs [ + '_#1r, + '_#2r, + T, + i32, + extern "rust-call" fn((std::cell::Cell<&'_#3r ()>, T)) + ] + note: No external requirements --> $DIR/projection-one-region-trait-bound-static-closure.rs:60:1 | @@ -118,6 +91,20 @@ note: No external requirements T ] +note: No external requirements + --> $DIR/projection-one-region-trait-bound-static-closure.rs:84:29 + | +84 | with_signature(cell, t, |cell, t| require(cell, t)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: defining type: DefId(0/1:31 ~ projection_one_region_trait_bound_static_closure[317d]::elements_outlive[0]::{{closure}}[0]) with closure substs [ + '_#1r, + '_#2r, + T, + i32, + extern "rust-call" fn((std::cell::Cell<&'_#3r ()>, T)) + ] + note: No external requirements --> $DIR/projection-one-region-trait-bound-static-closure.rs:79:1 | @@ -136,6 +123,19 @@ note: No external requirements T ] +note: No external requirements + --> $DIR/projection-one-region-trait-bound-static-closure.rs:96:29 + | +96 | with_signature(cell, t, |cell, t| require(cell, t)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: defining type: DefId(0/1:34 ~ projection_one_region_trait_bound_static_closure[317d]::one_region[0]::{{closure}}[0]) with closure substs [ + '_#1r, + T, + i32, + extern "rust-call" fn((std::cell::Cell<&'_#2r ()>, T)) + ] + note: No external requirements --> $DIR/projection-one-region-trait-bound-static-closure.rs:88:1 | diff --git a/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr b/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr index 21487899d3ba6..78775ce94addd 100644 --- a/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr +++ b/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr @@ -38,120 +38,6 @@ note: External requirements = note: number of external vids: 4 = note: where >::AssocType: '_#3r -note: External requirements - --> $DIR/projection-two-region-trait-bound-closure.rs:60:29 - | -60 | with_signature(cell, t, |cell, t| require(cell, t)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: defining type: DefId(0/1:27 ~ projection_two_region_trait_bound_closure[317d]::no_relationships_early[0]::{{closure}}[0]) with closure substs [ - '_#1r, - '_#2r, - '_#3r, - T, - i32, - extern "rust-call" fn((std::cell::Cell<&'_#4r ()>, T)) - ] - = note: number of external vids: 5 - = note: where >::AssocType: '_#4r - -note: External requirements - --> $DIR/projection-two-region-trait-bound-closure.rs:81:29 - | -81 | with_signature(cell, t, |cell, t| require(cell, t)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: defining type: DefId(0/1:32 ~ projection_two_region_trait_bound_closure[317d]::projection_outlives[0]::{{closure}}[0]) with closure substs [ - '_#1r, - '_#2r, - '_#3r, - T, - i32, - extern "rust-call" fn((std::cell::Cell<&'_#4r ()>, T)) - ] - = note: number of external vids: 5 - = note: where >::AssocType: '_#4r - -note: External requirements - --> $DIR/projection-two-region-trait-bound-closure.rs:92:29 - | -92 | with_signature(cell, t, |cell, t| require(cell, t)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: defining type: DefId(0/1:37 ~ projection_two_region_trait_bound_closure[317d]::elements_outlive1[0]::{{closure}}[0]) with closure substs [ - '_#1r, - '_#2r, - '_#3r, - T, - i32, - extern "rust-call" fn((std::cell::Cell<&'_#4r ()>, T)) - ] - = note: number of external vids: 5 - = note: where >::AssocType: '_#4r - -note: External requirements - --> $DIR/projection-two-region-trait-bound-closure.rs:101:29 - | -101 | with_signature(cell, t, |cell, t| require(cell, t)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: defining type: DefId(0/1:42 ~ projection_two_region_trait_bound_closure[317d]::elements_outlive2[0]::{{closure}}[0]) with closure substs [ - '_#1r, - '_#2r, - '_#3r, - T, - i32, - extern "rust-call" fn((std::cell::Cell<&'_#4r ()>, T)) - ] - = note: number of external vids: 5 - = note: where >::AssocType: '_#4r - -note: External requirements - --> $DIR/projection-two-region-trait-bound-closure.rs:109:29 - | -109 | with_signature(cell, t, |cell, t| require(cell, t)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: defining type: DefId(0/1:46 ~ projection_two_region_trait_bound_closure[317d]::two_regions[0]::{{closure}}[0]) with closure substs [ - '_#1r, - T, - i32, - extern "rust-call" fn((std::cell::Cell<&'_#2r ()>, T)) - ] - = note: number of external vids: 3 - = note: where >::AssocType: '_#2r - -note: External requirements - --> $DIR/projection-two-region-trait-bound-closure.rs:120:29 - | -120 | with_signature(cell, t, |cell, t| require(cell, t)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: defining type: DefId(0/1:50 ~ projection_two_region_trait_bound_closure[317d]::two_regions_outlive[0]::{{closure}}[0]) with closure substs [ - '_#1r, - '_#2r, - T, - i32, - extern "rust-call" fn((std::cell::Cell<&'_#3r ()>, T)) - ] - = note: number of external vids: 4 - = note: where >::AssocType: '_#3r - -note: External requirements - --> $DIR/projection-two-region-trait-bound-closure.rs:132:29 - | -132 | with_signature(cell, t, |cell, t| require(cell, t)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: defining type: DefId(0/1:53 ~ projection_two_region_trait_bound_closure[317d]::one_region[0]::{{closure}}[0]) with closure substs [ - '_#1r, - T, - i32, - extern "rust-call" fn((std::cell::Cell<&'_#2r ()>, T)) - ] - = note: number of external vids: 3 - = note: where >::AssocType: '_#2r - error[E0309]: the associated type `>::AssocType` may not live long enough --> $DIR/projection-two-region-trait-bound-closure.rs:49:29 | @@ -178,6 +64,23 @@ note: No external requirements T ] +note: External requirements + --> $DIR/projection-two-region-trait-bound-closure.rs:60:29 + | +60 | with_signature(cell, t, |cell, t| require(cell, t)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: defining type: DefId(0/1:27 ~ projection_two_region_trait_bound_closure[317d]::no_relationships_early[0]::{{closure}}[0]) with closure substs [ + '_#1r, + '_#2r, + '_#3r, + T, + i32, + extern "rust-call" fn((std::cell::Cell<&'_#4r ()>, T)) + ] + = note: number of external vids: 5 + = note: where >::AssocType: '_#4r + error[E0309]: the associated type `>::AssocType` may not live long enough --> $DIR/projection-two-region-trait-bound-closure.rs:60:29 | @@ -205,6 +108,23 @@ note: No external requirements T ] +note: External requirements + --> $DIR/projection-two-region-trait-bound-closure.rs:81:29 + | +81 | with_signature(cell, t, |cell, t| require(cell, t)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: defining type: DefId(0/1:32 ~ projection_two_region_trait_bound_closure[317d]::projection_outlives[0]::{{closure}}[0]) with closure substs [ + '_#1r, + '_#2r, + '_#3r, + T, + i32, + extern "rust-call" fn((std::cell::Cell<&'_#4r ()>, T)) + ] + = note: number of external vids: 5 + = note: where >::AssocType: '_#4r + error[E0309]: the associated type `>::AssocType` may not live long enough --> $DIR/projection-two-region-trait-bound-closure.rs:81:29 | @@ -232,6 +152,23 @@ note: No external requirements T ] +note: External requirements + --> $DIR/projection-two-region-trait-bound-closure.rs:92:29 + | +92 | with_signature(cell, t, |cell, t| require(cell, t)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: defining type: DefId(0/1:37 ~ projection_two_region_trait_bound_closure[317d]::elements_outlive1[0]::{{closure}}[0]) with closure substs [ + '_#1r, + '_#2r, + '_#3r, + T, + i32, + extern "rust-call" fn((std::cell::Cell<&'_#4r ()>, T)) + ] + = note: number of external vids: 5 + = note: where >::AssocType: '_#4r + note: No external requirements --> $DIR/projection-two-region-trait-bound-closure.rs:87:1 | @@ -251,6 +188,23 @@ note: No external requirements T ] +note: External requirements + --> $DIR/projection-two-region-trait-bound-closure.rs:101:29 + | +101 | with_signature(cell, t, |cell, t| require(cell, t)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: defining type: DefId(0/1:42 ~ projection_two_region_trait_bound_closure[317d]::elements_outlive2[0]::{{closure}}[0]) with closure substs [ + '_#1r, + '_#2r, + '_#3r, + T, + i32, + extern "rust-call" fn((std::cell::Cell<&'_#4r ()>, T)) + ] + = note: number of external vids: 5 + = note: where >::AssocType: '_#4r + note: No external requirements --> $DIR/projection-two-region-trait-bound-closure.rs:96:1 | @@ -270,6 +224,21 @@ note: No external requirements T ] +note: External requirements + --> $DIR/projection-two-region-trait-bound-closure.rs:109:29 + | +109 | with_signature(cell, t, |cell, t| require(cell, t)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: defining type: DefId(0/1:46 ~ projection_two_region_trait_bound_closure[317d]::two_regions[0]::{{closure}}[0]) with closure substs [ + '_#1r, + T, + i32, + extern "rust-call" fn((std::cell::Cell<&'_#2r ()>, T)) + ] + = note: number of external vids: 3 + = note: where >::AssocType: '_#2r + error: free region `ReEarlyBound(0, 'b)` does not outlive free region `ReFree(DefId(0/0:13 ~ projection_two_region_trait_bound_closure[317d]::two_regions[0]), BrNamed(crate0:DefIndex(1:43), 'a))` --> $DIR/projection-two-region-trait-bound-closure.rs:109:20 | @@ -293,6 +262,22 @@ note: No external requirements T ] +note: External requirements + --> $DIR/projection-two-region-trait-bound-closure.rs:120:29 + | +120 | with_signature(cell, t, |cell, t| require(cell, t)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: defining type: DefId(0/1:50 ~ projection_two_region_trait_bound_closure[317d]::two_regions_outlive[0]::{{closure}}[0]) with closure substs [ + '_#1r, + '_#2r, + T, + i32, + extern "rust-call" fn((std::cell::Cell<&'_#3r ()>, T)) + ] + = note: number of external vids: 4 + = note: where >::AssocType: '_#3r + note: No external requirements --> $DIR/projection-two-region-trait-bound-closure.rs:115:1 | @@ -311,6 +296,21 @@ note: No external requirements T ] +note: External requirements + --> $DIR/projection-two-region-trait-bound-closure.rs:132:29 + | +132 | with_signature(cell, t, |cell, t| require(cell, t)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: defining type: DefId(0/1:53 ~ projection_two_region_trait_bound_closure[317d]::one_region[0]::{{closure}}[0]) with closure substs [ + '_#1r, + T, + i32, + extern "rust-call" fn((std::cell::Cell<&'_#2r ()>, T)) + ] + = note: number of external vids: 3 + = note: where >::AssocType: '_#2r + note: No external requirements --> $DIR/projection-two-region-trait-bound-closure.rs:124:1 | diff --git a/src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr b/src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr index 023b58c927d86..f68a76c3d0de5 100644 --- a/src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr +++ b/src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr @@ -30,20 +30,6 @@ note: External requirements = note: number of external vids: 2 = note: where T: '_#1r -note: External requirements - --> $DIR/ty-param-closure-approximate-lower-bound.rs:43:24 - | -43 | twice(cell, value, |a, b| invoke(a, b)); - | ^^^^^^^^^^^^^^^^^^^ - | - = note: defining type: DefId(0/1:17 ~ ty_param_closure_approximate_lower_bound[317d]::generic_fail[0]::{{closure}}[0]) with closure substs [ - T, - i16, - for<'r, 's> extern "rust-call" fn((std::option::Option>, &ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 's)) T)) - ] - = note: number of external vids: 2 - = note: where T: '_#1r - note: No external requirements --> $DIR/ty-param-closure-approximate-lower-bound.rs:33:1 | @@ -60,6 +46,20 @@ note: No external requirements T ] +note: External requirements + --> $DIR/ty-param-closure-approximate-lower-bound.rs:43:24 + | +43 | twice(cell, value, |a, b| invoke(a, b)); + | ^^^^^^^^^^^^^^^^^^^ + | + = note: defining type: DefId(0/1:17 ~ ty_param_closure_approximate_lower_bound[317d]::generic_fail[0]::{{closure}}[0]) with closure substs [ + T, + i16, + for<'r, 's> extern "rust-call" fn((std::option::Option>, &ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 's)) T)) + ] + = note: number of external vids: 2 + = note: where T: '_#1r + error[E0309]: the parameter type `T` may not live long enough --> $DIR/ty-param-closure-approximate-lower-bound.rs:43:24 | diff --git a/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.stderr b/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.stderr index 2dd13810ae48a..ed4d4b1e68f7f 100644 --- a/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.stderr +++ b/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.stderr @@ -31,69 +31,6 @@ note: External requirements = note: number of external vids: 2 = note: where T: '_#1r -note: External requirements - --> $DIR/ty-param-closure-outlives-from-where-clause.rs:55:26 - | -55 | with_signature(a, b, |x, y| { - | __________________________^ -56 | | // Key point of this test: -57 | | // -58 | | // The *closure* is being type-checked with all of its free -... | -67 | | require(&x, &y) -68 | | }) - | |_____^ - | - = note: defining type: DefId(0/1:19 ~ ty_param_closure_outlives_from_where_clause[317d]::correct_region[0]::{{closure}}[0]) with closure substs [ - '_#1r, - T, - i32, - extern "rust-call" fn((std::cell::Cell<&'_#2r ()>, T)) - ] - = note: number of external vids: 3 - = note: where T: '_#2r - -note: External requirements - --> $DIR/ty-param-closure-outlives-from-where-clause.rs:76:26 - | -76 | with_signature(a, b, |x, y| { - | __________________________^ -77 | | //~^ ERROR the parameter type `T` may not live long enough -78 | | // See `correct_region` -79 | | require(&x, &y) -80 | | //~^ WARNING not reporting region error due to -Znll -81 | | }) - | |_____^ - | - = note: defining type: DefId(0/1:23 ~ ty_param_closure_outlives_from_where_clause[317d]::wrong_region[0]::{{closure}}[0]) with closure substs [ - '_#1r, - T, - i32, - extern "rust-call" fn((std::cell::Cell<&'_#2r ()>, T)) - ] - = note: number of external vids: 3 - = note: where T: '_#2r - -note: External requirements - --> $DIR/ty-param-closure-outlives-from-where-clause.rs:90:26 - | -90 | with_signature(a, b, |x, y| { - | __________________________^ -91 | | // See `correct_region` -92 | | require(&x, &y) -93 | | }) - | |_____^ - | - = note: defining type: DefId(0/1:27 ~ ty_param_closure_outlives_from_where_clause[317d]::outlives_region[0]::{{closure}}[0]) with closure substs [ - '_#1r, - '_#2r, - T, - i32, - extern "rust-call" fn((std::cell::Cell<&'_#3r ()>, T)) - ] - = note: number of external vids: 4 - = note: where T: '_#3r - error[E0309]: the parameter type `T` may not live long enough --> $DIR/ty-param-closure-outlives-from-where-clause.rs:38:26 | @@ -125,6 +62,28 @@ note: No external requirements T ] +note: External requirements + --> $DIR/ty-param-closure-outlives-from-where-clause.rs:55:26 + | +55 | with_signature(a, b, |x, y| { + | __________________________^ +56 | | // Key point of this test: +57 | | // +58 | | // The *closure* is being type-checked with all of its free +... | +67 | | require(&x, &y) +68 | | }) + | |_____^ + | + = note: defining type: DefId(0/1:19 ~ ty_param_closure_outlives_from_where_clause[317d]::correct_region[0]::{{closure}}[0]) with closure substs [ + '_#1r, + T, + i32, + extern "rust-call" fn((std::cell::Cell<&'_#2r ()>, T)) + ] + = note: number of external vids: 3 + = note: where T: '_#2r + note: No external requirements --> $DIR/ty-param-closure-outlives-from-where-clause.rs:51:1 | @@ -142,6 +101,27 @@ note: No external requirements T ] +note: External requirements + --> $DIR/ty-param-closure-outlives-from-where-clause.rs:76:26 + | +76 | with_signature(a, b, |x, y| { + | __________________________^ +77 | | //~^ ERROR the parameter type `T` may not live long enough +78 | | // See `correct_region` +79 | | require(&x, &y) +80 | | //~^ WARNING not reporting region error due to -Znll +81 | | }) + | |_____^ + | + = note: defining type: DefId(0/1:23 ~ ty_param_closure_outlives_from_where_clause[317d]::wrong_region[0]::{{closure}}[0]) with closure substs [ + '_#1r, + T, + i32, + extern "rust-call" fn((std::cell::Cell<&'_#2r ()>, T)) + ] + = note: number of external vids: 3 + = note: where T: '_#2r + error[E0309]: the parameter type `T` may not live long enough --> $DIR/ty-param-closure-outlives-from-where-clause.rs:76:26 | @@ -173,6 +153,26 @@ note: No external requirements T ] +note: External requirements + --> $DIR/ty-param-closure-outlives-from-where-clause.rs:90:26 + | +90 | with_signature(a, b, |x, y| { + | __________________________^ +91 | | // See `correct_region` +92 | | require(&x, &y) +93 | | }) + | |_____^ + | + = note: defining type: DefId(0/1:27 ~ ty_param_closure_outlives_from_where_clause[317d]::outlives_region[0]::{{closure}}[0]) with closure substs [ + '_#1r, + '_#2r, + T, + i32, + extern "rust-call" fn((std::cell::Cell<&'_#3r ()>, T)) + ] + = note: number of external vids: 4 + = note: where T: '_#3r + note: No external requirements --> $DIR/ty-param-closure-outlives-from-where-clause.rs:85:1 | diff --git a/src/test/ui/resolve/issue-23305.rs b/src/test/ui/resolve/issue-23305.rs index f249e0e1127ee..34f8a0a48431c 100644 --- a/src/test/ui/resolve/issue-23305.rs +++ b/src/test/ui/resolve/issue-23305.rs @@ -13,6 +13,6 @@ pub trait ToNbt { } impl ToNbt {} -//~^ ERROR unsupported cyclic reference +//~^ ERROR cyclic dependency detected fn main() {} diff --git a/src/test/ui/resolve/issue-23305.stderr b/src/test/ui/resolve/issue-23305.stderr index 5bba9fc41e276..a0b4d424ec968 100644 --- a/src/test/ui/resolve/issue-23305.stderr +++ b/src/test/ui/resolve/issue-23305.stderr @@ -1,4 +1,4 @@ -error[E0391]: unsupported cyclic reference between types/traits detected +error[E0391]: cyclic dependency detected --> $DIR/issue-23305.rs:15:12 | 15 | impl ToNbt {} diff --git a/src/test/compile-fail/issue-17718-recursive.rs b/src/test/ui/unsafe-block-without-braces.rs similarity index 65% rename from src/test/compile-fail/issue-17718-recursive.rs rename to src/test/ui/unsafe-block-without-braces.rs index 9959b0c6fc523..b6fb3ec5c44cf 100644 --- a/src/test/compile-fail/issue-17718-recursive.rs +++ b/src/test/ui/unsafe-block-without-braces.rs @@ -1,4 +1,4 @@ -// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -8,7 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -const A: usize = B; //~ ERROR: recursive constant -const B: usize = A; //~ ERROR: recursive constant - -fn main() {} +fn main() { + unsafe //{ + std::mem::transmute::(1.0); + //} +} +//~^^^ ERROR expected one of `extern`, `fn`, or `{`, found `std` diff --git a/src/test/ui/unsafe-block-without-braces.stderr b/src/test/ui/unsafe-block-without-braces.stderr new file mode 100644 index 0000000000000..fc6ddba382395 --- /dev/null +++ b/src/test/ui/unsafe-block-without-braces.stderr @@ -0,0 +1,10 @@ +error: expected one of `extern`, `fn`, or `{`, found `std` + --> $DIR/unsafe-block-without-braces.rs:13:9 + | +12 | unsafe //{ + | - expected one of `extern`, `fn`, or `{` here +13 | std::mem::transmute::(1.0); + | ^^^ unexpected token + +error: aborting due to previous error +