diff --git a/.mailmap b/.mailmap index 9587aaab35945..a2e3c581eabba 100644 --- a/.mailmap +++ b/.mailmap @@ -69,6 +69,7 @@ David Manescu David Ross Derek Chiang Derek Chiang (Enchi Jiang) Diggory Hardy Diggory Hardy +Dustin Bensing Dylan Braithwaite Dzmitry Malyshau E. Dunham edunham diff --git a/Cargo.lock b/Cargo.lock index 40a0b9fe59dbd..5a92011d57033 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -534,7 +534,7 @@ name = "compiletest" version = "0.0.0" dependencies = [ "diff", - "env_logger 0.6.2", + "env_logger 0.7.0", "getopts", "lazy_static 1.3.0", "libc", @@ -3409,7 +3409,7 @@ dependencies = [ name = "rustc_driver" version = "0.0.0" dependencies = [ - "env_logger 0.6.2", + "env_logger 0.7.0", "graphviz", "lazy_static 1.3.0", "log", diff --git a/RELEASES.md b/RELEASES.md index 766cf64410c77..e6512bb6f6de9 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -47,8 +47,6 @@ Stabilized APIs - [`<*mut T>::cast`] - [`Duration::as_secs_f32`] - [`Duration::as_secs_f64`] -- [`Duration::div_duration_f32`] -- [`Duration::div_duration_f64`] - [`Duration::div_f32`] - [`Duration::div_f64`] - [`Duration::from_secs_f32`] @@ -100,8 +98,6 @@ Compatibility Notes [`<*mut T>::cast`]: https://doc.rust-lang.org/std/primitive.pointer.html#method.cast [`Duration::as_secs_f32`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.as_secs_f32 [`Duration::as_secs_f64`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.as_secs_f64 -[`Duration::div_duration_f32`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.div_duration_f32 -[`Duration::div_duration_f64`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.div_duration_f64 [`Duration::div_f32`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.div_f32 [`Duration::div_f64`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.div_f64 [`Duration::from_secs_f32`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.from_secs_f32 diff --git a/src/liballoc/collections/btree/map.rs b/src/liballoc/collections/btree/map.rs index 1683b8105567f..ddf012d15029a 100644 --- a/src/liballoc/collections/btree/map.rs +++ b/src/liballoc/collections/btree/map.rs @@ -580,7 +580,6 @@ impl BTreeMap { /// # Examples /// /// ``` - /// #![feature(map_get_key_value)] /// use std::collections::BTreeMap; /// /// let mut map = BTreeMap::new(); @@ -588,7 +587,7 @@ impl BTreeMap { /// assert_eq!(map.get_key_value(&1), Some((&1, &"a"))); /// assert_eq!(map.get_key_value(&2), None); /// ``` - #[unstable(feature = "map_get_key_value", issue = "49347")] + #[stable(feature = "map_get_key_value", since = "1.40.0")] pub fn get_key_value(&self, k: &Q) -> Option<(&K, &V)> where K: Borrow, Q: Ord diff --git a/src/libcore/pin.rs b/src/libcore/pin.rs index 1dc6d54b08a5a..be057ed6d59a7 100644 --- a/src/libcore/pin.rs +++ b/src/libcore/pin.rs @@ -369,6 +369,8 @@ //! [drop-guarantee]: #drop-guarantee //! [`poll`]: ../../std/future/trait.Future.html#tymethod.poll //! [`Pin::get_unchecked_mut`]: struct.Pin.html#method.get_unchecked_mut +//! [`bool`]: ../../std/primitive.bool.html +//! [`i32`]: ../../std/primitive.i32.html #![stable(feature = "pin", since = "1.33.0")] diff --git a/src/librustc/dep_graph/dep_tracking_map.rs b/src/librustc/dep_graph/dep_tracking_map.rs deleted file mode 100644 index ee22d0b755a09..0000000000000 --- a/src/librustc/dep_graph/dep_tracking_map.rs +++ /dev/null @@ -1,87 +0,0 @@ -use rustc_data_structures::fx::FxHashMap; -use std::cell::RefCell; -use std::hash::Hash; -use std::marker::PhantomData; -use crate::util::common::MemoizationMap; - -use super::{DepKind, DepNodeIndex, DepGraph}; - -/// A DepTrackingMap offers a subset of the `Map` API and ensures that -/// we make calls to `read` and `write` as appropriate. We key the -/// maps with a unique type for brevity. -pub struct DepTrackingMap { - phantom: PhantomData, - graph: DepGraph, - map: FxHashMap, -} - -pub trait DepTrackingMapConfig { - type Key: Eq + Hash + Clone; - type Value: Clone; - fn to_dep_kind() -> DepKind; -} - -impl DepTrackingMap { - pub fn new(graph: DepGraph) -> DepTrackingMap { - DepTrackingMap { - phantom: PhantomData, - graph, - map: Default::default(), - } - } -} - -impl MemoizationMap for RefCell> { - type Key = M::Key; - type Value = M::Value; - - /// Memoizes an entry in the dep-tracking-map. If the entry is not - /// already present, then `op` will be executed to compute its value. - /// The resulting dependency graph looks like this: - /// - /// [op] -> Map(key) -> CurrentTask - /// - /// Here, `[op]` represents whatever nodes `op` reads in the - /// course of execution; `Map(key)` represents the node for this - /// map, and `CurrentTask` represents the current task when - /// `memoize` is invoked. - /// - /// **Important:** when `op` is invoked, the current task will be - /// switched to `Map(key)`. Therefore, if `op` makes use of any - /// HIR nodes or shared state accessed through its closure - /// environment, it must explicitly register a read of that - /// state. As an example, see `type_of_item` in `collect`, - /// which looks something like this: - /// - /// ``` - /// fn type_of_item(..., item: &hir::Item) -> Ty<'tcx> { - /// let item_def_id = ccx.tcx.hir().local_def_id(it.hir_id); - /// ccx.tcx.item_types.memoized(item_def_id, || { - /// ccx.tcx.dep_graph.read(DepNode::Hir(item_def_id)); // (*) - /// compute_type_of_item(ccx, item) - /// }); - /// } - /// ``` - /// - /// The key is the line marked `(*)`: the closure implicitly - /// accesses the body of the item `item`, so we register a read - /// from `Hir(item_def_id)`. - fn memoize(&self, key: M::Key, op: OP) -> M::Value - where OP: FnOnce() -> M::Value - { - let graph; - { - let this = self.borrow(); - if let Some(&(ref result, dep_node)) = this.map.get(&key) { - this.graph.read_index(dep_node); - return result.clone(); - } - graph = this.graph.clone(); - } - - let (result, dep_node) = graph.with_anon_task(M::to_dep_kind(), op); - self.borrow_mut().map.insert(key, (result.clone(), dep_node)); - graph.read_index(dep_node); - result - } -} diff --git a/src/librustc/dep_graph/graph.rs b/src/librustc/dep_graph/graph.rs index e76a70350b33e..acfdc91523f70 100644 --- a/src/librustc/dep_graph/graph.rs +++ b/src/librustc/dep_graph/graph.rs @@ -590,7 +590,7 @@ impl DepGraph { // mark it as green by recursively marking all of its // dependencies green. self.try_mark_previous_green( - tcx.global_tcx(), + tcx, data, prev_index, &dep_node diff --git a/src/librustc/dep_graph/mod.rs b/src/librustc/dep_graph/mod.rs index 1535e6d349cf1..43f3d7e89cd5c 100644 --- a/src/librustc/dep_graph/mod.rs +++ b/src/librustc/dep_graph/mod.rs @@ -1,6 +1,5 @@ pub mod debug; mod dep_node; -mod dep_tracking_map; mod graph; mod prev; mod query; @@ -8,7 +7,6 @@ mod safe; mod serialized; pub mod cgu_reuse_tracker; -pub use self::dep_tracking_map::{DepTrackingMap, DepTrackingMapConfig}; pub use self::dep_node::{DepNode, DepKind, DepConstructor, WorkProductId, RecoverKey, label_strs}; pub use self::graph::{DepGraph, WorkProduct, DepNodeIndex, DepNodeColor, TaskDeps, hash_result}; pub use self::graph::WorkProductFileKind; diff --git a/src/librustc/hir/check_attr.rs b/src/librustc/hir/check_attr.rs index c946118b1ea19..d5e956555bdfb 100644 --- a/src/librustc/hir/check_attr.rs +++ b/src/librustc/hir/check_attr.rs @@ -93,30 +93,35 @@ struct CheckAttrVisitor<'tcx> { impl CheckAttrVisitor<'tcx> { /// Checks any attribute. fn check_attributes(&self, item: &hir::Item, target: Target) { - if target == Target::Fn || target == Target::Const { - self.tcx.codegen_fn_attrs(self.tcx.hir().local_def_id(item.hir_id)); - } else if let Some(a) = item.attrs.iter().find(|a| a.check_name(sym::target_feature)) { - self.tcx.sess.struct_span_err(a.span, "attribute should be applied to a function") - .span_label(item.span, "not a function") - .emit(); - } - + let mut is_valid = true; for attr in &item.attrs { - if attr.check_name(sym::inline) { + is_valid &= if attr.check_name(sym::inline) { self.check_inline(attr, &item.span, target) } else if attr.check_name(sym::non_exhaustive) { self.check_non_exhaustive(attr, item, target) } else if attr.check_name(sym::marker) { self.check_marker(attr, item, target) - } + } else if attr.check_name(sym::target_feature) { + self.check_target_feature(attr, item, target) + } else { + true + }; + } + + if !is_valid { + return; + } + + if target == Target::Fn { + self.tcx.codegen_fn_attrs(self.tcx.hir().local_def_id(item.hir_id)); } self.check_repr(item, target); self.check_used(item, target); } - /// Checks if an `#[inline]` is applied to a function or a closure. - fn check_inline(&self, attr: &hir::Attribute, span: &Span, target: Target) { + /// Checks if an `#[inline]` is applied to a function or a closure. Returns `true` if valid. + fn check_inline(&self, attr: &hir::Attribute, span: &Span, target: Target) -> bool { if target != Target::Fn && target != Target::Closure { struct_span_err!(self.tcx.sess, attr.span, @@ -124,13 +129,21 @@ impl CheckAttrVisitor<'tcx> { "attribute should be applied to function or closure") .span_label(*span, "not a function or closure") .emit(); + false + } else { + true } } - /// Checks if the `#[non_exhaustive]` attribute on an `item` is valid. - fn check_non_exhaustive(&self, attr: &hir::Attribute, item: &hir::Item, target: Target) { + /// Checks if the `#[non_exhaustive]` attribute on an `item` is valid. Returns `true` if valid. + fn check_non_exhaustive( + &self, + attr: &hir::Attribute, + item: &hir::Item, + target: Target, + ) -> bool { match target { - Target::Struct | Target::Enum => { /* Valid */ }, + Target::Struct | Target::Enum => true, _ => { struct_span_err!(self.tcx.sess, attr.span, @@ -138,25 +151,44 @@ impl CheckAttrVisitor<'tcx> { "attribute can only be applied to a struct or enum") .span_label(item.span, "not a struct or enum") .emit(); - return; + false } } } - /// Checks if the `#[marker]` attribute on an `item` is valid. - fn check_marker(&self, attr: &hir::Attribute, item: &hir::Item, target: Target) { + /// Checks if the `#[marker]` attribute on an `item` is valid. Returns `true` if valid. + fn check_marker(&self, attr: &hir::Attribute, item: &hir::Item, target: Target) -> bool { match target { - Target::Trait => { /* Valid */ }, + Target::Trait => true, _ => { self.tcx.sess .struct_span_err(attr.span, "attribute can only be applied to a trait") .span_label(item.span, "not a trait") .emit(); - return; + false } } } + /// Checks if the `#[target_feature]` attribute on `item` is valid. Returns `true` if valid. + fn check_target_feature( + &self, + attr: &hir::Attribute, + item: &hir::Item, + target: Target, + ) -> bool { + match target { + Target::Fn => true, + _ => { + self.tcx.sess + .struct_span_err(attr.span, "attribute should be applied to a function") + .span_label(item.span, "not a function") + .emit(); + false + }, + } + } + /// Checks if the `#[repr]` attributes on `item` are valid. fn check_repr(&self, item: &hir::Item, target: Target) { // Extract the names of all repr hints, e.g., [foo, bar, align] for: diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs index d1ebdd2f086ab..05bdd0887f0f6 100644 --- a/src/librustc/hir/intravisit.rs +++ b/src/librustc/hir/intravisit.rs @@ -633,9 +633,6 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty) { TyKind::Typeof(ref expression) => { visitor.visit_anon_const(expression) } - TyKind::CVarArgs(ref lt) => { - visitor.visit_lifetime(lt) - } TyKind::Infer | TyKind::Err => {} } } diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index d0a9d967a649d..6f51e05881be5 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -1335,13 +1335,8 @@ impl<'a> LoweringContext<'a> { } } } - TyKind::Mac(_) => bug!("`TyMac` should have been expanded by now"), - TyKind::CVarArgs => { - // Create the implicit lifetime of the "spoofed" `VaListImpl`. - let span = self.sess.source_map().next_point(t.span.shrink_to_lo()); - let lt = self.new_implicit_lifetime(span); - hir::TyKind::CVarArgs(lt) - }, + TyKind::Mac(_) => bug!("`TyKind::Mac` should have been expanded by now"), + TyKind::CVarArgs => bug!("`TyKind::CVarArgs` should have been handled elsewhere"), }; hir::Ty { @@ -2093,7 +2088,14 @@ impl<'a> LoweringContext<'a> { } fn lower_fn_params_to_names(&mut self, decl: &FnDecl) -> hir::HirVec { - decl.inputs + // Skip the `...` (`CVarArgs`) trailing arguments from the AST, + // as they are not explicit in HIR/Ty function signatures. + // (instead, the `c_variadic` flag is set to `true`) + let mut inputs = &decl.inputs[..]; + if decl.c_variadic() { + inputs = &inputs[..inputs.len() - 1]; + } + inputs .iter() .map(|param| match param.pat.kind { PatKind::Ident(_, ident, _) => ident, @@ -2130,10 +2132,19 @@ impl<'a> LoweringContext<'a> { self.anonymous_lifetime_mode }; + let c_variadic = decl.c_variadic(); + // Remember how many lifetimes were already around so that we can // only look at the lifetime parameters introduced by the arguments. let inputs = self.with_anonymous_lifetime_mode(lt_mode, |this| { - decl.inputs + // Skip the `...` (`CVarArgs`) trailing arguments from the AST, + // as they are not explicit in HIR/Ty function signatures. + // (instead, the `c_variadic` flag is set to `true`) + let mut inputs = &decl.inputs[..]; + if c_variadic { + inputs = &inputs[..inputs.len() - 1]; + } + inputs .iter() .map(|param| { if let Some((_, ibty)) = &mut in_band_ty_params { @@ -2168,7 +2179,7 @@ impl<'a> LoweringContext<'a> { P(hir::FnDecl { inputs, output, - c_variadic: decl.c_variadic, + c_variadic, implicit_self: decl.inputs.get(0).map_or( hir::ImplicitSelfKind::None, |arg| { diff --git a/src/librustc/hir/lowering/expr.rs b/src/librustc/hir/lowering/expr.rs index caecc162c7866..2f0a318d5363e 100644 --- a/src/librustc/hir/lowering/expr.rs +++ b/src/librustc/hir/lowering/expr.rs @@ -450,7 +450,6 @@ impl LoweringContext<'_> { let ast_decl = FnDecl { inputs: vec![], output, - c_variadic: false }; let decl = self.lower_fn_decl(&ast_decl, None, /* impl trait allowed */ false, None); let body_id = self.lower_fn_body(&ast_decl, |this| { @@ -705,7 +704,6 @@ impl LoweringContext<'_> { E0628, "generators cannot have explicit parameters" ); - self.sess.abort_if_errors(); } Some(match movability { Movability::Movable => hir::GeneratorMovability::Movable, @@ -740,7 +738,6 @@ impl LoweringContext<'_> { let outer_decl = FnDecl { inputs: decl.inputs.clone(), output: FunctionRetTy::Default(fn_decl_span), - c_variadic: false, }; // We need to lower the declaration outside the new scope, because we // have to conserve the state of being inside a loop condition for the @@ -998,7 +995,7 @@ impl LoweringContext<'_> { E0727, "`async` generators are not yet supported", ); - self.sess.abort_if_errors(); + return hir::ExprKind::Err; }, None => self.generator_kind = Some(hir::GeneratorKind::Gen), } diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index d4efe0297b671..b45d3f0396047 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -23,8 +23,6 @@ use syntax::source_map::Spanned; use syntax::ext::base::MacroKind; use syntax_pos::{Span, DUMMY_SP}; -use std::result::Result::Err; - pub mod blocks; mod collector; mod def_collector; @@ -183,6 +181,44 @@ pub struct Map<'hir> { hir_to_node_id: FxHashMap, } +struct ParentHirIterator<'map> { + current_id: HirId, + map: &'map Map<'map>, +} + +impl<'map> ParentHirIterator<'map> { + fn new(current_id: HirId, map: &'map Map<'map>) -> ParentHirIterator<'map> { + ParentHirIterator { + current_id, + map, + } + } +} + +impl<'map> Iterator for ParentHirIterator<'map> { + type Item = (HirId, Node<'map>); + + fn next(&mut self) -> Option { + if self.current_id == CRATE_HIR_ID { + return None; + } + loop { // There are nodes that do not have entries, so we need to skip them. + let parent_id = self.map.get_parent_node(self.current_id); + + if parent_id == self.current_id { + self.current_id = CRATE_HIR_ID; + return None; + } + + self.current_id = parent_id; + if let Some(entry) = self.map.find_entry(parent_id) { + return Some((parent_id, entry.node)); + } + // If this `HirId` doesn't have an `Entry`, skip it and look for its `parent_id`. + } + } +} + impl<'hir> Map<'hir> { #[inline] fn lookup(&self, id: HirId) -> Option<&Entry<'hir>> { @@ -682,45 +718,6 @@ impl<'hir> Map<'hir> { } } - - /// If there is some error when walking the parents (e.g., a node does not - /// have a parent in the map or a node can't be found), then we return the - /// last good `HirId` we found. Note that reaching the crate root (`id == 0`), - /// is not an error, since items in the crate module have the crate root as - /// parent. - fn walk_parent_nodes(&self, - start_id: HirId, - found: F, - bail_early: F2) - -> Result - where F: Fn(&Node<'hir>) -> bool, F2: Fn(&Node<'hir>) -> bool - { - let mut id = start_id; - loop { - let parent_id = self.get_parent_node(id); - if parent_id == CRATE_HIR_ID { - return Ok(CRATE_HIR_ID); - } - if parent_id == id { - return Err(id); - } - - if let Some(entry) = self.find_entry(parent_id) { - if let Node::Crate = entry.node { - return Err(id); - } - if found(&entry.node) { - return Ok(parent_id); - } else if bail_early(&entry.node) { - return Err(parent_id); - } - id = parent_id; - } else { - return Err(id); - } - } - } - /// Retrieves the `HirId` for `id`'s enclosing method, unless there's a /// `while` or `loop` before reaching it, as block tail returns are not /// available in them. @@ -744,29 +741,46 @@ impl<'hir> Map<'hir> { /// } /// ``` pub fn get_return_block(&self, id: HirId) -> Option { - let match_fn = |node: &Node<'_>| { - match *node { + let mut iter = ParentHirIterator::new(id, &self).peekable(); + let mut ignore_tail = false; + if let Some(entry) = self.find_entry(id) { + if let Node::Expr(Expr { kind: ExprKind::Ret(_), .. }) = entry.node { + // When dealing with `return` statements, we don't care about climbing only tail + // expressions. + ignore_tail = true; + } + } + while let Some((hir_id, node)) = iter.next() { + if let (Some((_, next_node)), false) = (iter.peek(), ignore_tail) { + match next_node { + Node::Block(Block { expr: None, .. }) => return None, + Node::Block(Block { expr: Some(expr), .. }) => { + if hir_id != expr.hir_id { + // The current node is not the tail expression of its parent. + return None; + } + } + _ => {} + } + } + match node { Node::Item(_) | Node::ForeignItem(_) | Node::TraitItem(_) | Node::Expr(Expr { kind: ExprKind::Closure(..), ..}) | - Node::ImplItem(_) => true, - _ => false, - } - }; - let match_non_returning_block = |node: &Node<'_>| { - match *node { + Node::ImplItem(_) => return Some(hir_id), Node::Expr(ref expr) => { match expr.kind { - ExprKind::Loop(..) | ExprKind::Ret(..) => true, - _ => false, + // Ignore `return`s on the first iteration + ExprKind::Loop(..) | ExprKind::Ret(..) => return None, + _ => {} } } - _ => false, + Node::Local(_) => return None, + _ => {} } - }; - - self.walk_parent_nodes(id, match_fn, match_non_returning_block).ok() + } + None } /// Retrieves the `HirId` for `id`'s parent item, or `id` itself if no @@ -774,16 +788,17 @@ impl<'hir> Map<'hir> { /// in the HIR which is recorded by the map and is an item, either an item /// in a module, trait, or impl. pub fn get_parent_item(&self, hir_id: HirId) -> HirId { - match self.walk_parent_nodes(hir_id, |node| match *node { - Node::Item(_) | - Node::ForeignItem(_) | - Node::TraitItem(_) | - Node::ImplItem(_) => true, - _ => false, - }, |_| false) { - Ok(id) => id, - Err(id) => id, + for (hir_id, node) in ParentHirIterator::new(hir_id, &self) { + match node { + Node::Crate | + Node::Item(_) | + Node::ForeignItem(_) | + Node::TraitItem(_) | + Node::ImplItem(_) => return hir_id, + _ => {} + } } + hir_id } /// Returns the `DefId` of `id`'s nearest module parent, or `id` itself if no @@ -795,60 +810,64 @@ impl<'hir> Map<'hir> { /// Returns the `HirId` of `id`'s nearest module parent, or `id` itself if no /// module parent is in this map. pub fn get_module_parent_node(&self, hir_id: HirId) -> HirId { - match self.walk_parent_nodes(hir_id, |node| match *node { - Node::Item(&Item { kind: ItemKind::Mod(_), .. }) => true, - _ => false, - }, |_| false) { - Ok(id) => id, - Err(id) => id, + for (hir_id, node) in ParentHirIterator::new(hir_id, &self) { + if let Node::Item(&Item { kind: ItemKind::Mod(_), .. }) = node { + return hir_id; + } } + CRATE_HIR_ID } /// Returns the nearest enclosing scope. A scope is roughly an item or block. pub fn get_enclosing_scope(&self, hir_id: HirId) -> Option { - self.walk_parent_nodes(hir_id, |node| match *node { - Node::Item(i) => { - match i.kind { - ItemKind::Fn(..) - | ItemKind::Mod(..) - | ItemKind::Enum(..) - | ItemKind::Struct(..) - | ItemKind::Union(..) - | ItemKind::Trait(..) - | ItemKind::Impl(..) => true, - _ => false, - } - }, - Node::ForeignItem(fi) => { - match fi.kind { - ForeignItemKind::Fn(..) => true, - _ => false, - } - }, - Node::TraitItem(ti) => { - match ti.kind { - TraitItemKind::Method(..) => true, - _ => false, - } - }, - Node::ImplItem(ii) => { - match ii.kind { - ImplItemKind::Method(..) => true, - _ => false, - } - }, - Node::Block(_) => true, - _ => false, - }, |_| false).ok() + for (hir_id, node) in ParentHirIterator::new(hir_id, &self) { + if match node { + Node::Item(i) => { + match i.kind { + ItemKind::Fn(..) + | ItemKind::Mod(..) + | ItemKind::Enum(..) + | ItemKind::Struct(..) + | ItemKind::Union(..) + | ItemKind::Trait(..) + | ItemKind::Impl(..) => true, + _ => false, + } + }, + Node::ForeignItem(fi) => { + match fi.kind { + ForeignItemKind::Fn(..) => true, + _ => false, + } + }, + Node::TraitItem(ti) => { + match ti.kind { + TraitItemKind::Method(..) => true, + _ => false, + } + }, + Node::ImplItem(ii) => { + match ii.kind { + ImplItemKind::Method(..) => true, + _ => false, + } + }, + Node::Block(_) => true, + _ => false, + } { + return Some(hir_id); + } + } + None } /// Returns the defining scope for an opaque type definition. - pub fn get_defining_scope(&self, id: HirId) -> Option { + pub fn get_defining_scope(&self, id: HirId) -> HirId { let mut scope = id; loop { - scope = self.get_enclosing_scope(scope)?; + scope = self.get_enclosing_scope(scope).unwrap_or(CRATE_HIR_ID); if scope == CRATE_HIR_ID { - return Some(CRATE_HIR_ID); + return CRATE_HIR_ID; } match self.get(scope) { Node::Item(i) => { @@ -861,7 +880,7 @@ impl<'hir> Map<'hir> { _ => break, } } - Some(scope) + scope } pub fn get_parent_did(&self, id: HirId) -> DefId { diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 6bfe6de63f5f8..4e8b4337cc6dd 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -1552,7 +1552,7 @@ pub enum ExprKind { /// Thus, `x.foo::(a, b, c, d)` is represented as /// `ExprKind::MethodCall(PathSegment { foo, [Bar, Baz] }, [x, a, b, c, d])`. MethodCall(P, Span, HirVec), - /// A tuple (e.g., `(a, b, c ,d)`). + /// A tuple (e.g., `(a, b, c, d)`). Tup(HirVec), /// A binary operation (e.g., `a + b`, `a * b`). Binary(BinOp, P, P), @@ -2016,9 +2016,6 @@ pub enum TyKind { Infer, /// Placeholder for a type that has failed to be defined. Err, - /// Placeholder for C-variadic arguments. We "spoof" the `VaListImpl` created - /// from the variadic arguments. This type is only valid up to typeck. - CVarArgs(Lifetime), } #[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug, HashStable)] diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs index 91f2c5a0aaf85..6cffaa8a494c4 100644 --- a/src/librustc/hir/print.rs +++ b/src/librustc/hir/print.rs @@ -361,9 +361,6 @@ impl<'a> State<'a> { self.s.word("/*ERROR*/"); self.pclose(); } - hir::TyKind::CVarArgs(_) => { - self.s.word("..."); - } } self.end() } diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index 81183dc1f7908..750ca4e32a64e 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -1462,7 +1462,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { // type-checking closure types are in local tables only. if !self.in_progress_tables.is_some() || !ty.has_closure_types() { if !(param_env, ty).has_local_value() { - return ty.is_copy_modulo_regions(self.tcx.global_tcx(), param_env, span); + return ty.is_copy_modulo_regions(self.tcx, param_env, span); } } diff --git a/src/librustc/infer/opaque_types/mod.rs b/src/librustc/infer/opaque_types/mod.rs index 3b3649fd8112f..2e19c9c24e9b5 100644 --- a/src/librustc/infer/opaque_types/mod.rs +++ b/src/librustc/infer/opaque_types/mod.rs @@ -561,15 +561,13 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { def_id, instantiated_ty ); - let gcx = self.tcx.global_tcx(); - // Use substs to build up a reverse map from regions to their // identity mappings. This is necessary because of `impl // Trait` lifetimes are computed by replacing existing // lifetimes with 'static and remapping only those used in the // `impl Trait` return type, resulting in the parameters // shifting. - let id_substs = InternalSubsts::identity_for_item(gcx, def_id); + let id_substs = InternalSubsts::identity_for_item(self.tcx, def_id); let map: FxHashMap, GenericArg<'tcx>> = opaque_defn .substs .iter() @@ -854,7 +852,7 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> { ) .emit(); - self.tcx().global_tcx().mk_region(ty::ReStatic) + self.tcx().mk_region(ty::ReStatic) }, } } @@ -1215,7 +1213,7 @@ pub fn may_define_opaque_type( let mut hir_id = tcx.hir().as_local_hir_id(def_id).unwrap(); // Named opaque types can be defined by any siblings or children of siblings. - let scope = tcx.hir().get_defining_scope(opaque_hir_id).expect("could not get defining scope"); + let scope = tcx.hir().get_defining_scope(opaque_hir_id); // We walk up the node tree until we hit the root or the scope of the opaque type. while hir_id != scope && hir_id != hir::CRATE_HIR_ID { hir_id = tcx.hir().get_parent_item(hir_id); diff --git a/src/librustc/middle/intrinsicck.rs b/src/librustc/middle/intrinsicck.rs index ecca62349c985..c1435551a5918 100644 --- a/src/librustc/middle/intrinsicck.rs +++ b/src/librustc/middle/intrinsicck.rs @@ -82,7 +82,7 @@ impl ExprVisitor<'tcx> { // Special-case transmutting from `typeof(function)` and // `Option` to present a clearer error. - let from = unpack_option_like(self.tcx.global_tcx(), from); + let from = unpack_option_like(self.tcx, from); if let (&ty::FnDef(..), SizeSkeleton::Known(size_to)) = (&from.kind, sk_to) { if size_to == Pointer.size(&self.tcx) { struct_span_err!(self.tcx.sess, span, E0591, diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index c6a46f60927e8..3f5f54c94638e 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -749,7 +749,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> { .unwrap_or(ty::ClosureKind::LATTICE_BOTTOM), None => - closure_substs.closure_kind(closure_def_id, self.tcx.global_tcx()), + closure_substs.closure_kind(closure_def_id, self.tcx), } } _ => span_bug!(span, "unexpected type for fn in mem_categorization: {:?}", ty), diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index 94a85a97d36c9..31d250fa08215 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -764,13 +764,6 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { }); } } - hir::TyKind::CVarArgs(ref lt) => { - // Resolve the generated lifetime for the C-variadic arguments. - // The lifetime is generated in AST -> HIR lowering. - if lt.name.is_elided() { - self.resolve_elided_lifetimes(vec![lt]) - } - } _ => intravisit::walk_ty(self, ty), } } @@ -2378,7 +2371,6 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { self.visit_lifetime(lifetime); } } - hir::TyKind::CVarArgs(_) => {} _ => { intravisit::walk_ty(self, ty); } diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index 967d16fa0d902..cf82184ab032c 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -1504,7 +1504,7 @@ impl<'tcx> TerminatorKind<'tcx> { Goto { .. } => vec!["".into()], SwitchInt { ref values, switch_ty, .. } => ty::tls::with(|tcx| { let param_env = ty::ParamEnv::empty(); - let switch_ty = tcx.lift_to_global(&switch_ty).unwrap(); + let switch_ty = tcx.lift(&switch_ty).unwrap(); let size = tcx.layout_of(param_env.and(switch_ty)).unwrap().size; values .iter() diff --git a/src/librustc/traits/chalk_fulfill.rs b/src/librustc/traits/chalk_fulfill.rs index a7e1f2a6a73a7..d9e83df7ddda6 100644 --- a/src/librustc/traits/chalk_fulfill.rs +++ b/src/librustc/traits/chalk_fulfill.rs @@ -108,7 +108,7 @@ impl TraitEngine<'tcx> for FulfillmentContext<'tcx> { goal: obligation.goal.predicate, }, &mut orig_values); - match infcx.tcx.global_tcx().evaluate_goal(canonical_goal) { + match infcx.tcx.evaluate_goal(canonical_goal) { Ok(response) => { if response.is_proven() { making_progress = true; diff --git a/src/librustc/traits/codegen/mod.rs b/src/librustc/traits/codegen/mod.rs index 97fb430a3e051..9dff699deb8af 100644 --- a/src/librustc/traits/codegen/mod.rs +++ b/src/librustc/traits/codegen/mod.rs @@ -3,12 +3,10 @@ // seems likely that they should eventually be merged into more // general routines. -use crate::dep_graph::{DepKind, DepTrackingMapConfig}; -use std::marker::PhantomData; use crate::infer::InferCtxt; use crate::traits::{FulfillmentContext, Obligation, ObligationCause, SelectionContext, TraitEngine, Vtable}; -use crate::ty::{self, Ty, TyCtxt}; +use crate::ty::{self, TyCtxt}; use crate::ty::subst::{Subst, SubstsRef}; use crate::ty::fold::TypeFoldable; @@ -100,33 +98,8 @@ impl<'tcx> TyCtxt<'tcx> { } } -// Implement DepTrackingMapConfig for `trait_cache` -pub struct TraitSelectionCache<'tcx> { - data: PhantomData<&'tcx ()> -} - -impl<'tcx> DepTrackingMapConfig for TraitSelectionCache<'tcx> { - type Key = (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>); - type Value = Vtable<'tcx, ()>; - fn to_dep_kind() -> DepKind { - DepKind::TraitSelect - } -} - // # Global Cache -pub struct ProjectionCache<'tcx> { - data: PhantomData<&'tcx ()>, -} - -impl<'tcx> DepTrackingMapConfig for ProjectionCache<'tcx> { - type Key = Ty<'tcx>; - type Value = Ty<'tcx>; - fn to_dep_kind() -> DepKind { - DepKind::TraitSelect - } -} - impl<'a, 'tcx> InferCtxt<'a, 'tcx> { /// Finishes processes any obligations that remain in the /// fulfillment context, and then returns the result with all type diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 1ce5d72ba848e..c2d531793372a 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -497,7 +497,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { 4 }; - let normalize = |candidate| self.tcx.global_tcx().infer_ctxt().enter(|ref infcx| { + let normalize = |candidate| self.tcx.infer_ctxt().enter(|ref infcx| { let normalized = infcx .at(&ObligationCause::dummy(), ty::ParamEnv::empty()) .normalize(candidate) @@ -783,8 +783,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } ty::Predicate::ObjectSafe(trait_def_id) => { - let violations = self.tcx.global_tcx() - .object_safety_violations(trait_def_id); + let violations = self.tcx.object_safety_violations(trait_def_id); if let Some(err) = self.tcx.report_object_safety_error( span, trait_def_id, @@ -920,7 +919,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } TraitNotObjectSafe(did) => { - let violations = self.tcx.global_tcx().object_safety_violations(did); + let violations = self.tcx.object_safety_violations(did); if let Some(err) = self.tcx.report_object_safety_error(span, did, violations) { err } else { diff --git a/src/librustc/traits/fulfill.rs b/src/librustc/traits/fulfill.rs index 0a190af1f986d..a981162fdc326 100644 --- a/src/librustc/traits/fulfill.rs +++ b/src/librustc/traits/fulfill.rs @@ -495,7 +495,7 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> { } else { if !substs.has_local_value() { let instance = ty::Instance::resolve( - self.selcx.tcx().global_tcx(), + self.selcx.tcx(), obligation.param_env, def_id, substs, diff --git a/src/librustc/traits/query/dropck_outlives.rs b/src/librustc/traits/query/dropck_outlives.rs index c3c43132d8540..aa30541610e9b 100644 --- a/src/librustc/traits/query/dropck_outlives.rs +++ b/src/librustc/traits/query/dropck_outlives.rs @@ -40,12 +40,11 @@ impl<'cx, 'tcx> At<'cx, 'tcx> { }; } - let gcx = tcx.global_tcx(); let mut orig_values = OriginalQueryValues::default(); let c_ty = self.infcx.canonicalize_query(&self.param_env.and(ty), &mut orig_values); let span = self.cause.span; debug!("c_ty = {:?}", c_ty); - if let Ok(result) = &gcx.dropck_outlives(c_ty) { + if let Ok(result) = &tcx.dropck_outlives(c_ty) { if result.is_proven() { if let Ok(InferOk { value, obligations }) = self.infcx.instantiate_query_response_and_region_obligations( diff --git a/src/librustc/traits/query/evaluate_obligation.rs b/src/librustc/traits/query/evaluate_obligation.rs index b9557ceaa6d9f..17684df7e9b8e 100644 --- a/src/librustc/traits/query/evaluate_obligation.rs +++ b/src/librustc/traits/query/evaluate_obligation.rs @@ -50,7 +50,7 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { // Run canonical query. If overflow occurs, rerun from scratch but this time // in standard trait query mode so that overflow is handled appropriately // within `SelectionContext`. - self.tcx.global_tcx().evaluate_obligation(c_pred) + self.tcx.evaluate_obligation(c_pred) } // Helper function that canonicalizes and runs the query. If an diff --git a/src/librustc/traits/query/normalize.rs b/src/librustc/traits/query/normalize.rs index b334e6dd8f84e..ab42eab28440f 100644 --- a/src/librustc/traits/query/normalize.rs +++ b/src/librustc/traits/query/normalize.rs @@ -141,7 +141,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> { // binder). It would be better to normalize in a // binding-aware fashion. - let gcx = self.infcx.tcx.global_tcx(); + let tcx = self.infcx.tcx; let mut orig_values = OriginalQueryValues::default(); // HACK(matthewjasper) `'static` is special-cased in selection, @@ -150,7 +150,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> { &self.param_env.and(*data), &mut orig_values); debug!("QueryNormalizer: c_data = {:#?}", c_data); debug!("QueryNormalizer: orig_values = {:#?}", orig_values); - match gcx.normalize_projection_ty(c_data) { + match tcx.normalize_projection_ty(c_data) { Ok(result) => { // We don't expect ambiguity. if result.is_ambiguous() { diff --git a/src/librustc/traits/query/outlives_bounds.rs b/src/librustc/traits/query/outlives_bounds.rs index 40bd18738b528..f5808b6b5faaf 100644 --- a/src/librustc/traits/query/outlives_bounds.rs +++ b/src/librustc/traits/query/outlives_bounds.rs @@ -97,7 +97,7 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { let mut orig_values = OriginalQueryValues::default(); let key = self.canonicalize_query(¶m_env.and(ty), &mut orig_values); - let result = match self.tcx.global_tcx().implied_outlives_bounds(key) { + let result = match self.tcx.implied_outlives_bounds(key) { Ok(r) => r, Err(NoSolution) => { self.tcx.sess.delay_span_bug( diff --git a/src/librustc/traits/query/type_op/ascribe_user_type.rs b/src/librustc/traits/query/type_op/ascribe_user_type.rs index 05a4d4336a7c2..34aa4ee78da30 100644 --- a/src/librustc/traits/query/type_op/ascribe_user_type.rs +++ b/src/librustc/traits/query/type_op/ascribe_user_type.rs @@ -1,4 +1,4 @@ -use crate::infer::canonical::{Canonical, Canonicalized, CanonicalizedQueryResponse, QueryResponse}; +use crate::infer::canonical::{Canonicalized, CanonicalizedQueryResponse}; use crate::traits::query::Fallible; use crate::hir::def_id::DefId; use crate::ty::{ParamEnvAnd, Ty, TyCtxt}; @@ -37,12 +37,6 @@ impl<'tcx> super::QueryTypeOp<'tcx> for AscribeUserType<'tcx> { ) -> Fallible> { tcx.type_op_ascribe_user_type(canonicalized) } - - fn shrink_to_tcx_lifetime( - v: &'a CanonicalizedQueryResponse<'tcx, ()>, - ) -> &'a Canonical<'tcx, QueryResponse<'tcx, ()>> { - v - } } BraceStructTypeFoldableImpl! { diff --git a/src/librustc/traits/query/type_op/eq.rs b/src/librustc/traits/query/type_op/eq.rs index e8ec304f918a3..3653f9268dcde 100644 --- a/src/librustc/traits/query/type_op/eq.rs +++ b/src/librustc/traits/query/type_op/eq.rs @@ -1,4 +1,4 @@ -use crate::infer::canonical::{Canonical, Canonicalized, CanonicalizedQueryResponse, QueryResponse}; +use crate::infer::canonical::{Canonicalized, CanonicalizedQueryResponse}; use crate::traits::query::Fallible; use crate::ty::{ParamEnvAnd, Ty, TyCtxt}; @@ -34,12 +34,6 @@ impl<'tcx> super::QueryTypeOp<'tcx> for Eq<'tcx> { ) -> Fallible> { tcx.type_op_eq(canonicalized) } - - fn shrink_to_tcx_lifetime( - v: &'a CanonicalizedQueryResponse<'tcx, ()>, - ) -> &'a Canonical<'tcx, QueryResponse<'tcx, ()>> { - v - } } BraceStructTypeFoldableImpl! { diff --git a/src/librustc/traits/query/type_op/implied_outlives_bounds.rs b/src/librustc/traits/query/type_op/implied_outlives_bounds.rs index 3beb4d64656c5..12a834fbda6bd 100644 --- a/src/librustc/traits/query/type_op/implied_outlives_bounds.rs +++ b/src/librustc/traits/query/type_op/implied_outlives_bounds.rs @@ -1,4 +1,4 @@ -use crate::infer::canonical::{Canonical, Canonicalized, CanonicalizedQueryResponse, QueryResponse}; +use crate::infer::canonical::{Canonicalized, CanonicalizedQueryResponse}; use crate::traits::query::outlives_bounds::OutlivesBound; use crate::traits::query::Fallible; use crate::ty::{ParamEnvAnd, Ty, TyCtxt}; @@ -38,12 +38,6 @@ impl<'tcx> super::QueryTypeOp<'tcx> for ImpliedOutlivesBounds<'tcx> { tcx.implied_outlives_bounds(canonicalized) } - - fn shrink_to_tcx_lifetime( - v: &'a CanonicalizedQueryResponse<'tcx, Self::QueryResponse>, - ) -> &'a Canonical<'tcx, QueryResponse<'tcx, Self::QueryResponse>> { - v - } } BraceStructTypeFoldableImpl! { diff --git a/src/librustc/traits/query/type_op/mod.rs b/src/librustc/traits/query/type_op/mod.rs index e2a5cd9670e0c..98e535234b630 100644 --- a/src/librustc/traits/query/type_op/mod.rs +++ b/src/librustc/traits/query/type_op/mod.rs @@ -1,6 +1,6 @@ use crate::infer::canonical::{ - Canonical, Canonicalized, CanonicalizedQueryResponse, OriginalQueryValues, - QueryRegionConstraints, QueryResponse, + Canonicalized, CanonicalizedQueryResponse, OriginalQueryValues, + QueryRegionConstraints, }; use crate::infer::{InferCtxt, InferOk}; use std::fmt; @@ -66,22 +66,6 @@ pub trait QueryTypeOp<'tcx>: fmt::Debug + Sized + TypeFoldable<'tcx> + 'tcx { canonicalized: Canonicalized<'tcx, ParamEnvAnd<'tcx, Self>>, ) -> Fallible>; - /// Casts a lifted query result (which is in the gcx lifetime) - /// into the tcx lifetime. This is always just an identity cast, - /// but the generic code doesn't realize it -- put another way, in - /// the generic code, we have a `Lifted<'tcx, Self::QueryResponse>` - /// and we want to convert that to a `Self::QueryResponse`. This is - /// not a priori valid, so we can't do it -- but in practice, it - /// is always a no-op (e.g., the lifted form of a type, - /// `Ty<'tcx>`, is a subtype of `Ty<'tcx>`). So we have to push - /// the operation into the impls that know more specifically what - /// `QueryResponse` is. This operation would (maybe) be nicer with - /// something like HKTs or GATs, since then we could make - /// `QueryResponse` parametric and `'tcx` and `'tcx` etc. - fn shrink_to_tcx_lifetime( - lifted_query_result: &'a CanonicalizedQueryResponse<'tcx, Self::QueryResponse>, - ) -> &'a Canonical<'tcx, QueryResponse<'tcx, Self::QueryResponse>>; - fn fully_perform_into( query_key: ParamEnvAnd<'tcx, Self>, infcx: &InferCtxt<'_, 'tcx>, @@ -99,7 +83,6 @@ pub trait QueryTypeOp<'tcx>: fmt::Debug + Sized + TypeFoldable<'tcx> + 'tcx { let canonical_self = infcx.canonicalize_hr_query_hack(&query_key, &mut canonical_var_values); let canonical_result = Self::perform_query(infcx.tcx, canonical_self)?; - let canonical_result = Self::shrink_to_tcx_lifetime(&canonical_result); let param_env = query_key.param_env; diff --git a/src/librustc/traits/query/type_op/normalize.rs b/src/librustc/traits/query/type_op/normalize.rs index 3fe85d8d83eb9..2138f792d45bb 100644 --- a/src/librustc/traits/query/type_op/normalize.rs +++ b/src/librustc/traits/query/type_op/normalize.rs @@ -1,4 +1,4 @@ -use crate::infer::canonical::{Canonical, Canonicalized, CanonicalizedQueryResponse, QueryResponse}; +use crate::infer::canonical::{Canonicalized, CanonicalizedQueryResponse}; use std::fmt; use crate::traits::query::Fallible; use crate::ty::fold::TypeFoldable; @@ -38,12 +38,6 @@ where ) -> Fallible> { T::type_op_method(tcx, canonicalized) } - - fn shrink_to_tcx_lifetime( - v: &'a CanonicalizedQueryResponse<'tcx, T>, - ) -> &'a Canonical<'tcx, QueryResponse<'tcx, T>> { - T::shrink_to_tcx_lifetime(v) - } } pub trait Normalizable<'tcx>: fmt::Debug + TypeFoldable<'tcx> + Lift<'tcx> + Copy { @@ -51,12 +45,6 @@ pub trait Normalizable<'tcx>: fmt::Debug + TypeFoldable<'tcx> + Lift<'tcx> + Cop tcx: TyCtxt<'tcx>, canonicalized: Canonicalized<'tcx, ParamEnvAnd<'tcx, Normalize>>, ) -> Fallible>; - - /// Converts from the `'tcx` (lifted) form of `Self` into the `tcx` - /// form of `Self`. - fn shrink_to_tcx_lifetime( - v: &'a CanonicalizedQueryResponse<'tcx, Self>, - ) -> &'a Canonical<'tcx, QueryResponse<'tcx, Self>>; } impl Normalizable<'tcx> for Ty<'tcx> { @@ -66,12 +54,6 @@ impl Normalizable<'tcx> for Ty<'tcx> { ) -> Fallible> { tcx.type_op_normalize_ty(canonicalized) } - - fn shrink_to_tcx_lifetime( - v: &'a CanonicalizedQueryResponse<'tcx, Self>, - ) -> &'a Canonical<'tcx, QueryResponse<'tcx, Self>> { - v - } } impl Normalizable<'tcx> for ty::Predicate<'tcx> { @@ -81,12 +63,6 @@ impl Normalizable<'tcx> for ty::Predicate<'tcx> { ) -> Fallible> { tcx.type_op_normalize_predicate(canonicalized) } - - fn shrink_to_tcx_lifetime( - v: &'a CanonicalizedQueryResponse<'tcx, Self>, - ) -> &'a Canonical<'tcx, QueryResponse<'tcx, Self>> { - v - } } impl Normalizable<'tcx> for ty::PolyFnSig<'tcx> { @@ -96,12 +72,6 @@ impl Normalizable<'tcx> for ty::PolyFnSig<'tcx> { ) -> Fallible> { tcx.type_op_normalize_poly_fn_sig(canonicalized) } - - fn shrink_to_tcx_lifetime( - v: &'a CanonicalizedQueryResponse<'tcx, Self>, - ) -> &'a Canonical<'tcx, QueryResponse<'tcx, Self>> { - v - } } impl Normalizable<'tcx> for ty::FnSig<'tcx> { @@ -111,12 +81,6 @@ impl Normalizable<'tcx> for ty::FnSig<'tcx> { ) -> Fallible> { tcx.type_op_normalize_fn_sig(canonicalized) } - - fn shrink_to_tcx_lifetime( - v: &'a CanonicalizedQueryResponse<'tcx, Self>, - ) -> &'a Canonical<'tcx, QueryResponse<'tcx, Self>> { - v - } } BraceStructTypeFoldableImpl! { diff --git a/src/librustc/traits/query/type_op/outlives.rs b/src/librustc/traits/query/type_op/outlives.rs index d4b36356ffb06..9b956f3e55408 100644 --- a/src/librustc/traits/query/type_op/outlives.rs +++ b/src/librustc/traits/query/type_op/outlives.rs @@ -1,4 +1,4 @@ -use crate::infer::canonical::{Canonical, Canonicalized, CanonicalizedQueryResponse, QueryResponse}; +use crate::infer::canonical::{Canonicalized, CanonicalizedQueryResponse}; use crate::traits::query::dropck_outlives::trivial_dropck_outlives; use crate::traits::query::dropck_outlives::DropckOutlivesResult; use crate::traits::query::Fallible; @@ -53,12 +53,6 @@ impl super::QueryTypeOp<'tcx> for DropckOutlives<'tcx> { tcx.dropck_outlives(canonicalized) } - - fn shrink_to_tcx_lifetime( - lifted_query_result: &'a CanonicalizedQueryResponse<'tcx, Self::QueryResponse>, - ) -> &'a Canonical<'tcx, QueryResponse<'tcx, Self::QueryResponse>> { - lifted_query_result - } } BraceStructTypeFoldableImpl! { diff --git a/src/librustc/traits/query/type_op/prove_predicate.rs b/src/librustc/traits/query/type_op/prove_predicate.rs index 1efe66326d724..2a908d0f66e5b 100644 --- a/src/librustc/traits/query/type_op/prove_predicate.rs +++ b/src/librustc/traits/query/type_op/prove_predicate.rs @@ -1,4 +1,4 @@ -use crate::infer::canonical::{Canonical, Canonicalized, CanonicalizedQueryResponse, QueryResponse}; +use crate::infer::canonical::{Canonicalized, CanonicalizedQueryResponse}; use crate::traits::query::Fallible; use crate::ty::{ParamEnvAnd, Predicate, TyCtxt}; @@ -43,12 +43,6 @@ impl<'tcx> super::QueryTypeOp<'tcx> for ProvePredicate<'tcx> { ) -> Fallible> { tcx.type_op_prove_predicate(canonicalized) } - - fn shrink_to_tcx_lifetime( - v: &'a CanonicalizedQueryResponse<'tcx, ()>, - ) -> &'a Canonical<'tcx, QueryResponse<'tcx, ()>> { - v - } } BraceStructTypeFoldableImpl! { diff --git a/src/librustc/traits/query/type_op/subtype.rs b/src/librustc/traits/query/type_op/subtype.rs index 71c74999c2762..c89a55daa095e 100644 --- a/src/librustc/traits/query/type_op/subtype.rs +++ b/src/librustc/traits/query/type_op/subtype.rs @@ -1,4 +1,4 @@ -use crate::infer::canonical::{Canonical, Canonicalized, CanonicalizedQueryResponse, QueryResponse}; +use crate::infer::canonical::{Canonicalized, CanonicalizedQueryResponse}; use crate::traits::query::Fallible; use crate::ty::{ParamEnvAnd, Ty, TyCtxt}; @@ -34,12 +34,6 @@ impl<'tcx> super::QueryTypeOp<'tcx> for Subtype<'tcx> { ) -> Fallible> { tcx.type_op_subtype(canonicalized) } - - fn shrink_to_tcx_lifetime( - v: &'a CanonicalizedQueryResponse<'tcx, ()>, - ) -> &'a Canonical<'tcx, QueryResponse<'tcx, ()>> { - v - } } BraceStructTypeFoldableImpl! { diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index 911ecef802425..e1ca9a16d965f 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -2491,7 +2491,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { if other.evaluation.must_apply_modulo_regions() { match victim.candidate { ImplCandidate(victim_def) => { - let tcx = self.tcx().global_tcx(); + let tcx = self.tcx(); return tcx.specializes((other_def, victim_def)) || tcx.impls_are_allowed_to_overlap( other_def, victim_def).is_some(); diff --git a/src/librustc/traits/specialize/specialization_graph.rs b/src/librustc/traits/specialize/specialization_graph.rs index 8cbadebaea5a5..ce0f43021378b 100644 --- a/src/librustc/traits/specialize/specialization_graph.rs +++ b/src/librustc/traits/specialize/specialization_graph.rs @@ -162,7 +162,6 @@ impl<'tcx> Children { } }; - let tcx = tcx.global_tcx(); let (le, ge) = traits::overlapping_impls( tcx, possible_sibling, diff --git a/src/librustc/traits/util.rs b/src/librustc/traits/util.rs index 6d0347563d003..18ec2241b2df8 100644 --- a/src/librustc/traits/util.rs +++ b/src/librustc/traits/util.rs @@ -661,8 +661,7 @@ impl<'tcx> TyCtxt<'tcx> { } } None => { - self.global_tcx() - .impl_defaultness(node_item_def_id) + self.impl_defaultness(node_item_def_id) .is_default() } } diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index ad3fee171662a..efbc820365e2d 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -1067,14 +1067,6 @@ pub struct GlobalCtxt<'tcx> { } impl<'tcx> TyCtxt<'tcx> { - /// Gets the global `TyCtxt`. - #[inline] - pub fn global_tcx(self) -> TyCtxt<'tcx> { - TyCtxt { - gcx: self.gcx, - } - } - #[inline(always)] pub fn hir(self) -> &'tcx hir_map::Map<'tcx> { &self.hir_map @@ -1156,11 +1148,6 @@ impl<'tcx> TyCtxt<'tcx> { value.lift_to_tcx(self) } - /// Like lift, but only tries in the global tcx. - pub fn lift_to_global>(self, value: &T) -> Option { - value.lift_to_tcx(self.global_tcx()) - } - /// Creates a type context and call the closure with a `TyCtxt` reference /// to the context. The closure enforces that the type context and any interned /// value (types, substs, etc.) can only be used while `ty::tls` has a valid @@ -1432,7 +1419,7 @@ impl<'tcx> TyCtxt<'tcx> { -> Result<(), E::Error> where E: ty::codec::TyEncoder { - self.queries.on_disk_cache.serialize(self.global_tcx(), encoder) + self.queries.on_disk_cache.serialize(self, encoder) } /// If `true`, we should use the MIR-based borrowck, but also @@ -1600,7 +1587,7 @@ impl<'tcx> GlobalCtxt<'tcx> { let tcx = TyCtxt { gcx: self, }; - ty::tls::with_related_context(tcx.global_tcx(), |icx| { + ty::tls::with_related_context(tcx, |icx| { let new_icx = ty::tls::ImplicitCtxt { tcx, query: icx.query.clone(), @@ -2425,7 +2412,7 @@ impl<'tcx> TyCtxt<'tcx> { #[inline] pub fn mk_array(self, ty: Ty<'tcx>, n: u64) -> Ty<'tcx> { - self.mk_ty(Array(ty, ty::Const::from_usize(self.global_tcx(), n))) + self.mk_ty(Array(ty, ty::Const::from_usize(self, n))) } #[inline] @@ -2640,7 +2627,7 @@ impl<'tcx> TyCtxt<'tcx> { if ts.len() == 0 { List::empty() } else { - self.global_tcx()._intern_canonical_var_infos(ts) + self._intern_canonical_var_infos(ts) } } diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs index d12039de3136e..5851a48a8d377 100644 --- a/src/librustc/ty/error.rs +++ b/src/librustc/ty/error.rs @@ -193,7 +193,7 @@ impl<'tcx> ty::TyS<'tcx> { ty::Adt(def, _) => format!("{} `{}`", def.descr(), tcx.def_path_str(def.did)).into(), ty::Foreign(def_id) => format!("extern type `{}`", tcx.def_path_str(def_id)).into(), ty::Array(_, n) => { - let n = tcx.lift_to_global(&n).unwrap(); + let n = tcx.lift(&n).unwrap(); match n.try_eval_usize(tcx, ty::ParamEnv::empty()) { Some(n) => { format!("array of {} element{}", n, pluralise!(n)).into() diff --git a/src/librustc/ty/instance.rs b/src/librustc/ty/instance.rs index ecb512b0cd1a2..741830f205cb0 100644 --- a/src/librustc/ty/instance.rs +++ b/src/librustc/ty/instance.rs @@ -210,7 +210,7 @@ impl<'tcx> Instance<'tcx> { } pub fn mono(tcx: TyCtxt<'tcx>, def_id: DefId) -> Instance<'tcx> { - Instance::new(def_id, tcx.global_tcx().empty_substs_for_def_id(def_id)) + Instance::new(def_id, tcx.empty_substs_for_def_id(def_id)) } #[inline] diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs index 790b0c5cb48f4..bd6b6006c1a21 100644 --- a/src/librustc/ty/layout.rs +++ b/src/librustc/ty/layout.rs @@ -25,7 +25,7 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher, pub use rustc_target::abi::*; use rustc_target::spec::{HasTargetSpec, abi::Abi as SpecAbi}; use rustc_target::abi::call::{ - ArgAttribute, ArgAttributes, ArgType, Conv, FnType, IgnoreMode, PassMode, Reg, RegKind + ArgAttribute, ArgAttributes, ArgType, Conv, FnType, PassMode, Reg, RegKind }; pub trait IntegerExt { @@ -1883,7 +1883,7 @@ impl<'tcx> HasDataLayout for TyCtxt<'tcx> { impl<'tcx> HasTyCtxt<'tcx> for TyCtxt<'tcx> { fn tcx(&self) -> TyCtxt<'tcx> { - self.global_tcx() + *self } } @@ -2003,7 +2003,7 @@ impl TyCtxt<'tcx> { pub fn layout_of(self, param_env_and_ty: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> Result, LayoutError<'tcx>> { let cx = LayoutCx { - tcx: self.global_tcx(), + tcx: self, param_env: param_env_and_ty.param_env }; cx.layout_of(param_env_and_ty.value) @@ -2017,7 +2017,7 @@ impl ty::query::TyCtxtAt<'tcx> { pub fn layout_of(self, param_env_and_ty: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> Result, LayoutError<'tcx>> { let cx = LayoutCx { - tcx: self.global_tcx().at(self.span), + tcx: self.at(self.span), param_env: param_env_and_ty.param_env }; cx.layout_of(param_env_and_ty.value) @@ -2722,14 +2722,6 @@ where } }; - // Store the index of the last argument. This is useful for working with - // C-compatible variadic arguments. - let last_arg_idx = if sig.inputs().is_empty() { - None - } else { - Some(sig.inputs().len() - 1) - }; - let arg_of = |ty: Ty<'tcx>, arg_idx: Option| { let is_return = arg_idx.is_none(); let mut arg = mk_arg_type(ty, arg_idx); @@ -2739,30 +2731,7 @@ where // The same is true for s390x-unknown-linux-gnu // and sparc64-unknown-linux-gnu. if is_return || rust_abi || (!win_x64_gnu && !linux_s390x && !linux_sparc64) { - arg.mode = PassMode::Ignore(IgnoreMode::Zst); - } - } - - // If this is a C-variadic function, this is not the return value, - // and there is one or more fixed arguments; ensure that the `VaListImpl` - // is ignored as an argument. - if sig.c_variadic { - match (last_arg_idx, arg_idx) { - (Some(last_idx), Some(cur_idx)) if last_idx == cur_idx => { - let va_list_did = match cx.tcx().lang_items().va_list() { - Some(did) => did, - None => bug!("`va_list` lang item required for C-variadic functions"), - }; - match ty.kind { - ty::Adt(def, _) if def.did == va_list_did => { - // This is the "spoofed" `VaListImpl`. Set the arguments mode - // so that it will be ignored. - arg.mode = PassMode::Ignore(IgnoreMode::CVarArgs); - } - _ => (), - } - } - _ => {} + arg.mode = PassMode::Ignore; } } diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index f107af0cd07ec..0e9600449f62c 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -2378,7 +2378,7 @@ impl<'tcx> AdtDef { pub fn eval_explicit_discr(&self, tcx: TyCtxt<'tcx>, expr_did: DefId) -> Option> { let param_env = tcx.param_env(expr_did); let repr_type = self.repr.discr_type(); - let substs = InternalSubsts::identity_for_item(tcx.global_tcx(), expr_did); + let substs = InternalSubsts::identity_for_item(tcx, expr_did); let instance = ty::Instance::new(expr_did, substs); let cid = GlobalId { instance, @@ -2387,7 +2387,7 @@ impl<'tcx> AdtDef { match tcx.const_eval(param_env.and(cid)) { Ok(val) => { // FIXME: Find the right type and use it instead of `val.ty` here - if let Some(b) = val.try_eval_bits(tcx.global_tcx(), param_env, val.ty) { + if let Some(b) = val.try_eval_bits(tcx, param_env, val.ty) { trace!("discriminants: {} ({:?})", b, repr_type); Some(Discr { val: b, @@ -2423,7 +2423,7 @@ impl<'tcx> AdtDef { tcx: TyCtxt<'tcx>, ) -> impl Iterator)> + Captures<'tcx> { let repr_type = self.repr.discr_type(); - let initial = repr_type.initial_discriminant(tcx.global_tcx()); + let initial = repr_type.initial_discriminant(tcx); let mut prev_discr = None::>; self.variants.iter_enumerated().map(move |(i, v)| { let mut discr = prev_discr.map_or(initial, |d| d.wrap_incr(tcx)); @@ -2457,7 +2457,7 @@ impl<'tcx> AdtDef { let (val, offset) = self.discriminant_def_for_variant(variant_index); let explicit_value = val .and_then(|expr_did| self.eval_explicit_discr(tcx, expr_did)) - .unwrap_or_else(|| self.repr.discr_type().initial_discriminant(tcx.global_tcx())); + .unwrap_or_else(|| self.repr.discr_type().initial_discriminant(tcx)); explicit_value.checked_add(tcx, offset as u128).0 } diff --git a/src/librustc/ty/print/pretty.rs b/src/librustc/ty/print/pretty.rs index 2bc87d6b8ba5e..e004fa07f2c0f 100644 --- a/src/librustc/ty/print/pretty.rs +++ b/src/librustc/ty/print/pretty.rs @@ -917,7 +917,7 @@ pub trait PrettyPrinter<'tcx>: let min = 1u128 << (bit_size - 1); let max = min - 1; - let ty = self.tcx().lift_to_global(&ct.ty).unwrap(); + let ty = self.tcx().lift(&ct.ty).unwrap(); let size = self.tcx().layout_of(ty::ParamEnv::empty().and(ty)) .unwrap() .size; diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs index a1828bb5ab7a7..d247c0f9f69f3 100644 --- a/src/librustc/ty/query/plumbing.rs +++ b/src/librustc/ty/query/plumbing.rs @@ -265,7 +265,7 @@ impl<'tcx> TyCtxt<'tcx> { tls::with_related_context(self, move |current_icx| { // Update the `ImplicitCtxt` to point to our new query job. let new_icx = tls::ImplicitCtxt { - tcx: self.global_tcx(), + tcx: self, query: Some(job), diagnostics, layout_depth: current_icx.layout_depth, @@ -274,7 +274,7 @@ impl<'tcx> TyCtxt<'tcx> { // Use the `ImplicitCtxt` while we execute the query. tls::enter_context(&new_icx, |_| { - compute(self.global_tcx()) + compute(self) }) }) } @@ -384,7 +384,7 @@ impl<'tcx> TyCtxt<'tcx> { let ((result, dep_node_index), diagnostics) = with_diagnostics(|diagnostics| { self.start_query(job.job.clone(), diagnostics, |tcx| { tcx.dep_graph.with_anon_task(Q::dep_kind(), || { - Q::compute(tcx.global_tcx(), key) + Q::compute(tcx, key) }) }) }); @@ -445,10 +445,10 @@ impl<'tcx> TyCtxt<'tcx> { debug_assert!(self.dep_graph.is_green(dep_node)); // First we try to load the result from the on-disk cache. - let result = if Q::cache_on_disk(self.global_tcx(), key.clone(), None) && + let result = if Q::cache_on_disk(self, key.clone(), None) && self.sess.opts.debugging_opts.incremental_queries { self.sess.profiler(|p| p.incremental_load_result_start(Q::NAME)); - let result = Q::try_load_from_disk(self.global_tcx(), prev_dep_node_index); + let result = Q::try_load_from_disk(self, prev_dep_node_index); self.sess.profiler(|p| p.incremental_load_result_end(Q::NAME)); // We always expect to find a cached result for things that @@ -643,7 +643,7 @@ impl<'tcx> TyCtxt<'tcx> { macro_rules! handle_cycle_error { ([][$tcx: expr, $error:expr]) => {{ $tcx.report_cycle($error).emit(); - Value::from_cycle_error($tcx.global_tcx()) + Value::from_cycle_error($tcx) }}; ([fatal_cycle$(, $modifiers:ident)*][$tcx:expr, $error:expr]) => {{ $tcx.report_cycle($error).emit(); @@ -652,7 +652,7 @@ macro_rules! handle_cycle_error { }}; ([cycle_delay_bug$(, $modifiers:ident)*][$tcx:expr, $error:expr]) => {{ $tcx.report_cycle($error).delay_as_bug(); - Value::from_cycle_error($tcx.global_tcx()) + Value::from_cycle_error($tcx) }}; ([$other:ident$(, $modifiers:ident)*][$($args:tt)*]) => { handle_cycle_error!([$($modifiers),*][$($args)*]) @@ -999,7 +999,7 @@ macro_rules! define_queries_inner { // would be missing appropriate entries in `providers`. .unwrap_or(&tcx.queries.fallback_extern_providers) .$name; - provider(tcx.global_tcx(), key) + provider(tcx, key) }) } diff --git a/src/librustc/util/common.rs b/src/librustc/util/common.rs index 2475b93d95f32..0f472126695e0 100644 --- a/src/librustc/util/common.rs +++ b/src/librustc/util/common.rs @@ -1,10 +1,9 @@ #![allow(non_camel_case_types)] -use rustc_data_structures::{fx::FxHashMap, sync::Lock}; +use rustc_data_structures::sync::Lock; -use std::cell::{RefCell, Cell}; +use std::cell::Cell; use std::fmt::Debug; -use std::hash::Hash; use std::time::{Duration, Instant}; use std::sync::mpsc::{Sender}; @@ -279,39 +278,3 @@ pub fn indenter() -> Indenter { debug!(">>"); Indenter { _cannot_construct_outside_of_this_module: () } } - -pub trait MemoizationMap { - type Key: Clone; - type Value: Clone; - - /// If `key` is present in the map, return the value, - /// otherwise invoke `op` and store the value in the map. - /// - /// N.B., if the receiver is a `DepTrackingMap`, special care is - /// needed in the `op` to ensure that the correct edges are - /// added into the dep graph. See the `DepTrackingMap` impl for - /// more details! - fn memoize(&self, key: Self::Key, op: OP) -> Self::Value - where OP: FnOnce() -> Self::Value; -} - -impl MemoizationMap for RefCell> - where K: Hash+Eq+Clone, V: Clone -{ - type Key = K; - type Value = V; - - fn memoize(&self, key: K, op: OP) -> V - where OP: FnOnce() -> V - { - let result = self.borrow().get(&key).cloned(); - match result { - Some(result) => result, - None => { - let result = op(); - self.borrow_mut().insert(key, result.clone()); - result - } - } - } -} diff --git a/src/librustc_codegen_llvm/abi.rs b/src/librustc_codegen_llvm/abi.rs index 2ca517dc3b1a7..ae5cfc4d97b59 100644 --- a/src/librustc_codegen_llvm/abi.rs +++ b/src/librustc_codegen_llvm/abi.rs @@ -264,7 +264,7 @@ impl ArgTypeExt<'ll, 'tcx> for ArgType<'tcx, Ty<'tcx>> { val }; match self.mode { - PassMode::Ignore(_) => {} + PassMode::Ignore => {} PassMode::Pair(..) => { OperandValue::Pair(next(), next()).store(bx, dst); } @@ -319,9 +319,7 @@ impl<'tcx> FnTypeLlvmExt<'tcx> for FnType<'tcx, Ty<'tcx>> { ); let llreturn_ty = match self.ret.mode { - PassMode::Ignore(IgnoreMode::Zst) => cx.type_void(), - PassMode::Ignore(IgnoreMode::CVarArgs) => - bug!("`va_list` should never be a return type"), + PassMode::Ignore => cx.type_void(), PassMode::Direct(_) | PassMode::Pair(..) => { self.ret.layout.immediate_llvm_type(cx) } @@ -339,7 +337,7 @@ impl<'tcx> FnTypeLlvmExt<'tcx> for FnType<'tcx, Ty<'tcx>> { } let llarg_ty = match arg.mode { - PassMode::Ignore(_) => continue, + PassMode::Ignore => continue, PassMode::Direct(_) => arg.layout.immediate_llvm_type(cx), PassMode::Pair(..) => { llargument_tys.push(arg.layout.scalar_pair_element_llvm_type(cx, 0, true)); @@ -408,7 +406,7 @@ impl<'tcx> FnTypeLlvmExt<'tcx> for FnType<'tcx, Ty<'tcx>> { apply(&ArgAttributes::new(), None); } match arg.mode { - PassMode::Ignore(_) => {} + PassMode::Ignore => {} PassMode::Direct(ref attrs) | PassMode::Indirect(ref attrs, None) => apply(attrs, Some(arg.layout.llvm_type(cx))), PassMode::Indirect(ref attrs, Some(ref extra_attrs)) => { @@ -455,7 +453,7 @@ impl<'tcx> FnTypeLlvmExt<'tcx> for FnType<'tcx, Ty<'tcx>> { apply(&ArgAttributes::new(), None); } match arg.mode { - PassMode::Ignore(_) => {} + PassMode::Ignore => {} PassMode::Direct(ref attrs) | PassMode::Indirect(ref attrs, None) => apply(attrs, Some(arg.layout.llvm_type(bx))), PassMode::Indirect(ref attrs, Some(ref extra_attrs)) => { diff --git a/src/librustc_codegen_ssa/mir/block.rs b/src/librustc_codegen_ssa/mir/block.rs index 3069199a21256..7ebdfbdcdeb2d 100644 --- a/src/librustc_codegen_ssa/mir/block.rs +++ b/src/librustc_codegen_ssa/mir/block.rs @@ -1,9 +1,10 @@ +use rustc_data_structures::indexed_vec::Idx; use rustc::middle::lang_items; use rustc::ty::{self, Ty, TypeFoldable, Instance}; use rustc::ty::layout::{self, LayoutOf, HasTyCtxt, FnTypeExt}; use rustc::mir::{self, Place, PlaceBase, Static, StaticKind}; use rustc::mir::interpret::PanicInfo; -use rustc_target::abi::call::{ArgType, FnType, PassMode, IgnoreMode}; +use rustc_target::abi::call::{ArgType, FnType, PassMode}; use rustc_target::spec::abi::Abi; use crate::base; use crate::MemFlags; @@ -224,14 +225,15 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } fn codegen_return_terminator(&mut self, mut bx: Bx) { + // Call `va_end` if this is the definition of a C-variadic function. if self.fn_ty.c_variadic { - match self.va_list_ref { - Some(va_list) => { + // The `VaList` "spoofed" argument is just after all the real arguments. + let va_list_arg_idx = self.fn_ty.args.len(); + match self.locals[mir::Local::new(1 + va_list_arg_idx)] { + LocalRef::Place(va_list) => { bx.va_end(va_list.llval); } - None => { - bug!("C-variadic function must have a `va_list_ref`"); - } + _ => bug!("C-variadic function must have a `VaList` place"), } } if self.fn_ty.ret.layout.abi.is_uninhabited() { @@ -242,15 +244,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { return; } let llval = match self.fn_ty.ret.mode { - PassMode::Ignore(IgnoreMode::Zst) | PassMode::Indirect(..) => { + PassMode::Ignore | PassMode::Indirect(..) => { bx.ret_void(); return; } - PassMode::Ignore(IgnoreMode::CVarArgs) => { - bug!("C-variadic arguments should never be the return type"); - } - PassMode::Direct(_) | PassMode::Pair(..) => { let op = self.codegen_consume(&mut bx, &mir::Place::return_place().as_ref()); @@ -502,10 +500,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { return; } - // The "spoofed" `VaListImpl` added to a C-variadic functions signature - // should not be included in the `extra_args` calculation. - let extra_args_start_idx = sig.inputs().len() - if sig.c_variadic { 1 } else { 0 }; - let extra_args = &args[extra_args_start_idx..]; + let extra_args = &args[sig.inputs().len()..]; let extra_args = extra_args.iter().map(|op_arg| { let op_ty = op_arg.ty(self.mir, bx.tcx()); self.monomorphize(&op_ty) @@ -691,26 +686,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { (&args[..], None) }; - // Useful determining if the current argument is the "spoofed" `VaListImpl` - let last_arg_idx = if sig.inputs().is_empty() { - None - } else { - Some(sig.inputs().len() - 1) - }; 'make_args: for (i, arg) in first_args.iter().enumerate() { - // If this is a C-variadic function the function signature contains - // an "spoofed" `VaListImpl`. This argument is ignored, but we need to - // populate it with a dummy operand so that the users real arguments - // are not overwritten. - let i = if sig.c_variadic && last_arg_idx.map(|x| i >= x).unwrap_or(false) { - if i + 1 < fn_ty.args.len() { - i + 1 - } else { - break 'make_args - } - } else { - i - }; let mut op = self.codegen_operand(&mut bx, arg); if let (0, Some(ty::InstanceDef::Virtual(_, idx))) = (i, def) { diff --git a/src/librustc_codegen_ssa/mir/mod.rs b/src/librustc_codegen_ssa/mir/mod.rs index c341c0685c6a7..4f3a8bdb540b5 100644 --- a/src/librustc_codegen_ssa/mir/mod.rs +++ b/src/librustc_codegen_ssa/mir/mod.rs @@ -2,7 +2,7 @@ use rustc::ty::{self, Ty, TypeFoldable, UpvarSubsts, Instance}; use rustc::ty::layout::{TyLayout, HasTyCtxt, FnTypeExt}; use rustc::mir::{self, Body}; use rustc::session::config::DebugInfo; -use rustc_target::abi::call::{FnType, PassMode, IgnoreMode}; +use rustc_target::abi::call::{FnType, PassMode}; use rustc_target::abi::{Variants, VariantIdx}; use crate::base; use crate::debuginfo::{self, VariableAccess, VariableKind, FunctionDebugContext}; @@ -81,10 +81,6 @@ pub struct FunctionCx<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> { /// Debug information for MIR scopes. scopes: IndexVec>, - - /// If this function is a C-variadic function, this contains the `PlaceRef` of the - /// "spoofed" `VaListImpl`. - va_list_ref: Option>, } impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { @@ -236,18 +232,13 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( scopes, locals: IndexVec::new(), debug_context, - va_list_ref: None, }; let memory_locals = analyze::non_ssa_locals(&fx); // Allocate variable and temp allocas fx.locals = { - // FIXME(dlrobertson): This is ugly. Find a better way of getting the `PlaceRef` or - // `LocalRef` from `arg_local_refs` - let mut va_list_ref = None; - let args = arg_local_refs(&mut bx, &fx, &memory_locals, &mut va_list_ref); - fx.va_list_ref = va_list_ref; + let args = arg_local_refs(&mut bx, &fx, &memory_locals); let mut allocate_local = |local| { let decl = &mir.local_decls[local]; @@ -426,7 +417,6 @@ fn arg_local_refs<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( bx: &mut Bx, fx: &FunctionCx<'a, 'tcx, Bx>, memory_locals: &BitSet, - va_list_ref: &mut Option>, ) -> Vec> { let mir = fx.mir; let tcx = fx.cx.tcx(); @@ -441,15 +431,6 @@ fn arg_local_refs<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( None }; - // Store the index of the last argument. This is used to - // call va_start on the va_list instead of attempting - // to store_fn_arg. - let last_arg_idx = if fx.fn_ty.args.is_empty() { - None - } else { - Some(fx.fn_ty.args.len() - 1) - }; - mir.args_iter().enumerate().map(|(arg_index, local)| { let arg_decl = &mir.local_decls[local]; @@ -503,6 +484,31 @@ fn arg_local_refs<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( return LocalRef::Place(place); } + if fx.fn_ty.c_variadic && arg_index == fx.fn_ty.args.len() { + let arg_ty = fx.monomorphize(&arg_decl.ty); + + let va_list = PlaceRef::alloca(bx, bx.layout_of(arg_ty)); + bx.set_var_name(va_list.llval, name); + bx.va_start(va_list.llval); + + arg_scope.map(|scope| { + let variable_access = VariableAccess::DirectVariable { + alloca: va_list.llval + }; + bx.declare_local( + &fx.debug_context, + arg_decl.name.unwrap_or(kw::Invalid), + va_list.layout.ty, + scope, + variable_access, + VariableKind::ArgumentVariable(arg_index + 1), + DUMMY_SP + ); + }); + + return LocalRef::Place(va_list); + } + let arg = &fx.fn_ty.args[idx]; idx += 1; if arg.pad.is_some() { @@ -515,10 +521,9 @@ fn arg_local_refs<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( // of putting everything in allocas just so we can use llvm.dbg.declare. let local = |op| LocalRef::Operand(Some(op)); match arg.mode { - PassMode::Ignore(IgnoreMode::Zst) => { + PassMode::Ignore => { return local(OperandRef::new_zst(bx, arg.layout)); } - PassMode::Ignore(IgnoreMode::CVarArgs) => {} PassMode::Direct(_) => { let llarg = bx.get_param(llarg_idx); bx.set_var_name(llarg, &name); @@ -568,22 +573,7 @@ fn arg_local_refs<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( } else { let tmp = PlaceRef::alloca(bx, arg.layout); bx.set_var_name(tmp.llval, name); - if fx.fn_ty.c_variadic && last_arg_idx.map(|idx| arg_index == idx).unwrap_or(false) { - let va_list_did = match tcx.lang_items().va_list() { - Some(did) => did, - None => bug!("`va_list` lang item required for C-variadic functions"), - }; - match arg_decl.ty.kind { - ty::Adt(def, _) if def.did == va_list_did => { - // Call `va_start` on the spoofed `VaListImpl`. - bx.va_start(tmp.llval); - *va_list_ref = Some(tmp); - }, - _ => bug!("last argument of variadic function is not a `va_list`") - } - } else { - bx.store_fn_arg(arg, &mut llarg_idx, tmp); - } + bx.store_fn_arg(arg, &mut llarg_idx, tmp); tmp }; let upvar_debuginfo = &mir.__upvar_debuginfo_codegen_only_do_not_use; diff --git a/src/librustc_driver/Cargo.toml b/src/librustc_driver/Cargo.toml index d615e5b256d1a..aa74966d0ab4c 100644 --- a/src/librustc_driver/Cargo.toml +++ b/src/librustc_driver/Cargo.toml @@ -13,7 +13,7 @@ crate-type = ["dylib"] graphviz = { path = "../libgraphviz" } lazy_static = "1.0" log = "0.4" -env_logger = { version = "0.6", default-features = false } +env_logger = { version = "0.7", default-features = false } rustc = { path = "../librustc" } rustc_target = { path = "../librustc_target" } rustc_data_structures = { path = "../librustc_data_structures" } diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs index e4567dc8265d8..150719c1dbc0e 100644 --- a/src/librustc_lint/types.rs +++ b/src/librustc_lint/types.rs @@ -944,15 +944,8 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { let def_id = self.cx.tcx.hir().local_def_id(id); let sig = self.cx.tcx.fn_sig(def_id); let sig = self.cx.tcx.erase_late_bound_regions(&sig); - let inputs = if sig.c_variadic { - // Don't include the spoofed `VaListImpl` in the functions list - // of inputs. - &sig.inputs()[..sig.inputs().len() - 1] - } else { - &sig.inputs()[..] - }; - for (input_ty, input_hir) in inputs.iter().zip(&decl.inputs) { + for (input_ty, input_hir) in sig.inputs().iter().zip(&decl.inputs) { self.check_type_for_ffi_and_report_errors(input_hir.span, input_ty); } diff --git a/src/librustc_macros/src/query.rs b/src/librustc_macros/src/query.rs index a8df7e197a8c9..9a68dd0f5e3ce 100644 --- a/src/librustc_macros/src/query.rs +++ b/src/librustc_macros/src/query.rs @@ -442,8 +442,8 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream { .map(|c| c.is_green()) .unwrap_or(false)); - let key = RecoverKey::recover(tcx.global_tcx(), self).unwrap(); - if queries::#name::cache_on_disk(tcx.global_tcx(), key, None) { + let key = RecoverKey::recover(tcx, self).unwrap(); + if queries::#name::cache_on_disk(tcx, key, None) { let _ = tcx.#name(key); } } diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index 70a2526f70a7e..cf80a1bc6437e 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -621,7 +621,7 @@ impl<'cx, 'tcx> DataflowResultsConsumer<'cx, 'tcx> for MirBorrowckCtxt<'cx, 'tcx target: _, unwind: _, } => { - let gcx = self.infcx.tcx.global_tcx(); + let tcx = self.infcx.tcx; // Compute the type with accurate region information. let drop_place_ty = drop_place.ty(self.body, self.infcx.tcx); @@ -629,10 +629,10 @@ impl<'cx, 'tcx> DataflowResultsConsumer<'cx, 'tcx> for MirBorrowckCtxt<'cx, 'tcx // Erase the regions. let drop_place_ty = self.infcx.tcx.erase_regions(&drop_place_ty).ty; - // "Lift" into the gcx -- once regions are erased, this type should be in the + // "Lift" into the tcx -- once regions are erased, this type should be in the // global arenas; this "lift" operation basically just asserts that is true, but // that is useful later. - gcx.lift_to_global(&drop_place_ty).unwrap(); + tcx.lift(&drop_place_ty).unwrap(); debug!("visit_terminator_drop \ loc: {:?} term: {:?} drop_place: {:?} drop_place_ty: {:?} span: {:?}", diff --git a/src/librustc_mir/borrow_check/nll/type_check/input_output.rs b/src/librustc_mir/borrow_check/nll/type_check/input_output.rs index 99661b1f7370a..edf9549b626aa 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/input_output.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/input_output.rs @@ -9,8 +9,10 @@ use crate::borrow_check::nll::universal_regions::UniversalRegions; use rustc::infer::LateBoundRegionConversionTime; +use rustc::middle::lang_items; use rustc::mir::*; -use rustc::ty::Ty; +use rustc::ty::{self, Ty}; +use rustc::ty::subst::Subst; use rustc_data_structures::indexed_vec::Idx; use syntax_pos::Span; @@ -63,8 +65,22 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } }; + // C-variadic fns also have a `VaList` input that's not listed in the signature + // (as it's created inside the body itself, not passed in from outside). + let maybe_va_list = if universal_regions.c_variadic { + let va_list_did = + self.tcx().require_lang_item(lang_items::VaListTypeLangItem, Some(body.span)); + let region = self.tcx().mk_region(ty::ReVar(universal_regions.fr_fn_body)); + + Some(self.tcx().type_of(va_list_did).subst(self.tcx(), &[region.into()])) + } else { + None + }; + // Equate expected input tys with those in the MIR. - for (&normalized_input_ty, argument_index) in normalized_input_tys.iter().zip(0..) { + for (normalized_input_ty, argument_index) in + normalized_input_tys.iter().copied().chain(maybe_va_list).zip(0..) + { // In MIR, argument N is stored in local N+1. let local = Local::new(argument_index + 1); 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 e3e509799c936..fa326062fe2c9 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs @@ -1726,17 +1726,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { from_hir_call: bool, ) { debug!("check_call_inputs({:?}, {:?})", sig, args); - // Do not count the `VaListImpl` argument as a "true" argument to - // a C-variadic function. - let inputs = if sig.c_variadic { - &sig.inputs()[..sig.inputs().len() - 1] - } else { - &sig.inputs()[..] - }; - if args.len() < inputs.len() || (args.len() > inputs.len() && !sig.c_variadic) { + if args.len() < sig.inputs().len() || (args.len() > sig.inputs().len() && !sig.c_variadic) { span_mirbug!(self, term, "call to {:?} with wrong # of args", sig); } - for (n, (fn_arg, op_arg)) in inputs.iter().zip(args).enumerate() { + for (n, (fn_arg, op_arg)) in sig.inputs().iter().zip(args).enumerate() { let op_arg_ty = op_arg.ty(body, self.tcx()); let category = if from_hir_call { ConstraintCategory::CallArgument @@ -1894,9 +1887,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { // Erase the regions from `ty` to get a global type. The // `Sized` bound in no way depends on precise regions, so this // shouldn't affect `is_sized`. - let gcx = tcx.global_tcx(); let erased_ty = tcx.erase_regions(&ty); - if !erased_ty.is_sized(gcx.at(span), self.param_env) { + if !erased_ty.is_sized(tcx.at(span), self.param_env) { // in current MIR construction, all non-control-flow rvalue // expressions evaluate through `as_temp` or `into` a return // slot or local, so to find all unsized rvalues it is enough diff --git a/src/librustc_mir/borrow_check/nll/universal_regions.rs b/src/librustc_mir/borrow_check/nll/universal_regions.rs index b5af97a2217e8..cc6f6537bb269 100644 --- a/src/librustc_mir/borrow_check/nll/universal_regions.rs +++ b/src/librustc_mir/borrow_check/nll/universal_regions.rs @@ -72,6 +72,8 @@ pub struct UniversalRegions<'tcx> { pub unnormalized_input_tys: &'tcx [Ty<'tcx>], pub yield_ty: Option>, + + pub c_variadic: bool, } /// The "defining type" for this MIR. The key feature of the "defining @@ -451,6 +453,13 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { _ => None, }; + let c_variadic = match defining_ty { + DefiningTy::FnDef(def_id, _) => { + self.infcx.tcx.fn_sig(def_id).c_variadic() + } + _ => false, + }; + UniversalRegions { indices, fr_static, @@ -462,6 +471,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { unnormalized_output_ty, unnormalized_input_tys, yield_ty: yield_ty, + c_variadic, } } @@ -521,9 +531,8 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { defining_ty: DefiningTy<'tcx>, ) -> UniversalRegionIndices<'tcx> { let tcx = self.infcx.tcx; - let gcx = tcx.global_tcx(); let closure_base_def_id = tcx.closure_base_def_id(self.mir_def_id); - let identity_substs = InternalSubsts::identity_for_item(gcx, closure_base_def_id); + let identity_substs = InternalSubsts::identity_for_item(tcx, closure_base_def_id); let fr_substs = match defining_ty { DefiningTy::Closure(_, ClosureSubsts { ref substs }) | DefiningTy::Generator(_, GeneratorSubsts { ref substs }, _) => { @@ -542,7 +551,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { DefiningTy::FnDef(_, substs) | DefiningTy::Const(_, substs) => substs, }; - let global_mapping = iter::once((gcx.lifetimes.re_static, fr_static)); + let global_mapping = iter::once((tcx.lifetimes.re_static, fr_static)); let subst_mapping = identity_substs .regions() .zip(fr_substs.regions().map(|r| r.to_region_vid())); diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs index f1e045302eced..17932ae855767 100644 --- a/src/librustc_mir/build/mod.rs +++ b/src/librustc_mir/build/mod.rs @@ -7,9 +7,11 @@ use crate::util as mir_util; use rustc::hir; use rustc::hir::Node; use rustc::hir::def_id::DefId; +use rustc::middle::lang_items; use rustc::middle::region; use rustc::mir::*; use rustc::ty::{self, Ty, TyCtxt}; +use rustc::ty::subst::Subst; use rustc::util::nodemap::HirIdMap; use rustc_target::spec::PanicStrategy; use rustc_data_structures::indexed_vec::{IndexVec, Idx}; @@ -102,9 +104,7 @@ pub fn mir_build(tcx: TyCtxt<'_>, def_id: DefId) -> Body<'_> { let opt_ty_info; let self_arg; if let Some(ref fn_decl) = tcx.hir().fn_decl_by_hir_id(owner_id) { - let ty_hir_id = fn_decl.inputs[index].hir_id; - let ty_span = tcx.hir().span(ty_hir_id); - opt_ty_info = Some(ty_span); + opt_ty_info = fn_decl.inputs.get(index).map(|ty| ty.span); self_arg = if index == 0 && fn_decl.implicit_self.has_implicit_self() { match fn_decl.implicit_self { hir::ImplicitSelfKind::Imm => Some(ImplicitSelfKind::Imm), @@ -121,7 +121,24 @@ pub fn mir_build(tcx: TyCtxt<'_>, def_id: DefId) -> Body<'_> { self_arg = None; } - ArgInfo(fn_sig.inputs()[index], opt_ty_info, Some(&arg), self_arg) + // C-variadic fns also have a `VaList` input that's not listed in `fn_sig` + // (as it's created inside the body itself, not passed in from outside). + let ty = if fn_sig.c_variadic && index == fn_sig.inputs().len() { + let va_list_did = tcx.require_lang_item( + lang_items::VaListTypeLangItem, + Some(arg.span), + ); + let region = tcx.mk_region(ty::ReScope(region::Scope { + id: body.value.hir_id.local_id, + data: region::ScopeData::CallSite + })); + + tcx.type_of(va_list_did).subst(tcx, &[region.into()]) + } else { + fn_sig.inputs()[index] + }; + + ArgInfo(ty, opt_ty_info, Some(&arg), self_arg) }); let arguments = implicit_argument.into_iter().chain(explicit_arguments); diff --git a/src/librustc_mir/dataflow/drop_flag_effects.rs b/src/librustc_mir/dataflow/drop_flag_effects.rs index 51b717b69e9c1..0fe58c07b1b86 100644 --- a/src/librustc_mir/dataflow/drop_flag_effects.rs +++ b/src/librustc_mir/dataflow/drop_flag_effects.rs @@ -148,9 +148,8 @@ pub(crate) fn on_all_drop_children_bits<'tcx, F>( let ty = place.ty(body, tcx).ty; debug!("on_all_drop_children_bits({:?}, {:?} : {:?})", path, place, ty); - let gcx = tcx.global_tcx(); let erased_ty = tcx.erase_regions(&ty); - if erased_ty.needs_drop(gcx, ctxt.param_env) { + if erased_ty.needs_drop(tcx, ctxt.param_env) { each_child(child); } else { debug!("on_all_drop_children_bits - skipping") diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index da1b9ed7693e6..eed51cdab8c3c 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -543,9 +543,9 @@ fn make_mirror_unadjusted<'a, 'tcx>( // Now comes the rote stuff: hir::ExprKind::Repeat(ref v, ref count) => { let def_id = cx.tcx.hir().local_def_id(count.hir_id); - let substs = InternalSubsts::identity_for_item(cx.tcx.global_tcx(), def_id); + let substs = InternalSubsts::identity_for_item(cx.tcx, def_id); let instance = ty::Instance::resolve( - cx.tcx.global_tcx(), + cx.tcx, cx.param_env, def_id, substs, diff --git a/src/librustc_mir/hair/cx/mod.rs b/src/librustc_mir/hair/cx/mod.rs index f7cd29f2e67ef..32efbd6f01173 100644 --- a/src/librustc_mir/hair/cx/mod.rs +++ b/src/librustc_mir/hair/cx/mod.rs @@ -83,7 +83,7 @@ impl<'a, 'tcx> Cx<'a, 'tcx> { infcx, root_lint_level: src_id, param_env: tcx.param_env(src_def_id), - identity_substs: InternalSubsts::identity_for_item(tcx.global_tcx(), src_def_id), + identity_substs: InternalSubsts::identity_for_item(tcx, src_def_id), region_scope_tree: tcx.region_scope_tree(src_def_id), tables, constness, @@ -154,12 +154,11 @@ impl<'a, 'tcx> Cx<'a, 'tcx> { } pub fn pattern_from_hir(&mut self, p: &hir::Pat) -> Pat<'tcx> { - let tcx = self.tcx.global_tcx(); - let p = match tcx.hir().get(p.hir_id) { + let p = match self.tcx.hir().get(p.hir_id) { Node::Pat(p) | Node::Binding(p) => p, node => bug!("pattern became {:?}", node) }; - Pat::from_hir(tcx, self.param_env.and(self.identity_substs), self.tables(), p) + Pat::from_hir(self.tcx, self.param_env.and(self.identity_substs), self.tables(), p) } pub fn trait_method(&mut self, @@ -187,7 +186,7 @@ impl<'a, 'tcx> Cx<'a, 'tcx> { } pub fn needs_drop(&mut self, ty: Ty<'tcx>) -> bool { - ty.needs_drop(self.tcx.global_tcx(), self.param_env) + ty.needs_drop(self.tcx, self.param_env) } pub fn tcx(&self) -> TyCtxt<'tcx> { diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs index f5eb07882fe32..4fae0976ffb5a 100644 --- a/src/librustc_mir/shim.rs +++ b/src/librustc_mir/shim.rs @@ -79,7 +79,7 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> &'tcx } ty::InstanceDef::ClosureOnceShim { call_once } => { let fn_mut = tcx.lang_items().fn_mut_trait().unwrap(); - let call_mut = tcx.global_tcx() + let call_mut = tcx .associated_items(fn_mut) .find(|it| it.kind == ty::AssocKind::Method) .unwrap().def_id; diff --git a/src/librustc_target/abi/call/mod.rs b/src/librustc_target/abi/call/mod.rs index fbbd120f934be..bc21113527ecf 100644 --- a/src/librustc_target/abi/call/mod.rs +++ b/src/librustc_target/abi/call/mod.rs @@ -23,18 +23,10 @@ mod x86_64; mod x86_win64; mod wasm32; -#[derive(Clone, Copy, PartialEq, Eq, Debug)] -pub enum IgnoreMode { - /// C-variadic arguments. - CVarArgs, - /// A zero-sized type. - Zst, -} - #[derive(Clone, Copy, PartialEq, Eq, Debug)] pub enum PassMode { - /// Ignore the argument (useful for empty structs and C-variadic args). - Ignore(IgnoreMode), + /// Ignore the argument. + Ignore, /// Pass the argument directly. Direct(ArgAttributes), /// Pass a pair's elements directly in two arguments. @@ -490,7 +482,7 @@ impl<'a, Ty> ArgType<'a, Ty> { pub fn is_ignore(&self) -> bool { match self.mode { - PassMode::Ignore(_) => true, + PassMode::Ignore => true, _ => false } } diff --git a/src/librustc_target/abi/call/x86.rs b/src/librustc_target/abi/call/x86.rs index 6ca3ce88bd6eb..2e809571ab18b 100644 --- a/src/librustc_target/abi/call/x86.rs +++ b/src/librustc_target/abi/call/x86.rs @@ -88,7 +88,7 @@ pub fn compute_abi_info<'a, Ty, C>(cx: &C, fty: &mut FnType<'a, Ty>, flavor: Fla for arg in &mut fty.args { let attrs = match arg.mode { - PassMode::Ignore(_) | + PassMode::Ignore | PassMode::Indirect(_, None) => continue, PassMode::Direct(ref mut attrs) => attrs, PassMode::Pair(..) | diff --git a/src/librustc_traits/chalk_context/mod.rs b/src/librustc_traits/chalk_context/mod.rs index 06c1df70287c9..54d580ec05d71 100644 --- a/src/librustc_traits/chalk_context/mod.rs +++ b/src/librustc_traits/chalk_context/mod.rs @@ -474,7 +474,7 @@ impl context::UnificationOps, ChalkArenas<'tcx>> &self, value: DelayedLiteral>, ) -> DelayedLiteral> { - match self.infcx.tcx.lift_to_global(&value) { + match self.infcx.tcx.lift(&value) { Some(literal) => literal, None => bug!("cannot lift {:?}", value), } diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 6f1d854481a10..8ed0359848364 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -1269,7 +1269,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { // to avoid ICEs. for item in ®ular_traits { let object_safety_violations = - tcx.global_tcx().astconv_object_safety_violations(item.trait_ref().def_id()); + tcx.astconv_object_safety_violations(item.trait_ref().def_id()); if !object_safety_violations.is_empty() { tcx.report_object_safety_error( span, @@ -2151,15 +2151,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { // handled specially and will not descend into this routine. self.ty_infer(None, ast_ty.span) } - hir::TyKind::CVarArgs(lt) => { - let va_list_did = match tcx.lang_items().va_list() { - Some(did) => did, - None => span_bug!(ast_ty.span, - "`va_list` lang item required for variadics"), - }; - let region = self.ast_region_to_region(<, None); - tcx.type_of(va_list_did).subst(tcx, &[region.into()]) - } hir::TyKind::Err => { tcx.types.err } diff --git a/src/librustc_typeck/check/callee.rs b/src/librustc_typeck/check/callee.rs index 4d8ec6fb0b83d..9e1fbc067d2e3 100644 --- a/src/librustc_typeck/check/callee.rs +++ b/src/librustc_typeck/check/callee.rs @@ -406,27 +406,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .0; let fn_sig = self.normalize_associated_types_in(call_expr.span, &fn_sig); - let inputs = if fn_sig.c_variadic { - if fn_sig.inputs().len() > 1 { - &fn_sig.inputs()[..fn_sig.inputs().len() - 1] - } else { - span_bug!(call_expr.span, - "C-variadic functions are only valid with one or more fixed arguments"); - } - } else { - &fn_sig.inputs()[..] - }; // Call the generic checker. let expected_arg_tys = self.expected_inputs_for_expected_output( call_expr.span, expected, fn_sig.output(), - inputs, + fn_sig.inputs(), ); self.check_argument_types( call_expr.span, call_expr, - inputs, + fn_sig.inputs(), &expected_arg_tys[..], arg_exprs, fn_sig.c_variadic, diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs index 58f41ca4f88f9..0cdf2fa2a5b9e 100644 --- a/src/librustc_typeck/check/expr.rs +++ b/src/librustc_typeck/check/expr.rs @@ -620,8 +620,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expr: &'tcx hir::Expr ) -> Ty<'tcx> { if self.ret_coercion.is_none() { - struct_span_err!(self.tcx.sess, expr.span, E0572, - "return statement outside of function body").emit(); + struct_span_err!( + self.tcx.sess, + expr.span, + E0572, + "return statement outside of function body", + ).emit(); } else if let Some(ref e) = expr_opt { if self.ret_coercion_span.borrow().is_none() { *self.ret_coercion_span.borrow_mut() = Some(e.span); @@ -932,9 +936,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Ok(self.to_const(count, tcx.type_of(count_def_id))) } else { let param_env = ty::ParamEnv::empty(); - let substs = InternalSubsts::identity_for_item(tcx.global_tcx(), count_def_id); + let substs = InternalSubsts::identity_for_item(tcx, count_def_id); let instance = ty::Instance::resolve( - tcx.global_tcx(), + tcx, param_env, count_def_id, substs, diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 9f2c991fdd236..a7832b8c2cf17 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1132,8 +1132,29 @@ fn check_fn<'a, 'tcx>( let outer_hir_id = fcx.tcx.hir().as_local_hir_id(outer_def_id).unwrap(); GatherLocalsVisitor { fcx: &fcx, parent_id: outer_hir_id, }.visit_body(body); + // C-variadic fns also have a `VaList` input that's not listed in `fn_sig` + // (as it's created inside the body itself, not passed in from outside). + let maybe_va_list = if fn_sig.c_variadic { + let va_list_did = fcx.tcx.require_lang_item( + lang_items::VaListTypeLangItem, + Some(body.params.last().unwrap().span), + ); + let region = fcx.tcx.mk_region(ty::ReScope(region::Scope { + id: body.value.hir_id.local_id, + data: region::ScopeData::CallSite + })); + + Some(fcx.tcx.type_of(va_list_did).subst(fcx.tcx, &[region.into()])) + } else { + None + }; + // Add formal parameters. - for (param_ty, param) in fn_sig.inputs().iter().zip(&body.params) { + for (param_ty, param) in + fn_sig.inputs().iter().copied() + .chain(maybe_va_list) + .zip(&body.params) + { // Check the pattern. fcx.check_pat_top(¶m.pat, param_ty, None); diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index f4ba9fc03d3d0..20c517d779b42 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -48,7 +48,7 @@ impl<'tcx> CheckWfFcxBuilder<'tcx> { // empty `param_env`. check_false_global_bounds(&fcx, span, id); } - let wf_tys = f(&fcx, fcx.tcx.global_tcx()); + let wf_tys = f(&fcx, fcx.tcx); fcx.select_all_obligations_or_error(); fcx.regionck_item(id, span, &wf_tys); }); @@ -366,8 +366,8 @@ fn check_item_type( ) { debug!("check_item_type: {:?}", item_id); - for_id(tcx, item_id, ty_span).with_fcx(|fcx, gcx| { - let ty = gcx.type_of(gcx.hir().local_def_id(item_id)); + for_id(tcx, item_id, ty_span).with_fcx(|fcx, tcx| { + let ty = tcx.type_of(tcx.hir().local_def_id(item_id)); let item_ty = fcx.normalize_associated_types_in(ty_span, &ty); let mut forbid_unsized = true; diff --git a/src/librustc_typeck/coherence/builtin.rs b/src/librustc_typeck/coherence/builtin.rs index 64bd144dfa226..1e3939cbfcdf2 100644 --- a/src/librustc_typeck/coherence/builtin.rs +++ b/src/librustc_typeck/coherence/builtin.rs @@ -322,29 +322,29 @@ fn visit_implementation_of_dispatch_from_dyn(tcx: TyCtxt<'_>, impl_did: DefId) { } } -pub fn coerce_unsized_info<'tcx>(gcx: TyCtxt<'tcx>, impl_did: DefId) -> CoerceUnsizedInfo { +pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: DefId) -> CoerceUnsizedInfo { debug!("compute_coerce_unsized_info(impl_did={:?})", impl_did); - let coerce_unsized_trait = gcx.lang_items().coerce_unsized_trait().unwrap(); + let coerce_unsized_trait = tcx.lang_items().coerce_unsized_trait().unwrap(); - let unsize_trait = gcx.lang_items().require(UnsizeTraitLangItem).unwrap_or_else(|err| { - gcx.sess.fatal(&format!("`CoerceUnsized` implementation {}", err)); + let unsize_trait = tcx.lang_items().require(UnsizeTraitLangItem).unwrap_or_else(|err| { + tcx.sess.fatal(&format!("`CoerceUnsized` implementation {}", err)); }); // this provider should only get invoked for local def-ids - let impl_hir_id = gcx.hir().as_local_hir_id(impl_did).unwrap_or_else(|| { + let impl_hir_id = tcx.hir().as_local_hir_id(impl_did).unwrap_or_else(|| { bug!("coerce_unsized_info: invoked for non-local def-id {:?}", impl_did) }); - let source = gcx.type_of(impl_did); - let trait_ref = gcx.impl_trait_ref(impl_did).unwrap(); + let source = tcx.type_of(impl_did); + let trait_ref = tcx.impl_trait_ref(impl_did).unwrap(); assert_eq!(trait_ref.def_id, coerce_unsized_trait); let target = trait_ref.substs.type_at(1); debug!("visit_implementation_of_coerce_unsized: {:?} -> {:?} (bound)", source, target); - let span = gcx.hir().span(impl_hir_id); - let param_env = gcx.param_env(impl_did); + let span = tcx.hir().span(impl_hir_id); + let param_env = tcx.param_env(impl_did); assert!(!source.has_escaping_bound_vars()); let err_info = CoerceUnsizedInfo { custom_kind: None }; @@ -353,7 +353,7 @@ pub fn coerce_unsized_info<'tcx>(gcx: TyCtxt<'tcx>, impl_did: DefId) -> CoerceUn source, target); - gcx.infer_ctxt().enter(|infcx| { + tcx.infer_ctxt().enter(|infcx| { let cause = ObligationCause::misc(span, impl_hir_id); let check_mutbl = |mt_a: ty::TypeAndMut<'tcx>, mt_b: ty::TypeAndMut<'tcx>, @@ -372,24 +372,24 @@ pub fn coerce_unsized_info<'tcx>(gcx: TyCtxt<'tcx>, impl_did: DefId) -> CoerceUn infcx.sub_regions(infer::RelateObjectBound(span), r_b, r_a); let mt_a = ty::TypeAndMut { ty: ty_a, mutbl: mutbl_a }; let mt_b = ty::TypeAndMut { ty: ty_b, mutbl: mutbl_b }; - check_mutbl(mt_a, mt_b, &|ty| gcx.mk_imm_ref(r_b, ty)) + check_mutbl(mt_a, mt_b, &|ty| tcx.mk_imm_ref(r_b, ty)) } (&ty::Ref(_, ty_a, mutbl_a), &ty::RawPtr(mt_b)) => { let mt_a = ty::TypeAndMut { ty: ty_a, mutbl: mutbl_a }; - check_mutbl(mt_a, mt_b, &|ty| gcx.mk_imm_ptr(ty)) + check_mutbl(mt_a, mt_b, &|ty| tcx.mk_imm_ptr(ty)) } (&ty::RawPtr(mt_a), &ty::RawPtr(mt_b)) => { - check_mutbl(mt_a, mt_b, &|ty| gcx.mk_imm_ptr(ty)) + check_mutbl(mt_a, mt_b, &|ty| tcx.mk_imm_ptr(ty)) } (&ty::Adt(def_a, substs_a), &ty::Adt(def_b, substs_b)) if def_a.is_struct() && def_b.is_struct() => { if def_a != def_b { - let source_path = gcx.def_path_str(def_a.did); - let target_path = gcx.def_path_str(def_b.did); - span_err!(gcx.sess, + let source_path = tcx.def_path_str(def_a.did); + let target_path = tcx.def_path_str(def_b.did); + span_err!(tcx.sess, span, E0377, "the trait `CoerceUnsized` may only be implemented \ @@ -443,9 +443,9 @@ pub fn coerce_unsized_info<'tcx>(gcx: TyCtxt<'tcx>, impl_did: DefId) -> CoerceUn let diff_fields = fields.iter() .enumerate() .filter_map(|(i, f)| { - let (a, b) = (f.ty(gcx, substs_a), f.ty(gcx, substs_b)); + let (a, b) = (f.ty(tcx, substs_a), f.ty(tcx, substs_b)); - if gcx.type_of(f.did).is_phantom_data() { + if tcx.type_of(f.did).is_phantom_data() { // Ignore PhantomData fields return None; } @@ -472,7 +472,7 @@ pub fn coerce_unsized_info<'tcx>(gcx: TyCtxt<'tcx>, impl_did: DefId) -> CoerceUn .collect::>(); if diff_fields.is_empty() { - span_err!(gcx.sess, + span_err!(tcx.sess, span, E0374, "the trait `CoerceUnsized` may only be implemented \ @@ -480,14 +480,14 @@ pub fn coerce_unsized_info<'tcx>(gcx: TyCtxt<'tcx>, impl_did: DefId) -> CoerceUn being coerced, none found"); return err_info; } else if diff_fields.len() > 1 { - let item = gcx.hir().expect_item(impl_hir_id); + let item = tcx.hir().expect_item(impl_hir_id); let span = if let ItemKind::Impl(.., Some(ref t), _, _) = item.kind { t.path.span } else { - gcx.hir().span(impl_hir_id) + tcx.hir().span(impl_hir_id) }; - let mut err = struct_span_err!(gcx.sess, + let mut err = struct_span_err!(tcx.sess, span, E0375, "implementing the trait \ @@ -514,7 +514,7 @@ pub fn coerce_unsized_info<'tcx>(gcx: TyCtxt<'tcx>, impl_did: DefId) -> CoerceUn } _ => { - span_err!(gcx.sess, + span_err!(tcx.sess, span, E0376, "the trait `CoerceUnsized` may only be implemented \ @@ -527,7 +527,7 @@ pub fn coerce_unsized_info<'tcx>(gcx: TyCtxt<'tcx>, impl_did: DefId) -> CoerceUn // Register an obligation for `A: Trait`. let cause = traits::ObligationCause::misc(span, impl_hir_id); - let predicate = gcx.predicate_for_trait_def(param_env, + let predicate = tcx.predicate_for_trait_def(param_env, cause, trait_def_id, 0, diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 3ac3ce2a02c2e..db017394cd5f1 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -1717,9 +1717,7 @@ fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { } let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap(); - let scope = tcx.hir() - .get_defining_scope(hir_id) - .expect("could not get defining scope"); + let scope = tcx.hir().get_defining_scope(hir_id); let mut locator = ConstraintLocator { def_id, tcx, diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index ce21447105815..b530851b80de7 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -2032,6 +2032,7 @@ impl Clean for doctree::Function<'_> { pub struct FnDecl { pub inputs: Arguments, pub output: FunctionRetTy, + pub c_variadic: bool, pub attrs: Attributes, } @@ -2110,6 +2111,7 @@ impl<'a, A: Copy> Clean for (&'a hir::FnDecl, A) FnDecl { inputs: (&self.0.inputs[..], self.1).clean(cx), output: self.0.output.clean(cx), + c_variadic: self.0.c_variadic, attrs: Attributes::default(), } } @@ -2127,6 +2129,7 @@ impl<'tcx> Clean for (DefId, ty::PolyFnSig<'tcx>) { FnDecl { output: Return(sig.skip_binder().output().clean(cx)), attrs: Attributes::default(), + c_variadic: sig.skip_binder().c_variadic, inputs: Arguments { values: sig.skip_binder().inputs().iter().map(|t| { Argument { @@ -2545,7 +2548,6 @@ pub enum Type { Slice(Box), Array(Box, String), Never, - CVarArgs, RawPointer(Mutability, Box), BorrowedRef { lifetime: Option, @@ -2583,7 +2585,6 @@ pub enum PrimitiveType { Reference, Fn, Never, - CVarArgs, } #[derive(Clone, Copy, Debug)] @@ -2787,7 +2788,6 @@ impl PrimitiveType { Reference => "reference", Fn => "fn", Never => "never", - CVarArgs => "...", } } @@ -3032,7 +3032,6 @@ impl Clean for hir::Ty { TyKind::BareFn(ref barefn) => BareFunction(box barefn.clean(cx)), TyKind::Infer | TyKind::Err => Infer, TyKind::Typeof(..) => panic!("unimplemented type {:?}", self.kind), - TyKind::CVarArgs(_) => CVarArgs, } } } @@ -3980,7 +3979,6 @@ fn build_deref_target_impls(cx: &DocContext<'_>, Reference => None, Fn => None, Never => None, - CVarArgs => tcx.lang_items().va_list(), }; if let Some(did) = did { if !did.is_local() { diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index fafd43cb60b69..4cde868201eef 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -657,7 +657,6 @@ fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter<'_>, use_absolute: bool) -> primitive_link(f, PrimitiveType::Array, &format!("; {}]", n)) } clean::Never => primitive_link(f, PrimitiveType::Never, "!"), - clean::CVarArgs => primitive_link(f, PrimitiveType::CVarArgs, "..."), clean::RawPointer(m, ref t) => { let m = match m { clean::Immutable => "const", @@ -903,12 +902,15 @@ impl clean::BareFunctionDecl { impl clean::FnDecl { crate fn print(&self) -> impl fmt::Display + '_ { display_fn(move |f| { + let ellipsis = if self.c_variadic { ", ..." } else { "" }; if f.alternate() { write!(f, - "({args:#}){arrow:#}", args = self.inputs.print(), arrow = self.output.print()) + "({args:#}{ellipsis}){arrow:#}", + args = self.inputs.print(), ellipsis = ellipsis, arrow = self.output.print()) } else { write!(f, - "({args}){arrow}", args = self.inputs.print(), arrow = self.output.print()) + "({args}{ellipsis}){arrow}", + args = self.inputs.print(), ellipsis = ellipsis, arrow = self.output.print()) } }) } @@ -975,7 +977,12 @@ impl Function<'_> { } } - let args_plain = format!("({})", args_plain); + let mut args_plain = format!("({})", args_plain); + + if decl.c_variadic { + args.push_str(",
..."); + args_plain.push_str(", ..."); + } let output = if let hir::IsAsync::Async = asyncness { Cow::Owned(decl.sugared_async_return_type()) diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index a0538986a2242..69abbde9e6eba 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -714,7 +714,6 @@ where /// # Examples /// /// ``` - /// #![feature(map_get_key_value)] /// use std::collections::HashMap; /// /// let mut map = HashMap::new(); @@ -722,7 +721,7 @@ where /// assert_eq!(map.get_key_value(&1), Some((&1, &"a"))); /// assert_eq!(map.get_key_value(&2), None); /// ``` - #[unstable(feature = "map_get_key_value", issue = "49347")] + #[stable(feature = "map_get_key_value", since = "1.40.0")] #[inline] pub fn get_key_value(&self, k: &Q) -> Option<(&K, &V)> where diff --git a/src/libstd/primitive_docs.rs b/src/libstd/primitive_docs.rs index 45816ffd229f0..02f664760c08c 100644 --- a/src/libstd/primitive_docs.rs +++ b/src/libstd/primitive_docs.rs @@ -566,7 +566,9 @@ mod prim_array { } #[doc(alias = "[")] #[doc(alias = "]")] #[doc(alias = "[]")] -/// A dynamically-sized view into a contiguous sequence, `[T]`. +/// A dynamically-sized view into a contiguous sequence, `[T]`. Contiguous here +/// means that elements are layed out so that every element is the same +/// distance from its neighbors. /// /// *[See also the `std::slice` module](slice/index.html).* /// diff --git a/src/libstd/sys/vxworks/process/process_vxworks.rs b/src/libstd/sys/vxworks/process/process_vxworks.rs index beb20aa48169a..7446471ae3122 100644 --- a/src/libstd/sys/vxworks/process/process_vxworks.rs +++ b/src/libstd/sys/vxworks/process/process_vxworks.rs @@ -54,8 +54,8 @@ impl Command { let ret = libc::rtpSpawn( self.get_argv()[0], // executing program - self.get_argv().as_ptr() as *const _, // argv - *sys::os::environ() as *const *const c_char, + self.get_argv().as_ptr() as *mut *const c_char, // argv + *sys::os::environ() as *mut *const c_char, 100 as c_int, // initial priority thread::min_stack(), // initial stack size. 0, // options diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index a7f035dc9ecc7..bc468c1ad0ebe 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -1893,7 +1893,6 @@ impl Param { pub struct FnDecl { pub inputs: Vec, pub output: FunctionRetTy, - pub c_variadic: bool, } impl FnDecl { @@ -1903,6 +1902,12 @@ impl FnDecl { pub fn has_self(&self) -> bool { self.inputs.get(0).map(Param::is_self).unwrap_or(false) } + pub fn c_variadic(&self) -> bool { + self.inputs.last().map(|arg| match arg.ty.kind { + TyKind::CVarArgs => true, + _ => false, + }).unwrap_or(false) + } } /// Is the trait definition an auto trait? diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index 6b93d045588b9..8c5289671c98e 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -562,7 +562,6 @@ impl<'a> ExtCtxt<'a> { P(ast::FnDecl { inputs, output, - c_variadic: false }) } diff --git a/src/libsyntax/feature_gate/check.rs b/src/libsyntax/feature_gate/check.rs index 622b48ab9281e..d7fc74955bbbd 100644 --- a/src/libsyntax/feature_gate/check.rs +++ b/src/libsyntax/feature_gate/check.rs @@ -531,7 +531,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { self.check_abi(header.abi, span); } - if fn_decl.c_variadic { + if fn_decl.c_variadic() { gate_feature_post!(&self, c_variadic, span, "C-variadic functions are unstable"); } @@ -564,7 +564,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { if block.is_none() { self.check_abi(sig.header.abi, ti.span); } - if sig.decl.c_variadic { + if sig.decl.c_variadic() { gate_feature_post!(&self, c_variadic, ti.span, "C-variadic functions are unstable"); } @@ -601,7 +601,12 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { } match ii.kind { - ast::ImplItemKind::Method(..) => {} + ast::ImplItemKind::Method(ref sig, _) => { + if sig.decl.c_variadic() { + gate_feature_post!(&self, c_variadic, ii.span, + "C-variadic functions are unstable"); + } + } ast::ImplItemKind::OpaqueTy(..) => { gate_feature_post!( &self, diff --git a/src/libsyntax/mut_visit.rs b/src/libsyntax/mut_visit.rs index 43b5df38e143c..80dfe9e5be0ad 100644 --- a/src/libsyntax/mut_visit.rs +++ b/src/libsyntax/mut_visit.rs @@ -717,7 +717,7 @@ pub fn noop_visit_asyncness(asyncness: &mut IsAsync, vis: &mut T) } pub fn noop_visit_fn_decl(decl: &mut P, vis: &mut T) { - let FnDecl { inputs, output, c_variadic: _ } = decl.deref_mut(); + let FnDecl { inputs, output } = decl.deref_mut(); inputs.flat_map_in_place(|param| vis.flat_map_param(param)); match output { FunctionRetTy::Default(span) => vis.visit_span(span), diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index cc582819b6b61..f22fd5ad703d9 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -1194,7 +1194,7 @@ impl<'a> Parser<'a> { } fn parse_fn_params(&mut self, named_params: bool, allow_c_variadic: bool) - -> PResult<'a, (Vec , bool)> { + -> PResult<'a, Vec> { let sp = self.token.span; let mut c_variadic = false; let (params, _): (Vec>, _) = self.parse_paren_comma_seq(|p| { @@ -1218,6 +1218,8 @@ impl<'a> Parser<'a> { let span = p.token.span; p.span_err(span, "`...` must be the last argument of a C-variadic function"); + // FIXME(eddyb) this should probably still push `CVarArgs`. + // Maybe AST validation/HIR lowering should emit the above error? Ok(None) } else { Ok(Some(param)) @@ -1245,7 +1247,7 @@ impl<'a> Parser<'a> { "C-variadic function must be declared with at least one named argument"); } - Ok((params, c_variadic)) + Ok(params) } /// Returns the parsed optional self parameter and whether a self shortcut was used. @@ -1414,7 +1416,6 @@ impl<'a> Parser<'a> { Ok(P(FnDecl { inputs: fn_inputs, output: self.parse_ret_ty(true)?, - c_variadic: false })) } diff --git a/src/libsyntax/parse/parser/expr.rs b/src/libsyntax/parse/parser/expr.rs index c776704b285aa..23674ad589dc5 100644 --- a/src/libsyntax/parse/parser/expr.rs +++ b/src/libsyntax/parse/parser/expr.rs @@ -1176,7 +1176,6 @@ impl<'a> Parser<'a> { Ok(P(FnDecl { inputs: inputs_captures, output, - c_variadic: false })) } diff --git a/src/libsyntax/parse/parser/item.rs b/src/libsyntax/parse/parser/item.rs index 370030d02c717..92b19b73e5719 100644 --- a/src/libsyntax/parse/parser/item.rs +++ b/src/libsyntax/parse/parser/item.rs @@ -1292,13 +1292,12 @@ impl<'a> Parser<'a> { /// Parses the argument list and result type of a function declaration. fn parse_fn_decl(&mut self, allow_c_variadic: bool) -> PResult<'a, P> { - let (args, c_variadic) = self.parse_fn_params(true, allow_c_variadic)?; + let args = self.parse_fn_params(true, allow_c_variadic)?; let ret_ty = self.parse_ret_ty(true)?; Ok(P(FnDecl { inputs: args, output: ret_ty, - c_variadic, })) } diff --git a/src/libsyntax/parse/parser/ty.rs b/src/libsyntax/parse/parser/ty.rs index b4c006ca2b119..c52d3733b5e0a 100644 --- a/src/libsyntax/parse/parser/ty.rs +++ b/src/libsyntax/parse/parser/ty.rs @@ -292,12 +292,11 @@ impl<'a> Parser<'a> { }; self.expect_keyword(kw::Fn)?; - let (inputs, c_variadic) = self.parse_fn_params(false, true)?; + let inputs = self.parse_fn_params(false, true)?; let ret_ty = self.parse_ret_ty(false)?; let decl = P(FnDecl { inputs, output: ret_ty, - c_variadic, }); Ok(TyKind::BareFn(P(BareFnTy { abi, diff --git a/src/libsyntax/print/pprust/tests.rs b/src/libsyntax/print/pprust/tests.rs index 05d78cdd87ec6..faa70edbfa29b 100644 --- a/src/libsyntax/print/pprust/tests.rs +++ b/src/libsyntax/print/pprust/tests.rs @@ -29,7 +29,6 @@ fn test_fun_to_string() { let decl = ast::FnDecl { inputs: Vec::new(), output: ast::FunctionRetTy::Default(syntax_pos::DUMMY_SP), - c_variadic: false }; let generics = ast::Generics::default(); assert_eq!( diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs index e441514e59738..bcda5384204d8 100644 --- a/src/libtest/lib.rs +++ b/src/libtest/lib.rs @@ -1546,6 +1546,7 @@ fn calc_result(desc: &TestDesc, task_result: Result<(), Box>) -> } } } + (&ShouldPanic::Yes, Ok(())) => TrFailedMsg("test did not panic as expected".to_string()), _ if desc.allow_fail => TrAllowedFail, _ => TrFailed, } diff --git a/src/libtest/tests.rs b/src/libtest/tests.rs index 13ac8eb91f411..38ec7bd70930c 100644 --- a/src/libtest/tests.rs +++ b/src/libtest/tests.rs @@ -2,7 +2,7 @@ use super::*; use crate::test::{ filter_tests, parse_opts, run_test, DynTestFn, DynTestName, MetricMap, RunIgnored, - ShouldPanic, StaticTestName, TestDesc, TestDescAndFn, TestOpts, TrFailed, TrFailedMsg, + ShouldPanic, StaticTestName, TestDesc, TestDescAndFn, TestOpts, TrFailedMsg, TrIgnored, TrOk, }; use std::sync::mpsc::channel; @@ -167,7 +167,7 @@ fn test_should_panic_but_succeeds() { let (tx, rx) = channel(); run_test(&TestOpts::new(), false, desc, tx, Concurrent::No); let (_, res, _, _) = rx.recv().unwrap(); - assert!(res == TrFailed); + assert!(res == TrFailedMsg("test did not panic as expected".to_string())); } fn report_time_test_template(report_time: bool) -> Option { diff --git a/src/test/rustdoc/variadic.rs b/src/test/rustdoc/variadic.rs index 5af2aea21fcac..bd8f1775b3d04 100644 --- a/src/test/rustdoc/variadic.rs +++ b/src/test/rustdoc/variadic.rs @@ -1,4 +1,4 @@ extern "C" { - // @has variadic/fn.foo.html //pre 'pub unsafe extern "C" fn foo(x: i32, _: ...)' + // @has variadic/fn.foo.html //pre 'pub unsafe extern "C" fn foo(x: i32, ...)' pub fn foo(x: i32, ...); } diff --git a/src/test/ui-fulldeps/pprust-expr-roundtrip.rs b/src/test/ui-fulldeps/pprust-expr-roundtrip.rs index 784f71a61fd72..d4aff73590734 100644 --- a/src/test/ui-fulldeps/pprust-expr-roundtrip.rs +++ b/src/test/ui-fulldeps/pprust-expr-roundtrip.rs @@ -114,7 +114,6 @@ fn iter_exprs(depth: usize, f: &mut dyn FnMut(P)) { let decl = P(FnDecl { inputs: vec![], output: FunctionRetTy::Default(DUMMY_SP), - c_variadic: false, }); iter_exprs(depth - 1, &mut |e| g( ExprKind::Closure(CaptureBy::Value, diff --git a/src/test/ui/attributes/multiple-invalid.rs b/src/test/ui/attributes/multiple-invalid.rs new file mode 100644 index 0000000000000..ae044eb843bd9 --- /dev/null +++ b/src/test/ui/attributes/multiple-invalid.rs @@ -0,0 +1,10 @@ +// This test checks that all expected errors occur when there are multiple invalid attributes +// on an item. + +#[inline] +//~^ ERROR attribute should be applied to function or closure [E0518] +#[target_feature(enable = "sse2")] +//~^ ERROR attribute should be applied to a function +const FOO: u8 = 0; + +fn main() { } diff --git a/src/test/ui/attributes/multiple-invalid.stderr b/src/test/ui/attributes/multiple-invalid.stderr new file mode 100644 index 0000000000000..9bd29f15dbcca --- /dev/null +++ b/src/test/ui/attributes/multiple-invalid.stderr @@ -0,0 +1,21 @@ +error[E0518]: attribute should be applied to function or closure + --> $DIR/multiple-invalid.rs:4:1 + | +LL | #[inline] + | ^^^^^^^^^ +... +LL | const FOO: u8 = 0; + | ------------------ not a function or closure + +error: attribute should be applied to a function + --> $DIR/multiple-invalid.rs:6:1 + | +LL | #[target_feature(enable = "sse2")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | +LL | const FOO: u8 = 0; + | ------------------ not a function + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0518`. diff --git a/src/test/ui/c-variadic/variadic-ffi-1.stderr b/src/test/ui/c-variadic/variadic-ffi-1.stderr index 695eba2a7ee40..73f72a177bcaa 100644 --- a/src/test/ui/c-variadic/variadic-ffi-1.stderr +++ b/src/test/ui/c-variadic/variadic-ffi-1.stderr @@ -29,7 +29,7 @@ LL | let x: unsafe extern "C" fn(f: isize, x: u8) = foo; | ^^^ expected non-variadic fn, found variadic function | = note: expected type `unsafe extern "C" fn(isize, u8)` - found type `for<'r> unsafe extern "C" fn(isize, u8, std::ffi::VaListImpl<'r>, ...) {foo}` + found type `unsafe extern "C" fn(isize, u8, ...) {foo}` error[E0308]: mismatched types --> $DIR/variadic-ffi-1.rs:20:54 @@ -37,7 +37,7 @@ error[E0308]: mismatched types LL | let y: extern "C" fn(f: isize, x: u8, ...) = bar; | ^^^ expected variadic fn, found non-variadic function | - = note: expected type `for<'r> extern "C" fn(isize, u8, std::ffi::VaListImpl<'r>, ...)` + = note: expected type `extern "C" fn(isize, u8, ...)` found type `extern "C" fn(isize, u8) {bar}` error[E0617]: can't pass `f32` to variadic function diff --git a/src/test/ui/c-variadic/variadic-ffi-4.rs b/src/test/ui/c-variadic/variadic-ffi-4.rs index 4a50d352a5b20..a4d658cef1630 100644 --- a/src/test/ui/c-variadic/variadic-ffi-4.rs +++ b/src/test/ui/c-variadic/variadic-ffi-4.rs @@ -5,11 +5,11 @@ use core::ffi::{VaList, VaListImpl}; pub unsafe extern "C" fn no_escape0<'f>(_: usize, ap: ...) -> VaListImpl<'f> { - ap //~ ERROR: explicit lifetime required + ap //~ ERROR: mismatched types } pub unsafe extern "C" fn no_escape1(_: usize, ap: ...) -> VaListImpl<'static> { - ap //~ ERROR: explicit lifetime required + ap //~ ERROR: mismatched types } pub unsafe extern "C" fn no_escape2(_: usize, ap: ...) { @@ -18,18 +18,15 @@ pub unsafe extern "C" fn no_escape2(_: usize, ap: ...) { pub unsafe extern "C" fn no_escape3(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { *ap0 = ap1; //~ ERROR: mismatched types - //~^ ERROR: mismatched types } pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) { ap0 = &mut ap1; //~^ ERROR: a value of type `core::ffi::VaListImpl<'_>` is borrowed for too long - //~^^ ERROR: mismatched types - //~^^^ ERROR: mismatched types - //~^^^^ ERROR: cannot infer an appropriate lifetime + //~| ERROR: mismatched types + //~| ERROR: cannot infer an appropriate lifetime } pub unsafe extern "C" fn no_escape5(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { *ap0 = ap1.clone(); //~ ERROR: mismatched types - //~^ ERROR: mismatched types } diff --git a/src/test/ui/c-variadic/variadic-ffi-4.stderr b/src/test/ui/c-variadic/variadic-ffi-4.stderr index 7aa510e611304..b986d0c243506 100644 --- a/src/test/ui/c-variadic/variadic-ffi-4.stderr +++ b/src/test/ui/c-variadic/variadic-ffi-4.stderr @@ -1,18 +1,42 @@ -error[E0621]: explicit lifetime required in the type of `ap` +error[E0308]: mismatched types --> $DIR/variadic-ffi-4.rs:8:5 | -LL | pub unsafe extern "C" fn no_escape0<'f>(_: usize, ap: ...) -> VaListImpl<'f> { - | --- help: add explicit lifetime `'f` to the type of `ap`: `core::ffi::VaListImpl<'f>` LL | ap - | ^^ lifetime `'f` required + | ^^ lifetime mismatch + | + = note: expected type `core::ffi::VaListImpl<'f>` + found type `core::ffi::VaListImpl<'_>` +note: the scope of call-site for function at 7:78... + --> $DIR/variadic-ffi-4.rs:7:78 + | +LL | pub unsafe extern "C" fn no_escape0<'f>(_: usize, ap: ...) -> VaListImpl<'f> { + | ______________________________________________________________________________^ +LL | | ap +LL | | } + | |_^ +note: ...does not necessarily outlive the lifetime 'f as defined on the function body at 7:37 + --> $DIR/variadic-ffi-4.rs:7:37 + | +LL | pub unsafe extern "C" fn no_escape0<'f>(_: usize, ap: ...) -> VaListImpl<'f> { + | ^^ -error[E0621]: explicit lifetime required in the type of `ap` +error[E0308]: mismatched types --> $DIR/variadic-ffi-4.rs:12:5 | -LL | pub unsafe extern "C" fn no_escape1(_: usize, ap: ...) -> VaListImpl<'static> { - | --- help: add explicit lifetime `'static` to the type of `ap`: `core::ffi::VaListImpl<'static>` LL | ap - | ^^ lifetime `'static` required + | ^^ lifetime mismatch + | + = note: expected type `core::ffi::VaListImpl<'static>` + found type `core::ffi::VaListImpl<'_>` +note: the scope of call-site for function at 11:79... + --> $DIR/variadic-ffi-4.rs:11:79 + | +LL | pub unsafe extern "C" fn no_escape1(_: usize, ap: ...) -> VaListImpl<'static> { + | _______________________________________________________________________________^ +LL | | ap +LL | | } + | |_^ + = note: ...does not necessarily outlive the static lifetime error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements --> $DIR/variadic-ffi-4.rs:16:33 @@ -47,12 +71,12 @@ LL | *ap0 = ap1; | = note: expected type `core::ffi::VaListImpl<'_>` found type `core::ffi::VaListImpl<'_>` -note: the anonymous lifetime #3 defined on the function body at 19:1... - --> $DIR/variadic-ffi-4.rs:19:1 +note: the scope of call-site for function at 19:87... + --> $DIR/variadic-ffi-4.rs:19:87 | -LL | / pub unsafe extern "C" fn no_escape3(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { +LL | pub unsafe extern "C" fn no_escape3(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { + | _______________________________________________________________________________________^ LL | | *ap0 = ap1; -LL | | LL | | } | |_^ note: ...does not necessarily outlive the anonymous lifetime #2 defined on the function body at 19:1 @@ -60,216 +84,129 @@ note: ...does not necessarily outlive the anonymous lifetime #2 defined on the f | LL | / pub unsafe extern "C" fn no_escape3(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { LL | | *ap0 = ap1; -LL | | -LL | | } - | |_^ - -error[E0308]: mismatched types - --> $DIR/variadic-ffi-4.rs:20:12 - | -LL | *ap0 = ap1; - | ^^^ lifetime mismatch - | - = note: expected type `core::ffi::VaListImpl<'_>` - found type `core::ffi::VaListImpl<'_>` -note: the anonymous lifetime #2 defined on the function body at 19:1... - --> $DIR/variadic-ffi-4.rs:19:1 - | -LL | / pub unsafe extern "C" fn no_escape3(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { -LL | | *ap0 = ap1; -LL | | -LL | | } - | |_^ -note: ...does not necessarily outlive the anonymous lifetime #3 defined on the function body at 19:1 - --> $DIR/variadic-ffi-4.rs:19:1 - | -LL | / pub unsafe extern "C" fn no_escape3(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { -LL | | *ap0 = ap1; -LL | | LL | | } | |_^ error[E0490]: a value of type `core::ffi::VaListImpl<'_>` is borrowed for too long - --> $DIR/variadic-ffi-4.rs:25:11 + --> $DIR/variadic-ffi-4.rs:24:11 | LL | ap0 = &mut ap1; | ^^^^^^^^ | -note: the type is valid for the anonymous lifetime #1 defined on the function body at 24:1 - --> $DIR/variadic-ffi-4.rs:24:1 - | -LL | / pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) { -LL | | ap0 = &mut ap1; -LL | | -LL | | -LL | | -LL | | -LL | | } - | |_^ -note: but the borrow lasts for the anonymous lifetime #3 defined on the function body at 24:1 - --> $DIR/variadic-ffi-4.rs:24:1 - | -LL | / pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) { -LL | | ap0 = &mut ap1; -LL | | -LL | | -LL | | -LL | | -LL | | } - | |_^ - -error[E0308]: mismatched types - --> $DIR/variadic-ffi-4.rs:25:11 - | -LL | ap0 = &mut ap1; - | ^^^^^^^^ lifetime mismatch - | - = note: expected type `&mut core::ffi::VaListImpl<'_>` - found type `&mut core::ffi::VaListImpl<'_>` -note: the anonymous lifetime #3 defined on the function body at 24:1... - --> $DIR/variadic-ffi-4.rs:24:1 +note: the type is valid for the anonymous lifetime #1 defined on the function body at 23:1 + --> $DIR/variadic-ffi-4.rs:23:1 | LL | / pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) { LL | | ap0 = &mut ap1; LL | | LL | | LL | | -LL | | LL | | } | |_^ -note: ...does not necessarily outlive the anonymous lifetime #2 defined on the function body at 24:1 - --> $DIR/variadic-ffi-4.rs:24:1 +note: but the borrow lasts for the scope of call-site for function at 23:83 + --> $DIR/variadic-ffi-4.rs:23:83 | -LL | / pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) { +LL | pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) { + | ___________________________________________________________________________________^ LL | | ap0 = &mut ap1; LL | | LL | | LL | | -LL | | LL | | } | |_^ error[E0308]: mismatched types - --> $DIR/variadic-ffi-4.rs:25:11 + --> $DIR/variadic-ffi-4.rs:24:11 | LL | ap0 = &mut ap1; | ^^^^^^^^ lifetime mismatch | = note: expected type `&mut core::ffi::VaListImpl<'_>` found type `&mut core::ffi::VaListImpl<'_>` -note: the anonymous lifetime #2 defined on the function body at 24:1... - --> $DIR/variadic-ffi-4.rs:24:1 +note: the scope of call-site for function at 23:83... + --> $DIR/variadic-ffi-4.rs:23:83 | -LL | / pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) { +LL | pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) { + | ___________________________________________________________________________________^ LL | | ap0 = &mut ap1; LL | | LL | | LL | | -LL | | LL | | } | |_^ -note: ...does not necessarily outlive the anonymous lifetime #3 defined on the function body at 24:1 - --> $DIR/variadic-ffi-4.rs:24:1 +note: ...does not necessarily outlive the anonymous lifetime #2 defined on the function body at 23:1 + --> $DIR/variadic-ffi-4.rs:23:1 | LL | / pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) { LL | | ap0 = &mut ap1; LL | | LL | | LL | | -LL | | LL | | } | |_^ error[E0495]: cannot infer an appropriate lifetime for borrow expression due to conflicting requirements - --> $DIR/variadic-ffi-4.rs:25:11 + --> $DIR/variadic-ffi-4.rs:24:11 | LL | ap0 = &mut ap1; | ^^^^^^^^ | -note: first, the lifetime cannot outlive the anonymous lifetime #3 defined on the function body at 24:1... - --> $DIR/variadic-ffi-4.rs:24:1 +note: first, the lifetime cannot outlive the scope of call-site for function at 23:83... + --> $DIR/variadic-ffi-4.rs:23:83 | -LL | / pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) { +LL | pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) { + | ___________________________________________________________________________________^ LL | | ap0 = &mut ap1; LL | | LL | | LL | | -LL | | LL | | } | |_^ note: ...so that the type `core::ffi::VaListImpl<'_>` is not borrowed for too long - --> $DIR/variadic-ffi-4.rs:25:11 + --> $DIR/variadic-ffi-4.rs:24:11 | LL | ap0 = &mut ap1; | ^^^^^^^^ -note: but, the lifetime must be valid for the anonymous lifetime #1 defined on the function body at 24:1... - --> $DIR/variadic-ffi-4.rs:24:1 +note: but, the lifetime must be valid for the anonymous lifetime #1 defined on the function body at 23:1... + --> $DIR/variadic-ffi-4.rs:23:1 | LL | / pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) { LL | | ap0 = &mut ap1; LL | | LL | | LL | | -LL | | LL | | } | |_^ note: ...so that reference does not outlive borrowed content - --> $DIR/variadic-ffi-4.rs:25:11 + --> $DIR/variadic-ffi-4.rs:24:11 | LL | ap0 = &mut ap1; | ^^^^^^^^ error[E0308]: mismatched types - --> $DIR/variadic-ffi-4.rs:33:12 + --> $DIR/variadic-ffi-4.rs:31:12 | LL | *ap0 = ap1.clone(); | ^^^^^^^^^^^ lifetime mismatch | = note: expected type `core::ffi::VaListImpl<'_>` found type `core::ffi::VaListImpl<'_>` -note: the anonymous lifetime #3 defined on the function body at 32:1... - --> $DIR/variadic-ffi-4.rs:32:1 +note: the scope of call-site for function at 30:87... + --> $DIR/variadic-ffi-4.rs:30:87 | -LL | / pub unsafe extern "C" fn no_escape5(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { +LL | pub unsafe extern "C" fn no_escape5(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { + | _______________________________________________________________________________________^ LL | | *ap0 = ap1.clone(); -LL | | LL | | } | |_^ -note: ...does not necessarily outlive the anonymous lifetime #2 defined on the function body at 32:1 - --> $DIR/variadic-ffi-4.rs:32:1 +note: ...does not necessarily outlive the anonymous lifetime #2 defined on the function body at 30:1 + --> $DIR/variadic-ffi-4.rs:30:1 | LL | / pub unsafe extern "C" fn no_escape5(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { LL | | *ap0 = ap1.clone(); -LL | | -LL | | } - | |_^ - -error[E0308]: mismatched types - --> $DIR/variadic-ffi-4.rs:33:12 - | -LL | *ap0 = ap1.clone(); - | ^^^^^^^^^^^ lifetime mismatch - | - = note: expected type `core::ffi::VaListImpl<'_>` - found type `core::ffi::VaListImpl<'_>` -note: the anonymous lifetime #2 defined on the function body at 32:1... - --> $DIR/variadic-ffi-4.rs:32:1 - | -LL | / pub unsafe extern "C" fn no_escape5(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { -LL | | *ap0 = ap1.clone(); -LL | | -LL | | } - | |_^ -note: ...does not necessarily outlive the anonymous lifetime #3 defined on the function body at 32:1 - --> $DIR/variadic-ffi-4.rs:32:1 - | -LL | / pub unsafe extern "C" fn no_escape5(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { -LL | | *ap0 = ap1.clone(); -LL | | LL | | } | |_^ -error: aborting due to 11 previous errors +error: aborting due to 8 previous errors -Some errors have detailed explanations: E0308, E0621. -For more information about an error, try `rustc --explain E0308`. +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/error-codes/E0617.rs b/src/test/ui/error-codes/E0617.rs index 439c3db576864..c832e09ac1118 100644 --- a/src/test/ui/error-codes/E0617.rs +++ b/src/test/ui/error-codes/E0617.rs @@ -1,5 +1,3 @@ -// ignore-tidy-linelength - extern { fn printf(c: *const i8, ...); } @@ -22,7 +20,7 @@ fn main() { //~^ ERROR can't pass `u16` to variadic function //~| HELP cast the value to `c_uint` printf(::std::ptr::null(), printf); - //~^ ERROR can't pass `for<'r> unsafe extern "C" fn(*const i8, std::ffi::VaListImpl<'r>, ...) {printf}` to variadic function - //~| HELP cast the value to `for<'r> unsafe extern "C" fn(*const i8, std::ffi::VaListImpl<'r>, ...)` + //~^ ERROR can't pass `unsafe extern "C" fn(*const i8, ...) {printf}` to variadic function + //~| HELP cast the value to `unsafe extern "C" fn(*const i8, ...)` } } diff --git a/src/test/ui/error-codes/E0617.stderr b/src/test/ui/error-codes/E0617.stderr index d866320bbcdf7..7c4df099d0dd1 100644 --- a/src/test/ui/error-codes/E0617.stderr +++ b/src/test/ui/error-codes/E0617.stderr @@ -1,42 +1,42 @@ error[E0617]: can't pass `f32` to variadic function - --> $DIR/E0617.rs:9:36 + --> $DIR/E0617.rs:7:36 | LL | printf(::std::ptr::null(), 0f32); | ^^^^ help: cast the value to `c_double`: `0f32 as c_double` error[E0617]: can't pass `i8` to variadic function - --> $DIR/E0617.rs:12:36 + --> $DIR/E0617.rs:10:36 | LL | printf(::std::ptr::null(), 0i8); | ^^^ help: cast the value to `c_int`: `0i8 as c_int` error[E0617]: can't pass `i16` to variadic function - --> $DIR/E0617.rs:15:36 + --> $DIR/E0617.rs:13:36 | LL | printf(::std::ptr::null(), 0i16); | ^^^^ help: cast the value to `c_int`: `0i16 as c_int` error[E0617]: can't pass `u8` to variadic function - --> $DIR/E0617.rs:18:36 + --> $DIR/E0617.rs:16:36 | LL | printf(::std::ptr::null(), 0u8); | ^^^ help: cast the value to `c_uint`: `0u8 as c_uint` error[E0617]: can't pass `u16` to variadic function - --> $DIR/E0617.rs:21:36 + --> $DIR/E0617.rs:19:36 | LL | printf(::std::ptr::null(), 0u16); | ^^^^ help: cast the value to `c_uint`: `0u16 as c_uint` -error[E0617]: can't pass `for<'r> unsafe extern "C" fn(*const i8, std::ffi::VaListImpl<'r>, ...) {printf}` to variadic function - --> $DIR/E0617.rs:24:36 +error[E0617]: can't pass `unsafe extern "C" fn(*const i8, ...) {printf}` to variadic function + --> $DIR/E0617.rs:22:36 | LL | printf(::std::ptr::null(), printf); | ^^^^^^ -help: cast the value to `for<'r> unsafe extern "C" fn(*const i8, std::ffi::VaListImpl<'r>, ...)` +help: cast the value to `unsafe extern "C" fn(*const i8, ...)` | -LL | printf(::std::ptr::null(), printf as for<'r> unsafe extern "C" fn(*const i8, std::ffi::VaListImpl<'r>, ...)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | printf(::std::ptr::null(), printf as unsafe extern "C" fn(*const i8, ...)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 6 previous errors diff --git a/src/test/ui/generator/no-parameters-on-generators.rs b/src/test/ui/generator/no-parameters-on-generators.rs index a2632a4bd7d84..6b5a557933953 100644 --- a/src/test/ui/generator/no-parameters-on-generators.rs +++ b/src/test/ui/generator/no-parameters-on-generators.rs @@ -2,6 +2,7 @@ fn main() { let gen = |start| { //~ ERROR generators cannot have explicit parameters + //~^ ERROR type inside generator must be known in this context yield; }; } diff --git a/src/test/ui/generator/no-parameters-on-generators.stderr b/src/test/ui/generator/no-parameters-on-generators.stderr index 41862f2b0704b..5e8e043a391ce 100644 --- a/src/test/ui/generator/no-parameters-on-generators.stderr +++ b/src/test/ui/generator/no-parameters-on-generators.stderr @@ -4,5 +4,18 @@ error[E0628]: generators cannot have explicit parameters LL | let gen = |start| { | ^^^^^^^ -error: aborting due to previous error +error[E0698]: type inside generator must be known in this context + --> $DIR/no-parameters-on-generators.rs:4:16 + | +LL | let gen = |start| { + | ^^^^^ cannot infer type + | +note: the type is part of the generator because of this `yield` + --> $DIR/no-parameters-on-generators.rs:6:9 + | +LL | yield; + | ^^^^^ + +error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0698`. diff --git a/src/test/ui/struct-literal-variant-in-if.stderr b/src/test/ui/struct-literal-variant-in-if.stderr index f91b9d7dce60f..85cbc787bc2db 100644 --- a/src/test/ui/struct-literal-variant-in-if.stderr +++ b/src/test/ui/struct-literal-variant-in-if.stderr @@ -49,9 +49,6 @@ LL | if x == E::V { field } {} error[E0308]: mismatched types --> $DIR/struct-literal-variant-in-if.rs:10:20 | -LL | fn test_E(x: E) { - | - help: try adding a return type: `-> bool` -LL | let field = true; LL | if x == E::V { field } {} | ^^^^^ expected (), found bool | diff --git a/src/test/ui/symbol-names/impl1.legacy.stderr b/src/test/ui/symbol-names/impl1.legacy.stderr index c1d22a919d900..a3d966bb0b035 100644 --- a/src/test/ui/symbol-names/impl1.legacy.stderr +++ b/src/test/ui/symbol-names/impl1.legacy.stderr @@ -46,26 +46,26 @@ error: def-path(bar::::baz) LL | #[rustc_def_path] | ^^^^^^^^^^^^^^^^^ -error: symbol-name(_ZN198_$LT$$u5b$$RF$dyn$u20$impl1..Foo$u2b$Assoc$u20$$u3d$$u20$extern$u20$$u22$C$u22$$u20$fn$LP$$RF$u8$RP$$u2b$impl1..AutoTrait$u3b$$u20$_$u5d$$u20$as$u20$impl1..main..$u7b$$u7b$closure$u7d$$u7d$..Bar$GT$6method17h6f205aef6a8ccc7bE) - --> $DIR/impl1.rs:63:13 +error: symbol-name(_ZN209_$LT$$u5b$$RF$dyn$u20$impl1..Foo$u2b$Assoc$u20$$u3d$$u20$extern$u20$$u22$C$u22$$u20$fn$LP$$RF$u8$C$$u20$...$RP$$u2b$impl1..AutoTrait$u3b$$u20$_$u5d$$u20$as$u20$impl1..main..$u7b$$u7b$closure$u7d$$u7d$..Bar$GT$6method17h059bf53000885489E) + --> $DIR/impl1.rs:61:13 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ -error: demangling(<[&dyn impl1::Foo+Assoc = extern "C" fn(&u8)+impl1::AutoTrait; _] as impl1::main::{{closure}}::Bar>::method::h6f205aef6a8ccc7b) - --> $DIR/impl1.rs:63:13 +error: demangling(<[&dyn impl1::Foo+Assoc = extern "C" fn(&u8, ::.)+impl1::AutoTrait; _] as impl1::main::{{closure}}::Bar>::method::h059bf53000885489) + --> $DIR/impl1.rs:61:13 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ -error: demangling-alt(<[&dyn impl1::Foo+Assoc = extern "C" fn(&u8)+impl1::AutoTrait; _] as impl1::main::{{closure}}::Bar>::method) - --> $DIR/impl1.rs:63:13 +error: demangling-alt(<[&dyn impl1::Foo+Assoc = extern "C" fn(&u8, ::.)+impl1::AutoTrait; _] as impl1::main::{{closure}}::Bar>::method) + --> $DIR/impl1.rs:61:13 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ -error: def-path(<[&dyn Foo extern "C" fn(&'r u8)> + AutoTrait; _] as main::{{closure}}#1::Bar>::method) - --> $DIR/impl1.rs:70:13 +error: def-path(<[&dyn Foo extern "C" fn(&'r u8, ...)> + AutoTrait; _] as main::{{closure}}#1::Bar>::method) + --> $DIR/impl1.rs:68:13 | LL | #[rustc_def_path] | ^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/symbol-names/impl1.rs b/src/test/ui/symbol-names/impl1.rs index 137b72dcd9c44..add0d10ea6cb0 100644 --- a/src/test/ui/symbol-names/impl1.rs +++ b/src/test/ui/symbol-names/impl1.rs @@ -57,19 +57,17 @@ fn main() { } // Test type mangling, by putting them in an `impl` header. - // FIXME(eddyb) test C varargs when `core::ffi::VaListImpl` stops leaking into the signature - // (which is a problem because `core` has an unpredictable hash) - see also #44930. - impl Bar for [&'_ (dyn Foo + AutoTrait); 3] { + impl Bar for [&'_ (dyn Foo + AutoTrait); 3] { #[rustc_symbol_name] - //[legacy]~^ ERROR symbol-name(_ZN198_$LT$$u5b$$RF$dyn$u20$impl1..Foo$u2b$Assoc$u20$$u3d$$u20$extern$u20$$u22$C$u22$$u20$fn$LP$$RF$u8$RP$$u2b$impl1..AutoTrait$u3b$$u20$_$u5d$$u20$as$u20$impl1..main..$u7b$$u7b$closure$u7d$$u7d$..Bar$GT$6method - //[legacy]~| ERROR demangling(<[&dyn impl1::Foo+Assoc = extern "C" fn(&u8)+impl1::AutoTrait; _] as impl1::main::{{closure}}::Bar>::method - //[legacy]~| ERROR demangling-alt(<[&dyn impl1::Foo+Assoc = extern "C" fn(&u8)+impl1::AutoTrait; _] as impl1::main::{{closure}}::Bar>::method) - //[v0]~^^^^ ERROR symbol-name(_RNvXNCNvCs4fqI2P2rA04_5impl14mains_0ARDNtB6_3Foop5AssocFG_KCRL0_hEuNtB6_9AutoTraitEL_j3_NtB2_3Bar6method) - //[v0]~| ERROR demangling(<[&dyn impl1[317d481089b8c8fe]::Foo extern "C" fn(&'a u8)> + impl1[317d481089b8c8fe]::AutoTrait; 3: usize] as impl1[317d481089b8c8fe]::main::{closure#1}::Bar>::method) - //[v0]~| ERROR demangling-alt(<[&dyn impl1::Foo extern "C" fn(&'a u8)> + impl1::AutoTrait; 3] as impl1::main::{closure#1}::Bar>::method) + //[legacy]~^ ERROR symbol-name(_ZN209_$LT$$u5b$$RF$dyn$u20$impl1..Foo$u2b$Assoc$u20$$u3d$$u20$extern$u20$$u22$C$u22$$u20$fn$LP$$RF$u8$C$$u20$...$RP$$u2b$impl1..AutoTrait$u3b$$u20$_$u5d$$u20$as$u20$impl1..main..$u7b$$u7b$closure$u7d$$u7d$..Bar$GT$6method + //[legacy]~| ERROR demangling(<[&dyn impl1::Foo+Assoc = extern "C" fn(&u8, ::.)+impl1::AutoTrait; _] as impl1::main::{{closure}}::Bar>::method + //[legacy]~| ERROR demangling-alt(<[&dyn impl1::Foo+Assoc = extern "C" fn(&u8, ::.)+impl1::AutoTrait; _] as impl1::main::{{closure}}::Bar>::method) + //[v0]~^^^^ ERROR symbol-name(_RNvXNCNvCs4fqI2P2rA04_5impl14mains_0ARDNtB6_3Foop5AssocFG_KCRL0_hvEuNtB6_9AutoTraitEL_j3_NtB2_3Bar6method) + //[v0]~| ERROR demangling(<[&dyn impl1[317d481089b8c8fe]::Foo extern "C" fn(&'a u8, ...)> + impl1[317d481089b8c8fe]::AutoTrait; 3: usize] as impl1[317d481089b8c8fe]::main::{closure#1}::Bar>::method) + //[v0]~| ERROR demangling-alt(<[&dyn impl1::Foo extern "C" fn(&'a u8, ...)> + impl1::AutoTrait; 3] as impl1::main::{closure#1}::Bar>::method) #[rustc_def_path] - //[legacy]~^ ERROR def-path(<[&dyn Foo extern "C" fn(&'r u8)> + AutoTrait; _] as main::{{closure}}#1::Bar>::method) - //[v0]~^^ ERROR def-path(<[&dyn Foo extern "C" fn(&'r u8)> + AutoTrait; _] as main::{{closure}}#1::Bar>::method) + //[legacy]~^ ERROR def-path(<[&dyn Foo extern "C" fn(&'r u8, ...)> + AutoTrait; _] as main::{{closure}}#1::Bar>::method) + //[v0]~^^ ERROR def-path(<[&dyn Foo extern "C" fn(&'r u8, ...)> + AutoTrait; _] as main::{{closure}}#1::Bar>::method) fn method(&self) {} } }; diff --git a/src/test/ui/symbol-names/impl1.v0.stderr b/src/test/ui/symbol-names/impl1.v0.stderr index e024799df867c..01fe39ddf6cf9 100644 --- a/src/test/ui/symbol-names/impl1.v0.stderr +++ b/src/test/ui/symbol-names/impl1.v0.stderr @@ -46,26 +46,26 @@ error: def-path(bar::::baz) LL | #[rustc_def_path] | ^^^^^^^^^^^^^^^^^ -error: symbol-name(_RNvXNCNvCs4fqI2P2rA04_5impl14mains_0ARDNtB6_3Foop5AssocFG_KCRL0_hEuNtB6_9AutoTraitEL_j3_NtB2_3Bar6method) - --> $DIR/impl1.rs:63:13 +error: symbol-name(_RNvXNCNvCs4fqI2P2rA04_5impl14mains_0ARDNtB6_3Foop5AssocFG_KCRL0_hvEuNtB6_9AutoTraitEL_j3_NtB2_3Bar6method) + --> $DIR/impl1.rs:61:13 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ -error: demangling(<[&dyn impl1[317d481089b8c8fe]::Foo extern "C" fn(&'a u8)> + impl1[317d481089b8c8fe]::AutoTrait; 3: usize] as impl1[317d481089b8c8fe]::main::{closure#1}::Bar>::method) - --> $DIR/impl1.rs:63:13 +error: demangling(<[&dyn impl1[317d481089b8c8fe]::Foo extern "C" fn(&'a u8, ...)> + impl1[317d481089b8c8fe]::AutoTrait; 3: usize] as impl1[317d481089b8c8fe]::main::{closure#1}::Bar>::method) + --> $DIR/impl1.rs:61:13 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ -error: demangling-alt(<[&dyn impl1::Foo extern "C" fn(&'a u8)> + impl1::AutoTrait; 3] as impl1::main::{closure#1}::Bar>::method) - --> $DIR/impl1.rs:63:13 +error: demangling-alt(<[&dyn impl1::Foo extern "C" fn(&'a u8, ...)> + impl1::AutoTrait; 3] as impl1::main::{closure#1}::Bar>::method) + --> $DIR/impl1.rs:61:13 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ -error: def-path(<[&dyn Foo extern "C" fn(&'r u8)> + AutoTrait; _] as main::{{closure}}#1::Bar>::method) - --> $DIR/impl1.rs:70:13 +error: def-path(<[&dyn Foo extern "C" fn(&'r u8, ...)> + AutoTrait; _] as main::{{closure}}#1::Bar>::method) + --> $DIR/impl1.rs:68:13 | LL | #[rustc_def_path] | ^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/target-feature-wrong.stderr b/src/test/ui/target-feature-wrong.stderr deleted file mode 100644 index 47ca5a5ca478c..0000000000000 --- a/src/test/ui/target-feature-wrong.stderr +++ /dev/null @@ -1,50 +0,0 @@ -error: malformed `target_feature` attribute input - --> $DIR/target-feature-wrong.rs:16:1 - | -LL | #[target_feature = "+sse2"] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[target_feature(enable = "name")]` - -error: the feature named `foo` is not valid for this target - --> $DIR/target-feature-wrong.rs:18:18 - | -LL | #[target_feature(enable = "foo")] - | ^^^^^^^^^^^^^^ `foo` is not valid for this target - -error: malformed `target_feature` attribute input - --> $DIR/target-feature-wrong.rs:21:18 - | -LL | #[target_feature(bar)] - | ^^^ help: must be of the form: `enable = ".."` - -error: malformed `target_feature` attribute input - --> $DIR/target-feature-wrong.rs:23:18 - | -LL | #[target_feature(disable = "baz")] - | ^^^^^^^^^^^^^^^ help: must be of the form: `enable = ".."` - -error: `#[target_feature(..)]` can only be applied to `unsafe` functions - --> $DIR/target-feature-wrong.rs:27:1 - | -LL | #[target_feature(enable = "sse2")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can only be applied to `unsafe` functions -... -LL | fn bar() {} - | ----------- not an `unsafe` function - -error: attribute should be applied to a function - --> $DIR/target-feature-wrong.rs:33:1 - | -LL | #[target_feature(enable = "sse2")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | -LL | mod another {} - | -------------- not a function - -error: cannot use `#[inline(always)]` with `#[target_feature]` - --> $DIR/target-feature-wrong.rs:38:1 - | -LL | #[inline(always)] - | ^^^^^^^^^^^^^^^^^ - -error: aborting due to 7 previous errors - diff --git a/src/test/ui/target-feature-gate.rs b/src/test/ui/target-feature/gate.rs similarity index 100% rename from src/test/ui/target-feature-gate.rs rename to src/test/ui/target-feature/gate.rs diff --git a/src/test/ui/target-feature-gate.stderr b/src/test/ui/target-feature/gate.stderr similarity index 91% rename from src/test/ui/target-feature-gate.stderr rename to src/test/ui/target-feature/gate.stderr index 9f17110b6d874..05dbc6e90adc8 100644 --- a/src/test/ui/target-feature-gate.stderr +++ b/src/test/ui/target-feature/gate.stderr @@ -1,5 +1,5 @@ error[E0658]: the target feature `avx512bw` is currently unstable - --> $DIR/target-feature-gate.rs:30:18 + --> $DIR/gate.rs:30:18 | LL | #[target_feature(enable = "avx512bw")] | ^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/target-feature-wrong.rs b/src/test/ui/target-feature/invalid-attribute.rs similarity index 62% rename from src/test/ui/target-feature-wrong.rs rename to src/test/ui/target-feature/invalid-attribute.rs index 646a98763e1b3..46680336632f9 100644 --- a/src/test/ui/target-feature-wrong.rs +++ b/src/test/ui/target-feature/invalid-attribute.rs @@ -35,6 +35,31 @@ fn bar() {} mod another {} //~^ NOTE not a function +#[target_feature(enable = "sse2")] +//~^ ERROR attribute should be applied to a function +const FOO: usize = 7; +//~^ NOTE not a function + +#[target_feature(enable = "sse2")] +//~^ ERROR attribute should be applied to a function +struct Foo; +//~^ NOTE not a function + +#[target_feature(enable = "sse2")] +//~^ ERROR attribute should be applied to a function +enum Bar { } +//~^ NOTE not a function + +#[target_feature(enable = "sse2")] +//~^ ERROR attribute should be applied to a function +union Qux { f1: u16, f2: u16 } +//~^ NOTE not a function + +#[target_feature(enable = "sse2")] +//~^ ERROR attribute should be applied to a function +trait Baz { } +//~^ NOTE not a function + #[inline(always)] //~^ ERROR: cannot use `#[inline(always)]` #[target_feature(enable = "sse2")] diff --git a/src/test/ui/target-feature/invalid-attribute.stderr b/src/test/ui/target-feature/invalid-attribute.stderr new file mode 100644 index 0000000000000..abfe5dd219770 --- /dev/null +++ b/src/test/ui/target-feature/invalid-attribute.stderr @@ -0,0 +1,95 @@ +error: malformed `target_feature` attribute input + --> $DIR/invalid-attribute.rs:16:1 + | +LL | #[target_feature = "+sse2"] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[target_feature(enable = "name")]` + +error: the feature named `foo` is not valid for this target + --> $DIR/invalid-attribute.rs:18:18 + | +LL | #[target_feature(enable = "foo")] + | ^^^^^^^^^^^^^^ `foo` is not valid for this target + +error: malformed `target_feature` attribute input + --> $DIR/invalid-attribute.rs:21:18 + | +LL | #[target_feature(bar)] + | ^^^ help: must be of the form: `enable = ".."` + +error: malformed `target_feature` attribute input + --> $DIR/invalid-attribute.rs:23:18 + | +LL | #[target_feature(disable = "baz")] + | ^^^^^^^^^^^^^^^ help: must be of the form: `enable = ".."` + +error: `#[target_feature(..)]` can only be applied to `unsafe` functions + --> $DIR/invalid-attribute.rs:27:1 + | +LL | #[target_feature(enable = "sse2")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can only be applied to `unsafe` functions +... +LL | fn bar() {} + | ----------- not an `unsafe` function + +error: attribute should be applied to a function + --> $DIR/invalid-attribute.rs:33:1 + | +LL | #[target_feature(enable = "sse2")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | +LL | mod another {} + | -------------- not a function + +error: attribute should be applied to a function + --> $DIR/invalid-attribute.rs:38:1 + | +LL | #[target_feature(enable = "sse2")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | +LL | const FOO: usize = 7; + | --------------------- not a function + +error: attribute should be applied to a function + --> $DIR/invalid-attribute.rs:43:1 + | +LL | #[target_feature(enable = "sse2")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | +LL | struct Foo; + | ----------- not a function + +error: attribute should be applied to a function + --> $DIR/invalid-attribute.rs:48:1 + | +LL | #[target_feature(enable = "sse2")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | +LL | enum Bar { } + | ------------ not a function + +error: attribute should be applied to a function + --> $DIR/invalid-attribute.rs:53:1 + | +LL | #[target_feature(enable = "sse2")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | +LL | union Qux { f1: u16, f2: u16 } + | ------------------------------ not a function + +error: attribute should be applied to a function + --> $DIR/invalid-attribute.rs:58:1 + | +LL | #[target_feature(enable = "sse2")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | +LL | trait Baz { } + | ------------- not a function + +error: cannot use `#[inline(always)]` with `#[target_feature]` + --> $DIR/invalid-attribute.rs:63:1 + | +LL | #[inline(always)] + | ^^^^^^^^^^^^^^^^^ + +error: aborting due to 12 previous errors + diff --git a/src/tools/compiletest/Cargo.toml b/src/tools/compiletest/Cargo.toml index 745233c151cd6..80ef8dd662637 100644 --- a/src/tools/compiletest/Cargo.toml +++ b/src/tools/compiletest/Cargo.toml @@ -6,7 +6,7 @@ edition = "2018" [dependencies] diff = "0.1.10" -env_logger = { version = "0.6", default-features = false } +env_logger = { version = "0.7", default-features = false } getopts = "0.2" log = "0.4" regex = "1.0"